diff options
Diffstat (limited to 'xmppServer.hs')
-rw-r--r-- | xmppServer.hs | 102 |
1 files changed, 30 insertions, 72 deletions
diff --git a/xmppServer.hs b/xmppServer.hs index 4fbb775b..987e7dbc 100644 --- a/xmppServer.hs +++ b/xmppServer.hs | |||
@@ -27,14 +27,12 @@ import Data.Maybe (catMaybes,fromJust) | |||
27 | import Data.Monoid ( (<>) ) | 27 | import Data.Monoid ( (<>) ) |
28 | import Data.Text (Text) | 28 | import Data.Text (Text) |
29 | import qualified Data.Text as Text (pack) | 29 | import qualified Data.Text as Text (pack) |
30 | import qualified Data.Map as Map | ||
31 | 30 | ||
32 | import qualified Control.Concurrent.STM.UpdateStream as Slotted | 31 | import qualified Control.Concurrent.STM.UpdateStream as Slotted |
33 | import ControlMaybe | 32 | import ControlMaybe |
34 | import Nesting | 33 | import Nesting |
35 | import EventUtil | 34 | import EventUtil |
36 | import Server | 35 | import Server |
37 | import Data.Time.Clock (UTCTime,getCurrentTime) | ||
38 | 36 | ||
39 | addrToText :: SockAddr -> Text | 37 | addrToText :: SockAddr -> Text |
40 | addrToText (addr@(SockAddrInet _ _)) = Text.pack $ stripColon (show addr) | 38 | addrToText (addr@(SockAddrInet _ _)) = Text.pack $ stripColon (show addr) |
@@ -288,66 +286,49 @@ forkConnection k pingflag src snk stanzas = do | |||
288 | wlog $ "end reader fork: " ++ show k | 286 | wlog $ "end reader fork: " ++ show k |
289 | return output | 287 | return output |
290 | 288 | ||
289 | data ConnectionKey | ||
290 | = PeerKey { callBackAddress :: SockAddr } | ||
291 | | ClientKey { localAddress :: SockAddr } | ||
292 | deriving (Show, Ord, Eq) | ||
293 | |||
294 | {- | ||
295 | data Peer = Peer | ||
296 | { peerWanted :: TVar Bool -- ^ False when this peer is on a you-call-me basis | ||
297 | , peerState :: TVar PeerState | ||
298 | } | ||
299 | data PeerState | ||
300 | = PeerPendingConnect UTCTime | ||
301 | | PeerPendingAccept UTCTime | ||
302 | | PeerConnected (TChan Stanza) | ||
303 | -} | ||
304 | |||
305 | peerKey (sock,addr) = do | ||
306 | peer <- | ||
307 | sIsConnected sock >>= \c -> | ||
308 | if c then getPeerName sock -- addr is normally socketName | ||
309 | else return addr -- Weird hack: addr is would-be peer name | ||
310 | return $ PeerKey (peer `withPort` fromIntegral peerport) | ||
311 | |||
312 | clientKey (sock,addr) = return $ ClientKey addr | ||
313 | |||
291 | monitor sv params = do | 314 | monitor sv params = do |
292 | chan <- return $ serverEvent sv | 315 | chan <- return $ serverEvent sv |
293 | stanzas <- atomically newTChan | 316 | stanzas <- atomically newTChan |
294 | peersVar <- atomically $ newTVar Map.empty | ||
295 | let doConnect utc k = do | ||
296 | peers <- readTVar peersVar | ||
297 | let mb = Map.lookup k peers | ||
298 | maybe (do false <- newTVar False | ||
299 | pending <- newTVar (PeerPendingConnect utc) | ||
300 | let v = Peer { peerWanted = false | ||
301 | , peerState = pending } | ||
302 | writeTVar (peersVar) $ Map.insert k v peers) | ||
303 | (\peer -> | ||
304 | writeTVar (peerState peer) | ||
305 | $ PeerPendingConnect utc) | ||
306 | mb | ||
307 | fix $ \loop -> do | 317 | fix $ \loop -> do |
308 | action <- atomically $ foldr1 orElse | 318 | action <- atomically $ foldr1 orElse |
309 | [ readTChan chan >>= \(k,e) -> return $ do | 319 | [ readTChan chan >>= \(k,e) -> return $ do |
310 | case e of | 320 | case e of |
311 | Connection pingflag conread conwrite -> do | 321 | Connection pingflag conread conwrite -> do |
312 | wlog $ tomsg k "Connection" | 322 | wlog $ tomsg k "Connection" |
313 | let (xsrc,xsnk) = xmlStream conread conwrite | 323 | let (xsrc,xsnk) = xmlStream conread conwrite |
314 | outs <- forkConnection k pingflag xsrc xsnk stanzas | 324 | forkConnection k pingflag xsrc xsnk stanzas |
315 | atomically $ do | 325 | return () |
316 | peers <- readTVar peersVar | ||
317 | let mb = Map.lookup k peers | ||
318 | maybe (do false <- newTVar True -- False -- TODO: should be False | ||
319 | connected <- newTVar (PeerConnected outs) | ||
320 | let v = Peer { peerWanted = false | ||
321 | , peerState = connected } | ||
322 | writeTVar (peersVar) $ Map.insert k v peers) | ||
323 | (\peer -> do | ||
324 | writeTVar (peerWanted peer) True -- TODO REMOVE | ||
325 | writeTVar (peerState peer) | ||
326 | $ PeerConnected outs) | ||
327 | mb | ||
328 | return () | ||
329 | ConnectFailure addr -> do | 326 | ConnectFailure addr -> do |
330 | wlog $ tomsg k "ConnectFailure" | 327 | wlog $ tomsg k "ConnectFailure" |
331 | action <- atomically $ do | ||
332 | peers <- readTVar peersVar | ||
333 | let mb = Map.lookup k peers | ||
334 | maybe (return $ return ()) | ||
335 | (\peer -> do | ||
336 | wanted <- readTVar (peerWanted peer) | ||
337 | if wanted then return $ do | ||
338 | utc <- getCurrentTime | ||
339 | control sv (Connect addr params) | ||
340 | wlog $ tomsg k "Retry" | ||
341 | atomically $ doConnect utc k | ||
342 | else return $ return ()) | ||
343 | mb | ||
344 | action | ||
345 | EOF -> wlog $ tomsg k "EOF" | 328 | EOF -> wlog $ tomsg k "EOF" |
346 | HalfConnection In -> do | 329 | HalfConnection In -> do |
347 | wlog $ tomsg k "ReadOnly" | 330 | wlog $ tomsg k "ReadOnly" |
348 | utc <- getCurrentTime | ||
349 | control sv (Connect (callBackAddress k) params) | 331 | control sv (Connect (callBackAddress k) params) |
350 | atomically $ doConnect utc k | ||
351 | HalfConnection Out -> wlog $ tomsg k "WriteOnly" | 332 | HalfConnection Out -> wlog $ tomsg k "WriteOnly" |
352 | RequiresPing -> wlog $ tomsg k "RequiresPing" | 333 | RequiresPing -> wlog $ tomsg k "RequiresPing" |
353 | _ -> return () | 334 | _ -> return () |
@@ -363,29 +344,6 @@ monitor sv params = do | |||
363 | where | 344 | where |
364 | _ = str :: String | 345 | _ = str :: String |
365 | 346 | ||
366 | data ConnectionKey | ||
367 | = PeerKey { callBackAddress :: SockAddr } | ||
368 | | ClientKey { localAddress :: SockAddr } | ||
369 | deriving (Show, Ord, Eq) | ||
370 | |||
371 | data Peer = Peer | ||
372 | { peerWanted :: TVar Bool -- ^ False when this peer is on a you-call-me basis | ||
373 | , peerState :: TVar PeerState | ||
374 | } | ||
375 | data PeerState | ||
376 | = PeerPendingConnect UTCTime | ||
377 | | PeerPendingAccept UTCTime | ||
378 | | PeerConnected (TChan Stanza) | ||
379 | |||
380 | peerKey (sock,addr) = do | ||
381 | peer <- | ||
382 | sIsConnected sock >>= \c -> | ||
383 | if c then getPeerName sock -- addr is normally socketName | ||
384 | else return addr -- Weird hack: addr is would-be peer name | ||
385 | return $ PeerKey (peer `withPort` fromIntegral peerport) | ||
386 | |||
387 | clientKey (sock,addr) = return $ ClientKey addr | ||
388 | |||
389 | 347 | ||
390 | peerport = 5269 | 348 | peerport = 5269 |
391 | clientport = 5222 | 349 | clientport = 5222 |
@@ -404,7 +362,7 @@ main = runResourceT $ do | |||
404 | (Just testaddr0) | 362 | (Just testaddr0) |
405 | (Just "5269") | 363 | (Just "5269") |
406 | putStrLn $ "Connecting to "++show testaddr | 364 | putStrLn $ "Connecting to "++show testaddr |
407 | control sv (Connect testaddr peer_params) | 365 | control sv (ConnectWithEndlessRetry testaddr peer_params 2000) |
408 | forkIO $ monitor sv peer_params | 366 | forkIO $ monitor sv peer_params |
409 | control sv (Listen peerport peer_params) | 367 | control sv (Listen peerport peer_params) |
410 | -- control sv (Listen clientport client_params) | 368 | -- control sv (Listen clientport client_params) |