summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/Tracker/Message.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/Tracker/Message.hs')
-rw-r--r--src/Network/BitTorrent/Tracker/Message.hs57
1 files changed, 34 insertions, 23 deletions
diff --git a/src/Network/BitTorrent/Tracker/Message.hs b/src/Network/BitTorrent/Tracker/Message.hs
index 22733a51..e49a9e58 100644
--- a/src/Network/BitTorrent/Tracker/Message.hs
+++ b/src/Network/BitTorrent/Tracker/Message.hs
@@ -6,7 +6,7 @@
6-- Portability : portable 6-- Portability : portable
7-- 7--
8-- Every tracker should support announce query. This query is used 8-- Every tracker should support announce query. This query is used
9-- to discover peers within swarm and have two-fold effect: 9-- to discover peers within a swarm and have two-fold effect:
10-- 10--
11-- * peer doing announce discover other peers using peer list from 11-- * peer doing announce discover other peers using peer list from
12-- the response to the announce query. 12-- the response to the announce query.
@@ -14,8 +14,8 @@
14-- * tracker store peer information and use it in the succeeding 14-- * tracker store peer information and use it in the succeeding
15-- requests made by other peers, until the peer info expires. 15-- requests made by other peers, until the peer info expires.
16-- 16--
17-- By convention most trackers support another form of request -- 17-- By convention most trackers support another form of request
18-- scrape query -- which queries the state of a given torrent (or 18-- scrape query which queries the state of a given torrent (or
19-- a list of torrents) that the tracker is managing. 19-- a list of torrents) that the tracker is managing.
20-- 20--
21{-# LANGUAGE FlexibleInstances #-} 21{-# LANGUAGE FlexibleInstances #-}
@@ -77,7 +77,7 @@ import Network.BitTorrent.Core.PeerAddr
77-- Events 77-- Events
78-----------------------------------------------------------------------} 78-----------------------------------------------------------------------}
79 79
80-- | Events used to specify which kind of tracker request is performed. 80-- | Events used to specify which kind of announce query is performed.
81data Event = Started 81data Event = Started
82 -- ^ For the first request: when a peer join the swarm. 82 -- ^ For the first request: when a peer join the swarm.
83 | Stopped 83 | Stopped
@@ -127,32 +127,34 @@ getEvent = do
127-- the torrent. The most important, requests are used by the tracker 127-- the torrent. The most important, requests are used by the tracker
128-- to keep track lists of active peer for a particular torrent. 128-- to keep track lists of active peer for a particular torrent.
129-- 129--
130data AnnounceQuery = AnnounceQuery { 130data AnnounceQuery = AnnounceQuery
131 reqInfoHash :: !InfoHash 131 {
132 -- ^ Hash of info part of the torrent usually obtained from 132 -- | Hash of info part of the torrent usually obtained from
133 -- 'Torrent'. 133 -- 'Torrent'.
134 reqInfoHash :: !InfoHash
134 135
136 -- | ID of the peer doing request.
135 , reqPeerId :: !PeerId 137 , reqPeerId :: !PeerId
136 -- ^ ID of the peer doing request.
137 138
139 -- | Port to listen to for connections from other
140 -- peers. Tracker should respond with this port when
141 -- some /other/ peer request the tracker with the same info hash.
142 -- Normally, this port is choosed from 'defaultPorts'.
138 , reqPort :: !PortNumber 143 , reqPort :: !PortNumber
139 -- ^ Port to listen to for connections from other
140 -- peers. Normally, tracker should respond with this port when
141 -- some peer request the tracker with the same info hash.
142 144
145 -- | Current progress of peer doing request.
143 , reqProgress :: !Progress 146 , reqProgress :: !Progress
144 -- ^ Current progress of peer doing request.
145 147
146 , reqIP :: Maybe HostAddress 148 -- | The peer IP. Needed only when client communicated with
147 -- ^ The peer IP. Needed only when client communicated with
148 -- tracker throught a proxy. 149 -- tracker throught a proxy.
150 , reqIP :: Maybe HostAddress
149 151
150 , reqNumWant :: Maybe Int 152 -- | Number of peers that the peers wants to receive from. See
151 -- ^ Number of peers that the peers wants to receive from. See
152 -- note for 'defaultNumWant'. 153 -- note for 'defaultNumWant'.
154 , reqNumWant :: Maybe Int
153 155
156 -- | If not specified, the request is regular periodic request.
154 , reqEvent :: Maybe Event 157 , reqEvent :: Maybe Event
155 -- ^ If not specified, the request is regular periodic request.
156 } deriving (Show, Typeable) 158 } deriving (Show, Typeable)
157 159
158$(deriveJSON (L.map toLower . L.dropWhile isLower) ''AnnounceQuery) 160$(deriveJSON (L.map toLower . L.dropWhile isLower) ''AnnounceQuery)
@@ -208,11 +210,12 @@ instance Serialize AnnounceQuery where
208 , reqPort = port 210 , reqPort = port
209 , reqProgress = progress 211 , reqProgress = progress
210 , reqIP = if ip == 0 then Nothing else Just ip 212 , reqIP = if ip == 0 then Nothing else Just ip
211 , reqNumWant = if want == -1 then Nothing else Just (fromIntegral want) 213 , reqNumWant = if want == -1 then Nothing
214 else Just (fromIntegral want)
212 , reqEvent = ev 215 , reqEvent = ev
213 } 216 }
214 217
215-- | Encoding announce query and add it to the base tracker URL. 218-- | Encode announce query and add it to the base tracker URL.
216renderAnnounceQuery :: URI -> AnnounceQuery -> URI 219renderAnnounceQuery :: URI -> AnnounceQuery -> URI
217renderAnnounceQuery announceURI req 220renderAnnounceQuery announceURI req
218 = URL.urlEncode req 221 = URL.urlEncode req
@@ -230,7 +233,7 @@ data QueryParam
230 deriving (Show, Eq, Ord, Enum) 233 deriving (Show, Eq, Ord, Enum)
231 234
232data ParamParseFailure 235data ParamParseFailure
233 = Missing QueryParam -- ^ param not found in query string 236 = Missing QueryParam -- ^ param not found in query string;
234 | Invalid QueryParam -- ^ param present but not valid. 237 | Invalid QueryParam -- ^ param present but not valid.
235 238
236type ParamResult = Either ParamParseFailure 239type ParamResult = Either ParamParseFailure
@@ -255,7 +258,7 @@ paramName ParamInfoHash = "info_hash"
255paramName ParamPeerId = "peer_id" 258paramName ParamPeerId = "peer_id"
256paramName ParamPort = "port" 259paramName ParamPort = "port"
257 260
258-- | Parse announce request from a query string. 261-- | Parse announce request from a decoded query string.
259parseAnnounceQuery :: [(Text, Text)] -> Either ParamParseFailure AnnounceQuery 262parseAnnounceQuery :: [(Text, Text)] -> Either ParamParseFailure AnnounceQuery
260parseAnnounceQuery params = AnnounceQuery 263parseAnnounceQuery params = AnnounceQuery
261 <$> reqParam ParamInfoHash textToInfoHash params 264 <$> reqParam ParamInfoHash textToInfoHash params
@@ -280,11 +283,17 @@ parseAnnounceQuery params = AnnounceQuery
280 numwant = undefined 283 numwant = undefined
281 event = undefined 284 event = undefined
282 285
286-- TODO add extension datatype
287
283{----------------------------------------------------------------------- 288{-----------------------------------------------------------------------
284-- Announce response 289-- Announce response
285-----------------------------------------------------------------------} 290-----------------------------------------------------------------------}
286 291
287-- | For more info see: <http://www.bittorrent.org/beps/bep_0023.html> 292-- | Tracker can return peer list in either compact(BEP23) or not
293-- compact form.
294--
295-- For more info see: <http://www.bittorrent.org/beps/bep_0023.html>
296--
288data PeerList 297data PeerList
289 = PeerList { getPeerList :: [PeerAddr] } 298 = PeerList { getPeerList :: [PeerAddr] }
290 | CompactPeerList { getPeerList :: [PeerAddr] } 299 | CompactPeerList { getPeerList :: [PeerAddr] }
@@ -408,10 +417,12 @@ missingOffset = 101
408invalidOffset :: Int 417invalidOffset :: Int
409invalidOffset = 150 418invalidOffset = 150
410 419
411-- | Get 420-- | Get HTTP response error code from a announce params parse
421-- failure.
412-- 422--
413-- For more info see: 423-- For more info see:
414-- <https://wiki.theory.org/BitTorrent_Tracker_Protocol#Response_Codes> 424-- <https://wiki.theory.org/BitTorrent_Tracker_Protocol#Response_Codes>
425--
415paramFailureCode :: ParamParseFailure -> Int 426paramFailureCode :: ParamParseFailure -> Int
416paramFailureCode (Missing param) = missingOffset + fromEnum param 427paramFailureCode (Missing param) = missingOffset + fromEnum param
417paramFailureCode (Invalid param) = invalidOffset + fromEnum param 428paramFailureCode (Invalid param) = invalidOffset + fromEnum param