diff options
-rw-r--r-- | src/Network/BitTorrent/Tracker/Protocol.hs | 1 | ||||
-rw-r--r-- | src/Network/BitTorrent/Tracker/UDP.hs | 41 |
2 files changed, 35 insertions, 7 deletions
diff --git a/src/Network/BitTorrent/Tracker/Protocol.hs b/src/Network/BitTorrent/Tracker/Protocol.hs index b67b856d..e7755a10 100644 --- a/src/Network/BitTorrent/Tracker/Protocol.hs +++ b/src/Network/BitTorrent/Tracker/Protocol.hs | |||
@@ -338,6 +338,7 @@ data ScrapeInfo = ScrapeInfo { | |||
338 | 338 | ||
339 | $(deriveJSON (L.map toLower . L.dropWhile isLower) ''ScrapeInfo) | 339 | $(deriveJSON (L.map toLower . L.dropWhile isLower) ''ScrapeInfo) |
340 | 340 | ||
341 | -- TODO hash map | ||
341 | -- | Scrape info about a set of torrents. | 342 | -- | Scrape info about a set of torrents. |
342 | type Scrape = Map InfoHash ScrapeInfo | 343 | type Scrape = Map InfoHash ScrapeInfo |
343 | 344 | ||
diff --git a/src/Network/BitTorrent/Tracker/UDP.hs b/src/Network/BitTorrent/Tracker/UDP.hs index 6143a1e1..e5475a23 100644 --- a/src/Network/BitTorrent/Tracker/UDP.hs +++ b/src/Network/BitTorrent/Tracker/UDP.hs | |||
@@ -16,10 +16,9 @@ | |||
16 | module Network.BitTorrent.Tracker.UDP | 16 | module Network.BitTorrent.Tracker.UDP |
17 | ( UDPTracker | 17 | ( UDPTracker |
18 | , initialTracker | 18 | , initialTracker |
19 | |||
20 | -- * Debug | ||
19 | , putTracker | 21 | , putTracker |
20 | , connectUDP | ||
21 | , freshConnection | ||
22 | , announceUDP | ||
23 | ) where | 22 | ) where |
24 | 23 | ||
25 | import Control.Applicative | 24 | import Control.Applicative |
@@ -28,6 +27,7 @@ import Control.Monad | |||
28 | import Data.ByteString (ByteString) | 27 | import Data.ByteString (ByteString) |
29 | import Data.IORef | 28 | import Data.IORef |
30 | import Data.List as L | 29 | import Data.List as L |
30 | import Data.Map as M | ||
31 | import Data.Maybe | 31 | import Data.Maybe |
32 | import Data.Monoid | 32 | import Data.Monoid |
33 | import Data.Serialize | 33 | import Data.Serialize |
@@ -40,6 +40,7 @@ import Network.Socket hiding (Connected) | |||
40 | import Network.Socket.ByteString as BS | 40 | import Network.Socket.ByteString as BS |
41 | import Network.URI | 41 | import Network.URI |
42 | import System.Entropy | 42 | import System.Entropy |
43 | import System.Timeout | ||
43 | import Numeric | 44 | import Numeric |
44 | 45 | ||
45 | import Data.Torrent.Metainfo () | 46 | import Data.Torrent.Metainfo () |
@@ -304,17 +305,43 @@ freshConnection tracker @ UDPTracker {..} = do | |||
304 | 305 | ||
305 | announceUDP :: UDPTracker -> AnnounceQuery -> IO AnnounceInfo | 306 | announceUDP :: UDPTracker -> AnnounceQuery -> IO AnnounceInfo |
306 | announceUDP tracker ann = do | 307 | announceUDP tracker ann = do |
308 | freshConnection tracker | ||
307 | resp <- transaction tracker (Announce ann) | 309 | resp <- transaction tracker (Announce ann) |
308 | case resp of | 310 | case resp of |
309 | Announced info -> return info | 311 | Announced info -> return info |
310 | _ -> fail "response type mismatch" | 312 | _ -> fail "announce: response type mismatch" |
311 | 313 | ||
312 | scrapeUDP :: UDPTracker -> ScrapeQuery -> IO Scrape | 314 | scrapeUDP :: UDPTracker -> ScrapeQuery -> IO Scrape |
313 | scrapeUDP tracker scr = do | 315 | scrapeUDP tracker scr = do |
316 | freshConnection tracker | ||
314 | resp <- transaction tracker (Scrape scr) | 317 | resp <- transaction tracker (Scrape scr) |
315 | case resp of | 318 | case resp of |
316 | Scraped scrape -> return undefined | 319 | Scraped scrape -> return $ M.fromList $ L.zip scr scrape |
320 | _ -> fail "scrape: response type mismatch" | ||
321 | |||
322 | {----------------------------------------------------------------------- | ||
323 | Retransmission | ||
324 | -----------------------------------------------------------------------} | ||
325 | |||
326 | sec :: Int | ||
327 | sec = 1000000 | ||
328 | |||
329 | minTimeout :: Int | ||
330 | minTimeout = 15 * sec | ||
331 | |||
332 | maxTimeout :: Int | ||
333 | maxTimeout = 15 * 2 ^ (8 :: Int) * sec | ||
334 | |||
335 | retransmission :: IO a -> IO a | ||
336 | retransmission action = go minTimeout | ||
337 | where | ||
338 | go curTimeout | ||
339 | | maxTimeout < curTimeout = throwIO $ userError "tracker down" | ||
340 | | otherwise = do | ||
341 | r <- timeout curTimeout action | ||
342 | maybe (go (2 * curTimeout)) return r | ||
317 | 343 | ||
344 | {----------------------------------------------------------------------} | ||
318 | instance Tracker UDPTracker where | 345 | instance Tracker UDPTracker where |
319 | announce = announceUDP | 346 | announce t = retransmission . announceUDP t |
320 | scrape_ = scrapeUDP | 347 | scrape_ t = retransmission . scrapeUDP t |