diff options
author | James Crayne <jim.crayne@gmail.com> | 2019-09-28 13:43:29 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2020-01-01 19:27:53 -0500 |
commit | 11987749fc6e6d3e53ea737d46d5ab13a16faeb8 (patch) | |
tree | 5716463275c2d3e902889db619908ded2a73971c /src/Network/SessionTransports.hs | |
parent | add2c76bced51fde5e9917e7449ef52be70faf87 (diff) |
Factor out some new libraries
word64-map:
Data.Word64Map
network-addr:
Network.Address
tox-crypto:
Crypto.Tox
lifted-concurrent:
Control.Concurrent.Lifted.Instrument
Control.Concurrent.Async.Lifted.Instrument
psq-wrap:
Data.Wrapper.PSQInt
Data.Wrapper.PSQ
minmax-psq:
Data.MinMaxPSQ
tasks:
Control.Concurrent.Tasks
kad:
Network.Kademlia
Network.Kademlia.Bootstrap
Network.Kademlia.Routing
Network.Kademlia.CommonAPI
Network.Kademlia.Persistence
Network.Kademlia.Search
Diffstat (limited to 'src/Network/SessionTransports.hs')
-rw-r--r-- | src/Network/SessionTransports.hs | 98 |
1 files changed, 0 insertions, 98 deletions
diff --git a/src/Network/SessionTransports.hs b/src/Network/SessionTransports.hs deleted file mode 100644 index e9daf6c1..00000000 --- a/src/Network/SessionTransports.hs +++ /dev/null | |||
@@ -1,98 +0,0 @@ | |||
1 | {-# LANGUAGE NamedFieldPuns #-} | ||
2 | module Network.SessionTransports | ||
3 | ( Sessions | ||
4 | , initSessions | ||
5 | , newSession | ||
6 | , sessionHandler | ||
7 | ) where | ||
8 | |||
9 | import Control.Concurrent | ||
10 | import Control.Concurrent.STM | ||
11 | import Control.Monad | ||
12 | import qualified Data.IntMap.Strict as IntMap | ||
13 | ;import Data.IntMap.Strict (IntMap) | ||
14 | import qualified Data.Map.Strict as Map | ||
15 | ;import Data.Map.Strict (Map) | ||
16 | |||
17 | import Network.Address (SockAddr,either4or6) | ||
18 | import Network.QueryResponse | ||
19 | import qualified Data.IntervalSet as S | ||
20 | ;import Data.IntervalSet (IntSet) | ||
21 | |||
22 | data Sessions x = Sessions | ||
23 | { sessionsByAddr :: TVar (Map SockAddr (IntMap (x -> IO Bool))) | ||
24 | , sessionsById :: TVar (IntMap SockAddr) | ||
25 | , sessionIds :: TVar IntSet | ||
26 | , sessionsSendRaw :: SockAddr -> x -> IO () | ||
27 | } | ||
28 | |||
29 | initSessions :: (SockAddr -> x -> IO ()) -> IO (Sessions x) | ||
30 | initSessions send = atomically $ do | ||
31 | byaddr <- newTVar Map.empty | ||
32 | byid <- newTVar IntMap.empty | ||
33 | idset <- newTVar S.empty | ||
34 | return Sessions { sessionsByAddr = byaddr | ||
35 | , sessionsById = byid | ||
36 | , sessionIds = idset | ||
37 | , sessionsSendRaw = send | ||
38 | } | ||
39 | |||
40 | |||
41 | |||
42 | rmSession :: Int -> (Maybe (IntMap x)) -> (Maybe (IntMap x)) | ||
43 | rmSession sid Nothing = Nothing | ||
44 | rmSession sid (Just m) = case IntMap.delete sid m of | ||
45 | m' | IntMap.null m' -> Nothing | ||
46 | | otherwise -> Just m' | ||
47 | |||
48 | newSession :: Sessions raw | ||
49 | -> (addr -> y -> IO raw) | ||
50 | -> (SockAddr -> raw -> IO (Maybe (x, addr))) | ||
51 | -> SockAddr | ||
52 | -> IO (Maybe (Int,TransportA err addr x y)) | ||
53 | newSession Sessions{sessionsByAddr,sessionsById,sessionIds,sessionsSendRaw} unwrap wrap addr0 = do | ||
54 | mvar <- newEmptyMVar | ||
55 | let saddr = -- Canonical in case of 6-mapped-4 addresses. | ||
56 | either id id $ either4or6 addr0 | ||
57 | handlePacket x = do | ||
58 | m <- wrap saddr x | ||
59 | case m of | ||
60 | Nothing -> return False | ||
61 | Just x' -> do putMVar mvar $! Just $! x' | ||
62 | return True | ||
63 | msid <- atomically $ do | ||
64 | msid <- S.nearestOutsider 0 <$> readTVar sessionIds | ||
65 | forM msid $ \sid -> do | ||
66 | modifyTVar' sessionIds $ S.insert sid | ||
67 | modifyTVar' sessionsById $ IntMap.insert sid saddr | ||
68 | modifyTVar' sessionsByAddr $ Map.insertWith IntMap.union saddr | ||
69 | $ IntMap.singleton sid handlePacket | ||
70 | return sid | ||
71 | forM msid $ \sid -> do | ||
72 | let tr = Transport | ||
73 | { awaitMessage = \kont -> do | ||
74 | x <- takeMVar mvar | ||
75 | kont $! Right <$> x | ||
76 | , sendMessage = \addr x -> do | ||
77 | x' <- unwrap addr x | ||
78 | sessionsSendRaw saddr x' | ||
79 | , closeTransport = do | ||
80 | tryTakeMVar mvar | ||
81 | putMVar mvar Nothing | ||
82 | atomically $ do | ||
83 | modifyTVar' sessionIds $ S.delete sid | ||
84 | modifyTVar' sessionsById $ IntMap.delete sid | ||
85 | modifyTVar' sessionsByAddr $ Map.alter (rmSession sid) saddr | ||
86 | } | ||
87 | return (sid,tr) | ||
88 | |||
89 | sessionHandler :: Sessions x -> (SockAddr -> x -> IO (Maybe (x -> x))) | ||
90 | sessionHandler Sessions{sessionsByAddr} = \addr0 x -> do | ||
91 | let addr = -- Canonical in case of 6-mapped-4 addresses. | ||
92 | either id id $ either4or6 addr0 | ||
93 | dispatch [] = return () | ||
94 | dispatch (f:fs) = do b <- f x | ||
95 | when (not b) $ dispatch fs | ||
96 | fs <- atomically $ Map.lookup addr <$> readTVar sessionsByAddr | ||
97 | mapM_ (dispatch . IntMap.elems) fs | ||
98 | return Nothing -- consume all packets. | ||