summaryrefslogtreecommitdiff
path: root/xmppServer.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2014-03-06 02:22:47 -0500
committerjoe <joe@jerkface.net>2014-03-06 02:22:47 -0500
commit52efeff2233c896b87effcec8641e695c7120607 (patch)
tree63a3e4f296b9dd8c96575c315a968e565b4f86c1 /xmppServer.hs
parenta41ffe16f5f3237a0b16c49f743ba423b19e46d6 (diff)
offline notifications
Diffstat (limited to 'xmppServer.hs')
-rw-r--r--xmppServer.hs68
1 files changed, 57 insertions, 11 deletions
diff --git a/xmppServer.hs b/xmppServer.hs
index 107054bf..699c6a7a 100644
--- a/xmppServer.hs
+++ b/xmppServer.hs
@@ -292,7 +292,24 @@ newConn state k addr outchan = do
292 when (isPeerKey k) 292 when (isPeerKey k)
293 $ sendProbesAndSolicitations state k addr outchan 293 $ sendProbesAndSolicitations state k addr outchan
294 294
295eofConn state k = atomically $ modifyTVar' (keyToChan state) $ Map.delete k 295eofConn state k = do
296 atomically $ modifyTVar' (keyToChan state) $ Map.delete k
297 case k of
298 ClientKey {} -> do
299 stanza <- makePresenceStanza "{jabber:server}" Nothing Offline
300 informClientPresence state k stanza
301 PeerKey {} -> do
302 let h = peerKeyToText k
303 jids <- atomically $ do
304 rbp <- readTVar (remotesByPeer state)
305 return $ do
306 umap <- maybeToList $ Map.lookup k rbp
307 (u,rp) <- Map.toList umap
308 r <- Map.keys (resources rp)
309 return $ unsplitJID (Just u, h, Just r)
310 forM_ jids $ \jid -> do
311 stanza <- makePresenceStanza "{jabber:client}" (Just jid) Offline
312 informPeerPresence state k stanza
296 313
297{- 314{-
298rewriteJIDForClient1:: Text -> IO (Maybe ((Maybe Text,Text,Maybe Text),SockAddr)) 315rewriteJIDForClient1:: Text -> IO (Maybe ((Maybe Text,Text,Maybe Text),SockAddr))
@@ -427,6 +444,9 @@ deliverMessage state fail msg =
427 sendModifiedStanzaToClient dup 444 sendModifiedStanzaToClient dup
428 chan 445 chan
429 446
447-- | Send presence notification to subscribed peers.
448-- Note that a full JID from address will be added to the
449-- stanza if it is not present.
430informClientPresence state k stanza = do 450informClientPresence state k stanza = do
431 dup <- cloneStanza stanza 451 dup <- cloneStanza stanza
432 atomically $ do 452 atomically $ do
@@ -461,9 +481,24 @@ informPeerPresence state k stanza = do
461 flip (maybe $ return ()) muser $ \user -> do 481 flip (maybe $ return ()) muser $ \user -> do
462 482
463 clients <- atomically $ do 483 clients <- atomically $ do
464 -- TODO: Store the stanza 484
485 -- Update remotesByPeer...
486 rbp <- readTVar (remotesByPeer state)
487 let umap = maybe Map.empty id $ Map.lookup k rbp
488 rp = case (presenceShow $ stanzaType stanza) of
489 Offline ->
490 maybe (Map.empty)
491 (Map.delete resource . resources)
492 $ Map.lookup user umap
493 _ -> maybe (Map.singleton resource ())
494 (Map.insert resource () . resources )
495 $ Map.lookup user umap
496 umap' = Map.insert user (RemotePresence rp) umap
497 writeTVar (remotesByPeer state) $ Map.insert k umap' rbp
498 -- TODO: Store or delete the stanza (remotesByPeer)
499
465 -- For now, all clients: 500 -- For now, all clients:
466 -- (TODO: interested/authorized clients only.) 501 -- (TODO: interested/auteorized clients only.)
467 ktc <- readTVar (keyToChan state) 502 ktc <- readTVar (keyToChan state)
468 runTraversableT $ do 503 runTraversableT $ do
469 (ck,client) <- liftMT $ fmap Map.toList $ readTVar (clients state) 504 (ck,client) <- liftMT $ fmap Map.toList $ readTVar (clients state)
@@ -482,15 +517,21 @@ informPeerPresence state k stanza = do
482 (connChan con) 517 (connChan con)
483 518
484answerProbe state k stanza chan = do 519answerProbe state k stanza chan = do
485 putStrLn $ "answerProbe! " ++ show (stanzaType stanza) 520 -- putStrLn $ "answerProbe! " ++ show (stanzaType stanza)
486 ktc <- atomically $ readTVar (keyToChan state) 521 ktc <- atomically $ readTVar (keyToChan state)
487 replies <- runTraversableT $ do 522 muser <- runTraversableT $ do
488 to <- liftMaybe $ stanzaTo stanza 523 to <- liftT $ stanzaTo stanza
489 conn <- liftMaybe $ Map.lookup k ktc 524 conn <- liftT $ Map.lookup k ktc
490 let (mu,h,_) = splitJID to -- TODO: currently resource-id is ignored on presence 525 let (mu,h,_) = splitJID to -- TODO: currently resource-id is ignored on presence
491 -- probes. Is this correct? Check the spec. 526 -- probes. Is this correct? Check the spec.
492 liftIOMaybe $ guardPortStrippedAddress h (auxAddr conn) 527 liftMT $ guardPortStrippedAddress h (auxAddr conn)
493 u <- liftMaybe mu 528 u <- liftT mu
529 let ch = addrToText (auxAddr conn)
530 return (u,conn,ch)
531
532 flip (maybe $ return ()) muser $ \(u,conn,ch) -> do
533
534 replies <- runTraversableT $ do
494 cbu <- lift . atomically $ readTVar (clientsByUser state) 535 cbu <- lift . atomically $ readTVar (clientsByUser state)
495 lpres <- liftMaybe $ Map.lookup u cbu 536 lpres <- liftMaybe $ Map.lookup u cbu
496 clientState <- liftT $ Map.elems (networkClients lpres) 537 clientState <- liftT $ Map.elems (networkClients lpres)
@@ -499,11 +540,16 @@ answerProbe state k stanza chan = do
499 let jid = unsplitJID (Just $ clientUser clientState 540 let jid = unsplitJID (Just $ clientUser clientState
500 , ch 541 , ch
501 ,Just $ clientResource clientState) 542 ,Just $ clientResource clientState)
502 ch = addrToText (auxAddr conn)
503 return stanza { stanzaFrom = Just jid } 543 return stanza { stanzaFrom = Just jid }
544
504 forM_ replies $ \reply -> do 545 forM_ replies $ \reply -> do
505 sendModifiedStanzaToPeer reply chan 546 sendModifiedStanzaToPeer reply chan
506 -- TODO: if null replies, send offline message 547
548 -- if no presence, send offline message
549 when (null replies) $ do
550 let jid = unsplitJID (Just u,ch,Nothing)
551 pstanza <- makePresenceStanza "{jabber:server}" (Just jid) Offline
552 atomically $ writeTChan (connChan conn) pstanza
507 553
508main = runResourceT $ do 554main = runResourceT $ do
509 state <- liftIO . atomically $ do 555 state <- liftIO . atomically $ do