summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2014-03-05 13:54:14 -0500
committerjoe <joe@jerkface.net>2014-03-05 13:54:14 -0500
commit6bf4115d15dbfafbfa6bf435a1b5674ea2b0a008 (patch)
tree1b900600778a5afb9cdc4dc239530e9261bf3574
parent33fea88dca26e3cc8a000ec1c6e043a9759d252c (diff)
reply to probes (untested)
-rw-r--r--Presence/XMPPServer.hs5
-rw-r--r--xmppServer.hs54
2 files changed, 47 insertions, 12 deletions
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs
index 0103ba46..e66eea70 100644
--- a/Presence/XMPPServer.hs
+++ b/Presence/XMPPServer.hs
@@ -183,6 +183,7 @@ data XMPPServerParameters =
183 , xmppTellClientNameOfPeer :: ConnectionKey -> IO Text 183 , xmppTellClientNameOfPeer :: ConnectionKey -> IO Text
184 , xmppDeliverMessage :: (IO ()) -> Stanza -> IO () 184 , xmppDeliverMessage :: (IO ()) -> Stanza -> IO ()
185 , xmppInformClientPresence :: ConnectionKey -> Stanza -> IO () 185 , xmppInformClientPresence :: ConnectionKey -> Stanza -> IO ()
186 , xmppAnswerProbe :: ConnectionKey -> Stanza -> TChan Stanza -> IO ()
186 } 187 }
187 188
188 189
@@ -1569,6 +1570,10 @@ monitor sv params xmpp = do
1569 guard . not . null . mapMaybe (msgBody . snd) $ msgLangMap (stanzaType stanza) 1570 guard . not . null . mapMaybe (msgBody . snd) $ msgLangMap (stanzaType stanza)
1570 stanzaId stanza 1571 stanzaId stanza
1571 _ -> return () 1572 _ -> return ()
1573 NetworkOrigin k@(PeerKey {}) replyto ->
1574 case stanzaType stanza of
1575 PresenceRequestStatus {} -> do
1576 xmppAnswerProbe xmpp k stanza replyto
1572 _ -> return () 1577 _ -> return ()
1573 let deliver replyto = do 1578 let deliver replyto = do
1574 -- TODO: Issuing RecipientUnavailable for all errors is a presence leak 1579 -- TODO: Issuing RecipientUnavailable for all errors is a presence leak
diff --git a/xmppServer.hs b/xmppServer.hs
index a30d15d0..27ae7941 100644
--- a/xmppServer.hs
+++ b/xmppServer.hs
@@ -30,7 +30,7 @@ import Control.Exception ({-evaluate,-}handle,SomeException(..),bracketOnError,E
30import System.Posix.User (getUserEntryForID,userName) 30import 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 (listToMaybe,mapMaybe) 33import Data.Maybe (maybeToList,listToMaybe,mapMaybe)
34 34
35import TraversableT 35import TraversableT
36import UTmp (ProcessID,users) 36import UTmp (ProcessID,users)
@@ -77,6 +77,7 @@ data ClientState = ClientState
77 { clientResource :: Text 77 { clientResource :: Text
78 , clientUser :: Text 78 , clientUser :: Text
79 , clientPid :: Maybe ProcessID 79 , clientPid :: Maybe ProcessID
80 , clientStatus :: TVar (Maybe Stanza)
80 } 81 }
81 82
82 83
@@ -155,9 +156,11 @@ chooseResourceName state k addr desired = do
155 muid <- getLocalPeerCred' addr 156 muid <- getLocalPeerCred' addr
156 (mtty,pid) <- getTTYandPID muid 157 (mtty,pid) <- getTTYandPID muid
157 user <- getJabberUserForId muid 158 user <- getJabberUserForId muid
159 status <- atomically $ newTVar Nothing
158 let client = ClientState { clientResource = maybe "fallback" id mtty 160 let client = ClientState { clientResource = maybe "fallback" id mtty
159 , clientUser = user 161 , clientUser = user
160 , clientPid = pid } 162 , clientPid = pid
163 , clientStatus = status }
161 164
162 atomically $ do 165 atomically $ do
163 modifyTVar' (clients state) $ Map.insert k client 166 modifyTVar' (clients state) $ Map.insert k client
@@ -325,6 +328,16 @@ rewriteJIDForClient laddr jid = do
325 else peerKeyToResolvedName (PeerKey addr) 328 else peerKeyToResolvedName (PeerKey addr)
326 return (mine,(n,h',r)) 329 return (mine,(n,h',r))
327 330
331addrTextToKey h = do
332 maddr <- parseAddress (strip_brackets h)
333 return (fmap PeerKey maddr)
334
335guardPortStrippedAddress h laddr = do
336 maddr <- fmap (fmap (`withPort` 0)) $ parseAddress (strip_brackets h)
337 let laddr' = laddr `withPort` 0
338 return $ maddr >>= guard . (==laddr')
339
340
328-- | Accepts a textual representation of a domainname 341-- | Accepts a textual representation of a domainname
329-- JID suitable for client connections, and returns the 342-- JID suitable for client connections, and returns the
330-- coresponding ipv6 address JID suitable for peers paired 343-- coresponding ipv6 address JID suitable for peers paired
@@ -393,6 +406,30 @@ deliverMessage state fail msg =
393 sendModifiedStanzaToClient dup 406 sendModifiedStanzaToClient dup
394 chan 407 chan
395 408
409informClientPresence state k stanza = do
410 dup <- cloneStanza stanza
411 atomically $ do
412 mb <- fmap (Map.lookup k) $ readTVar (clients state)
413 flip (maybe $ return ()) mb $ \cstate -> do
414 writeTVar (clientStatus cstate) $ Just dup
415
416answerProbe state k stanza chan = do
417 ktc <- atomically $ readTVar (keyToChan state)
418 replies <- runTraversableT $ do
419 let liftMaybe = liftT . maybeToList
420 liftIOMaybe = liftMT . fmap maybeToList
421 to <- liftMaybe $ stanzaTo stanza
422 conn <- liftMaybe $ Map.lookup k ktc
423 let (mu,h,_) = splitJID to -- TODO: currently resource-id is ignored on presence
424 -- probes. Is this correct? Check the spec.
425 cbu <- lift . atomically $ readTVar (clientsByUser state)
426 lpres <- liftMaybe $ Map.lookup u cbu
427 clientState <- liftT $ Map.elems (networkClients lpres)
428 mstanza <- lift $ atomically (readTVar (clientStatus clientState))
429 liftMaybe mstanza
430 forM_ replies $ \reply -> do
431 sendModifiedStanzaToPeer reply chan
432 -- TODO: if null replies, send offline message
396 433
397main = runResourceT $ do 434main = runResourceT $ do
398 state <- liftIO . atomically $ do 435 state <- liftIO . atomically $ do
@@ -425,16 +462,9 @@ main = runResourceT $ do
425 , xmppRosterSolicited = rosterGetSolicited state 462 , xmppRosterSolicited = rosterGetSolicited state
426 , xmppRosterOthers = rosterGetOthers state 463 , xmppRosterOthers = rosterGetOthers state
427 , xmppSubscribeToRoster = \k -> return () 464 , xmppSubscribeToRoster = \k -> return ()
428 -- , xmppLookupClientJID = \k -> return $ "nobody@" <> hostname <> "/tty666" 465 , xmppDeliverMessage = deliverMessage state
429 , {- xmppDeliverMessage = \fail msg -> do 466 , xmppInformClientPresence = informClientPresence state
430 let msgs = msgLangMap (stanzaType msg) 467 , xmppAnswerProbe = answerProbe state
431 body = fmap (maybe "" id . msgBody . snd) $ take 1 msgs
432 when (not $ null body) $ do
433 Text.putStrLn $ "MESSAGE " <> head body
434 return ()
435 -}
436 xmppDeliverMessage = deliverMessage state
437 , xmppInformClientPresence = \k stanza -> return ()
438 } 468 }
439 liftIO $ do 469 liftIO $ do
440 atomically $ putTMVar (server state) sv 470 atomically $ putTMVar (server state) sv