diff options
Diffstat (limited to 'Presence/Presence.hs')
-rw-r--r-- | Presence/Presence.hs | 65 |
1 files changed, 51 insertions, 14 deletions
diff --git a/Presence/Presence.hs b/Presence/Presence.hs index 4f0deb32..fad87aeb 100644 --- a/Presence/Presence.hs +++ b/Presence/Presence.hs | |||
@@ -475,19 +475,49 @@ delclient k mlp = do | |||
475 | 475 | ||
476 | eofConn :: PresenceState -> SockAddr -> ConnectionData -> IO () | 476 | eofConn :: PresenceState -> SockAddr -> ConnectionData -> IO () |
477 | eofConn state saddr cdta = do | 477 | eofConn state saddr cdta = do |
478 | atomically $ case classifyConnection saddr cdta of | ||
479 | Left (pkey,_) -> modifyTVar' (pkeyToChan state) $ Map.delete pkey | ||
480 | Right (ckey,_) -> modifyTVar' (ckeyToChan state) $ Map.delete ckey | ||
481 | case classifyConnection saddr cdta of | 478 | case classifyConnection saddr cdta of |
482 | Left (k,_) -> do | 479 | Left (k,_) -> do |
483 | let h = peerKeyToText k | 480 | h <- case cdType cdta of |
481 | -- TODO: This should be cached (perhaps by rewriteJIDForClient?) so that we | ||
482 | -- guarantee that the OFFLINE message matches the ONLINE message. | ||
483 | -- For now, we reverse-resolve the peer key. | ||
484 | XMPP -> -- For XMPP peers, informPeerPresence expects a textual | ||
485 | -- representation of the IP address to reverse-resolve. | ||
486 | return $ peerKeyToText k | ||
487 | Tox -> do | ||
488 | -- For Tox peers, informPeerPresence expects the actual hostname | ||
489 | -- so we will use the one that the peer told us at greeting time. | ||
490 | m <- atomically $ swapTVar (cdRemoteName cdta) Nothing | ||
491 | case m of | ||
492 | Nothing -> do | ||
493 | dput XJabber $ "BUG: Tox peer didn't inform us of its name." | ||
494 | -- The following fallback behavior is probably wrong. | ||
495 | return $ peerKeyToText k | ||
496 | Just toxname -> return toxname | ||
497 | -- ioToSource terminated. | ||
498 | -- | ||
499 | -- dhtd: Network.Socket.getAddrInfo | ||
500 | -- (called with preferred socket type/protocol: AddrInfo | ||
501 | -- { addrFlags = [AI_NUMERICHOST], addrFamily = AF_UNSPEC | ||
502 | -- , addrSocketType = NoSocketType, addrProtocol = 0 | ||
503 | -- , addrAddress = <assumed to be undefined> | ||
504 | -- , addrCanonName = <assumed to be undefined>} | ||
505 | -- , host name: Just "DdhbLjiwaV0GAiGKgesNPbvj2TbhrBHEWEEc5icfvQN.tox" | ||
506 | -- , service name: Just "0") | ||
507 | -- : does not exist (Name or service not known) | ||
508 | |||
484 | jids <- atomically $ do | 509 | jids <- atomically $ do |
485 | rbp <- readTVar (remotesByPeer state) | 510 | rbp <- readTVar (remotesByPeer state) |
486 | return $ do | 511 | return $ do |
487 | umap <- maybeToList $ Map.lookup k rbp | 512 | umap <- maybeToList $ Map.lookup k rbp |
488 | (u,rp) <- Map.toList umap | 513 | (u,rp) <- Map.toList umap |
489 | r <- Map.keys (resources rp) | 514 | r <- Map.keys (resources rp) |
490 | return $ unsplitJID (Just u, h, Just r) | 515 | let excludeEmpty "" = Nothing |
516 | excludeEmpty x = Just x | ||
517 | return $ unsplitJID (excludeEmpty u, h, excludeEmpty r) | ||
518 | -- EOF PEER PeerAddress [d768:82dd:3e86:a6ba:8fb3:6f9c:6327:75d8%4236342772]:0: | ||
519 | -- ["@[d768:82dd:3e86:a6ba:8fb3:6f9c:6327:75d8%4236342772]/"] | ||
520 | -- dput XJabber $ "EOF PEER "++show k++": "++show jids | ||
491 | forM_ jids $ \jid -> do | 521 | forM_ jids $ \jid -> do |
492 | stanza <- makePresenceStanza "jabber:client" (Just jid) Offline | 522 | stanza <- makePresenceStanza "jabber:client" (Just jid) Offline |
493 | informPeerPresence state k stanza | 523 | informPeerPresence state k stanza |
@@ -502,6 +532,9 @@ eofConn state saddr cdta = do | |||
502 | atomically $ do | 532 | atomically $ do |
503 | modifyTVar' (clientsByUser state) $ Map.alter (delclient k) (clientUser client) | 533 | modifyTVar' (clientsByUser state) $ Map.alter (delclient k) (clientUser client) |
504 | modifyTVar' (clientsByProfile state) $ Map.alter (delclient k) (clientProfile client) | 534 | modifyTVar' (clientsByProfile state) $ Map.alter (delclient k) (clientProfile client) |
535 | atomically $ case classifyConnection saddr cdta of | ||
536 | Left (pkey,_) -> modifyTVar' (pkeyToChan state) $ Map.delete pkey | ||
537 | Right (ckey,_) -> modifyTVar' (ckeyToChan state) $ Map.delete ckey | ||
505 | 538 | ||
506 | {- | 539 | {- |
507 | parseRemoteAddress :: Text -> IO (Maybe (Remote SockAddr)) | 540 | parseRemoteAddress :: Text -> IO (Maybe (Remote SockAddr)) |
@@ -594,8 +627,9 @@ deliverMessage state fail msg = | |||
594 | -- Case 1. Client -> Peer | 627 | -- Case 1. Client -> Peer |
595 | mto <- join $ atomically $ do | 628 | mto <- join $ atomically $ do |
596 | mclient <- Map.lookup senderk <$> readTVar (clients state) | 629 | mclient <- Map.lookup senderk <$> readTVar (clients state) |
597 | return | 630 | return $ do |
598 | $ fromMaybe -- Resolve XMPP peer. | 631 | dput XJabber $ "deliverMessage: to="++show (stanzaTo msg,fmap clientProfile mclient) |
632 | fromMaybe -- Resolve XMPP peer. | ||
599 | (fmap join $ mapM rewriteJIDForPeer (stanzaTo msg)) | 633 | (fmap join $ mapM rewriteJIDForPeer (stanzaTo msg)) |
600 | $ do | 634 | $ do |
601 | client <- mclient | 635 | client <- mclient |
@@ -603,6 +637,7 @@ deliverMessage state fail msg = | |||
603 | let (mu,th,rsc) = splitJID to | 637 | let (mu,th,rsc) = splitJID to |
604 | (toxman,me,_) <- weAreTox state client th | 638 | (toxman,me,_) <- weAreTox state client th |
605 | return $ do | 639 | return $ do |
640 | dput XJabber $ "deliverMessage: weAreTox="++show me | ||
606 | -- In case the client sends us a lower-cased version of the base64 | 641 | -- In case the client sends us a lower-cased version of the base64 |
607 | -- tox key hostname, we resolve it by comparing it with roster entries. | 642 | -- tox key hostname, we resolve it by comparing it with roster entries. |
608 | xs <- getBuddiesAndSolicited state (clientProfile client) $ \case | 643 | xs <- getBuddiesAndSolicited state (clientProfile client) $ \case |
@@ -637,7 +672,7 @@ deliverMessage state fail msg = | |||
637 | fail) | 672 | fail) |
638 | $ Map.lookup senderk pchans | 673 | $ Map.lookup senderk pchans |
639 | <&> \(Conn { connChan = sender_chan | 674 | <&> \(Conn { connChan = sender_chan |
640 | , auxData = ConnectionData (Left laddr) ctyp cprof }) -> do | 675 | , auxData = ConnectionData (Left laddr) ctyp cprof _ }) -> do |
641 | fromMaybe (do dput XJabber $ "Message missing \"to\" attribute." | 676 | fromMaybe (do dput XJabber $ "Message missing \"to\" attribute." |
642 | fail) | 677 | fail) |
643 | $ (stanzaTo msg) <&> \to -> do | 678 | $ (stanzaTo msg) <&> \to -> do |
@@ -777,7 +812,7 @@ informPeerPresence state k stanza = do | |||
777 | let (muser0,h,mresource0) = splitJID from | 812 | let (muser0,h,mresource0) = splitJID from |
778 | -- We'll allow the case that user and resource are simultaneously | 813 | -- We'll allow the case that user and resource are simultaneously |
779 | -- absent. They will be stored in the remotesByPeer map using the | 814 | -- absent. They will be stored in the remotesByPeer map using the |
780 | -- empty string. This is to accomodate the tox protocol which didn't | 815 | -- empty string. This is to accommodate the tox protocol which didn't |
781 | -- anticipate a single peer would have multiple users or front-ends. | 816 | -- anticipate a single peer would have multiple users or front-ends. |
782 | (muser,mresource) = case (muser0,mresource0) of | 817 | (muser,mresource) = case (muser0,mresource0) of |
783 | (Nothing,Nothing) -> (Just "", Just "") | 818 | (Nothing,Nothing) -> (Just "", Just "") |
@@ -826,14 +861,16 @@ informPeerPresence state k stanza = do | |||
826 | (ctyp,cprof) <- atomically $ do | 861 | (ctyp,cprof) <- atomically $ do |
827 | mconn <- Map.lookup k <$> readTVar (pkeyToChan state) | 862 | mconn <- Map.lookup k <$> readTVar (pkeyToChan state) |
828 | return $ fromMaybe (XMPP,".") $ do | 863 | return $ fromMaybe (XMPP,".") $ do |
829 | ConnectionData _ ctyp cprof <- auxData <$> mconn | 864 | ConnectionData _ ctyp cprof _ <- auxData <$> mconn |
830 | return (ctyp,cprof) | 865 | return (ctyp,cprof) |
831 | forM_ clients $ \(ck,con,client) -> do | 866 | forM_ clients $ \(ck,con,client) -> do |
832 | -- (TODO: appropriately authorized clients only.) | 867 | -- (TODO: appropriately authorized clients only.) |
833 | -- For now, all "available" clients (available = sent initial presence) | 868 | -- For now, all "available" clients (available = sent initial presence) |
834 | is_avail <- atomically $ clientIsAvailable client | 869 | is_avail <- atomically $ clientIsAvailable client |
835 | when is_avail $ do | 870 | when is_avail $ do |
836 | dput XJabber $ "reversing for client: " ++ show from | 871 | -- reversing for client: ("DdhbLjiwaV0GAiGKgesNPbvj2TbhrBHEWEEc5icfvQN.tox" |
872 | -- ,XMPP,"OrjBG.GyWuQhGc1pb0KssgmYAocohFh35Vx8mREC9Nu.tox",".") | ||
873 | dput XJabber $ "reversing for client: " ++ show (from,ctyp,clientProfile client,cprof) | ||
837 | froms <- case ctyp of | 874 | froms <- case ctyp of |
838 | Tox | clientProfile client == cprof -> return [from] | 875 | Tox | clientProfile client == cprof -> return [from] |
839 | _ -> do -- flip (maybe $ return [from]) k . const $ do | 876 | _ -> do -- flip (maybe $ return [from]) k . const $ do |
@@ -1030,7 +1067,7 @@ clientSubscriptionRequest :: PresenceState -> IO () -> ClientAddress -> Stanza - | |||
1030 | clientSubscriptionRequest state fail k stanza chan = do | 1067 | clientSubscriptionRequest state fail k stanza chan = do |
1031 | forClient state k fail $ \client -> do | 1068 | forClient state k fail $ \client -> do |
1032 | fromMaybe fail $ (splitJID <$> stanzaTo stanza) <&> \(mu,h,_) -> do | 1069 | fromMaybe fail $ (splitJID <$> stanzaTo stanza) <&> \(mu,h,_) -> do |
1033 | dput XJabber $ "Forwarding solictation to peer" | 1070 | dput XJabber $ "Forwarding solicitation to peer" |
1034 | let to0 = unsplitJID (mu,h,Nothing) -- deleted resource | 1071 | let to0 = unsplitJID (mu,h,Nothing) -- deleted resource |
1035 | cuser = clientUser client | 1072 | cuser = clientUser client |
1036 | cprof = clientProfile client | 1073 | cprof = clientProfile client |
@@ -1166,7 +1203,7 @@ peerSubscriptionRequest state fail k stanza chan = do | |||
1166 | cmap <- readTVar (clients state) | 1203 | cmap <- readTVar (clients state) |
1167 | return (pktc,cktc,cmap) | 1204 | return (pktc,cktc,cmap) |
1168 | fromMaybe fail $ (Map.lookup k pktc) | 1205 | fromMaybe fail $ (Map.lookup k pktc) |
1169 | <&> \Conn { auxData=ConnectionData (Left laddr) ctyp profile } -> do | 1206 | <&> \Conn { auxData=ConnectionData (Left laddr) ctyp profile _ } -> do |
1170 | (mine,totup) <- case (ctyp,profile) of | 1207 | (mine,totup) <- case (ctyp,profile) of |
1171 | (Tox,p) -> let (u,h,r) = splitJID to | 1208 | (Tox,p) -> let (u,h,r) = splitJID to |
1172 | in return ( h == p, (u,h,r) ) | 1209 | in return ( h == p, (u,h,r) ) |
@@ -1314,7 +1351,7 @@ peerInformSubscription state fail k stanza = do | |||
1314 | return (pktc,cktc,cmap) | 1351 | return (pktc,cktc,cmap) |
1315 | fromMaybe fail $ Map.lookup k ktc | 1352 | fromMaybe fail $ Map.lookup k ktc |
1316 | <&> \(Conn { connChan=sender_chan | 1353 | <&> \(Conn { connChan=sender_chan |
1317 | , auxData =ConnectionData (Left laddr) ctyp profile}) -> do | 1354 | , auxData =ConnectionData (Left laddr) ctyp profile _ }) -> do |
1318 | (from_u,from_h,_) <- case ctyp of | 1355 | (from_u,from_h,_) <- case ctyp of |
1319 | Tox -> return $ splitJID from | 1356 | Tox -> return $ splitJID from |
1320 | XMPP -> snd <$> rewriteJIDForClient laddr from [] | 1357 | XMPP -> snd <$> rewriteJIDForClient laddr from [] |