summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/Tracker
diff options
context:
space:
mode:
authorSam T <pxqr.sta@gmail.com>2013-08-17 22:44:35 +0400
committerSam T <pxqr.sta@gmail.com>2013-08-17 22:44:35 +0400
commit20db22d1b09079b88e95e5054df2589fa956fc01 (patch)
tree1a2d741ca8d9da74ba154299b63ed8e287f239da /src/Network/BitTorrent/Tracker
parentde48f6eee93a719c170ef68a0924db83ab0de12d (diff)
+ Add retransmission.
Diffstat (limited to 'src/Network/BitTorrent/Tracker')
-rw-r--r--src/Network/BitTorrent/Tracker/Protocol.hs1
-rw-r--r--src/Network/BitTorrent/Tracker/UDP.hs41
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.
342type Scrape = Map InfoHash ScrapeInfo 343type 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 @@
16module Network.BitTorrent.Tracker.UDP 16module 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
25import Control.Applicative 24import Control.Applicative
@@ -28,6 +27,7 @@ import Control.Monad
28import Data.ByteString (ByteString) 27import Data.ByteString (ByteString)
29import Data.IORef 28import Data.IORef
30import Data.List as L 29import Data.List as L
30import Data.Map as M
31import Data.Maybe 31import Data.Maybe
32import Data.Monoid 32import Data.Monoid
33import Data.Serialize 33import Data.Serialize
@@ -40,6 +40,7 @@ import Network.Socket hiding (Connected)
40import Network.Socket.ByteString as BS 40import Network.Socket.ByteString as BS
41import Network.URI 41import Network.URI
42import System.Entropy 42import System.Entropy
43import System.Timeout
43import Numeric 44import Numeric
44 45
45import Data.Torrent.Metainfo () 46import Data.Torrent.Metainfo ()
@@ -304,17 +305,43 @@ freshConnection tracker @ UDPTracker {..} = do
304 305
305announceUDP :: UDPTracker -> AnnounceQuery -> IO AnnounceInfo 306announceUDP :: UDPTracker -> AnnounceQuery -> IO AnnounceInfo
306announceUDP tracker ann = do 307announceUDP 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
312scrapeUDP :: UDPTracker -> ScrapeQuery -> IO Scrape 314scrapeUDP :: UDPTracker -> ScrapeQuery -> IO Scrape
313scrapeUDP tracker scr = do 315scrapeUDP 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
326sec :: Int
327sec = 1000000
328
329minTimeout :: Int
330minTimeout = 15 * sec
331
332maxTimeout :: Int
333maxTimeout = 15 * 2 ^ (8 :: Int) * sec
334
335retransmission :: IO a -> IO a
336retransmission 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{----------------------------------------------------------------------}
318instance Tracker UDPTracker where 345instance Tracker UDPTracker where
319 announce = announceUDP 346 announce t = retransmission . announceUDP t
320 scrape_ = scrapeUDP 347 scrape_ t = retransmission . scrapeUDP t