diff options
Diffstat (limited to 'src/Network/BitTorrent/DHT')
-rw-r--r-- | src/Network/BitTorrent/DHT/ContactInfo.hs | 29 | ||||
-rw-r--r-- | src/Network/BitTorrent/DHT/Query.hs | 7 | ||||
-rw-r--r-- | src/Network/BitTorrent/DHT/Session.hs | 18 |
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 @@ | |||
1 | module Network.BitTorrent.DHT.ContactInfo | 1 | module 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 | |||
124 | knownSwarms :: PeerStore ip -> [ (InfoHash, Int, Maybe ByteString) ] | 124 | knownSwarms :: PeerStore ip -> [ (InfoHash, Int, Maybe ByteString) ] |
125 | knownSwarms (PeerStore m) = L.map (\(ih,SwarmData q n) -> (ih,PSQ.size q,n)) $ HM.toList m | 125 | knownSwarms (PeerStore m) = L.map (\(ih,SwarmData q n) -> (ih,PSQ.size q,n)) $ HM.toList m |
126 | 126 | ||
127 | swarmSinglton :: Ord ip => PeerAddr ip -> SwarmData ip | 127 | swarmSingleton :: Ord ip => PeerAddr ip -> SwarmData ip |
128 | swarmSinglton a = SwarmData | 128 | swarmSingleton 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. |
160 | lookup :: Ord a => InfoHash -> PeerStore a -> [PeerAddr a] | 160 | -- lookup :: Ord a => InfoHash -> PeerStore a -> [PeerAddr a] |
161 | lookup 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 | |||
163 | batchSize = 64 | ||
164 | |||
165 | -- | Used in 'get_peers' DHT queries. | ||
166 | freshPeers :: Ord a => InfoHash -> Timestamp -> PeerStore a -> ([PeerAddr a], PeerStore a) | ||
167 | freshPeers 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 | |||
177 | incomp :: (x -> Maybe (r,x)) -> x -> Maybe ((r,x),x) | ||
178 | incomp 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. |
164 | insertPeer :: Ord a => InfoHash -> Maybe ByteString -> PeerAddr a -> PeerStore a -> PeerStore a | 183 | insertPeer :: 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 | |||
109 | getPeersH = nodeHandler $ \ naddr (GetPeers ih) -> do | 109 | getPeersH = 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 | ||
198 | getTimestamp :: DHT ip Timestamp | ||
199 | getTimestamp = do | ||
200 | utcTime <- liftIO $ getCurrentTime | ||
201 | $(logDebugS) "routing.make_timestamp" (T.pack (render (pPrint utcTime))) | ||
202 | return $ utcTimeToPOSIXSeconds utcTime | ||
203 | |||
204 | 197 | ||
205 | probeNode :: Address ip => NodeAddr ip -> DHT ip (Bool, Maybe ReflectedIP) | 198 | probeNode :: Address ip => NodeAddr ip -> DHT ip (Bool, Maybe ReflectedIP) |
206 | probeNode addr = do | 199 | probeNode 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 | |||
86 | import Data.Time | 87 | import Data.Time |
87 | import Network (PortNumber) | 88 | import Network (PortNumber) |
88 | import System.Random (randomIO) | 89 | import System.Random (randomIO) |
90 | import Data.Time.Clock.POSIX | ||
91 | import Data.Text as Text | ||
92 | import Text.PrettyPrint.HughesPJClass hiding ((<>),($$)) | ||
93 | |||
89 | 94 | ||
90 | import Data.Torrent as Torrent | 95 | import Data.Torrent as Torrent |
91 | import Network.KRPC as KRPC hiding (Options, def) | 96 | import Network.KRPC as KRPC hiding (Options, def) |
@@ -435,7 +440,18 @@ lookupPeers :: Ord ip => InfoHash -> DHT ip [PeerAddr ip] | |||
435 | lookupPeers ih = do | 440 | lookupPeers 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 | |||
449 | getTimestamp :: DHT ip Timestamp | ||
450 | getTimestamp = 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 | -- |