summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Presence/XMPPServer.hs29
-rw-r--r--xmppServer.hs27
2 files changed, 35 insertions, 21 deletions
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs
index f6df1525..0103ba46 100644
--- a/Presence/XMPPServer.hs
+++ b/Presence/XMPPServer.hs
@@ -456,22 +456,29 @@ stanzaFromList stype reply = do
456 mid = stanzaTag >>= lookupAttrib "id" . tagAttrs 456 mid = stanzaTag >>= lookupAttrib "id" . tagAttrs
457 mfrom = stanzaTag >>= lookupAttrib "from" . tagAttrs 457 mfrom = stanzaTag >>= lookupAttrib "from" . tagAttrs
458 mto = stanzaTag >>= lookupAttrib "to" . tagAttrs 458 mto = stanzaTag >>= lookupAttrib "to" . tagAttrs
459 {-
459 isInternal (InternalEnableHack {}) = True 460 isInternal (InternalEnableHack {}) = True
460 isInternal (InternalCacheId {}) = True 461 isInternal (InternalCacheId {}) = True
461 isInternal _ = False 462 isInternal _ = False
462 atomically $ do 463 -}
463 donevar <- newEmptyTMVar 464 (donevar,replyChan,replyClsrs) <- atomically $ do
465 donevar <- newEmptyTMVar -- TMVar ()
464 replyChan <- newLockedChan 466 replyChan <- newLockedChan
465 replyClsrs <- newTVar (Just []) 467 replyClsrs <- newTVar (Just [])
466 return Stanza { stanzaType = stype 468 return (donevar,replyChan, replyClsrs)
467 , stanzaId = mid 469 forkIO $ do
468 , stanzaTo = mto -- as-is from reply list 470 forM_ reply $ atomically . writeLChan replyChan
469 , stanzaFrom = mfrom -- as-is from reply list 471 atomically $ do putTMVar donevar ()
470 , stanzaChan = replyChan 472 writeTVar replyClsrs Nothing
471 , stanzaClosers = replyClsrs 473 return Stanza { stanzaType = stype
472 , stanzaInterrupt = donevar 474 , stanzaId = mid
473 , stanzaOrigin = LocalPeer 475 , stanzaTo = mto -- as-is from reply list
474 } 476 , stanzaFrom = mfrom -- as-is from reply list
477 , stanzaChan = replyChan
478 , stanzaClosers = replyClsrs
479 , stanzaInterrupt = donevar
480 , stanzaOrigin = LocalPeer
481 }
475 482
476grokStanzaIQGet :: Monad m => XML.Event -> NestingXML o m (Maybe StanzaType) 483grokStanzaIQGet :: Monad m => XML.Event -> NestingXML o m (Maybe StanzaType)
477grokStanzaIQGet stanza = do 484grokStanzaIQGet stanza = do
diff --git a/xmppServer.hs b/xmppServer.hs
index b812e584..a30d15d0 100644
--- a/xmppServer.hs
+++ b/xmppServer.hs
@@ -15,6 +15,7 @@ import Network.Socket
15 , SockAddr(..) 15 , SockAddr(..)
16 ) 16 )
17import System.Endian (fromBE32) 17import System.Endian (fromBE32)
18import Data.List (nub)
18import Data.Monoid ( (<>) ) 19import Data.Monoid ( (<>) )
19import qualified Data.Text as Text 20import qualified Data.Text as Text
20import qualified Data.Text.IO as Text 21import qualified Data.Text.IO as Text
@@ -244,35 +245,41 @@ getSolicited' = textAdapter ConfigFiles.getSolicited
244 245
245sendProbesAndSolicitations state k laddr chan = do 246sendProbesAndSolicitations state k laddr chan = do
246 -- get all buddies & solicited matching k for all users 247 -- get all buddies & solicited matching k for all users
247 runTraversableT $ do 248 xs <- runTraversableT $ do
248 cbu <- lift $ atomically $ readTVar $ clientsByUser state 249 cbu <- lift $ atomically $ readTVar $ clientsByUser state
249 user <- liftT $ Map.keys cbu 250 user <- liftT $ Map.keys cbu
250 (isbud,getter) <- liftT [(True ,getBuddies' ) 251 (isbud,getter) <- liftT [(True ,getBuddies' )
251 ,(False,getSolicited')] 252 ,(False,getSolicited')]
252 bud <- liftMT $ getter user 253 bud <- liftMT $ getter user
253 let (u,h,r) = splitJID bud 254 let (u,h,r) = splitJID bud
254 addr <- liftMT $ resolvePeer h 255 addr <- liftMT $ nub `fmap` resolvePeer h
255 liftT $ guard (PeerKey addr == k) 256 liftT $ guard (PeerKey addr == k)
257 -- Note: Earlier I was tempted to do all the IO
258 -- within the TraversableT monad. That apparently
259 -- is a bad idea. Perhaps due to laziness and an
260 -- unforced list? Instead, we will return a list
261 -- of (Bool,Text) for processing outside.
262 return (isbud,u)
263 -- XXX: The following O(n²) nub may be a little
264 -- too onerous.
265 forM_ (nub xs) $ \(isbud,u) -> do
256 let make = if isbud then presenceProbe 266 let make = if isbud then presenceProbe
257 else presenceSolicitation 267 else presenceSolicitation
258 toh = peerKeyToText k 268 toh = peerKeyToText k
259 jid = unsplitJID (u,toh,r) 269 jid = unsplitJID (u,toh,Nothing)
260 me = addrToText laddr 270 me = addrToText laddr
261 stanza <- lift $ make me jid 271 stanza <- make me jid
262 -- send probes for buddies, solicitations for solicited. 272 -- send probes for buddies, solicitations for solicited.
263 lift $ atomically $ writeTChan chan stanza 273 putStrLn $ "probing "++show k++" for: " ++ show (isbud,jid)
264 return () 274 atomically $ writeTChan chan stanza
275 -- reverse xs `seq` return ()
265 276
266newConn state k addr outchan = do 277newConn state k addr outchan = do
267 atomically $ modifyTVar' (keyToChan state) 278 atomically $ modifyTVar' (keyToChan state)
268 $ Map.insert k Conn { connChan = outchan 279 $ Map.insert k Conn { connChan = outchan
269 , auxAddr = addr } 280 , auxAddr = addr }
270 {-
271 -- DISABLED FOR NOW
272 -- (probably is terminating a thread via exception)
273 when (isPeerKey k) 281 when (isPeerKey k)
274 $ sendProbesAndSolicitations state k addr outchan 282 $ sendProbesAndSolicitations state k addr outchan
275 -}
276 283
277eofConn state k = atomically $ modifyTVar' (keyToChan state) $ Map.delete k 284eofConn state k = atomically $ modifyTVar' (keyToChan state) $ Map.delete k
278 285