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/ContactInfo.hs29
-rw-r--r--src/Network/BitTorrent/DHT/Query.hs7
-rw-r--r--src/Network/BitTorrent/DHT/Session.hs18
3 files changed, 41 insertions, 13 deletions
diff --git a/src/Network/BitTorrent/DHT/ContactInfo.hs b/src/Network/BitTorrent/DHT/ContactInfo.hs
index 979dbb62..823982d4 100644
--- a/src/Network/BitTorrent/DHT/ContactInfo.hs
+++ b/src/Network/BitTorrent/DHT/ContactInfo.hs
@@ -1,6 +1,6 @@
1module Network.BitTorrent.DHT.ContactInfo 1module Network.BitTorrent.DHT.ContactInfo
2 ( PeerStore 2 ( PeerStore
3 , Network.BitTorrent.DHT.ContactInfo.lookup 3 , Network.BitTorrent.DHT.ContactInfo.freshPeers
4 , Network.BitTorrent.DHT.ContactInfo.insertPeer 4 , Network.BitTorrent.DHT.ContactInfo.insertPeer
5 , knownSwarms 5 , knownSwarms
6 ) where 6 ) where
@@ -124,8 +124,8 @@ data SwarmData ip = SwarmData
124knownSwarms :: PeerStore ip -> [ (InfoHash, Int, Maybe ByteString) ] 124knownSwarms :: PeerStore ip -> [ (InfoHash, Int, Maybe ByteString) ]
125knownSwarms (PeerStore m) = L.map (\(ih,SwarmData q n) -> (ih,PSQ.size q,n)) $ HM.toList m 125knownSwarms (PeerStore m) = L.map (\(ih,SwarmData q n) -> (ih,PSQ.size q,n)) $ HM.toList m
126 126
127swarmSinglton :: Ord ip => PeerAddr ip -> SwarmData ip 127swarmSingleton :: Ord ip => PeerAddr ip -> SwarmData ip
128swarmSinglton a = SwarmData 128swarmSingleton a = SwarmData
129 { peers = PSQ.singleton a 0 129 { peers = PSQ.singleton a 0
130 , name = Nothing } 130 , name = Nothing }
131 131
@@ -157,8 +157,27 @@ instance Serialize (PeerStore a) where
157 put = undefined 157 put = undefined
158 158
159-- | Used in 'get_peers' DHT queries. 159-- | Used in 'get_peers' DHT queries.
160lookup :: Ord a => InfoHash -> PeerStore a -> [PeerAddr a] 160-- lookup :: Ord a => InfoHash -> PeerStore a -> [PeerAddr a]
161lookup ih (PeerStore m) = maybe [] (PSQ.keys . peers) $ HM.lookup ih m 161-- lookup ih (PeerStore m) = maybe [] (PSQ.keys . peers) $ HM.lookup ih m
162
163batchSize = 64
164
165-- | Used in 'get_peers' DHT queries.
166freshPeers :: Ord a => InfoHash -> Timestamp -> PeerStore a -> ([PeerAddr a], PeerStore a)
167freshPeers ih tm (PeerStore m) = (ps, PeerStore m')
168 where
169 swarm = fromMaybe (SwarmData PSQ.empty Nothing) $ HM.lookup ih m
170 ps0 = take batchSize $ unfoldr (incomp minView) (peers swarm)
171 peers' = case reverse ps0 of
172 (_,psq):_ -> psq
173 _ -> peers swarm
174 ps = L.map (key . fst) ps0
175 m' = HM.insert ih swarm { peers = L.foldl' (\q p -> PSQ.insert p tm q) peers' ps } m
176
177incomp :: (x -> Maybe (r,x)) -> x -> Maybe ((r,x),x)
178incomp f x = do
179 (result,x') <- f x
180 pure $ ( (result,x'), x' )
162 181
163-- | Used in 'announce_peer' DHT queries. 182-- | Used in 'announce_peer' DHT queries.
164insertPeer :: Ord a => InfoHash -> Maybe ByteString -> PeerAddr a -> PeerStore a -> PeerStore a 183insertPeer :: Ord a => InfoHash -> Maybe ByteString -> PeerAddr a -> PeerStore a -> PeerStore a
diff --git a/src/Network/BitTorrent/DHT/Query.hs b/src/Network/BitTorrent/DHT/Query.hs
index 0bec867d..73b3d492 100644
--- a/src/Network/BitTorrent/DHT/Query.hs
+++ b/src/Network/BitTorrent/DHT/Query.hs
@@ -109,7 +109,6 @@ getPeersH :: Ord ip => Address ip => NodeHandler ip
109getPeersH = nodeHandler $ \ naddr (GetPeers ih) -> do 109getPeersH = nodeHandler $ \ naddr (GetPeers ih) -> do
110 ps <- getPeerList ih 110 ps <- getPeerList ih
111 tok <- grantToken naddr 111 tok <- grantToken naddr
112 $(logDebugS) "getPeersH" $ "INFO-HASH " <> T.pack (show (ih,fmap fromAddr naddr :: NodeAddr (Maybe IP)))
113 return $ GotPeers ps tok 112 return $ GotPeers ps tok
114 113
115-- | Default 'Announce' handler. 114-- | Default 'Announce' handler.
@@ -195,12 +194,6 @@ publish ih p = do
195 _ <- sourceList [nodes] $= search ih (announceQ ih p) $$ C.take r 194 _ <- sourceList [nodes] $= search ih (announceQ ih p) $$ C.take r
196 return () 195 return ()
197 196
198getTimestamp :: DHT ip Timestamp
199getTimestamp = do
200 utcTime <- liftIO $ getCurrentTime
201 $(logDebugS) "routing.make_timestamp" (T.pack (render (pPrint utcTime)))
202 return $ utcTimeToPOSIXSeconds utcTime
203
204 197
205probeNode :: Address ip => NodeAddr ip -> DHT ip (Bool, Maybe ReflectedIP) 198probeNode :: Address ip => NodeAddr ip -> DHT ip (Bool, Maybe ReflectedIP)
206probeNode addr = do 199probeNode addr = do
diff --git a/src/Network/BitTorrent/DHT/Session.hs b/src/Network/BitTorrent/DHT/Session.hs
index 339b18eb..4f861a1e 100644
--- a/src/Network/BitTorrent/DHT/Session.hs
+++ b/src/Network/BitTorrent/DHT/Session.hs
@@ -33,6 +33,7 @@ module Network.BitTorrent.DHT.Session
33 , myNodeIdAccordingTo 33 , myNodeIdAccordingTo
34 , routingInfo 34 , routingInfo
35 , routableAddress 35 , routableAddress
36 , getTimestamp
36 37
37 -- ** Initialization 38 -- ** Initialization
38 , LogFun 39 , LogFun
@@ -86,6 +87,10 @@ import Data.Set as S
86import Data.Time 87import Data.Time
87import Network (PortNumber) 88import Network (PortNumber)
88import System.Random (randomIO) 89import System.Random (randomIO)
90import Data.Time.Clock.POSIX
91import Data.Text as Text
92import Text.PrettyPrint.HughesPJClass hiding ((<>),($$))
93
89 94
90import Data.Torrent as Torrent 95import Data.Torrent as Torrent
91import Network.KRPC as KRPC hiding (Options, def) 96import Network.KRPC as KRPC hiding (Options, def)
@@ -435,7 +440,18 @@ lookupPeers :: Ord ip => InfoHash -> DHT ip [PeerAddr ip]
435lookupPeers ih = do 440lookupPeers ih = do
436 refreshContacts 441 refreshContacts
437 var <- asks contactInfo 442 var <- asks contactInfo
438 liftIO $ P.lookup ih <$> readTVarIO var 443 tm <- getTimestamp
444 liftIO $ atomically $ do
445 (ps,store') <- P.freshPeers ih tm <$> readTVar var
446 writeTVar var store'
447 return ps
448
449getTimestamp :: DHT ip Timestamp
450getTimestamp = do
451 utcTime <- liftIO $ getCurrentTime
452 $(logDebugS) "routing.make_timestamp" (Text.pack (render (pPrint utcTime)))
453 return $ utcTimeToPOSIXSeconds utcTime
454
439 455
440-- | Prepare result for 'get_peers' query. 456-- | Prepare result for 'get_peers' query.
441-- 457--