diff options
-rw-r--r-- | Presence/XMPPServer.hs | 29 | ||||
-rw-r--r-- | xmppServer.hs | 27 |
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 | ||
476 | grokStanzaIQGet :: Monad m => XML.Event -> NestingXML o m (Maybe StanzaType) | 483 | grokStanzaIQGet :: Monad m => XML.Event -> NestingXML o m (Maybe StanzaType) |
477 | grokStanzaIQGet stanza = do | 484 | grokStanzaIQGet 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 | ) |
17 | import System.Endian (fromBE32) | 17 | import System.Endian (fromBE32) |
18 | import Data.List (nub) | ||
18 | import Data.Monoid ( (<>) ) | 19 | import Data.Monoid ( (<>) ) |
19 | import qualified Data.Text as Text | 20 | import qualified Data.Text as Text |
20 | import qualified Data.Text.IO as Text | 21 | import qualified Data.Text.IO as Text |
@@ -244,35 +245,41 @@ getSolicited' = textAdapter ConfigFiles.getSolicited | |||
244 | 245 | ||
245 | sendProbesAndSolicitations state k laddr chan = do | 246 | sendProbesAndSolicitations 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 | ||
266 | newConn state k addr outchan = do | 277 | newConn 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 | ||
277 | eofConn state k = atomically $ modifyTVar' (keyToChan state) $ Map.delete k | 284 | eofConn state k = atomically $ modifyTVar' (keyToChan state) $ Map.delete k |
278 | 285 | ||