diff options
Diffstat (limited to 'src/Network/Tox')
-rw-r--r-- | src/Network/Tox/DHT/Handlers.hs | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/src/Network/Tox/DHT/Handlers.hs b/src/Network/Tox/DHT/Handlers.hs index 494e319b..d3d36525 100644 --- a/src/Network/Tox/DHT/Handlers.hs +++ b/src/Network/Tox/DHT/Handlers.hs | |||
@@ -1,7 +1,8 @@ | |||
1 | {-# LANGUAGE CPP #-} | ||
1 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} | 2 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} |
3 | {-# LANGUAGE NamedFieldPuns #-} | ||
2 | {-# LANGUAGE PatternSynonyms #-} | 4 | {-# LANGUAGE PatternSynonyms #-} |
3 | {-# LANGUAGE TupleSections #-} | 5 | {-# LANGUAGE TupleSections #-} |
4 | {-# LANGUAGE CPP #-} | ||
5 | module Network.Tox.DHT.Handlers where | 6 | module Network.Tox.DHT.Handlers where |
6 | 7 | ||
7 | import Network.Tox.DHT.Transport as DHTTransport | 8 | import Network.Tox.DHT.Transport as DHTTransport |
@@ -11,7 +12,7 @@ import Crypto.Tox | |||
11 | import Network.Kademlia.Search | 12 | import Network.Kademlia.Search |
12 | import qualified Data.Wrapper.PSQInt as Int | 13 | import qualified Data.Wrapper.PSQInt as Int |
13 | import Network.Kademlia | 14 | import Network.Kademlia |
14 | import Network.Kademlia.Bootstrap (touchBucket) | 15 | import Network.Kademlia.Bootstrap |
15 | import Network.Address (WantIP (..), ipFamily, testIdBit,fromSockAddr, sockAddrPort) | 16 | import Network.Address (WantIP (..), ipFamily, testIdBit,fromSockAddr, sockAddrPort) |
16 | import qualified Network.Kademlia.Routing as R | 17 | import qualified Network.Kademlia.Routing as R |
17 | import Control.TriadCommittee | 18 | import Control.TriadCommittee |
@@ -111,18 +112,28 @@ classify client msg = fromMaybe (IsUnknown "unknown") | |||
111 | 112 | ||
112 | data Routing = Routing | 113 | data Routing = Routing |
113 | { tentativeId :: NodeInfo | 114 | { tentativeId :: NodeInfo |
114 | , sched4 :: !( TVar (Int.PSQ POSIXTime) ) | ||
115 | , routing4 :: !( TVar (R.BucketList NodeInfo) ) | ||
116 | , committee4 :: TriadCommittee NodeId SockAddr | 115 | , committee4 :: TriadCommittee NodeId SockAddr |
117 | , sched6 :: !( TVar (Int.PSQ POSIXTime) ) | ||
118 | , routing6 :: !( TVar (R.BucketList NodeInfo) ) | ||
119 | , committee6 :: TriadCommittee NodeId SockAddr | 116 | , committee6 :: TriadCommittee NodeId SockAddr |
117 | , refresher4 :: BucketRefresher NodeId NodeInfo | ||
118 | , refresher6 :: BucketRefresher NodeId NodeInfo | ||
120 | } | 119 | } |
121 | 120 | ||
121 | sched4 :: Routing -> TVar (Int.PSQ POSIXTime) | ||
122 | sched4 Routing { refresher4 = BucketRefresher { refreshQueue } } = refreshQueue | ||
123 | |||
124 | sched6 :: Routing -> TVar (Int.PSQ POSIXTime) | ||
125 | sched6 Routing { refresher6 = BucketRefresher { refreshQueue } } = refreshQueue | ||
126 | |||
127 | routing4 :: Routing -> TVar (R.BucketList NodeInfo) | ||
128 | routing4 Routing { refresher4 = BucketRefresher { refreshBuckets } } = refreshBuckets | ||
129 | |||
130 | routing6 :: Routing -> TVar (R.BucketList NodeInfo) | ||
131 | routing6 Routing { refresher6 = BucketRefresher { refreshBuckets } } = refreshBuckets | ||
132 | |||
122 | newRouting :: SockAddr -> TransportCrypto | 133 | newRouting :: SockAddr -> TransportCrypto |
123 | -> (TVar (R.BucketList NodeInfo) -> SockAddr -> STM ()) -- ^ invoked on IPv4 change | 134 | -> (TVar (R.BucketList NodeInfo) -> SockAddr -> STM ()) -- ^ invoked on IPv4 change |
124 | -> (TVar (R.BucketList NodeInfo) -> SockAddr -> STM ()) -- ^ invoked on IPv6 change | 135 | -> (TVar (R.BucketList NodeInfo) -> SockAddr -> STM ()) -- ^ invoked on IPv6 change |
125 | -> IO Routing | 136 | -> IO (Client -> Routing) |
126 | newRouting addr crypto update4 update6 = do | 137 | newRouting addr crypto update4 update6 = do |
127 | let tentative_ip4 = fromMaybe (IPv4 $ toEnum 0) (IPv4 <$> fromSockAddr addr) | 138 | let tentative_ip4 = fromMaybe (IPv4 $ toEnum 0) (IPv4 <$> fromSockAddr addr) |
128 | tentative_ip6 = fromMaybe (IPv6 $ toEnum 0) (IPv6 <$> fromSockAddr addr) | 139 | tentative_ip6 = fromMaybe (IPv6 $ toEnum 0) (IPv6 <$> fromSockAddr addr) |
@@ -146,7 +157,17 @@ newRouting addr crypto update4 update6 = do | |||
146 | committee6 <- newTriadCommittee (update6 tbl6) -- updateIPVote tbl6 addr6 | 157 | committee6 <- newTriadCommittee (update6 tbl6) -- updateIPVote tbl6 addr6 |
147 | sched4 <- newTVar Int.empty | 158 | sched4 <- newTVar Int.empty |
148 | sched6 <- newTVar Int.empty | 159 | sched6 <- newTVar Int.empty |
149 | return $ Routing tentative_info sched4 tbl4 committee4 sched6 tbl6 committee6 | 160 | return $ \client -> |
161 | let refresher sched bkts = BucketRefresher | ||
162 | { refreshInterval = 15 * 60 | ||
163 | , refreshQueue = sched | ||
164 | , refreshSearch = nodeSearch client | ||
165 | , refreshBuckets = bkts | ||
166 | , refreshPing = ping client | ||
167 | } | ||
168 | refresher4 = refresher sched4 tbl6 | ||
169 | refresher6 = refresher sched6 tbl6 | ||
170 | in Routing tentative_info committee4 committee6 refresher4 refresher6 | ||
150 | 171 | ||
151 | 172 | ||
152 | -- TODO: This should cover more cases | 173 | -- TODO: This should cover more cases |
@@ -322,26 +343,28 @@ updateRouting client routing orouter naddr msg | |||
322 | | PacketKind 0x21 <- msgType msg = return () -- ignore lan discovery | 343 | | PacketKind 0x21 <- msgType msg = return () -- ignore lan discovery |
323 | | otherwise = do | 344 | | otherwise = do |
324 | case prefer4or6 naddr Nothing of | 345 | case prefer4or6 naddr Nothing of |
325 | Want_IP4 -> updateTable client naddr orouter (routing4 routing) (committee4 routing) (sched4 routing) | 346 | Want_IP4 -> updateTable client naddr orouter (committee4 routing) (refresher4 routing) |
326 | Want_IP6 -> updateTable client naddr orouter (routing6 routing) (committee6 routing) (sched6 routing) | 347 | Want_IP6 -> updateTable client naddr orouter (committee6 routing) (refresher4 routing) |
327 | Want_Both -> error $ "BUG:unreachable at " ++ __FILE__ ++ ":" ++ show __LINE__ | 348 | Want_Both -> error $ "BUG:unreachable at " ++ __FILE__ ++ ":" ++ show __LINE__ |
328 | 349 | ||
329 | updateTable :: Client -> NodeInfo -> OnionRouter -> TVar (R.BucketList NodeInfo) -> TriadCommittee NodeId SockAddr -> TVar (Int.PSQ POSIXTime) -> IO () | 350 | updateTable :: Client -> NodeInfo -> OnionRouter -> TriadCommittee NodeId SockAddr -> BucketRefresher NodeId NodeInfo -> IO () |
330 | updateTable client naddr orouter tbl committee sched = do | 351 | updateTable client naddr orouter committee refresher = do |
331 | self <- atomically $ R.thisNode <$> readTVar tbl | 352 | self <- atomically $ R.thisNode <$> readTVar (refreshBuckets refresher) |
332 | when (nodeIP self /= nodeIP naddr) $ do | 353 | when (nodeIP self /= nodeIP naddr) $ do |
333 | -- TODO: IP address vote? | 354 | -- TODO: IP address vote? |
334 | insertNode (toxKademlia client committee orouter tbl sched) naddr | 355 | insertNode (toxKademlia client committee orouter refresher) naddr |
335 | 356 | ||
336 | toxKademlia :: Client -> TriadCommittee NodeId SockAddr -> OnionRouter -> TVar (R.BucketList NodeInfo) -> TVar (Int.PSQ POSIXTime) -> Kademlia NodeId NodeInfo | 357 | toxKademlia :: Client -> TriadCommittee NodeId SockAddr -> OnionRouter |
337 | toxKademlia client committee orouter var sched | 358 | -> BucketRefresher NodeId NodeInfo |
359 | -> Kademlia NodeId NodeInfo | ||
360 | toxKademlia client committee orouter refresher | ||
338 | = Kademlia quietInsertions | 361 | = Kademlia quietInsertions |
339 | toxSpace | 362 | toxSpace |
340 | (vanillaIO var $ ping client) | 363 | (vanillaIO (refreshBuckets refresher) $ ping client) |
341 | { tblTransition = \tr -> do | 364 | { tblTransition = \tr -> do |
342 | io1 <- transitionCommittee committee tr | 365 | io1 <- transitionCommittee committee tr |
343 | io2 <- touchBucket toxSpace (15*60) var sched tr | 366 | io2 <- touchBucket refresher tr -- toxSpace (15*60) var sched tr |
344 | hookBucketList toxSpace var orouter tr | 367 | hookBucketList toxSpace (refreshBuckets refresher) orouter tr |
345 | return $ do | 368 | return $ do |
346 | io1 >> io2 | 369 | io1 >> io2 |
347 | {- | 370 | {- |