|
|
|
@ -44,6 +44,9 @@ import Text.XML.Unresolved(InvalidEventStream(..)) |
|
|
|
import Control.Monad.Trans.Resource as R |
|
|
|
import Control.Monad.Trans.Resource as R |
|
|
|
import Network.Xmpp.Utilities |
|
|
|
import Network.Xmpp.Utilities |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import Network.DNS hiding (encode, lookup) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- import Text.XML.Stream.Elements |
|
|
|
-- import Text.XML.Stream.Elements |
|
|
|
|
|
|
|
|
|
|
|
mbl :: Maybe [a] -> [a] |
|
|
|
mbl :: Maybe [a] -> [a] |
|
|
|
@ -248,17 +251,43 @@ streamS expectedTo = do |
|
|
|
Just r -> streamUnpickleElem xpStreamFeatures r |
|
|
|
Just r -> streamUnpickleElem xpStreamFeatures r |
|
|
|
|
|
|
|
|
|
|
|
-- | Connects to the XMPP server and opens the XMPP stream against the given |
|
|
|
-- | Connects to the XMPP server and opens the XMPP stream against the given |
|
|
|
-- host name, port, and realm. |
|
|
|
-- realm. |
|
|
|
openStream :: HostName -> PortID -> Text -> StreamConfiguration -> IO (Either XmppFailure (TMVar Stream)) |
|
|
|
openStream :: Text -> StreamConfiguration -> IO (Either XmppFailure (TMVar Stream)) |
|
|
|
openStream address port hostname config = do |
|
|
|
openStream realm config = runErrorT $ do |
|
|
|
stream <- connectTcp address port hostname config |
|
|
|
(address, port) <- case hardcodedTcpDetails config of |
|
|
|
case stream of |
|
|
|
Nothing -> dnsLookup realm (resolvConf config) |
|
|
|
Right stream' -> do |
|
|
|
Just (address, port) -> return (address, port) |
|
|
|
result <- withStream startStream stream' |
|
|
|
stream' <- connectTcp (Text.unpack address) port realm config |
|
|
|
liftIO $ print result |
|
|
|
result <- liftIO $ withStream startStream stream' |
|
|
|
return $ Right stream' |
|
|
|
return stream' |
|
|
|
Left e -> do |
|
|
|
|
|
|
|
return $ Left e |
|
|
|
dnsLookup :: Text -> ResolvConf -> ErrorT XmppFailure IO (Text, PortID) |
|
|
|
|
|
|
|
dnsLookup realm resolvConf = ErrorT $ do |
|
|
|
|
|
|
|
resolvSeed <- makeResolvSeed resolvConf |
|
|
|
|
|
|
|
withResolver resolvSeed $ \resolver -> do |
|
|
|
|
|
|
|
debugM "Pontarius.Xmpp" "Performing SRV lookup..." |
|
|
|
|
|
|
|
srvResult <- lookupSRV resolver (BSC8.pack $ Text.unpack realm) |
|
|
|
|
|
|
|
debugM "Pontarius.Xmpp" $ "SRV result: " ++ (show srvResult) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- TODO: Use SRV result. Is list always empty? |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- TODO: How to connect to IPv6 address? Doesn't seem to work |
|
|
|
|
|
|
|
-- with connectTo. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- aaaaResult <- lookupAAAA resolver (BSC8.pack $ Text.unpack realm) |
|
|
|
|
|
|
|
-- debugM "Pontarius.Xmpp" $ "AAAA result: " ++ (show aaaaResult) |
|
|
|
|
|
|
|
-- if isJust aaaaResult && (Prelude.length $ fromJust aaaaResult) > 0 |
|
|
|
|
|
|
|
-- then return $ Right (Text.pack $ show $ Prelude.head $ fromJust aaaaResult, (PortNumber 5222)) |
|
|
|
|
|
|
|
-- else |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
do |
|
|
|
|
|
|
|
aResult <- lookupA resolver (BSC8.pack $ Text.unpack realm) |
|
|
|
|
|
|
|
debugM "Pontarius.Xmpp" $ "A result: " ++ (show aResult) |
|
|
|
|
|
|
|
case aResult of |
|
|
|
|
|
|
|
Nothing -> return $ Left DnsLookupFailed |
|
|
|
|
|
|
|
Just r | Prelude.length r == 0 -> return $ Left DnsLookupFailed |
|
|
|
|
|
|
|
-- Is it safe to ignore tail of A records? |
|
|
|
|
|
|
|
| otherwise -> return $ Right (Text.pack $ show $ Prelude.head r, (PortNumber 5222)) |
|
|
|
|
|
|
|
|
|
|
|
-- | Send "</stream:stream>" and wait for the server to finish processing and to |
|
|
|
-- | Send "</stream:stream>" and wait for the server to finish processing and to |
|
|
|
-- close the connection. Any remaining elements from the server are returned. |
|
|
|
-- close the connection. Any remaining elements from the server are returned. |
|
|
|
@ -396,14 +425,14 @@ xmppNoStream = Stream { |
|
|
|
, streamId = Nothing |
|
|
|
, streamId = Nothing |
|
|
|
, streamLang = Nothing |
|
|
|
, streamLang = Nothing |
|
|
|
, streamJid = Nothing |
|
|
|
, streamJid = Nothing |
|
|
|
, streamConfiguration = StreamConfiguration Nothing Nothing |
|
|
|
, streamConfiguration = def |
|
|
|
} |
|
|
|
} |
|
|
|
where |
|
|
|
where |
|
|
|
zeroSource :: Source IO output |
|
|
|
zeroSource :: Source IO output |
|
|
|
zeroSource = liftIO . ExL.throwIO $ XmppOtherFailure "zeroSource" |
|
|
|
zeroSource = liftIO . ExL.throwIO $ XmppOtherFailure "zeroSource" |
|
|
|
|
|
|
|
|
|
|
|
connectTcp :: HostName -> PortID -> Text -> StreamConfiguration -> IO (Either XmppFailure (TMVar Stream)) |
|
|
|
connectTcp :: HostName -> PortID -> Text -> StreamConfiguration -> ErrorT XmppFailure IO (TMVar Stream) |
|
|
|
connectTcp host port hostname config = do |
|
|
|
connectTcp host port hostname config = ErrorT $ do |
|
|
|
let PortNumber portNumber = port |
|
|
|
let PortNumber portNumber = port |
|
|
|
debugM "Pontarius.Xmpp" $ "Connecting to " ++ host ++ " on port " ++ |
|
|
|
debugM "Pontarius.Xmpp" $ "Connecting to " ++ host ++ " on port " ++ |
|
|
|
(show portNumber) ++ " through the realm " ++ (Text.unpack hostname) ++ "." |
|
|
|
(show portNumber) ++ " through the realm " ++ (Text.unpack hostname) ++ "." |
|
|
|
|