diff options
author | joe <joe@jerkface.net> | 2017-11-07 18:51:05 -0500 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-11-08 02:30:43 -0500 |
commit | dbce015d0137152f74f46dea3b00d2b51e7c53f7 (patch) | |
tree | 39947fb5a0d0d0aedb0121f4bdd95c41caf0e152 /src/Network/BitTorrent | |
parent | 8c94bb53cc2eb09a5e1c550c3430935701c6f090 (diff) |
Moved BucketRefresher construction responsibility for greater
encapsulation.
Diffstat (limited to 'src/Network/BitTorrent')
-rw-r--r-- | src/Network/BitTorrent/MainlineDHT.hs | 48 |
1 files changed, 23 insertions, 25 deletions
diff --git a/src/Network/BitTorrent/MainlineDHT.hs b/src/Network/BitTorrent/MainlineDHT.hs index 268cacfb..3e7a0eda 100644 --- a/src/Network/BitTorrent/MainlineDHT.hs +++ b/src/Network/BitTorrent/MainlineDHT.hs | |||
@@ -530,15 +530,19 @@ traced (TableMethods ins del lkup) | |||
530 | 530 | ||
531 | type MainlineClient = Client String Method TransactionId NodeInfo (Message BValue) | 531 | type MainlineClient = Client String Method TransactionId NodeInfo (Message BValue) |
532 | 532 | ||
533 | -- | Like 'nodeInfo' but falls back to 'iNADDR_ANY' for nodeIP' and 'nodePort'. | ||
534 | mkNodeInfo :: NodeId -> SockAddr -> NodeInfo | ||
535 | mkNodeInfo nid addr = NodeInfo | ||
536 | { nodeId = nid | ||
537 | , nodeIP = fromMaybe (toEnum 0) $ fromSockAddr addr | ||
538 | , nodePort = fromMaybe 0 $ sockAddrPort addr | ||
539 | } | ||
540 | |||
533 | newClient :: SwarmsDatabase -> SockAddr -> IO (MainlineClient, Routing) | 541 | newClient :: SwarmsDatabase -> SockAddr -> IO (MainlineClient, Routing) |
534 | newClient swarms addr = do | 542 | newClient swarms addr = do |
535 | udp <- udpTransport addr | 543 | udp <- udpTransport addr |
536 | nid <- NodeId <$> getRandomBytes 20 | 544 | nid <- NodeId <$> getRandomBytes 20 |
537 | let tentative_info = NodeInfo | 545 | let tentative_info = mkNodeInfo nid addr |
538 | { nodeId = nid | ||
539 | , nodeIP = fromMaybe (toEnum 0) $ fromSockAddr addr | ||
540 | , nodePort = fromMaybe 0 $ sockAddrPort addr | ||
541 | } | ||
542 | tentative_info6 <- | 546 | tentative_info6 <- |
543 | maybe tentative_info | 547 | maybe tentative_info |
544 | (\ip6 -> tentative_info { nodeId = fromMaybe (nodeId tentative_info) | 548 | (\ip6 -> tentative_info { nodeId = fromMaybe (nodeId tentative_info) |
@@ -549,37 +553,31 @@ newClient swarms addr = do | |||
549 | addr4 <- atomically $ newTChan | 553 | addr4 <- atomically $ newTChan |
550 | addr6 <- atomically $ newTChan | 554 | addr6 <- atomically $ newTChan |
551 | mkrouting <- atomically $ do | 555 | mkrouting <- atomically $ do |
552 | let nobkts = R.defaultBucketCount :: Int | 556 | -- We defer initializing the refreshSearch and refreshPing until we |
553 | tbl4 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info nobkts | 557 | -- have a client to send queries with. |
554 | tbl6 <- newTVar $ R.nullTable (comparing nodeId) (\s -> hashWithSalt s . nodeId) tentative_info6 nobkts | 558 | let nullPing = const $ return False |
555 | let updateIPVote tblvar addrvar a = do | 559 | nullSearch = mainlineSearch $ \_ _ -> return Nothing |
560 | refresher4 <- newBucketRefresher mainlineSpace tentative_info nullSearch nullPing | ||
561 | refresher6 <- newBucketRefresher mainlineSpace tentative_info6 nullSearch nullPing | ||
562 | let tbl4 = refreshBuckets refresher4 | ||
563 | tbl6 = refreshBuckets refresher6 | ||
564 | updateIPVote tblvar addrvar a = do | ||
556 | bkts <- readTVar tblvar | 565 | bkts <- readTVar tblvar |
557 | case bep42 a (nodeId $ R.thisNode bkts) of | 566 | case bep42 a (nodeId $ R.thisNode bkts) of |
558 | Just nid -> do | 567 | Just nid -> do |
559 | let tbl = R.nullTable (comparing nodeId) | 568 | let tbl = R.nullTable (comparing nodeId) |
560 | (\s -> hashWithSalt s . nodeId) | 569 | (\s -> hashWithSalt s . nodeId) |
561 | (NodeInfo nid | 570 | (mkNodeInfo nid a) |
562 | (fromMaybe (toEnum 0) $ fromSockAddr a) | 571 | (R.defaultBucketCount) |
563 | (fromMaybe 0 $ sockAddrPort a)) | ||
564 | nobkts | ||
565 | writeTVar tblvar tbl | 572 | writeTVar tblvar tbl |
566 | writeTChan addrvar (a,map fst $ concat $ R.toList bkts) | 573 | writeTChan addrvar (a,map fst $ concat $ R.toList bkts) |
567 | Nothing -> return () | 574 | Nothing -> return () |
568 | committee4 <- newTriadCommittee $ updateIPVote tbl4 addr4 | 575 | committee4 <- newTriadCommittee $ updateIPVote tbl4 addr4 |
569 | committee6 <- newTriadCommittee $ updateIPVote tbl6 addr6 | 576 | committee6 <- newTriadCommittee $ updateIPVote tbl6 addr6 |
570 | sched4 <- newTVar Int.empty | ||
571 | sched6 <- newTVar Int.empty | ||
572 | return $ \client -> | 577 | return $ \client -> |
573 | let refresher sched bkts = BucketRefresher | 578 | -- Now we have a client, so tell the BucketRefresher how to search and ping. |
574 | { refreshInterval = 15 * 60 | 579 | let updIO r = updateRefresherIO (nodeSearch client) (ping client) r |
575 | , refreshQueue = sched | 580 | in Routing tentative_info committee4 committee6 (updIO refresher4) (updIO refresher6) |
576 | , refreshSearch = nodeSearch client | ||
577 | , refreshBuckets = bkts | ||
578 | , refreshPing = ping client | ||
579 | } | ||
580 | refresher4 = refresher sched4 tbl4 | ||
581 | refresher6 = refresher sched6 tbl6 | ||
582 | in Routing tentative_info committee4 committee6 refresher4 refresher6 | ||
583 | map_var <- atomically $ newTVar (0, mempty) | 581 | map_var <- atomically $ newTVar (0, mempty) |
584 | 582 | ||
585 | let routing = mkrouting outgoingClient | 583 | let routing = mkrouting outgoingClient |