summaryrefslogtreecommitdiff
path: root/src/Network/Tox
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/Tox')
-rw-r--r--src/Network/Tox/DHT/Handlers.hs61
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 #-}
5module Network.Tox.DHT.Handlers where 6module Network.Tox.DHT.Handlers where
6 7
7import Network.Tox.DHT.Transport as DHTTransport 8import Network.Tox.DHT.Transport as DHTTransport
@@ -11,7 +12,7 @@ import Crypto.Tox
11import Network.Kademlia.Search 12import Network.Kademlia.Search
12import qualified Data.Wrapper.PSQInt as Int 13import qualified Data.Wrapper.PSQInt as Int
13import Network.Kademlia 14import Network.Kademlia
14import Network.Kademlia.Bootstrap (touchBucket) 15import Network.Kademlia.Bootstrap
15import Network.Address (WantIP (..), ipFamily, testIdBit,fromSockAddr, sockAddrPort) 16import Network.Address (WantIP (..), ipFamily, testIdBit,fromSockAddr, sockAddrPort)
16import qualified Network.Kademlia.Routing as R 17import qualified Network.Kademlia.Routing as R
17import Control.TriadCommittee 18import Control.TriadCommittee
@@ -111,18 +112,28 @@ classify client msg = fromMaybe (IsUnknown "unknown")
111 112
112data Routing = Routing 113data 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
121sched4 :: Routing -> TVar (Int.PSQ POSIXTime)
122sched4 Routing { refresher4 = BucketRefresher { refreshQueue } } = refreshQueue
123
124sched6 :: Routing -> TVar (Int.PSQ POSIXTime)
125sched6 Routing { refresher6 = BucketRefresher { refreshQueue } } = refreshQueue
126
127routing4 :: Routing -> TVar (R.BucketList NodeInfo)
128routing4 Routing { refresher4 = BucketRefresher { refreshBuckets } } = refreshBuckets
129
130routing6 :: Routing -> TVar (R.BucketList NodeInfo)
131routing6 Routing { refresher6 = BucketRefresher { refreshBuckets } } = refreshBuckets
132
122newRouting :: SockAddr -> TransportCrypto 133newRouting :: 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)
126newRouting addr crypto update4 update6 = do 137newRouting 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
329updateTable :: Client -> NodeInfo -> OnionRouter -> TVar (R.BucketList NodeInfo) -> TriadCommittee NodeId SockAddr -> TVar (Int.PSQ POSIXTime) -> IO () 350updateTable :: Client -> NodeInfo -> OnionRouter -> TriadCommittee NodeId SockAddr -> BucketRefresher NodeId NodeInfo -> IO ()
330updateTable client naddr orouter tbl committee sched = do 351updateTable 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
336toxKademlia :: Client -> TriadCommittee NodeId SockAddr -> OnionRouter -> TVar (R.BucketList NodeInfo) -> TVar (Int.PSQ POSIXTime) -> Kademlia NodeId NodeInfo 357toxKademlia :: Client -> TriadCommittee NodeId SockAddr -> OnionRouter
337toxKademlia client committee orouter var sched 358 -> BucketRefresher NodeId NodeInfo
359 -> Kademlia NodeId NodeInfo
360toxKademlia 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 {-