diff options
Diffstat (limited to 'src/Network/BitTorrent/DHT/Routing.hs')
-rw-r--r-- | src/Network/BitTorrent/DHT/Routing.hs | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/src/Network/BitTorrent/DHT/Routing.hs b/src/Network/BitTorrent/DHT/Routing.hs index cf4a4de3..6cf7f122 100644 --- a/src/Network/BitTorrent/DHT/Routing.hs +++ b/src/Network/BitTorrent/DHT/Routing.hs | |||
@@ -83,8 +83,10 @@ import Text.PrettyPrint.HughesPJClass (pPrint,Pretty) | |||
83 | import qualified Data.ByteString as BS | 83 | import qualified Data.ByteString as BS |
84 | import Data.Bits | 84 | import Data.Bits |
85 | 85 | ||
86 | import Network.KRPC.Message (KMessageOf) | ||
86 | import Data.Torrent | 87 | import Data.Torrent |
87 | import Network.BitTorrent.Address | 88 | import Network.BitTorrent.Address |
89 | import Network.DHT.Mainline | ||
88 | 90 | ||
89 | {----------------------------------------------------------------------- | 91 | {----------------------------------------------------------------------- |
90 | -- Routing monad | 92 | -- Routing monad |
@@ -180,7 +182,7 @@ runRouting ping_node find_nodes timestamper = go | |||
180 | -- other words: new nodes are used only when older nodes disappear. | 182 | -- other words: new nodes are used only when older nodes disappear. |
181 | 183 | ||
182 | -- | Timestamp - last time this node is pinged. | 184 | -- | Timestamp - last time this node is pinged. |
183 | type NodeEntry ip = Binding (NodeInfo ip) Timestamp | 185 | type NodeEntry ip = Binding (NodeInfo KMessageOf ip ()) Timestamp |
184 | 186 | ||
185 | -- TODO instance Pretty where | 187 | -- TODO instance Pretty where |
186 | 188 | ||
@@ -211,7 +213,7 @@ fromQ embed project QueueMethods{..} = | |||
211 | } | 213 | } |
212 | -} | 214 | -} |
213 | 215 | ||
214 | seqQ :: QueueMethods Identity (NodeInfo ip) (Seq.Seq (NodeInfo ip)) | 216 | seqQ :: QueueMethods Identity (NodeInfo KMessageOf ip ()) (Seq.Seq (NodeInfo KMessageOf ip ())) |
215 | seqQ = QueueMethods | 217 | seqQ = QueueMethods |
216 | { pushBack = \e fifo -> pure (fifo Seq.|> e) | 218 | { pushBack = \e fifo -> pure (fifo Seq.|> e) |
217 | , popFront = \fifo -> case Seq.viewl fifo of | 219 | , popFront = \fifo -> case Seq.viewl fifo of |
@@ -220,9 +222,9 @@ seqQ = QueueMethods | |||
220 | , emptyQueue = pure Seq.empty | 222 | , emptyQueue = pure Seq.empty |
221 | } | 223 | } |
222 | 224 | ||
223 | type BucketQueue ip = Seq.Seq (NodeInfo ip) | 225 | type BucketQueue ip = Seq.Seq (NodeInfo KMessageOf ip ()) |
224 | 226 | ||
225 | bucketQ :: QueueMethods Identity (NodeInfo ip) (BucketQueue ip) | 227 | bucketQ :: QueueMethods Identity (NodeInfo KMessageOf ip ()) (BucketQueue ip) |
226 | bucketQ = seqQ | 228 | bucketQ = seqQ |
227 | 229 | ||
228 | -- | Bucket is also limited in its length — thus it's called k-bucket. | 230 | -- | Bucket is also limited in its length — thus it's called k-bucket. |
@@ -232,7 +234,7 @@ bucketQ = seqQ | |||
232 | -- very unlikely that all nodes in bucket fail within an hour of | 234 | -- very unlikely that all nodes in bucket fail within an hour of |
233 | -- each other. | 235 | -- each other. |
234 | -- | 236 | -- |
235 | data Bucket ip = Bucket { bktNodes :: !(PSQ (NodeInfo ip) Timestamp) | 237 | data Bucket ip = Bucket { bktNodes :: !(PSQ (NodeInfo KMessageOf ip ()) Timestamp) |
236 | , bktQ :: !(BucketQueue ip) | 238 | , bktQ :: !(BucketQueue ip) |
237 | } deriving (Show,Generic) | 239 | } deriving (Show,Generic) |
238 | 240 | ||
@@ -303,7 +305,7 @@ insertBucket curTime (PingResult bad_node got_response) bucket | |||
303 | pure $ PSQ.insert info curTime nodes' | 305 | pure $ PSQ.insert info curTime nodes' |
304 | | otherwise = id | 306 | | otherwise = id |
305 | 307 | ||
306 | updateStamps :: Eq ip => Timestamp -> [NodeInfo ip] -> PSQ (NodeInfo ip) Timestamp -> PSQ (NodeInfo ip) Timestamp | 308 | updateStamps :: Eq ip => Timestamp -> [NodeInfo KMessageOf ip ()] -> PSQ (NodeInfo KMessageOf ip ()) Timestamp -> PSQ (NodeInfo KMessageOf ip ()) Timestamp |
307 | updateStamps curTime stales nodes = foldl' (\q n -> PSQ.insert n curTime q) nodes stales | 309 | updateStamps curTime stales nodes = foldl' (\q n -> PSQ.insert n curTime q) nodes stales |
308 | 310 | ||
309 | 311 | ||
@@ -330,6 +332,12 @@ split i b = (Bucket ns qs, Bucket ms rs) | |||
330 | where | 332 | where |
331 | (ns,ms) = (PSQ.fromList *** PSQ.fromList) . partition (spanBit . key) . PSQ.toList $ bktNodes b | 333 | (ns,ms) = (PSQ.fromList *** PSQ.fromList) . partition (spanBit . key) . PSQ.toList $ bktNodes b |
332 | (qs,rs) = runIdentity $ partitionQ bucketQ spanBit $ bktQ b | 334 | (qs,rs) = runIdentity $ partitionQ bucketQ spanBit $ bktQ b |
335 | {- | ||
336 | spanBit :: forall (dht :: * -> *) addr u. | ||
337 | FiniteBits (Network.RPC.NodeId dht) => | ||
338 | NodeInfo dht addr u -> Bool | ||
339 | -} | ||
340 | spanBit :: NodeInfo KMessageOf addr () -> Bool | ||
333 | spanBit entry = testIdBit (nodeId entry) i | 341 | spanBit entry = testIdBit (nodeId entry) i |
334 | 342 | ||
335 | {----------------------------------------------------------------------- | 343 | {----------------------------------------------------------------------- |
@@ -458,7 +466,7 @@ compatibleNodeId tbl = genBucketSample prefix br | |||
458 | where | 466 | where |
459 | br = bucketRange (L.length (shape tbl) - 1) True | 467 | br = bucketRange (L.length (shape tbl) - 1) True |
460 | bs = BS.pack $ take nodeIdSize $ tablePrefix tbl ++ repeat 0 | 468 | bs = BS.pack $ take nodeIdSize $ tablePrefix tbl ++ repeat 0 |
461 | prefix = asNodeId bs | 469 | prefix = either error id $ S.decode bs |
462 | 470 | ||
463 | tablePrefix :: Table ip -> [Word8] | 471 | tablePrefix :: Table ip -> [Word8] |
464 | tablePrefix = map (packByte . take 8 . (++repeat False)) | 472 | tablePrefix = map (packByte . take 8 . (++repeat False)) |
@@ -503,7 +511,7 @@ instance TableKey InfoHash where | |||
503 | 511 | ||
504 | -- | Get a list of /K/ closest nodes using XOR metric. Used in | 512 | -- | Get a list of /K/ closest nodes using XOR metric. Used in |
505 | -- 'find_node' and 'get_peers' queries. | 513 | -- 'find_node' and 'get_peers' queries. |
506 | kclosest :: Eq ip => TableKey a => K -> a -> Table ip -> [NodeInfo ip] | 514 | kclosest :: Eq ip => TableKey a => K -> a -> Table ip -> [NodeInfo KMessageOf ip ()] |
507 | kclosest k (toNodeId -> nid) tbl = take k $ rank nodeId nid (L.concat bucket) | 515 | kclosest k (toNodeId -> nid) tbl = take k $ rank nodeId nid (L.concat bucket) |
508 | ++ rank nodeId nid (L.concat everyone) | 516 | ++ rank nodeId nid (L.concat everyone) |
509 | where | 517 | where |
@@ -547,19 +555,19 @@ modifyBucket nodeId f = go (0 :: BitIx) | |||
547 | <|> go i (splitTip nid n i bucket) | 555 | <|> go i (splitTip nid n i bucket) |
548 | 556 | ||
549 | -- | Triggering event for atomic table update | 557 | -- | Triggering event for atomic table update |
550 | data Event ip = TryInsert { foreignNode :: NodeInfo ip } | 558 | data Event ip = TryInsert { foreignNode :: NodeInfo KMessageOf ip () } |
551 | | PingResult { foreignNode :: NodeInfo ip | 559 | | PingResult { foreignNode :: NodeInfo KMessageOf ip () |
552 | , ponged :: Bool | 560 | , ponged :: Bool |
553 | } | 561 | } |
554 | deriving (Eq,Ord,Show) | 562 | deriving (Eq,Show) -- Ord |
555 | 563 | ||
556 | eventId :: Event ip -> NodeId | 564 | eventId :: Event ip -> NodeId |
557 | eventId (TryInsert NodeInfo{..}) = nodeId | 565 | eventId (TryInsert NodeInfo{..}) = nodeId |
558 | eventId (PingResult NodeInfo{..} _) = nodeId | 566 | eventId (PingResult NodeInfo{..} _) = nodeId |
559 | 567 | ||
560 | -- | Actions requested by atomic table update | 568 | -- | Actions requested by atomic table update |
561 | data CheckPing ip = CheckPing [NodeInfo ip] | 569 | data CheckPing ip = CheckPing [NodeInfo KMessageOf ip ()] |
562 | deriving (Eq,Ord,Show) | 570 | deriving (Eq,Show) -- Ord |
563 | 571 | ||
564 | 572 | ||
565 | -- | Atomic 'Table' update | 573 | -- | Atomic 'Table' update |
@@ -571,7 +579,7 @@ insert tm event tbl = pure $ fromMaybe ([],tbl) $ modifyBucket (eventId event) ( | |||
571 | -- Conversion | 579 | -- Conversion |
572 | -----------------------------------------------------------------------} | 580 | -----------------------------------------------------------------------} |
573 | 581 | ||
574 | type TableEntry ip = (NodeInfo ip, Timestamp) | 582 | type TableEntry ip = (NodeInfo KMessageOf ip (), Timestamp) |
575 | 583 | ||
576 | tableEntry :: NodeEntry ip -> TableEntry ip | 584 | tableEntry :: NodeEntry ip -> TableEntry ip |
577 | tableEntry (a :-> b) = (a, b) | 585 | tableEntry (a :-> b) = (a, b) |