summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/DHT
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/DHT')
-rw-r--r--src/Network/BitTorrent/DHT/Routing.hs37
-rw-r--r--src/Network/BitTorrent/DHT/Session.hs24
2 files changed, 28 insertions, 33 deletions
diff --git a/src/Network/BitTorrent/DHT/Routing.hs b/src/Network/BitTorrent/DHT/Routing.hs
index 293d58ab..73fe358a 100644
--- a/src/Network/BitTorrent/DHT/Routing.hs
+++ b/src/Network/BitTorrent/DHT/Routing.hs
@@ -14,6 +14,7 @@
14-- <http://www.bittorrent.org/beps/bep_0005.html#routing-table> 14-- <http://www.bittorrent.org/beps/bep_0005.html#routing-table>
15-- 15--
16{-# LANGUAGE RecordWildCards #-} 16{-# LANGUAGE RecordWildCards #-}
17{-# LANGUAGE ViewPatterns #-}
17{-# LANGUAGE TypeOperators #-} 18{-# LANGUAGE TypeOperators #-}
18{-# LANGUAGE DeriveGeneric #-} 19{-# LANGUAGE DeriveGeneric #-}
19{-# OPTIONS_GHC -fno-warn-orphans #-} 20{-# OPTIONS_GHC -fno-warn-orphans #-}
@@ -39,8 +40,8 @@ module Network.BitTorrent.DHT.Routing
39 -- * Lookup 40 -- * Lookup
40 , K 41 , K
41 , defaultK 42 , defaultK
42 , Network.BitTorrent.DHT.Routing.kclosest 43 , TableKey (..)
43 , Network.BitTorrent.DHT.Routing.kclosestHash 44 , kclosest
44 45
45 -- * Construction 46 -- * Construction
46 , Network.BitTorrent.DHT.Routing.nullTable 47 , Network.BitTorrent.DHT.Routing.nullTable
@@ -383,22 +384,24 @@ type K = Int
383defaultK :: K 384defaultK :: K
384defaultK = 8 385defaultK = 8
385 386
386-- | Get a list of /K/ closest nodes using XOR metric. Used in 387class TableKey k where
387-- 'find_node' queries. 388 toNodeId :: k -> NodeId
388kclosest :: Eq ip => K -> NodeId -> Table ip -> [NodeInfo ip] 389
389kclosest k nid = L.take k . rank nid 390instance TableKey NodeId where
390 . L.map key . PSQ.toList . fromMaybe PSQ.empty 391 toNodeId = id
391 . lookupBucket nid
392
393coerceId :: (Serialize a, Serialize b) => a -> b
394coerceId = either (error msg) id . S.decode . S.encode
395 where
396 msg = "coerceId: impossible"
397 392
398-- | Get a list of /K/ nodes with node id closest to the specific 393instance TableKey InfoHash where
399-- infohash. Used in 'get_peers' queries. 394 toNodeId = either (error msg) id . S.decode . S.encode
400kclosestHash :: Eq a => K -> InfoHash -> Table a -> [NodeInfo a] 395 where -- TODO unsafe coerse?
401kclosestHash k nid t = kclosest k (coerceId nid) t 396 msg = "tableKey: impossible"
397
398-- | Get a list of /K/ closest nodes using XOR metric. Used in
399-- 'find_node' and 'get_peers' queries.
400kclosest :: Eq ip => TableKey a => K -> a -> Table ip -> [NodeInfo ip]
401kclosest k (toNodeId -> nid)
402 = L.take k . rank nid
403 . L.map PSQ.key . PSQ.toList . fromMaybe PSQ.empty
404 . lookupBucket nid
402 405
403{----------------------------------------------------------------------- 406{-----------------------------------------------------------------------
404-- Routing 407-- Routing
diff --git a/src/Network/BitTorrent/DHT/Session.hs b/src/Network/BitTorrent/DHT/Session.hs
index 149b7dd2..5ceca4a3 100644
--- a/src/Network/BitTorrent/DHT/Session.hs
+++ b/src/Network/BitTorrent/DHT/Session.hs
@@ -26,7 +26,6 @@ module Network.BitTorrent.DHT.Session
26 , getTable 26 , getTable
27 , getNodeId 27 , getNodeId
28 , getClosest 28 , getClosest
29 , getClosestHash
30 , insertNode 29 , insertNode
31 30
32 -- * Peer storage 31 -- * Peer storage
@@ -327,21 +326,10 @@ getNodeId = asks thisNodeId
327-- 326--
328-- This operation used for 'find_nodes' query. 327-- This operation used for 'find_nodes' query.
329-- 328--
330getClosest :: Eq ip => NodeId -> DHT ip [NodeInfo ip] 329getClosest :: Eq ip => TableKey k => k -> DHT ip [NodeInfo ip]
331getClosest nid = do 330getClosest node = do
332 k <- asks (optK . options) 331 k <- asks (optK . options)
333 kclosest k nid <$> getTable 332 kclosest k node <$> getTable
334
335-- | Find a set of closest nodes from routing table of this node. (in
336-- no particular order)
337--
338-- This operation used as failback in 'get_peers' query, see
339-- 'getPeerList'.
340--
341getClosestHash :: Eq ip => InfoHash -> DHT ip [NodeInfo ip]
342getClosestHash ih = do
343 k <- asks (optK . options)
344 kclosestHash k ih <$> getTable
345 333
346-- | This operation do not block but acquire exclusive access to 334-- | This operation do not block but acquire exclusive access to
347-- routing table. 335-- routing table.
@@ -378,11 +366,15 @@ lookupPeers ih = do
378 366
379type PeerList ip = Either [NodeInfo ip] [PeerAddr ip] 367type PeerList ip = Either [NodeInfo ip] [PeerAddr ip]
380 368
369-- |
370--
371-- This operation used 'getClosest' as failback.
372--
381getPeerList :: Eq ip => InfoHash -> DHT ip (PeerList ip) 373getPeerList :: Eq ip => InfoHash -> DHT ip (PeerList ip)
382getPeerList ih = do 374getPeerList ih = do
383 ps <- lookupPeers ih 375 ps <- lookupPeers ih
384 if L.null ps 376 if L.null ps
385 then Left <$> getClosestHash ih 377 then Left <$> getClosest ih
386 else return (Right ps) 378 else return (Right ps)
387 379
388{----------------------------------------------------------------------- 380{-----------------------------------------------------------------------