summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/Tracker
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/Tracker')
-rw-r--r--src/Network/BitTorrent/Tracker/Message.hs33
1 files changed, 19 insertions, 14 deletions
diff --git a/src/Network/BitTorrent/Tracker/Message.hs b/src/Network/BitTorrent/Tracker/Message.hs
index 6249cdc4..95b9c7ca 100644
--- a/src/Network/BitTorrent/Tracker/Message.hs
+++ b/src/Network/BitTorrent/Tracker/Message.hs
@@ -22,6 +22,8 @@
22{-# LANGUAGE GeneralizedNewtypeDeriving #-} 22{-# LANGUAGE GeneralizedNewtypeDeriving #-}
23{-# LANGUAGE TemplateHaskell #-} 23{-# LANGUAGE TemplateHaskell #-}
24{-# LANGUAGE DeriveDataTypeable #-} 24{-# LANGUAGE DeriveDataTypeable #-}
25{-# LANGUAGE DeriveFunctor #-}
26{-# LANGUAGE ScopedTypeVariables #-}
25{-# OPTIONS -fno-warn-orphans #-} 27{-# OPTIONS -fno-warn-orphans #-}
26module Network.BitTorrent.Tracker.Message 28module Network.BitTorrent.Tracker.Message
27 ( -- * Announce 29 ( -- * Announce
@@ -83,6 +85,7 @@ import Data.Text (Text)
83import Data.Text.Encoding 85import Data.Text.Encoding
84import Data.Typeable 86import Data.Typeable
85import Data.Word 87import Data.Word
88import Data.IP
86import Network 89import Network
87import Network.HTTP.Types.QueryLike 90import Network.HTTP.Types.QueryLike
88import Network.HTTP.Types.URI hiding (urlEncode) 91import Network.HTTP.Types.URI hiding (urlEncode)
@@ -431,18 +434,18 @@ renderAnnounceRequest = queryToSimpleQuery . toQuery
431-- 434--
432-- For more info see: <http://www.bittorrent.org/beps/bep_0023.html> 435-- For more info see: <http://www.bittorrent.org/beps/bep_0023.html>
433-- 436--
434data PeerList 437data PeerList a
435 = PeerList { getPeerList :: [PeerAddr] } 438 = PeerList { getPeerList :: [PeerAddr a] }
436 | CompactPeerList { getPeerList :: [PeerAddr] } 439 | CompactPeerList { getPeerList :: [PeerAddr a] }
437 deriving (Show, Eq, Typeable) 440 deriving (Show, Eq, Typeable, Functor)
438 441
439putCompactPeerList :: S.Putter [PeerAddr] 442putCompactPeerList :: (Serialize a) => S.Putter [PeerAddr a]
440putCompactPeerList = mapM_ put 443putCompactPeerList = mapM_ put
441 444
442getCompactPeerList :: S.Get [PeerAddr] 445getCompactPeerList :: (Serialize a) => S.Get [PeerAddr a]
443getCompactPeerList = many get 446getCompactPeerList = many get
444 447
445instance BEncode PeerList where 448instance (Typeable a, BEncode a, Serialize a) => BEncode (PeerList a) where
446 toBEncode (PeerList xs) = toBEncode xs 449 toBEncode (PeerList xs) = toBEncode xs
447 toBEncode (CompactPeerList xs) = toBEncode $ runPut (putCompactPeerList xs) 450 toBEncode (CompactPeerList xs) = toBEncode $ runPut (putCompactPeerList xs)
448 451
@@ -473,7 +476,7 @@ data AnnounceInfo =
473 , respMinInterval :: !(Maybe Int) 476 , respMinInterval :: !(Maybe Int)
474 477
475 -- | Peers that must be contacted. 478 -- | Peers that must be contacted.
476 , respPeers :: !PeerList 479 , respPeers :: !(PeerList IP)
477 480
478 -- | Human readable warning. 481 -- | Human readable warning.
479 , respWarning :: !(Maybe Text) 482 , respWarning :: !(Maybe Text)
@@ -490,19 +493,21 @@ instance BEncode AnnounceInfo where
490 .: "incomplete" .=? respIncomplete 493 .: "incomplete" .=? respIncomplete
491 .: "interval" .=! respInterval 494 .: "interval" .=! respInterval
492 .: "min interval" .=? respMinInterval 495 .: "min interval" .=? respMinInterval
493 .: "peers" .=! respPeers 496 .: "peers" .=! peers
497 .: "peers6" .=! peers6
494 .: "warning message" .=? respWarning 498 .: "warning message" .=? respWarning
495 .: endDict 499 .: endDict
500 where (peers,peers6) = splitIPList $ getPeerList respPeers
496 501
497 fromBEncode (BDict d) 502 fromBEncode (BDict d)
498 | Just t <- BE.lookup "failure reason" d = Failure <$> fromBEncode t 503 | Just t <- BE.lookup "failure reason" d = Failure <$> fromBEncode t
499 | otherwise = (`fromDict` (BDict d)) $ do 504 | otherwise = (`fromDict` (BDict d)) $
500 AnnounceInfo 505 AnnounceInfo
501 <$>? "complete" 506 <$>? "complete"
502 <*>? "incomplete" 507 <*>? "incomplete"
503 <*>! "interval" 508 <*>! "interval"
504 <*>? "min interval" 509 <*>? "min interval"
505 <*>! "peers" 510 <*> (PeerList <$> (mergeIPLists <$>! "peers" <*>? "peers6"))
506 <*>? "warning message" 511 <*>? "warning message"
507 fromBEncode _ = decodingError "Announce info" 512 fromBEncode _ = decodingError "Announce info"
508 513
@@ -513,13 +518,13 @@ instance Serialize AnnounceInfo where
513 putWord32be $ fromIntegral respInterval 518 putWord32be $ fromIntegral respInterval
514 putWord32be $ fromIntegral $ fromMaybe 0 respIncomplete 519 putWord32be $ fromIntegral $ fromMaybe 0 respIncomplete
515 putWord32be $ fromIntegral $ fromMaybe 0 respComplete 520 putWord32be $ fromIntegral $ fromMaybe 0 respComplete
516 forM_ (getPeerList respPeers) put 521 forM_ (fmap ipv4 <$> getPeerList respPeers) put
517 522
518 get = do 523 get = do
519 interval <- getWord32be 524 interval <- getWord32be
520 leechers <- getWord32be 525 leechers <- getWord32be
521 seeders <- getWord32be 526 seeders <- getWord32be
522 peers <- many get 527 peers <- many $ fmap IPv4 <$> get
523 528
524 return $ AnnounceInfo { 529 return $ AnnounceInfo {
525 respWarning = Nothing 530 respWarning = Nothing