diff options
author | joe <joe@jerkface.net> | 2014-03-06 22:47:16 -0500 |
---|---|---|
committer | joe <joe@jerkface.net> | 2014-03-06 22:47:16 -0500 |
commit | e0e39465f0e3816a46d3ee3f3ba8a02d597d39e8 (patch) | |
tree | e9fb7500f8d741dfce72233ca6bdc9d0f2cf5a7e | |
parent | 8dc56b8f1d6417f2699171fd823fdbfd683ec0ac (diff) |
Do not send cached presence until a resource has sent initial presence.
-rw-r--r-- | Presence/XMPPServer.hs | 2 | ||||
-rw-r--r-- | xmppServer.hs | 31 |
2 files changed, 27 insertions, 6 deletions
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs index 9661391e..4dda1f70 100644 --- a/Presence/XMPPServer.hs +++ b/Presence/XMPPServer.hs | |||
@@ -190,7 +190,6 @@ data XMPPServerParameters = | |||
190 | , xmppInformClientPresence :: ConnectionKey -> Stanza -> IO () | 190 | , xmppInformClientPresence :: ConnectionKey -> Stanza -> IO () |
191 | , xmppInformPeerPresence :: ConnectionKey -> Stanza -> IO () | 191 | , xmppInformPeerPresence :: ConnectionKey -> Stanza -> IO () |
192 | , xmppAnswerProbe :: ConnectionKey -> Stanza -> TChan Stanza -> IO () | 192 | , xmppAnswerProbe :: ConnectionKey -> Stanza -> TChan Stanza -> IO () |
193 | , xmppSendCachedPresenceToClient :: ConnectionKey -> TChan Stanza -> IO () | ||
194 | } | 193 | } |
195 | 194 | ||
196 | 195 | ||
@@ -1592,7 +1591,6 @@ monitor sv params xmpp = do | |||
1592 | (Just rsc) -- to | 1591 | (Just rsc) -- to |
1593 | requestVersion | 1592 | requestVersion |
1594 | >>= ioWriteChan replyto | 1593 | >>= ioWriteChan replyto |
1595 | xmppSendCachedPresenceToClient xmpp k replyto | ||
1596 | SessionRequest -> do | 1594 | SessionRequest -> do |
1597 | me <- xmppTellMyNameToClient xmpp | 1595 | me <- xmppTellMyNameToClient xmpp |
1598 | let reply = iq_session_reply (stanzaId stanza) me | 1596 | let reply = iq_session_reply (stanzaId stanza) me |
diff --git a/xmppServer.hs b/xmppServer.hs index 709137dc..30ce774d 100644 --- a/xmppServer.hs +++ b/xmppServer.hs | |||
@@ -31,6 +31,8 @@ import System.Posix.User (getUserEntryForID,userName) | |||
31 | import qualified Data.ByteString.Lazy.Char8 as L | 31 | import qualified Data.ByteString.Lazy.Char8 as L |
32 | import qualified ConfigFiles | 32 | import qualified ConfigFiles |
33 | import Data.Maybe (maybeToList,listToMaybe,mapMaybe) | 33 | import Data.Maybe (maybeToList,listToMaybe,mapMaybe) |
34 | import Data.Bits | ||
35 | import Data.Int (Int8) | ||
34 | 36 | ||
35 | import TraversableT | 37 | import TraversableT |
36 | import UTmp (ProcessID,users) | 38 | import UTmp (ProcessID,users) |
@@ -73,13 +75,24 @@ localJID user resource = do | |||
73 | hostname <- textHostName | 75 | hostname <- textHostName |
74 | return $ user <> "@" <> hostname <> "/" <> resource | 76 | return $ user <> "@" <> hostname <> "/" <> resource |
75 | 77 | ||
78 | cf_available :: Int8 | ||
79 | cf_available = 0x1 | ||
80 | cf_interested :: Int8 | ||
81 | cf_interested = 0x2 | ||
82 | |||
76 | data ClientState = ClientState | 83 | data ClientState = ClientState |
77 | { clientResource :: Text | 84 | { clientResource :: Text |
78 | , clientUser :: Text | 85 | , clientUser :: Text |
79 | , clientPid :: Maybe ProcessID | 86 | , clientPid :: Maybe ProcessID |
80 | , clientStatus :: TVar (Maybe Stanza) | 87 | , clientStatus :: TVar (Maybe Stanza) |
88 | , clientFlags :: Int8 | ||
81 | } | 89 | } |
82 | 90 | ||
91 | -- | True if the client has sent an initial presence | ||
92 | clientIsAvailable c = clientFlags c .&. cf_available /= 0 | ||
93 | |||
94 | -- | True if the client has requested a roster | ||
95 | clientIsInterested c = clientFlags c .&. cf_interested /= 0 | ||
83 | 96 | ||
84 | data LocalPresence = LocalPresence | 97 | data LocalPresence = LocalPresence |
85 | { networkClients :: Map ConnectionKey ClientState | 98 | { networkClients :: Map ConnectionKey ClientState |
@@ -160,7 +173,8 @@ chooseResourceName state k addr desired = do | |||
160 | let client = ClientState { clientResource = maybe "fallback" id mtty | 173 | let client = ClientState { clientResource = maybe "fallback" id mtty |
161 | , clientUser = user | 174 | , clientUser = user |
162 | , clientPid = pid | 175 | , clientPid = pid |
163 | , clientStatus = status } | 176 | , clientStatus = status |
177 | , clientFlags = 0 } | ||
164 | 178 | ||
165 | atomically $ do | 179 | atomically $ do |
166 | modifyTVar' (clients state) $ Map.insert k client | 180 | modifyTVar' (clients state) $ Map.insert k client |
@@ -454,6 +468,12 @@ informClientPresence state k stanza = do | |||
454 | flip (maybe $ return ()) mb $ \cstate -> do | 468 | flip (maybe $ return ()) mb $ \cstate -> do |
455 | writeTVar (clientStatus cstate) $ Just dup | 469 | writeTVar (clientStatus cstate) $ Just dup |
456 | forClient state k (return ()) $ \client -> do | 470 | forClient state k (return ()) $ \client -> do |
471 | when (not $ clientIsAvailable client) $ do | ||
472 | atomically $ modifyTVar' (clients state) | ||
473 | $ Map.adjust | ||
474 | (\c -> c { clientFlags = clientFlags c .|. cf_available }) | ||
475 | k | ||
476 | sendCachedPresence state k | ||
457 | jids <- configText ConfigFiles.getSubscribers (clientUser client) | 477 | jids <- configText ConfigFiles.getSubscribers (clientUser client) |
458 | let hosts = map ((\(_,h,_)->h) . splitJID) jids | 478 | let hosts = map ((\(_,h,_)->h) . splitJID) jids |
459 | addrs <- fmap Map.keys $ resolveAllPeers hosts | 479 | addrs <- fmap Map.keys $ resolveAllPeers hosts |
@@ -551,7 +571,7 @@ answerProbe state k stanza chan = do | |||
551 | pstanza <- makePresenceStanza "jabber:server" (Just jid) Offline | 571 | pstanza <- makePresenceStanza "jabber:server" (Just jid) Offline |
552 | atomically $ writeTChan (connChan conn) pstanza | 572 | atomically $ writeTChan (connChan conn) pstanza |
553 | 573 | ||
554 | sendCachedPresence state k chan = do | 574 | sendCachedPresence state k = do |
555 | -- TODO: send buddies in remotesByPeer | 575 | -- TODO: send buddies in remotesByPeer |
556 | forClient state k (return ()) $ \client -> do | 576 | forClient state k (return ()) $ \client -> do |
557 | rbp <- atomically $ readTVar (remotesByPeer state) | 577 | rbp <- atomically $ readTVar (remotesByPeer state) |
@@ -569,8 +589,11 @@ sendCachedPresence state k chan = do | |||
569 | forM_ js $ \jid -> do | 589 | forM_ js $ \jid -> do |
570 | let from' = unsplitJID jid | 590 | let from' = unsplitJID jid |
571 | dup <- cloneStanza stanza | 591 | dup <- cloneStanza stanza |
592 | mcon <- atomically $ do ktc <- readTVar (keyToChan state) | ||
593 | return $ Map.lookup k ktc | ||
594 | flip (maybe $ return ()) mcon $ \con -> do | ||
572 | sendModifiedStanzaToClient (dup { stanzaFrom=Just from' }) | 595 | sendModifiedStanzaToClient (dup { stanzaFrom=Just from' }) |
573 | chan -- (connChan con) | 596 | (connChan con) |
574 | 597 | ||
575 | -- TODO: send local buddies in clientsByUser | 598 | -- TODO: send local buddies in clientsByUser |
576 | return () | 599 | return () |
@@ -610,7 +633,7 @@ main = runResourceT $ do | |||
610 | , xmppInformClientPresence = informClientPresence state | 633 | , xmppInformClientPresence = informClientPresence state |
611 | , xmppInformPeerPresence = informPeerPresence state | 634 | , xmppInformPeerPresence = informPeerPresence state |
612 | , xmppAnswerProbe = answerProbe state | 635 | , xmppAnswerProbe = answerProbe state |
613 | , xmppSendCachedPresenceToClient = sendCachedPresence state | 636 | -- , xmppSendCachedPresenceToClient = sendCachedPresence state |
614 | } | 637 | } |
615 | liftIO $ do | 638 | liftIO $ do |
616 | atomically $ putTMVar (server state) sv | 639 | atomically $ putTMVar (server state) sv |