summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2020-01-13 05:28:21 -0500
committerJoe Crayne <joe@jerkface.net>2020-01-14 03:37:41 -0500
commitb56ac5aa4a4d9c026f6aadad58daeee7729e9f4c (patch)
treedb74187d2d1d4ed9255a2fd810a97e5b8f59e99f
parent8183644b29224b1f2a33b9428729744052373fb5 (diff)
Made client's handshake to/from attributes available to xmppTellNameToClient.
-rw-r--r--dht/Presence/Nesting.hs10
-rw-r--r--dht/Presence/Presence.hs39
-rw-r--r--dht/Presence/XMPPServer.hs173
-rw-r--r--dht/examples/dhtd.hs17
4 files changed, 160 insertions, 79 deletions
diff --git a/dht/Presence/Nesting.hs b/dht/Presence/Nesting.hs
index 403d63cf..a9e550d4 100644
--- a/dht/Presence/Nesting.hs
+++ b/dht/Presence/Nesting.hs
@@ -24,12 +24,10 @@ doNestingXML :: Monad m => NestingXML o m r -> ConduitM Event o m r
24doNestingXML m = 24doNestingXML m =
25 evalStateC (XMLState 0 StrictNil) (trackNesting .| m) 25 evalStateC (XMLState 0 StrictNil) (trackNesting .| m)
26 26
27startNestingXML :: Monad m => NestingXML o m r -> ConduitM Event o m (r, XMLState) 27startNestingXML :: Monad m => NestingXML o m r -> ConduitM Event o m (r, NestingXML o m ())
28startNestingXML m = 28startNestingXML m = do
29 runStateC (XMLState 0 StrictNil) (trackNesting .| m) 29 (r,st) <- runStateC (XMLState 0 StrictNil) (trackNesting .| m)
30 30 return (r, lift $ put st)
31finishNestingXML :: Monad m => XMLState -> NestingXML o m r -> ConduitM Event o m r
32finishNestingXML = evalStateC
33 31
34nesting :: Monad m => NestingXML o m Int 32nesting :: Monad m => NestingXML o m Int
35nesting = lift $ (return . nestingLevel) =<< get 33nesting = lift $ (return . nestingLevel) =<< get
diff --git a/dht/Presence/Presence.hs b/dht/Presence/Presence.hs
index 866aad78..c54c3659 100644
--- a/dht/Presence/Presence.hs
+++ b/dht/Presence/Presence.hs
@@ -13,6 +13,7 @@ import Control.Concurrent
13import Control.Concurrent.Lifted.Instrument 13import Control.Concurrent.Lifted.Instrument
14#endif 14#endif
15 15
16import Control.Arrow
16import Control.Concurrent.STM 17import Control.Concurrent.STM
17import Control.Monad.Trans 18import Control.Monad.Trans
18import Network.Socket ( SockAddr(..) ) 19import Network.Socket ( SockAddr(..) )
@@ -133,17 +134,21 @@ newPresenceState cw toxman sv man = atomically $ do
133 return $ st { toxManager = fmap ($ st) toxman } 134 return $ st { toxManager = fmap ($ st) toxman }
134 135
135 136
136nameForClient :: PresenceState stat -> ClientAddress -> IO Text 137nameForClient' :: PresenceState stat -> Maybe Text -> Maybe Text -> ClientAddress -> IO Text
137nameForClient state k = do 138nameForClient' state mbNameForMe mbTheirName k = do
138 mc <- atomically $ do 139 mc <- atomically $ do
139 cmap <- readTVar (clients state) 140 cmap <- readTVar (clients state)
140 return $ Map.lookup k cmap 141 return $ Map.lookup k cmap
141 case mc of 142 case mc of
142 Nothing -> textHostName 143 Nothing -> textHostName -- TODO: We can use mbNameForMe to initialize the clientProfile
143 Just client -> case clientProfile client of 144 Just client -> case clientProfile client of
144 "." -> textHostName 145 "." -> textHostName
145 profile -> return profile 146 profile -> return profile
146 147
148nameForClient :: PresenceState stat -> ClientAddress -> IO Text
149nameForClient state k = nameForClient' state Nothing Nothing k
150
151
147presenceHooks :: PresenceState stat -> Map Text MUC 152presenceHooks :: PresenceState stat -> Map Text MUC
148 -> Int 153 -> Int
149 -> Maybe SockAddr -- ^ client-to-server bind address 154 -> Maybe SockAddr -- ^ client-to-server bind address
@@ -152,7 +157,7 @@ presenceHooks :: PresenceState stat -> Map Text MUC
152presenceHooks state chats verbosity mclient mpeer = XMPPServerParameters 157presenceHooks state chats verbosity mclient mpeer = XMPPServerParameters
153 { xmppChooseResourceName = chooseResourceName state 158 { xmppChooseResourceName = chooseResourceName state
154 , xmppTellClientHisName = tellClientHisName state 159 , xmppTellClientHisName = tellClientHisName state
155 , xmppTellMyNameToClient = nameForClient state 160 , xmppTellMyNameToClient = nameForClient' state
156 , xmppTellMyNameToPeer = \(Local addr) -> return $ addrToText addr 161 , xmppTellMyNameToPeer = \(Local addr) -> return $ addrToText addr
157 , xmppTellPeerHisName = return . peerKeyToText 162 , xmppTellPeerHisName = return . peerKeyToText
158 , xmppNewConnection = newConn state 163 , xmppNewConnection = newConn state
@@ -726,8 +731,12 @@ deliverMessage state fail msg =
726 fromMaybe (do dput XJabber $ "Unknown peer " ++ show senderk 731 fromMaybe (do dput XJabber $ "Unknown peer " ++ show senderk
727 fail) 732 fail)
728 $ Map.lookup senderk pchans 733 $ Map.lookup senderk pchans
729 <&> \(Conn { connChan = sender_chan 734 <&> \Conn { connChan = sender_chan
730 , auxData = ConnectionData (Left laddr) ctyp cprof _ }) -> do 735 , auxData = ConnectionData { cdAddr = Left laddr
736 , cdType = ctyp
737 , cdProfile = cprof
738 }
739 } -> do
731 fromMaybe (do dput XJabber $ "Message missing \"to\" attribute." 740 fromMaybe (do dput XJabber $ "Message missing \"to\" attribute."
732 fail) 741 fail)
733 $ (stanzaTo msg) <&> \to -> do 742 $ (stanzaTo msg) <&> \to -> do
@@ -916,9 +925,7 @@ informPeerPresence state k stanza = do
916 dput XJabber $ "xmppInformPeerPresence (length clients="++show (length clients)++")" 925 dput XJabber $ "xmppInformPeerPresence (length clients="++show (length clients)++")"
917 (ctyp,cprof) <- atomically $ do 926 (ctyp,cprof) <- atomically $ do
918 mconn <- Map.lookup k <$> readTVar (pkeyToChan state) 927 mconn <- Map.lookup k <$> readTVar (pkeyToChan state)
919 return $ fromMaybe (XMPP,".") $ do 928 return $ fromMaybe (XMPP,".") $ (cdType &&& cdProfile) . auxData <$> mconn
920 ConnectionData _ ctyp cprof _ <- auxData <$> mconn
921 return (ctyp,cprof)
922 forM_ clients $ \(ck,con,client) -> do 929 forM_ clients $ \(ck,con,client) -> do
923 -- (TODO: appropriately authorized clients only.) 930 -- (TODO: appropriately authorized clients only.)
924 -- For now, all "available" clients (available = sent initial presence) 931 -- For now, all "available" clients (available = sent initial presence)
@@ -1263,7 +1270,11 @@ peerSubscriptionRequest state fail k stanza chan = do
1263 cmap <- readTVar (clients state) 1270 cmap <- readTVar (clients state)
1264 return (pktc,cktc,cmap) 1271 return (pktc,cktc,cmap)
1265 fromMaybe fail $ (Map.lookup k pktc) 1272 fromMaybe fail $ (Map.lookup k pktc)
1266 <&> \Conn { auxData=ConnectionData (Left laddr) ctyp profile _ } -> do 1273 <&> \Conn { auxData = ConnectionData { cdAddr = Left laddr
1274 , cdType = ctyp
1275 , cdProfile = profile
1276 }
1277 } -> do
1267 (mine,totup) <- case (ctyp,profile) of 1278 (mine,totup) <- case (ctyp,profile) of
1268 (Tox,p) -> let (u,h,r) = splitJID to 1279 (Tox,p) -> let (u,h,r) = splitJID to
1269 in return ( h == p, (u,h,r) ) 1280 in return ( h == p, (u,h,r) )
@@ -1412,8 +1423,12 @@ peerInformSubscription state fail k stanza = do
1412 cmap <- readTVar (clients state) 1423 cmap <- readTVar (clients state)
1413 return (pktc,cktc,cmap) 1424 return (pktc,cktc,cmap)
1414 fromMaybe fail $ Map.lookup k ktc 1425 fromMaybe fail $ Map.lookup k ktc
1415 <&> \(Conn { connChan=sender_chan 1426 <&> \Conn { connChan = sender_chan
1416 , auxData =ConnectionData (Left laddr) ctyp profile _ }) -> do 1427 , auxData = ConnectionData { cdAddr = Left laddr
1428 , cdType = ctyp
1429 , cdProfile = profile }
1430 } -> do
1431
1417 let man = manager state profile 1432 let man = manager state profile
1418 (from_u,from_h,_) <- case ctyp of 1433 (from_u,from_h,_) <- case ctyp of
1419 Tox -> return $ splitJID from 1434 Tox -> return $ splitJID from
diff --git a/dht/Presence/XMPPServer.hs b/dht/Presence/XMPPServer.hs
index 0aef1ed6..89fd76b6 100644
--- a/dht/Presence/XMPPServer.hs
+++ b/dht/Presence/XMPPServer.hs
@@ -129,8 +129,10 @@ data XMPPServerParameters =
129 -- 129 --
130 -- A Left result causes an error stanza to be sent instead. 130 -- A Left result causes an error stanza to be sent instead.
131 xmppChooseResourceName :: ClientAddress -> Remote SockAddr -> Maybe Text -> Maybe Text -> IO (Either Text Text) 131 xmppChooseResourceName :: ClientAddress -> Remote SockAddr -> Maybe Text -> Maybe Text -> IO (Either Text Text)
132 , -- | This should indicate the server's hostname that all client's see. 132 , -- | This should indicate the server's hostname that the client will see.
133 xmppTellMyNameToClient :: ClientAddress -> IO Text 133 -- The first two arguments are the "to" and "from" attributes,
134 -- respectively, that the client sent in its greeting to the server.
135 xmppTellMyNameToClient :: Maybe Text -> Maybe Text -> ClientAddress -> IO Text
134 , xmppTellMyNameToPeer :: Local SockAddr -> IO Text 136 , xmppTellMyNameToPeer :: Local SockAddr -> IO Text
135 , xmppTellClientHisName :: ClientAddress -> IO Text 137 , xmppTellClientHisName :: ClientAddress -> IO Text
136 , xmppTellPeerHisName :: PeerAddress -> IO Text 138 , xmppTellPeerHisName :: PeerAddress -> IO Text
@@ -476,16 +478,14 @@ C->Unrecognized </iq>
476 478
477-- Sends all stanzas to announce channel except ping, for which it sends a pong 479-- Sends all stanzas to announce channel except ping, for which it sends a pong
478-- to the output channel. 480-- to the output channel.
479xmppInbound :: Maybe Text -- ^ "to" attribute sent from remote 481xmppInbound :: ConnectionData
480 -> Maybe Text -- ^ "from" attribute sent from remote
481 -> ConnectionData
482 -> (Text, IO Text, IO Text, TChan Stanza -> StanzaOrigin) 482 -> (Text, IO Text, IO Text, TChan Stanza -> StanzaOrigin)
483 -> FlagCommand -- ^ action to check whether the connection needs a ping (XXX: unused) 483 -> FlagCommand -- ^ action to check whether the connection needs a ping (XXX: unused)
484 -> TChan Stanza -- ^ channel to announce incoming stanzas on 484 -> TChan Stanza -- ^ channel to announce incoming stanzas on
485 -> TChan Stanza -- ^ channel used to send stanzas 485 -> TChan Stanza -- ^ channel used to send stanzas
486 -> TMVar () -- ^ mvar that is filled when the connection quits 486 -> TMVar () -- ^ mvar that is filled when the connection quits
487 -> NestingXML o IO () 487 -> NestingXML o IO ()
488xmppInbound stream_name stream_remote cdta (namespace,tellmyname,tellyourname,mkorigin) pingflag stanzas output donevar = 488xmppInbound cdta (namespace,tellmyname,tellyourname,mkorigin) pingflag stanzas output donevar =
489 fix $ \loop -> do 489 fix $ \loop -> do
490 -- liftIO . wlog $ "waiting for stanza." 490 -- liftIO . wlog $ "waiting for stanza."
491 (chan,clsrs) <- liftIO . atomically $ 491 (chan,clsrs) <- liftIO . atomically $
@@ -540,7 +540,7 @@ xmppInbound stream_name stream_remote cdta (namespace,tellmyname,tellyourname,mk
540 } 540 }
541 stype -> ioWriteChan stanzas Stanza 541 stype -> ioWriteChan stanzas Stanza
542 { stanzaType = case stype of 542 { stanzaType = case stype of
543 RequestResource _ rsc -> RequestResource stream_name rsc 543 RequestResource _ rsc -> RequestResource (cdTheirNameForMe cdta) rsc
544 _ -> stype 544 _ -> stype
545 , stanzaId = mid 545 , stanzaId = mid
546 , stanzaTo = mto 546 , stanzaTo = mto
@@ -911,44 +911,81 @@ forkConnection :: Server PeerAddress ConnectionData releaseKey XML.Event
911 -> ConduitT (Flush XML.Event) Void IO () 911 -> ConduitT (Flush XML.Event) Void IO ()
912 -> TChan Stanza 912 -> TChan Stanza
913 -> MVar () 913 -> MVar ()
914 -> IO (TChan Stanza) 914 -> IO (TChan Stanza, ConnectionData)
915forkConnection sv xmpp saddr cdta pingflag src snk stanzas pp_mvar = do 915forkConnection sv xmpp saddr cdta0 pingflag src snk stanzas pp_mvar = do
916 -- client.PeerAddress {peerAddress = [::1]:5222} 916 -- client.PeerAddress {peerAddress = [::1]:5222}
917 let lbl n = concat [ n 917 let auxAddr = cdAddr cdta0
918 , Text.unpack (Text.drop 7 namespace) -- "client" or "server"
919 , "."
920 , case cdProfile cdta of
921 _ | Right _ <- cdAddr cdta -> show saddr
922 "." -> show saddr
923 mytoxname -> show saddr {- TODO: remote tox peer name? -} ]
924 918
925 auxAddr = cdAddr cdta 919 is_client = case auxAddr of { Right _ -> True ; Left _ -> False }
926 920
927 clientOrServer@(namespace,tellmyname,telltheirname,_) = case auxAddr of 921 (namespace,clientOrServer0) = case auxAddr of
928 Right _ -> ("jabber:client", xmppTellMyNameToClient xmpp (ClientAddress $ peerAddress saddr) 922 Right _ -> ( "jabber:client"
929 , xmppTellClientHisName xmpp (ClientAddress $ peerAddress saddr) 923 , ( xmppTellMyNameToClient xmpp Nothing Nothing $ ClientAddress $ peerAddress saddr
930 , ClientOrigin (ClientAddress $ peerAddress saddr)) 924 , xmppTellClientHisName xmpp $ ClientAddress $ peerAddress saddr
931 Left laddr -> ("jabber:server", xmppTellMyNameToPeer xmpp laddr 925 , ClientOrigin $ ClientAddress $ peerAddress saddr ) )
932 , xmppTellPeerHisName xmpp saddr 926 Left laddr -> ( "jabber:server"
933 , PeerOrigin saddr) 927 , ( xmppTellMyNameToPeer xmpp laddr
928 , xmppTellPeerHisName xmpp saddr
929 , PeerOrigin saddr) )
930
931 updateNameField f (tmn,ttn,o) = (namespace,f tmn,ttn,o)
932
933 lbl n = concat [ n
934 , Text.unpack (Text.drop 7 namespace) -- "client" or "server"
935 , "."
936 , case cdProfile cdta0 of
937 _ | Right _ <- auxAddr -> show saddr
938 "." -> show saddr
939 mytoxname -> show saddr {- TODO: remote tox peer name? -} ]
940
941
942 realDoGreeting = await >>= \case
943 Just EventBeginDocument ->
944 nextElement >>= \case
945 Just xml ->
946 forM (elementAttrs "stream" xml) $ \stream_attrs -> do
947 -- liftIO $ dput XMisc $ "STREAM ATTRS "++show stream_attrs
948 let stream_name = lookupAttrib "to" stream_attrs
949 stream_remote = lookupAttrib "from" stream_attrs
950 -- xmpp_version = lookupAttrib "version" stream_attrs
951 liftIO $ atomically $ writeTVar (cdRemoteName cdta0) stream_remote
952 return (stream_name, stream_remote)
953 Nothing -> return Nothing
954 _ -> return Nothing
955
956 (clientOrServer@(namespace,tellmyname,telltheirname,_), (cdta, src', doGreeting))
957 <- if is_client
958 then do
959 -- For a client, we can wait for them to greet us before we send them
960 -- any information.
961 (srcSealed,(mb,resume)) <- src $$+ startNestingXML realDoGreeting
962 let stream_name = mb >>= fst
963 stream_remote = mb >>= snd
964 cdta = cdta0 { cdTheirNameForMe = stream_name
965 , cdTheirName = stream_remote
966 }
967 newName _ = xmppTellMyNameToClient xmpp stream_name stream_remote
968 $ ClientAddress $ peerAddress saddr
969 atomically $
970 modifyTVar' (conmap sv) $
971 Map.adjust (\c -> c { cdata = cdta }) saddr
972 return ( updateNameField newName clientOrServer0
973 , (cdta, unsealConduitT srcSealed, resume >> return mb) )
974 else -- For a server, this is a no-op.
975 return ( updateNameField id clientOrServer0
976 , (cdta0, src, realDoGreeting) )
934 977
935 output <- atomically newTChan 978 output <- atomically newTChan
936 rdone <- atomically newEmptyTMVar 979 rdone <- atomically newEmptyTMVar
937 forkLabeled (lbl "xmpp-reader.") $ do 980 forkLabeled (lbl "xmpp-reader.") $ do
938 -- src $$ awaitForever (lift . putStrLn . takeWhile (/=' ') . show) 981 -- src $$ awaitForever (lift . putStrLn . takeWhile (/=' ') . show)
939 runConduit $ (.|) src $ 982 runConduit $ (.|) src' $
940 -- :: ConduitM Event o IO () 983 -- :: ConduitM Event o IO ()
941 doNestingXML $ do 984 doNestingXML $ do
942 withXML $ \begindoc -> do 985 doGreeting >>= \case
943 when (begindoc==EventBeginDocument) $ do 986 Just (stream_name, stream_remote) ->
944 whenJust nextElement $ \xml -> do 987 xmppInbound cdta clientOrServer pingflag stanzas output rdone
945 withJust (elementAttrs "stream" xml) $ \stream_attrs -> do 988 Nothing -> return ()
946 -- liftIO $ dput XMisc $ "STREAM ATTRS "++show stream_attrs
947 let stream_name = lookupAttrib "to" stream_attrs
948 stream_remote = lookupAttrib "from" stream_attrs
949 -- xmpp_version = lookupAttrib "version" stream_attrs
950 liftIO $ atomically $ writeTVar (cdRemoteName cdta) stream_remote
951 xmppInbound stream_name stream_remote cdta clientOrServer pingflag stanzas output rdone
952 atomically $ putTMVar rdone () 989 atomically $ putTMVar rdone ()
953 wlog $ "end reader fork: " ++ lbl "" 990 wlog $ "end reader fork: " ++ lbl ""
954 991
@@ -1087,7 +1124,7 @@ forkConnection sv xmpp saddr cdta pingflag src snk stanzas pp_mvar = do
1087 ] 1124 ]
1088 what 1125 what
1089 wlog $ "end xmpp-pre fork: " ++ show (lbl "") 1126 wlog $ "end xmpp-pre fork: " ++ show (lbl "")
1090 return output 1127 return (output, cdta)
1091 1128
1092{- 1129{-
1093data Peer = Peer 1130data Peer = Peer
@@ -1121,7 +1158,9 @@ peerKey bind_addr (sock,(laddr,Remote raddr)) = do
1121 , ConnectionData { cdAddr = Left laddr 1158 , ConnectionData { cdAddr = Left laddr
1122 , cdType = XMPP 1159 , cdType = XMPP
1123 , cdProfile = "." 1160 , cdProfile = "."
1124 , cdRemoteName = rname } ) 1161 , cdRemoteName = rname
1162 , cdTheirNameForMe = Nothing
1163 , cdTheirName = Nothing } )
1125 1164
1126clientKey :: SocketLike sock => (sock, (Local SockAddr,Remote SockAddr)) -> IO (PeerAddress,ConnectionData) 1165clientKey :: SocketLike sock => (sock, (Local SockAddr,Remote SockAddr)) -> IO (PeerAddress,ConnectionData)
1127clientKey (sock,(laddr,Remote raddr)) = do 1166clientKey (sock,(laddr,Remote raddr)) = do
@@ -1138,7 +1177,9 @@ clientKey (sock,(laddr,Remote raddr)) = do
1138 , ConnectionData { cdAddr = Right (Remote raddr) -- FIXME: This is a bad way to detect client/peer. 1177 , ConnectionData { cdAddr = Right (Remote raddr) -- FIXME: This is a bad way to detect client/peer.
1139 , cdType = XMPP 1178 , cdType = XMPP
1140 , cdProfile = "." 1179 , cdProfile = "."
1141 , cdRemoteName = rname } ) 1180 , cdRemoteName = rname
1181 , cdTheirNameForMe = Nothing
1182 , cdTheirName = Nothing } )
1142 1183
1143 1184
1144xmlifyRosterItems :: Monad m => Set Text -> Text -> Set Text -> ConduitM i Event m () 1185xmlifyRosterItems :: Monad m => Set Text -> Text -> Set Text -> ConduitM i Event m ()
@@ -1154,17 +1195,18 @@ xmlifyRosterItems solicited stype set = mapM_ item (Set.toList set)
1154 1195
1155sendRoster :: 1196sendRoster ::
1156 StanzaWrap a 1197 StanzaWrap a
1198 -> Server PeerAddress ConnectionData releaseKey xml
1157 -> XMPPServerParameters 1199 -> XMPPServerParameters
1158 -> ClientAddress 1200 -> ClientAddress
1159 -> TChan Stanza 1201 -> TChan Stanza
1160 -> IO () 1202 -> IO ()
1161sendRoster query xmpp clientKey replyto = do 1203sendRoster query sv xmpp clientKey replyto = do
1162 let maddr = case stanzaOrigin query of 1204 let maddr = case stanzaOrigin query of
1163 ClientOrigin addr _ -> Just addr 1205 ClientOrigin addr _ -> Just addr
1164 PeerOrigin {} -> Nothing -- remote peer requested roster? 1206 PeerOrigin {} -> Nothing -- remote peer requested roster?
1165 LocalPeer -> Nothing -- local peer requested roster? 1207 LocalPeer -> Nothing -- local peer requested roster?
1166 forM_ maddr $ \k -> do 1208 forM_ maddr $ \k -> do
1167 hostname <- xmppTellMyNameToClient xmpp clientKey 1209 hostname <- svTellMyName sv xmpp clientKey
1168 let getlist f = do 1210 let getlist f = do
1169 bs <- f xmpp k 1211 bs <- f xmpp k
1170 return (Set.fromList bs) -- js) 1212 return (Set.fromList bs) -- js)
@@ -1278,13 +1320,24 @@ makeErrorStanza' stanza err attrs = do
1278 , endTag 1320 , endTag
1279 ] 1321 ]
1280 1322
1323svTellMyName :: Server PeerAddress ConnectionData releaseKey xml
1324 -> XMPPServerParameters
1325 -> ClientAddress
1326 -> IO Text
1327svTellMyName sv xmpp k@(ClientAddress saddr) = do
1328 mc <- atomically $
1329 fmap cdata . Map.lookup (PeerAddress saddr) <$> readTVar (conmap sv)
1330 let me = mc >>= cdTheirNameForMe
1331 them = mc >>= cdTheirName
1332 xmppTellMyNameToClient xmpp me them k
1333
1281monitor :: 1334monitor ::
1282 Server PeerAddress ConnectionData releaseKey XML.Event 1335 Server PeerAddress ConnectionData releaseKey XML.Event
1283 -> ConnectionParameters PeerAddress ConnectionData 1336 -> ConnectionParameters PeerAddress ConnectionData
1284 -> XMPPServerParameters 1337 -> XMPPServerParameters
1285 -> IO b 1338 -> IO b
1286monitor sv params xmpp = do 1339monitor sv params xmpp = do
1287 chan <- return $ serverEvent sv 1340 let chan = serverEvent sv
1288 stanzas <- atomically newTChan 1341 stanzas <- atomically newTChan
1289 quitVar <- atomically newEmptyTMVar 1342 quitVar <- atomically newEmptyTMVar
1290 pp_mvar <- newMVar () -- Lock for synchronous pretty-printing of stanzas in log. 1343 pp_mvar <- newMVar () -- Lock for synchronous pretty-printing of stanzas in log.
@@ -1296,16 +1349,18 @@ monitor sv params xmpp = do
1296 case e of 1349 case e of
1297 Connection pingflag xsrc xsnk 1350 Connection pingflag xsrc xsnk
1298 -> do wlog $ tomsg addr "Connection" 1351 -> do wlog $ tomsg addr "Connection"
1299 outs <- forkConnection sv xmpp addr u pingflag xsrc xsnk stanzas pp_mvar 1352 (outs,u') <- forkConnection sv xmpp addr u pingflag xsrc xsnk stanzas pp_mvar
1300 -- /addr/ may be a peer or a client. So we'll strip off 1353 -- /addr/ may be a peer or a client. So we'll strip off
1301 -- the PeerAddress constructor before exposing it. 1354 -- the PeerAddress constructor before exposing it.
1302 xmppNewConnection xmpp (peerAddress addr) u outs 1355 xmppNewConnection xmpp (peerAddress addr) u' outs
1303 ConnectFailure addr 1356 ConnectFailure addr
1304 -> do return () -- wlog $ tomsg k "ConnectFailure" 1357 -> do return () -- wlog $ tomsg k "ConnectFailure"
1305 EOF -> do wlog $ tomsg addr "EOF" 1358 EOF -> do wlog $ tomsg addr "EOF"
1306 -- /addr/ may be a peer or a client. So we'll strip off 1359 -- /addr/ may be a peer or a client. So we'll strip off
1307 -- the PeerAddress constructor before exposing it. 1360 -- the PeerAddress constructor before exposing it.
1308 xmppEOF xmpp (peerAddress addr) u 1361 xmppEOF xmpp (peerAddress addr) u -- Note: cdTheirName and cdTheirNameForMe are with their
1362 -- default values rather than the updated versions provided
1363 -- by 'forkConnection'.
1309 HalfConnection In 1364 HalfConnection In
1310 -> do wlog $ tomsg addr "ReadOnly" 1365 -> do wlog $ tomsg addr "ReadOnly"
1311 case cdAddr u of 1366 case cdAddr u of
@@ -1359,7 +1414,7 @@ monitor sv params xmpp = do
1359 $ \(k,((rkey,muckey),(replyto,r))) -> do 1414 $ \(k,((rkey,muckey),(replyto,r))) -> do
1360 (mine,ChatTransaction no cjid cnick es) <- readRoom k r 1415 (mine,ChatTransaction no cjid cnick es) <- readRoom k r
1361 return $ do 1416 return $ do
1362 me <- xmppTellMyNameToClient xmpp k 1417 me <- svTellMyName sv xmpp k
1363 dput XJabber $ "CHAT " ++ Text.unpack rkey ++ ": <" ++ Text.unpack cnick ++ "> " ++ show es 1418 dput XJabber $ "CHAT " ++ Text.unpack rkey ++ ": <" ++ Text.unpack cnick ++ "> " ++ show es
1364 forM_ es $ \case 1419 forM_ es $ \case
1365 Join | mine -> sendRoomOccupants muckey me cnick rkey r replyto 1420 Join | mine -> sendRoomOccupants muckey me cnick rkey r replyto
@@ -1387,7 +1442,7 @@ monitor sv params xmpp = do
1387 else Map.insert k m' jrs 1442 else Map.insert k m' jrs
1388 writeTVar joined_rooms jrs' 1443 writeTVar joined_rooms jrs'
1389 Talk talk -> do 1444 Talk talk -> do
1390 them <- xmppTellClientHisName xmpp k 1445 them <- svTellMyName sv xmpp k
1391 stanza <- makeMessageEx "jabber:client" (roomjid muckey me rkey cnick) them GroupChatMsg talk 1446 stanza <- makeMessageEx "jabber:client" (roomjid muckey me rkey cnick) them GroupChatMsg talk
1392 ioWriteChan replyto stanza 1447 ioWriteChan replyto stanza
1393 return () 1448 return ()
@@ -1475,7 +1530,7 @@ applyStanza sv joined_rooms quitVar xmpp stanza = do
1475 sockaddr <- socketFromKey sv k 1530 sockaddr <- socketFromKey sv k
1476 xmppChooseResourceName xmpp k sockaddr clientsNameForMe wanted >>= \case 1531 xmppChooseResourceName xmpp k sockaddr clientsNameForMe wanted >>= \case
1477 Right rsc0 -> do 1532 Right rsc0 -> do
1478 hostname <- xmppTellMyNameToClient xmpp k 1533 hostname <- svTellMyName sv xmpp k
1479 let rsc = unsplitJID (n,hostname,r) where (n,_,r) = splitJID rsc0 1534 let rsc = unsplitJID (n,hostname,r) where (n,_,r) = splitJID rsc0
1480 let reply = iq_bind_reply (stanzaId stanza) rsc 1535 let reply = iq_bind_reply (stanzaId stanza) rsc
1481 sendReply quitVar SetResource reply replyto 1536 sendReply quitVar SetResource reply replyto
@@ -1486,19 +1541,19 @@ applyStanza sv joined_rooms quitVar xmpp stanza = do
1486 (requestVersion rsc hostname) 1541 (requestVersion rsc hostname)
1487 >>= ioWriteChan replyto 1542 >>= ioWriteChan replyto
1488 Left err -> do 1543 Left err -> do
1489 hostname <- xmppTellMyNameToClient xmpp k 1544 hostname <- svTellMyName sv xmpp k
1490 reply <- makeErrorStanza' stanza NotAllowed [] 1545 reply <- makeErrorStanza' stanza NotAllowed []
1491 sendReply quitVar (Error NotAuthorized (head reply)) reply replyto 1546 sendReply quitVar (Error NotAuthorized (head reply)) reply replyto
1492 SessionRequest -> do 1547 SessionRequest -> do
1493 me <- xmppTellMyNameToClient xmpp k 1548 me <- svTellMyName sv xmpp k
1494 let reply = iq_session_reply (stanzaId stanza) me 1549 let reply = iq_session_reply (stanzaId stanza) me
1495 sendReply quitVar Pong reply replyto 1550 sendReply quitVar Pong reply replyto
1496 RequestRoster -> do 1551 RequestRoster -> do
1497 sendRoster stanza xmpp k replyto 1552 sendRoster stanza sv xmpp k replyto
1498 xmppSubscribeToRoster xmpp k 1553 xmppSubscribeToRoster xmpp k
1499 PresenceStatus {} -> do 1554 PresenceStatus {} -> do
1500 let mucs = xmppGroupChat xmpp 1555 let mucs = xmppGroupChat xmpp
1501 me <- xmppTellMyNameToClient xmpp k 1556 me <- svTellMyName sv xmpp k
1502 if | Just to <- stanzaTo stanza 1557 if | Just to <- stanzaTo stanza
1503 , (Just room,h,mnick) <- splitJID to 1558 , (Just room,h,mnick) <- splitJID to
1504 , let roomjid = unsplitJID ((Just room,h,Nothing)) 1559 , let roomjid = unsplitJID ((Just room,h,Nothing))
@@ -1550,7 +1605,7 @@ applyStanza sv joined_rooms quitVar xmpp stanza = do
1550 NotifyClientVersion name version -> do 1605 NotifyClientVersion name version -> do
1551 enableClientHacks name version replyto 1606 enableClientHacks name version replyto
1552 RequestInfo mnode -> do 1607 RequestInfo mnode -> do
1553 me <- xmppTellMyNameToClient xmpp k 1608 me <- svTellMyName sv xmpp k
1554 let unavail = let query = "{http://jabber.org/protocol/disco#info}info" 1609 let unavail = let query = "{http://jabber.org/protocol/disco#info}info"
1555 reply = iq_service_unavailable (stanzaId stanza) me query 1610 reply = iq_service_unavailable (stanzaId stanza) me query
1556 in return (Error ServiceUnavailable (head reply), reply) 1611 in return (Error ServiceUnavailable (head reply), reply)
@@ -1608,7 +1663,7 @@ applyStanza sv joined_rooms quitVar xmpp stanza = do
1608 sendReply quitVar rtyp reply replyto 1663 sendReply quitVar rtyp reply replyto
1609 RequestItems mnode -> do 1664 RequestItems mnode -> do
1610 -- let query = "{http://jabber.org/protocol/disco#items}query" 1665 -- let query = "{http://jabber.org/protocol/disco#items}query"
1611 me <- xmppTellMyNameToClient xmpp k 1666 me <- svTellMyName sv xmpp k
1612 let unavail = let query = "{http://jabber.org/protocol/disco#info}info" 1667 let unavail = let query = "{http://jabber.org/protocol/disco#info}info"
1613 reply = iq_service_unavailable (stanzaId stanza) me query 1668 reply = iq_service_unavailable (stanzaId stanza) me query
1614 in return (Error ServiceUnavailable (head reply), reply) 1669 in return (Error ServiceUnavailable (head reply), reply)
@@ -1635,12 +1690,12 @@ applyStanza sv joined_rooms quitVar xmpp stanza = do
1635 return (Items, reply) 1690 return (Items, reply)
1636 sendReply quitVar rtyp reply replyto 1691 sendReply quitVar rtyp reply replyto
1637 UnrecognizedQuery query -> do 1692 UnrecognizedQuery query -> do
1638 me <- xmppTellMyNameToClient xmpp k 1693 me <- svTellMyName sv xmpp k
1639 let reply = iq_service_unavailable (stanzaId stanza) me query 1694 let reply = iq_service_unavailable (stanzaId stanza) me query
1640 sendReply quitVar (Error ServiceUnavailable (head reply)) reply replyto 1695 sendReply quitVar (Error ServiceUnavailable (head reply)) reply replyto
1641 Message { msgType = GroupChatMsg } -> do 1696 Message { msgType = GroupChatMsg } -> do
1642 let mucs = xmppGroupChat xmpp 1697 let mucs = xmppGroupChat xmpp
1643 me <- xmppTellMyNameToClient xmpp k 1698 me <- svTellMyName sv xmpp k
1644 if | Just to <- stanzaTo stanza 1699 if | Just to <- stanzaTo stanza
1645 , (Just room,h,mnick) <- splitJID to 1700 , (Just room,h,mnick) <- splitJID to
1646 , let roomjid = unsplitJID ((Just room,h,Nothing)) 1701 , let roomjid = unsplitJID ((Just room,h,Nothing))
@@ -1732,7 +1787,13 @@ data ConnectionData = ConnectionData
1732 1787
1733 -- Initially Nothing, when the remote end identifies itself by a given name, 1788 -- Initially Nothing, when the remote end identifies itself by a given name,
1734 -- the result will be stored here. 1789 -- the result will be stored here.
1735 , cdRemoteName :: TVar (Maybe Text) 1790 , cdRemoteName :: TVar (Maybe Text) -- This is similar to 'cdTheirName' except that
1791 -- it is available for remote xmpp servers and to
1792 -- the 'xmppEOF' function.
1793 , cdTheirNameForMe :: Maybe Text -- (client only) "to" attribute sent with <stream>
1794 -- Also: currently unavailable to 'xmppEOF'
1795 , cdTheirName :: Maybe Text -- (client only) "from" attribute sent with <stream>
1796 -- Also: currently unavailable to 'xmppEOF'
1736 } 1797 }
1737 1798
1738addrToPeerKey :: Remote SockAddr -> PeerAddress 1799addrToPeerKey :: Remote SockAddr -> PeerAddress
diff --git a/dht/examples/dhtd.hs b/dht/examples/dhtd.hs
index d7c817ca..f9dc777d 100644
--- a/dht/examples/dhtd.hs
+++ b/dht/examples/dhtd.hs
@@ -1366,17 +1366,24 @@ onNewToxSession runio sv ssvar invc ContactInfo{accounts} addrTox netcrypto = do
1366 1366
1367 uniqkey <- xor24 <$> hash24 (them netcrypto) <*> hash24 (me netcrypto) 1367 uniqkey <- xor24 <$> hash24 (them netcrypto) <*> hash24 (me netcrypto)
1368 1368
1369 let me_dot_tox = xmppHostname $ me netcrypto
1370 them_dot_tox = xmppHostname $ them netcrypto
1371
1369 c <- atomically $ do 1372 c <- atomically $ do
1370 mc <- Map.lookup uniqkey <$> readTVar ssvar 1373 mc <- Map.lookup uniqkey <$> readTVar ssvar
1371 case mc of 1374 case mc of
1372 Nothing -> do 1375 Nothing -> do
1373 announce <- do 1376 announce <- do
1374 v <- newTVar Nothing 1377 v <- newTVar $ Just them_dot_tox
1375 let ck = uniqueAsKey uniqkey 1378 let ck = uniqueAsKey uniqkey
1376 condta s = ConnectionData (Left (Local addrTox)) 1379 condta s = ConnectionData
1377 XMPPServer.Tox 1380 { cdAddr = Left (Local addrTox)
1378 (xmppHostname $ me s) 1381 , cdType = XMPPServer.Tox
1379 v 1382 , cdProfile = me_dot_tox
1383 , cdRemoteName = v
1384 , cdTheirNameForMe = Just me_dot_tox
1385 , cdTheirName = Just them_dot_tox
1386 }
1380 return $ \s e -> writeTChan (xmppEventChannel sv) ( (ck, condta s), e) 1387 return $ \s e -> writeTChan (xmppEventChannel sv) ( (ck, condta s), e)
1381 c <- newAggregateSession $ onStatusChange announce 1388 c <- newAggregateSession $ onStatusChange announce
1382 modifyTVar' ssvar $ Map.insert uniqkey c 1389 modifyTVar' ssvar $ Map.insert uniqkey c