diff options
Diffstat (limited to 'dht/src/Network/Tox/DHT/Handlers.hs')
-rw-r--r-- | dht/src/Network/Tox/DHT/Handlers.hs | 58 |
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 | |||
172 | routing6 :: Routing -> TVar (R.BucketList NodeInfo) | 172 | routing6 :: Routing -> TVar (R.BucketList NodeInfo) |
173 | routing6 Routing { refresher6 = BucketRefresher { refreshBuckets } } = refreshBuckets | 173 | routing6 Routing { refresher6 = BucketRefresher { refreshBuckets } } = refreshBuckets |
174 | 174 | ||
175 | nullTransactionId :: TransactionId | ||
176 | nullTransactionId = TransactionId (Nonce8 0) (Nonce24 zeros24) | ||
177 | |||
178 | nullSearch :: Search NodeId (IP, PortNumber) tok NodeInfo r TransactionId | ||
179 | nullSearch = 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 | |||
175 | newRouting :: SockAddr -> TransportCrypto | 189 | newRouting :: 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 ())) |
433 | getNodesUDP client cbvar nid addr = getNodes client cbvar nid (Multi.UDP ==> addr) | 440 | getNodesUDP client cbvar nid addr = getNodes client cbvar nid (Multi.UDP ==> addr) |
434 | 441 | ||
442 | asyncGetNodes :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> NodeId -> Multi.NodeInfo | ||
443 | -> (TransactionId -> QR.Result ([NodeInfo],[NodeInfo],Maybe ()) -> IO ()) | ||
444 | -> IO TransactionId | ||
445 | asyncGetNodes 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 | |||
460 | asyncGetNodesUDP :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> NodeId -> NodeInfo | ||
461 | -> (TransactionId -> QR.Result ([NodeInfo],[NodeInfo],Maybe ()) -> IO ()) | ||
462 | -> IO TransactionId | ||
463 | asyncGetNodesUDP client cbvar nid addr go = asyncGetNodes client cbvar nid (Multi.UDP ==> addr) go | ||
464 | |||
465 | |||
435 | updateRouting :: Client -> Routing | 466 | updateRouting :: 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 | |||
473 | toxKademlia :: Client | 504 | toxKademlia :: 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 |
478 | toxKademlia client orouter committee refresher | 509 | toxKademlia client orouter committee refresher |
479 | = Kademlia quietInsertions | 510 | = Kademlia quietInsertions |
@@ -541,11 +572,12 @@ handlers crypto _ CookieRequestType = Just $ MethodHandler (isCookieReques | |||
541 | handlers _ _ DHTRequestType = Just $ NoReply (isDHTRequest snd) $ dhtRequestH | 572 | handlers _ _ DHTRequestType = Just $ NoReply (isDHTRequest snd) $ dhtRequestH |
542 | handlers _ _ typ = error $ "TODO DHT handlers " ++ show typ | 573 | handlers _ _ typ = error $ "TODO DHT handlers " ++ show typ |
543 | 574 | ||
544 | nodeSearch :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo | 575 | nodeSearch :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> Search NodeId (IP,PortNumber) () NodeInfo NodeInfo TransactionId |
545 | nodeSearch client cbvar = Search | 576 | nodeSearch 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 | } |