summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/MainlineDHT.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-11-07 18:51:05 -0500
committerjoe <joe@jerkface.net>2017-11-08 02:30:43 -0500
commitdbce015d0137152f74f46dea3b00d2b51e7c53f7 (patch)
tree39947fb5a0d0d0aedb0121f4bdd95c41caf0e152 /src/Network/BitTorrent/MainlineDHT.hs
parent8c94bb53cc2eb09a5e1c550c3430935701c6f090 (diff)
Moved BucketRefresher construction responsibility for greater
encapsulation.
Diffstat (limited to 'src/Network/BitTorrent/MainlineDHT.hs')
-rw-r--r--src/Network/BitTorrent/MainlineDHT.hs48
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
531type MainlineClient = Client String Method TransactionId NodeInfo (Message BValue) 531type MainlineClient = Client String Method TransactionId NodeInfo (Message BValue)
532 532
533-- | Like 'nodeInfo' but falls back to 'iNADDR_ANY' for nodeIP' and 'nodePort'.
534mkNodeInfo :: NodeId -> SockAddr -> NodeInfo
535mkNodeInfo nid addr = NodeInfo
536 { nodeId = nid
537 , nodeIP = fromMaybe (toEnum 0) $ fromSockAddr addr
538 , nodePort = fromMaybe 0 $ sockAddrPort addr
539 }
540
533newClient :: SwarmsDatabase -> SockAddr -> IO (MainlineClient, Routing) 541newClient :: SwarmsDatabase -> SockAddr -> IO (MainlineClient, Routing)
534newClient swarms addr = do 542newClient 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