diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2013-11-28 06:27:51 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2013-11-28 06:27:51 +0400 |
commit | 533068e7ebbf3ae5f15bd7b65312a69ab50052e5 (patch) | |
tree | d4f41d742caf9082ba6442e905ae9d3030236910 /src/Network/BitTorrent | |
parent | a5b5c13610d2097d6541e9d0d5a118735607dfab (diff) |
Add extended module for extended messages
Diffstat (limited to 'src/Network/BitTorrent')
-rw-r--r-- | src/Network/BitTorrent/Exchange/Message/Extended.hs | 51 | ||||
-rw-r--r-- | src/Network/BitTorrent/Exchange/Protocol.hs | 135 |
2 files changed, 127 insertions, 59 deletions
diff --git a/src/Network/BitTorrent/Exchange/Message/Extended.hs b/src/Network/BitTorrent/Exchange/Message/Extended.hs new file mode 100644 index 00000000..5d26b582 --- /dev/null +++ b/src/Network/BitTorrent/Exchange/Message/Extended.hs | |||
@@ -0,0 +1,51 @@ | |||
1 | -- | | ||
2 | -- Copyright : (c) Sam Truzjan 2013 | ||
3 | -- License : BSD3 | ||
4 | -- Maintainer : pxqr.sta@gmail.com | ||
5 | -- Stability : experimental | ||
6 | -- Portability : portable | ||
7 | -- | ||
8 | -- For more info see <http://www.bittorrent.org/beps/bep_0010.html> | ||
9 | -- | ||
10 | {-# LANGUAGE DeriveDataTypeable #-} | ||
11 | module Network.BitTorrent.Exchange.Message.Extended | ||
12 | ( | ||
13 | ) where | ||
14 | |||
15 | import Data.BEncode | ||
16 | import Data.IntMap as IM | ||
17 | import Data.Text | ||
18 | import Data.Typeable | ||
19 | import Network | ||
20 | import Network.Socket | ||
21 | |||
22 | import Network.BitTorrent.Core.PeerAddr | ||
23 | |||
24 | |||
25 | type Extension = () | ||
26 | |||
27 | type ExtMap = IntMap Extension | ||
28 | |||
29 | data ExtendedHandshake = H | ||
30 | { extMap :: ExtMap | ||
31 | , port :: Maybe PortNumber | ||
32 | , version :: Maybe Text -- TODO ClientInfo | ||
33 | , yourip :: Maybe SockAddr | ||
34 | -- , ipv6 , ipv4 | ||
35 | |||
36 | -- | The number of outstanding 'Request' messages this | ||
37 | -- client supports without dropping any. | ||
38 | , requestQueueLength :: Maybe Int | ||
39 | } deriving (Show, Typeable) | ||
40 | |||
41 | instance BEncode ExtendedHandshake where | ||
42 | toBEncode H {..} = toDict $ | ||
43 | "p" .=? port | ||
44 | .: endDict | ||
45 | |||
46 | fromBEncode = fromDict $ do | ||
47 | undefined | ||
48 | |||
49 | data ExtendedMessage | ||
50 | = ExtendedHandshake | ||
51 | deriving (Show, Eq) | ||
diff --git a/src/Network/BitTorrent/Exchange/Protocol.hs b/src/Network/BitTorrent/Exchange/Protocol.hs index 037ef31f..4ef7baf3 100644 --- a/src/Network/BitTorrent/Exchange/Protocol.hs +++ b/src/Network/BitTorrent/Exchange/Protocol.hs | |||
@@ -188,73 +188,88 @@ handshake sock hs = do | |||
188 | Regular messages | 188 | Regular messages |
189 | -----------------------------------------------------------------------} | 189 | -----------------------------------------------------------------------} |
190 | 190 | ||
191 | data StatusUpdate | ||
192 | = Choke | ||
193 | | Unchoke | ||
194 | | Interested | ||
195 | | NotInterested | ||
196 | deriving (Show, Eq, Ord, Enum, Bounded) | ||
197 | |||
198 | data RegularMessage = | ||
199 | -- | Zero-based index of a piece that has just been successfully | ||
200 | -- downloaded and verified via the hash. | ||
201 | Have ! PieceIx | ||
202 | |||
203 | -- | The bitfield message may only be sent immediately after the | ||
204 | -- handshaking sequence is complete, and before any other message | ||
205 | -- are sent. If client have no pieces then bitfield need not to be | ||
206 | -- sent. | ||
207 | | Bitfield !Bitfield | ||
208 | |||
209 | -- | Request for a particular block. If a client is requested a | ||
210 | -- block that another peer do not have the peer might not answer | ||
211 | -- at all. | ||
212 | | Request ! BlockIx | ||
213 | |||
214 | -- | Response to a request for a block. | ||
215 | | Piece !(Block BL.ByteString) | ||
216 | |||
217 | -- | Used to cancel block requests. It is typically used during | ||
218 | -- "End Game". | ||
219 | | Cancel !BlockIx | ||
220 | deriving (Show, Eq) | ||
221 | |||
222 | data DHTMessage | ||
223 | = Port !PortNumber | ||
224 | deriving (Show, Eq) | ||
225 | |||
226 | -- | BEP6 messages. | ||
227 | data FastMessage = | ||
228 | -- | If a peer have all pieces it might send the 'HaveAll' message | ||
229 | -- instead of 'Bitfield' message. Used to save bandwidth. | ||
230 | HaveAll | ||
231 | |||
232 | -- | If a peer have no pieces it might send 'HaveNone' message | ||
233 | -- intead of 'Bitfield' message. Used to save bandwidth. | ||
234 | | HaveNone | ||
235 | |||
236 | -- | This is an advisory message meaning "you might like to | ||
237 | -- download this piece." Used to avoid excessive disk seeks and | ||
238 | -- amount of IO. | ||
239 | | SuggestPiece !PieceIx | ||
240 | |||
241 | -- | Notifies a requesting peer that its request will not be satisfied. | ||
242 | | RejectRequest !BlockIx | ||
243 | |||
244 | -- | This is an advisory messsage meaning "if you ask for this | ||
245 | -- piece, I'll give it to you even if you're choked." Used to | ||
246 | -- shorten starting phase. | ||
247 | | AllowedFast !PieceIx | ||
248 | deriving (Show, Eq) | ||
249 | |||
250 | -- TODO make Network.BitTorrent.Exchange.Session | ||
251 | |||
191 | -- | Messages used in communication between peers. | 252 | -- | Messages used in communication between peers. |
192 | -- | 253 | -- |
193 | -- Note: If some extensions are disabled (not present in extension | 254 | -- Note: If some extensions are disabled (not present in extension |
194 | -- mask) and client receive message used by the disabled | 255 | -- mask) and client receive message used by the disabled |
195 | -- extension then the client MUST close the connection. | 256 | -- extension then the client MUST close the connection. |
196 | -- | 257 | -- |
197 | data Message = KeepAlive | 258 | data Message |
198 | -- TODO data PeerStatusUpdate = Choke | Unchoke | Interested | NotInterested | 259 | -- core |
199 | | Choke | 260 | = KeepAlive |
200 | | Unchoke | 261 | | Status !StatusUpdate |
201 | | Interested | 262 | | Regular !RegularMessage |
202 | | NotInterested | 263 | |
203 | 264 | -- extensions | |
204 | -- | Zero-based index of a piece that has just been | 265 | | DHT !DHTMessage |
205 | -- successfully downloaded and verified via the hash. | 266 | | Fast !FastMessage |
206 | | Have !PieceIx | 267 | deriving (Show, Eq) |
207 | |||
208 | -- | The bitfield message may only be sent immediately | ||
209 | -- after the handshaking sequence is complete, and | ||
210 | -- before any other message are sent. If client have no | ||
211 | -- pieces then bitfield need not to be sent. | ||
212 | | Bitfield !Bitfield | ||
213 | |||
214 | -- | Request for a particular block. If a client is | ||
215 | -- requested a block that another peer do not have the | ||
216 | -- peer might not answer at all. | ||
217 | | Request !BlockIx | ||
218 | |||
219 | -- | Response for a request for a block. | ||
220 | | Piece !(Block BL.ByteString) | ||
221 | |||
222 | -- | Used to cancel block requests. It is typically | ||
223 | -- used during "End Game". | ||
224 | | Cancel !BlockIx | ||
225 | |||
226 | | Port !PortNumber | ||
227 | |||
228 | -- TODO data FastMessage = HaveAll | HaveNone | ... | ||
229 | -- | BEP 6: Then peer have all pieces it might send the | ||
230 | -- 'HaveAll' message instead of 'Bitfield' | ||
231 | -- message. Used to save bandwidth. | ||
232 | | HaveAll | ||
233 | |||
234 | -- | BEP 6: Then peer have no pieces it might send | ||
235 | -- 'HaveNone' message intead of 'Bitfield' | ||
236 | -- message. Used to save bandwidth. | ||
237 | | HaveNone | ||
238 | |||
239 | -- | BEP 6: This is an advisory message meaning "you | ||
240 | -- might like to download this piece." Used to avoid | ||
241 | -- excessive disk seeks and amount of IO. | ||
242 | | SuggestPiece !PieceIx | ||
243 | |||
244 | -- | BEP 6: Notifies a requesting peer that its request | ||
245 | -- will not be satisfied. | ||
246 | | RejectRequest !BlockIx | ||
247 | |||
248 | -- | BEP 6: This is an advisory messsage meaning "if | ||
249 | -- you ask for this piece, I'll give it to you even if | ||
250 | -- you're choked." Used to shorten starting phase. | ||
251 | | AllowedFast !PieceIx | ||
252 | deriving (Show, Eq) | ||
253 | 268 | ||
254 | instance Default Message where | 269 | instance Default Message where |
255 | def = KeepAlive | 270 | def = KeepAlive |
256 | {-# INLINE def #-} | 271 | {-# INLINE def #-} |
257 | 272 | {- | |
258 | -- | Payload bytes are omitted. | 273 | -- | Payload bytes are omitted. |
259 | instance Pretty Message where | 274 | instance Pretty Message where |
260 | pretty (Bitfield _) = "Bitfield" | 275 | pretty (Bitfield _) = "Bitfield" |
@@ -282,9 +297,9 @@ instance Serialize Message where | |||
282 | 0x07 -> Piece <$> getBlock (len - 9) | 297 | 0x07 -> Piece <$> getBlock (len - 9) |
283 | 0x08 -> Cancel <$> S.get | 298 | 0x08 -> Cancel <$> S.get |
284 | 0x09 -> Port <$> S.get | 299 | 0x09 -> Port <$> S.get |
300 | 0x0D -> SuggestPiece <$> getInt | ||
285 | 0x0E -> return HaveAll | 301 | 0x0E -> return HaveAll |
286 | 0x0F -> return HaveNone | 302 | 0x0F -> return HaveNone |
287 | 0x0D -> SuggestPiece <$> getInt | ||
288 | 0x10 -> RejectRequest <$> S.get | 303 | 0x10 -> RejectRequest <$> S.get |
289 | 0x11 -> AllowedFast <$> getInt | 304 | 0x11 -> AllowedFast <$> getInt |
290 | _ -> do | 305 | _ -> do |
@@ -324,7 +339,8 @@ instance Serialize Message where | |||
324 | put (SuggestPiece pix) = putInt 5 >> S.putWord8 0x0D >> putInt pix | 339 | put (SuggestPiece pix) = putInt 5 >> S.putWord8 0x0D >> putInt pix |
325 | put (RejectRequest i ) = putInt 13 >> S.putWord8 0x10 >> S.put i | 340 | put (RejectRequest i ) = putInt 13 >> S.putWord8 0x10 >> S.put i |
326 | put (AllowedFast i ) = putInt 5 >> S.putWord8 0x11 >> putInt i | 341 | put (AllowedFast i ) = putInt 5 >> S.putWord8 0x11 >> putInt i |
327 | 342 | -} | |
343 | {- | ||
328 | instance Binary Message where | 344 | instance Binary Message where |
329 | get = do | 345 | get = do |
330 | len <- getIntB | 346 | len <- getIntB |
@@ -381,3 +397,4 @@ instance Binary Message where | |||
381 | put (SuggestPiece pix) = putIntB 5 >> B.putWord8 0x0D >> putIntB pix | 397 | put (SuggestPiece pix) = putIntB 5 >> B.putWord8 0x0D >> putIntB pix |
382 | put (RejectRequest i ) = putIntB 13 >> B.putWord8 0x10 >> B.put i | 398 | put (RejectRequest i ) = putIntB 13 >> B.putWord8 0x10 >> B.put i |
383 | put (AllowedFast i ) = putIntB 5 >> B.putWord8 0x11 >> putIntB i | 399 | put (AllowedFast i ) = putIntB 5 >> B.putWord8 0x11 >> putIntB i |
400 | -} \ No newline at end of file | ||