diff options
Diffstat (limited to 'xmppServer.hs')
-rw-r--r-- | xmppServer.hs | 69 |
1 files changed, 25 insertions, 44 deletions
diff --git a/xmppServer.hs b/xmppServer.hs index d5ad7c6a..1ab36cd6 100644 --- a/xmppServer.hs +++ b/xmppServer.hs | |||
@@ -37,6 +37,7 @@ import LocalPeerCred | |||
37 | import XMPPServer | 37 | import XMPPServer |
38 | import PeerResolve | 38 | import PeerResolve |
39 | import ConsoleWriter | 39 | import ConsoleWriter |
40 | import ClientState | ||
40 | 41 | ||
41 | type UserName = Text | 42 | type UserName = Text |
42 | type ResourceName = Text | 43 | type ResourceName = Text |
@@ -74,28 +75,6 @@ localJID user resource = do | |||
74 | hostname <- textHostName | 75 | hostname <- textHostName |
75 | return $ user <> "@" <> hostname <> "/" <> resource | 76 | return $ user <> "@" <> hostname <> "/" <> resource |
76 | 77 | ||
77 | cf_available :: Int8 | ||
78 | cf_available = 0x1 | ||
79 | cf_interested :: Int8 | ||
80 | cf_interested = 0x2 | ||
81 | |||
82 | data ClientState = ClientState | ||
83 | { clientResource :: Text | ||
84 | , clientUser :: Text | ||
85 | , clientPid :: Maybe ProcessID | ||
86 | , clientStatus :: TVar (Maybe Stanza) | ||
87 | , clientFlags :: TVar Int8 | ||
88 | } | ||
89 | |||
90 | -- | True if the client has sent an initial presence | ||
91 | clientIsAvailable c = do | ||
92 | flgs <- readTVar (clientFlags c) | ||
93 | return $ flgs .&. cf_available /= 0 | ||
94 | |||
95 | -- | True if the client has requested a roster | ||
96 | clientIsInterested c = do | ||
97 | flgs <- readTVar (clientFlags c) | ||
98 | return $ flgs .&. cf_interested /= 0 | ||
99 | 78 | ||
100 | data LocalPresence = LocalPresence | 79 | data LocalPresence = LocalPresence |
101 | { networkClients :: Map ConnectionKey ClientState | 80 | { networkClients :: Map ConnectionKey ClientState |
@@ -130,7 +109,7 @@ pcIsEmpty pc = Map.null (networkClients pc) | |||
130 | data PresenceState = PresenceState | 109 | data PresenceState = PresenceState |
131 | { clients :: TVar (Map ConnectionKey ClientState) | 110 | { clients :: TVar (Map ConnectionKey ClientState) |
132 | , clientsByUser :: TVar (Map Text LocalPresence) | 111 | , clientsByUser :: TVar (Map Text LocalPresence) |
133 | , remotesByPeer :: TVar (Map (Maybe ConnectionKey) | 112 | , remotesByPeer :: TVar (Map ConnectionKey |
134 | (Map UserName | 113 | (Map UserName |
135 | RemotePresence)) | 114 | RemotePresence)) |
136 | , associatedPeers :: TVar (Map SockAddr ()) | 115 | , associatedPeers :: TVar (Map SockAddr ()) |
@@ -326,13 +305,13 @@ eofConn state k = do | |||
326 | jids <- atomically $ do | 305 | jids <- atomically $ do |
327 | rbp <- readTVar (remotesByPeer state) | 306 | rbp <- readTVar (remotesByPeer state) |
328 | return $ do | 307 | return $ do |
329 | umap <- maybeToList $ Map.lookup (Just k) rbp | 308 | umap <- maybeToList $ Map.lookup k rbp |
330 | (u,rp) <- Map.toList umap | 309 | (u,rp) <- Map.toList umap |
331 | r <- Map.keys (resources rp) | 310 | r <- Map.keys (resources rp) |
332 | return $ unsplitJID (Just u, h, Just r) | 311 | return $ unsplitJID (Just u, h, Just r) |
333 | forM_ jids $ \jid -> do | 312 | forM_ jids $ \jid -> do |
334 | stanza <- makePresenceStanza "jabber:client" (Just jid) Offline | 313 | stanza <- makePresenceStanza "jabber:client" (Just jid) Offline |
335 | informPeerPresence state (Just k) stanza | 314 | informPeerPresence state k stanza |
336 | 315 | ||
337 | {- | 316 | {- |
338 | rewriteJIDForClient1:: Text -> IO (Maybe ((Maybe Text,Text,Maybe Text),SockAddr)) | 317 | rewriteJIDForClient1:: Text -> IO (Maybe ((Maybe Text,Text,Maybe Text),SockAddr)) |
@@ -480,10 +459,13 @@ deliverMessage state fail msg = | |||
480 | 459 | ||
481 | 460 | ||
482 | setClientFlag state k flag = | 461 | setClientFlag state k flag = |
483 | atomically $ do | 462 | atomically $ do |
484 | cmap <- readTVar (clients state) | 463 | cmap <- readTVar (clients state) |
485 | flip (maybe $ return ()) (Map.lookup k cmap) $ \client -> do | 464 | flip (maybe $ return ()) (Map.lookup k cmap) $ \client -> do |
486 | modifyTVar' (clientFlags client) (\flgs -> flgs .|. flag) | 465 | setClientFlag0 client flag |
466 | |||
467 | setClientFlag0 client flag = | ||
468 | modifyTVar' (clientFlags client) (\flgs -> flgs .|. flag) | ||
487 | 469 | ||
488 | informSentRoster state k = do | 470 | informSentRoster state k = do |
489 | setClientFlag state k cf_interested | 471 | setClientFlag state k cf_interested |
@@ -503,16 +485,16 @@ clientJID con client = unsplitJID ( Just $ clientUser client | |||
503 | -- Note that a full JID from address will be added to the | 485 | -- Note that a full JID from address will be added to the |
504 | -- stanza if it is not present. | 486 | -- stanza if it is not present. |
505 | informClientPresence state k stanza = do | 487 | informClientPresence state k stanza = do |
506 | dup <- cloneStanza stanza | ||
507 | atomically $ do | ||
508 | mb <- fmap (Map.lookup k) $ readTVar (clients state) | ||
509 | flip (maybe $ return ()) mb $ \cstate -> do | ||
510 | writeTVar (clientStatus cstate) $ Just dup | ||
511 | forClient state k (return ()) $ \client -> do | 488 | forClient state k (return ()) $ \client -> do |
489 | informClientPresence0 state (Just k) client stanza | ||
490 | |||
491 | informClientPresence0 state mbk client stanza = do | ||
492 | dup <- cloneStanza stanza | ||
493 | atomically $ writeTVar (clientStatus client) $ Just dup | ||
512 | is_avail <- atomically $ clientIsAvailable client | 494 | is_avail <- atomically $ clientIsAvailable client |
513 | when (not is_avail) $ do | 495 | when (not is_avail) $ do |
514 | setClientFlag state k cf_available | 496 | atomically $ setClientFlag0 client cf_available |
515 | sendCachedPresence state k | 497 | maybe (return ()) (sendCachedPresence state) mbk |
516 | addrs <- subscribedPeers (clientUser client) | 498 | addrs <- subscribedPeers (clientUser client) |
517 | ktc <- atomically $ readTVar (keyToChan state) | 499 | ktc <- atomically $ readTVar (keyToChan state) |
518 | let connected = mapMaybe (flip Map.lookup ktc . PeerKey) addrs | 500 | let connected = mapMaybe (flip Map.lookup ktc . PeerKey) addrs |
@@ -579,7 +561,7 @@ informPeerPresence state k stanza = do | |||
579 | is_avail <- atomically $ clientIsAvailable client | 561 | is_avail <- atomically $ clientIsAvailable client |
580 | when is_avail $ do | 562 | when is_avail $ do |
581 | putStrLn $ "reversing for client: " ++ show from | 563 | putStrLn $ "reversing for client: " ++ show from |
582 | froms <- flip (maybe $ return [from]) k . const $ do | 564 | froms <- do -- flip (maybe $ return [from]) k . const $ do |
583 | let ClientKey laddr = ck | 565 | let ClientKey laddr = ck |
584 | (_,trip) <- multiplyJIDForClient laddr from | 566 | (_,trip) <- multiplyJIDForClient laddr from |
585 | return (map unsplitJID trip) | 567 | return (map unsplitJID trip) |
@@ -649,16 +631,15 @@ sendCachedPresence state k = do | |||
649 | jids <- configText ConfigFiles.getBuddies (clientUser client) | 631 | jids <- configText ConfigFiles.getBuddies (clientUser client) |
650 | let hosts = map ((\(_,h,_)->h) . splitJID) jids | 632 | let hosts = map ((\(_,h,_)->h) . splitJID) jids |
651 | addrs <- resolveAllPeers hosts | 633 | addrs <- resolveAllPeers hosts |
652 | let onlines = rbp `Map.intersection` (Map.insert Nothing () -- send console presences | 634 | let onlines = rbp `Map.intersection` Map.mapKeys PeerKey addrs |
653 | $ Map.mapKeys (Just . PeerKey) addrs) | ||
654 | ClientKey laddr = k | 635 | ClientKey laddr = k |
655 | mcon <- atomically $ do ktc <- readTVar (keyToChan state) | 636 | mcon <- atomically $ do ktc <- readTVar (keyToChan state) |
656 | return $ Map.lookup k ktc | 637 | return $ Map.lookup k ktc |
657 | flip (maybe $ return ()) mcon $ \con -> do | 638 | flip (maybe $ return ()) mcon $ \con -> do |
658 | me <- textHostName | 639 | -- me <- textHostName |
659 | forM_ (Map.toList onlines) $ \(pk, umap) -> do | 640 | forM_ (Map.toList onlines) $ \(pk, umap) -> do |
660 | forM_ (Map.toList umap) $ \(user,rp) -> do | 641 | forM_ (Map.toList umap) $ \(user,rp) -> do |
661 | let h = maybe me peerKeyToText pk | 642 | let h = peerKeyToText pk |
662 | forM_ (Map.toList $ resources rp) $ \(resource,stanza) -> do | 643 | forM_ (Map.toList $ resources rp) $ \(resource,stanza) -> do |
663 | let jid = unsplitJID (Just user,h,Just resource) | 644 | let jid = unsplitJID (Just user,h,Just resource) |
664 | (mine,js) <- multiplyJIDForClient laddr jid | 645 | (mine,js) <- multiplyJIDForClient laddr jid |
@@ -1002,7 +983,7 @@ main = runResourceT $ do | |||
1002 | , xmppSubscribeToRoster = informSentRoster state | 983 | , xmppSubscribeToRoster = informSentRoster state |
1003 | , xmppDeliverMessage = deliverMessage state | 984 | , xmppDeliverMessage = deliverMessage state |
1004 | , xmppInformClientPresence = informClientPresence state | 985 | , xmppInformClientPresence = informClientPresence state |
1005 | , xmppInformPeerPresence = \k -> informPeerPresence state (Just k) | 986 | , xmppInformPeerPresence = informPeerPresence state |
1006 | , xmppAnswerProbe = \k stanza chan -> answerProbe state (stanzaTo stanza) k chan | 987 | , xmppAnswerProbe = \k stanza chan -> answerProbe state (stanzaTo stanza) k chan |
1007 | , xmppClientSubscriptionRequest = clientSubscriptionRequest state | 988 | , xmppClientSubscriptionRequest = clientSubscriptionRequest state |
1008 | , xmppPeerSubscriptionRequest = peerSubscriptionRequest state | 989 | , xmppPeerSubscriptionRequest = peerSubscriptionRequest state |
@@ -1020,8 +1001,8 @@ main = runResourceT $ do | |||
1020 | console <- atomically $ dupTChan (cwPresenceChan $ consoleWriter state) | 1001 | console <- atomically $ dupTChan (cwPresenceChan $ consoleWriter state) |
1021 | fix $ \loop -> do | 1002 | fix $ \loop -> do |
1022 | what <- atomically | 1003 | what <- atomically |
1023 | $ orElse (do stanza <- readTChan console | 1004 | $ orElse (do (client,stanza) <- readTChan console |
1024 | return $ do informPeerPresence state Nothing stanza | 1005 | return $ do informClientPresence0 state Nothing client stanza |
1025 | loop) | 1006 | loop) |
1026 | (do readTMVar quitVar | 1007 | (do readTMVar quitVar |
1027 | return $ return ()) | 1008 | return $ return ()) |