summaryrefslogtreecommitdiff
path: root/dht/src/Network/Tox/DHT/Handlers.hs
diff options
context:
space:
mode:
Diffstat (limited to 'dht/src/Network/Tox/DHT/Handlers.hs')
-rw-r--r--dht/src/Network/Tox/DHT/Handlers.hs58
1 files changed, 45 insertions, 13 deletions
diff --git a/dht/src/Network/Tox/DHT/Handlers.hs b/dht/src/Network/Tox/DHT/Handlers.hs
index d132da88..f4563a3b 100644
--- a/dht/src/Network/Tox/DHT/Handlers.hs
+++ b/dht/src/Network/Tox/DHT/Handlers.hs
@@ -133,8 +133,8 @@ data Routing = Routing
133 { tentativeId :: NodeInfo 133 { tentativeId :: NodeInfo
134 , committee4 :: TriadCommittee NodeId SockAddr 134 , committee4 :: TriadCommittee NodeId SockAddr
135 , committee6 :: TriadCommittee NodeId SockAddr 135 , committee6 :: TriadCommittee NodeId SockAddr
136 , refresher4 :: BucketRefresher NodeId NodeInfo 136 , refresher4 :: BucketRefresher NodeId NodeInfo TransactionId
137 , refresher6 :: BucketRefresher NodeId NodeInfo 137 , refresher6 :: BucketRefresher NodeId NodeInfo TransactionId
138 , nodesOfInterest :: TVar (HashMap NodeId [NodeInfoCallback]) 138 , nodesOfInterest :: TVar (HashMap NodeId [NodeInfoCallback])
139 } 139 }
140 140
@@ -172,6 +172,20 @@ routing4 Routing { refresher4 = BucketRefresher { refreshBuckets } } = refreshBu
172routing6 :: Routing -> TVar (R.BucketList NodeInfo) 172routing6 :: Routing -> TVar (R.BucketList NodeInfo)
173routing6 Routing { refresher6 = BucketRefresher { refreshBuckets } } = refreshBuckets 173routing6 Routing { refresher6 = BucketRefresher { refreshBuckets } } = refreshBuckets
174 174
175nullTransactionId :: TransactionId
176nullTransactionId = TransactionId (Nonce8 0) (Nonce24 zeros24)
177
178nullSearch :: Search NodeId (IP, PortNumber) tok NodeInfo r TransactionId
179nullSearch = Search
180 { searchSpace = toxSpace
181 , searchNodeAddress = nodeIP &&& nodePort
182 , searchQuery = \_ _ f -> f nullTransactionId Canceled >> return nullTransactionId
183 , searchQueryCancel = \_ _ -> return ()
184 , searchAlpha = 1
185 , searchK = 2
186 }
187
188
175newRouting :: SockAddr -> TransportCrypto 189newRouting :: SockAddr -> TransportCrypto
176 -> (TVar (R.BucketList NodeInfo) -> SockAddr -> STM ()) -- ^ invoked on IPv4 change 190 -> (TVar (R.BucketList NodeInfo) -> SockAddr -> STM ()) -- ^ invoked on IPv4 change
177 -> (TVar (R.BucketList NodeInfo) -> SockAddr -> STM ()) -- ^ invoked on IPv6 change 191 -> (TVar (R.BucketList NodeInfo) -> SockAddr -> STM ()) -- ^ invoked on IPv6 change
@@ -195,13 +209,6 @@ newRouting addr crypto update4 update6 = do
195 -- We defer initializing the refreshSearch and refreshPing until we 209 -- We defer initializing the refreshSearch and refreshPing until we
196 -- have a client to send queries with. 210 -- have a client to send queries with.
197 let nullPing = const $ return False 211 let nullPing = const $ return False
198 nullSearch = Search
199 { searchSpace = toxSpace
200 , searchNodeAddress = nodeIP &&& nodePort
201 , searchQuery = \_ _ -> return Canceled
202 , searchAlpha = 1
203 , searchK = 2
204 }
205 tbl4 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info4 R.defaultBucketCount 212 tbl4 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info4 R.defaultBucketCount
206 tbl6 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info6 R.defaultBucketCount 213 tbl6 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info6 R.defaultBucketCount
207 refresher4 <- newBucketRefresher tbl4 nullSearch nullPing 214 refresher4 <- newBucketRefresher tbl4 nullSearch nullPing
@@ -432,6 +439,30 @@ getNodesUDP :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> NodeId -> N
432 -> IO (QR.Result ([NodeInfo],[NodeInfo],Maybe ())) 439 -> IO (QR.Result ([NodeInfo],[NodeInfo],Maybe ()))
433getNodesUDP client cbvar nid addr = getNodes client cbvar nid (Multi.UDP ==> addr) 440getNodesUDP client cbvar nid addr = getNodes client cbvar nid (Multi.UDP ==> addr)
434 441
442asyncGetNodes :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> NodeId -> Multi.NodeInfo
443 -> (TransactionId -> QR.Result ([NodeInfo],[NodeInfo],Maybe ()) -> IO ())
444 -> IO TransactionId
445asyncGetNodes client cbvar nid addr withResult = do
446 QR.asyncQuery client (serializer GetNodesType DHTGetNodes unsendNodes) (GetNodes nid) addr $
447 \qid reply -> do
448 forM_ (join $ resultToMaybe reply) $ \(SendNodes ns) ->
449 forM_ ns $ \n -> do
450 now <- getPOSIXTime
451 atomically $ do
452 mcbs <- HashMap.lookup (nodeId . udpNodeInfo $ n) <$> readTVar cbvar
453 forM_ mcbs $ \cbs -> do
454 forM_ cbs $ \cb -> do
455 rumoredAddress cb now addr (udpNodeInfo n)
456 withResult qid $ case reply of
457 Success x -> maybe Canceled (Success . unwrapNodes) x
458 _ -> fmap (error "Network.Tox.DHT.Handlers.getNodes: the impossible happened!") reply
459
460asyncGetNodesUDP :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> NodeId -> NodeInfo
461 -> (TransactionId -> QR.Result ([NodeInfo],[NodeInfo],Maybe ()) -> IO ())
462 -> IO TransactionId
463asyncGetNodesUDP client cbvar nid addr go = asyncGetNodes client cbvar nid (Multi.UDP ==> addr) go
464
465
435updateRouting :: Client -> Routing 466updateRouting :: Client -> Routing
436 -> (TVar (R.BucketList NodeInfo) -> RoutingTransition NodeInfo -> STM ()) 467 -> (TVar (R.BucketList NodeInfo) -> RoutingTransition NodeInfo -> STM ())
437 -> Multi.NodeInfo 468 -> Multi.NodeInfo
@@ -462,7 +493,7 @@ updateTable client routing orouter naddr = do
462 Want_Both -> do dput XMisc "BUG:unreachable" 493 Want_Both -> do dput XMisc "BUG:unreachable"
463 error $ "BUG:unreachable at " ++ __FILE__ ++ ":" ++ show __LINE__ 494 error $ "BUG:unreachable at " ++ __FILE__ ++ ":" ++ show __LINE__
464 where 495 where
465 go :: TriadCommittee NodeId SockAddr -> BucketRefresher NodeId NodeInfo -> IO () 496 go :: TriadCommittee NodeId SockAddr -> BucketRefresher NodeId NodeInfo TransactionId -> IO ()
466 go committee refresher = do 497 go committee refresher = do
467 self <- atomically $ R.thisNode <$> readTVar (refreshBuckets refresher) 498 self <- atomically $ R.thisNode <$> readTVar (refreshBuckets refresher)
468 -- dput XMisc $ "(tox)updateRouting: " ++ show (nodeIP self, nodeIP naddr) 499 -- dput XMisc $ "(tox)updateRouting: " ++ show (nodeIP self, nodeIP naddr)
@@ -473,7 +504,7 @@ updateTable client routing orouter naddr = do
473toxKademlia :: Client 504toxKademlia :: Client
474 -> (TVar (R.BucketList NodeInfo) -> RoutingTransition NodeInfo -> STM ()) 505 -> (TVar (R.BucketList NodeInfo) -> RoutingTransition NodeInfo -> STM ())
475 -> TriadCommittee NodeId SockAddr 506 -> TriadCommittee NodeId SockAddr
476 -> BucketRefresher NodeId NodeInfo 507 -> BucketRefresher NodeId NodeInfo TransactionId
477 -> Kademlia NodeId NodeInfo 508 -> Kademlia NodeId NodeInfo
478toxKademlia client orouter committee refresher 509toxKademlia client orouter committee refresher
479 = Kademlia quietInsertions 510 = Kademlia quietInsertions
@@ -541,11 +572,12 @@ handlers crypto _ CookieRequestType = Just $ MethodHandler (isCookieReques
541handlers _ _ DHTRequestType = Just $ NoReply (isDHTRequest snd) $ dhtRequestH 572handlers _ _ DHTRequestType = Just $ NoReply (isDHTRequest snd) $ dhtRequestH
542handlers _ _ typ = error $ "TODO DHT handlers " ++ show typ 573handlers _ _ typ = error $ "TODO DHT handlers " ++ show typ
543 574
544nodeSearch :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo 575nodeSearch :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo TransactionId
545nodeSearch client cbvar = Search 576nodeSearch client cbvar = Search
546 { searchSpace = toxSpace 577 { searchSpace = toxSpace
547 , searchNodeAddress = nodeIP &&& nodePort 578 , searchNodeAddress = nodeIP &&& nodePort
548 , searchQuery = getNodesUDP client cbvar 579 , searchQuery = asyncGetNodesUDP client cbvar
580 , searchQueryCancel = cancelQuery client
549 , searchAlpha = 8 581 , searchAlpha = 8
550 , searchK = 16 582 , searchK = 16
551 } 583 }