summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2014-03-06 22:47:16 -0500
committerjoe <joe@jerkface.net>2014-03-06 22:47:16 -0500
commite0e39465f0e3816a46d3ee3f3ba8a02d597d39e8 (patch)
treee9fb7500f8d741dfce72233ca6bdc9d0f2cf5a7e
parent8dc56b8f1d6417f2699171fd823fdbfd683ec0ac (diff)
Do not send cached presence until a resource has sent initial presence.
-rw-r--r--Presence/XMPPServer.hs2
-rw-r--r--xmppServer.hs31
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)
31import qualified Data.ByteString.Lazy.Char8 as L 31import qualified Data.ByteString.Lazy.Char8 as L
32import qualified ConfigFiles 32import qualified ConfigFiles
33import Data.Maybe (maybeToList,listToMaybe,mapMaybe) 33import Data.Maybe (maybeToList,listToMaybe,mapMaybe)
34import Data.Bits
35import Data.Int (Int8)
34 36
35import TraversableT 37import TraversableT
36import UTmp (ProcessID,users) 38import 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
78cf_available :: Int8
79cf_available = 0x1
80cf_interested :: Int8
81cf_interested = 0x2
82
76data ClientState = ClientState 83data 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
92clientIsAvailable c = clientFlags c .&. cf_available /= 0
93
94-- | True if the client has requested a roster
95clientIsInterested c = clientFlags c .&. cf_interested /= 0
83 96
84data LocalPresence = LocalPresence 97data 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
554sendCachedPresence state k chan = do 574sendCachedPresence 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