summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/Exchange/Message.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent/Exchange/Message.hs')
-rw-r--r--src/Network/BitTorrent/Exchange/Message.hs69
1 files changed, 50 insertions, 19 deletions
diff --git a/src/Network/BitTorrent/Exchange/Message.hs b/src/Network/BitTorrent/Exchange/Message.hs
index 8fcf582f..8ef9f3da 100644
--- a/src/Network/BitTorrent/Exchange/Message.hs
+++ b/src/Network/BitTorrent/Exchange/Message.hs
@@ -210,9 +210,12 @@ instance Serialize Handshake where
210 <*> S.get 210 <*> S.get
211 <*> S.get 211 <*> S.get
212 212
213-- | Show handshake protocol string, caps and fingerprint.
213instance Pretty Handshake where 214instance Pretty Handshake where
214 pretty Handshake {..} 215 pretty Handshake {..}
215 = text (BC.unpack hsProtocol) <+> pretty (fingerprint hsPeerId) 216 = text (BC.unpack hsProtocol) $$
217 pretty hsReserved $$
218 pretty (fingerprint hsPeerId)
216 219
217-- | Get handshake message size in bytes from the length of protocol 220-- | Get handshake message size in bytes from the length of protocol
218-- string. 221-- string.
@@ -227,31 +230,49 @@ handshakeMaxSize = handshakeSize maxBound
227defaultBTProtocol :: BS.ByteString 230defaultBTProtocol :: BS.ByteString
228defaultBTProtocol = "BitTorrent protocol" 231defaultBTProtocol = "BitTorrent protocol"
229 232
230-- | Length of info hash and peer id is unchecked, so it /should/ be 233-- | Handshake with default protocol string and reserved bitmask.
231-- equal 20.
232defaultHandshake :: InfoHash -> PeerId -> Handshake 234defaultHandshake :: InfoHash -> PeerId -> Handshake
233defaultHandshake = Handshake defaultBTProtocol def 235defaultHandshake = Handshake defaultBTProtocol def
234 236
235{----------------------------------------------------------------------- 237{-----------------------------------------------------------------------
236 Regular messages 238-- Regular messages
237-----------------------------------------------------------------------} 239-----------------------------------------------------------------------}
238 240
239class PeerMessage a where 241class PeerMessage a where
240 envelop :: ExtendedCaps -> a -> Message 242 -- | Construct a message to be /sent/.
243 envelop :: ExtendedCaps -- ^ The /receiver/ extended capabilities;
244 -> a -- ^ An regular message;
245 -> Message -- ^ Enveloped message to sent.
241 246
247{-----------------------------------------------------------------------
248-- Status messages
249-----------------------------------------------------------------------}
250
251-- | Notification that the sender have updated its
252-- 'Network.BitTorrent.Exchange.Status.PeerStatus'.
242data StatusUpdate 253data StatusUpdate
243 = Choke 254 -- | Notification that the sender will not upload data to the
244 | Unchoke 255 -- receiver until unchoking happen.
245 | Interested 256 = Choking !Bool
246 | NotInterested 257
247 deriving (Show, Eq, Ord, Enum, Bounded) 258 -- | Notification that the sender is interested (or not interested)
259 -- in any of the receiver's data pieces.
260 | Interested !Bool
261 deriving (Show, Eq, Ord, Typeable)
248 262
249instance Pretty StatusUpdate where 263instance Pretty StatusUpdate where
250 pretty = text . show 264 pretty (Choking False) = "not choking"
265 pretty (Choking True ) = "choking"
266 pretty (Interested False) = "not interested"
267 pretty (Interested True ) = "interested"
251 268
252instance PeerMessage StatusUpdate where 269instance PeerMessage StatusUpdate where
253 envelop _ = Status 270 envelop _ = Status
254 271
272{-----------------------------------------------------------------------
273-- Available and transfer messages
274-----------------------------------------------------------------------}
275
255data RegularMessage = 276data RegularMessage =
256 -- | Zero-based index of a piece that has just been successfully 277 -- | Zero-based index of a piece that has just been successfully
257 -- downloaded and verified via the hash. 278 -- downloaded and verified via the hash.
@@ -303,6 +324,10 @@ instance PeerMessage BlockIx where
303instance PeerMessage (Block BL.ByteString) where 324instance PeerMessage (Block BL.ByteString) where
304 envelop c = envelop c . Piece 325 envelop c = envelop c . Piece
305 326
327{-----------------------------------------------------------------------
328-- Fast messages
329-----------------------------------------------------------------------}
330
306-- | BEP6 messages. 331-- | BEP6 messages.
307data FastMessage = 332data FastMessage =
308 -- | If a peer have all pieces it might send the 'HaveAll' message 333 -- | If a peer have all pieces it might send the 'HaveAll' message
@@ -526,12 +551,14 @@ type MessageId = Word8
526-- extension then the client MUST close the connection. 551-- extension then the client MUST close the connection.
527-- 552--
528data Message 553data Message
529 -- core 554 -- | Peers may close the TCP connection if they have not received
555 -- any messages for a given period of time, generally 2
556 -- minutes. Thus, the "keep-alive" message is sent tot keep the
557 -- connection between two peers alive, if no /other/ message has
558 -- been sentin a given period of time.
530 = KeepAlive 559 = KeepAlive
531 | Status !StatusUpdate 560 | Status !StatusUpdate
532 | Regular !RegularMessage 561 | Regular !RegularMessage
533
534 -- extensions
535 | Port !PortNumber 562 | Port !PortNumber
536 | Fast !FastMessage 563 | Fast !FastMessage
537 | Extended !ExtendedMessage 564 | Extended !ExtendedMessage
@@ -581,10 +608,10 @@ instance Serialize Message where
581 else do 608 else do
582 mid <- S.getWord8 609 mid <- S.getWord8
583 case mid of 610 case mid of
584 0x00 -> return $ Status Choke 611 0x00 -> return $ Status (Choking True)
585 0x01 -> return $ Status Unchoke 612 0x01 -> return $ Status (Choking False)
586 0x02 -> return $ Status Interested 613 0x02 -> return $ Status (Interested True)
587 0x03 -> return $ Status NotInterested 614 0x03 -> return $ Status (Interested False)
588 0x04 -> (Regular . Have) <$> getInt 615 0x04 -> (Regular . Have) <$> getInt
589 0x05 -> (Regular . Bitfield . fromBitmap) 616 0x05 -> (Regular . Bitfield . fromBitmap)
590 <$> S.getByteString (pred len) 617 <$> S.getByteString (pred len)
@@ -616,8 +643,12 @@ instance Serialize Message where
616 put (Fast msg) = putFast msg 643 put (Fast msg) = putFast msg
617 put (Extended m ) = putExtendedMessage m 644 put (Extended m ) = putExtendedMessage m
618 645
646statusUpdateId :: StatusUpdate -> MessageId
647statusUpdateId (Choking choking) = fromIntegral (0 + fromEnum choking)
648statusUpdateId (Interested choking) = fromIntegral (2 + fromEnum choking)
649
619putStatus :: Putter StatusUpdate 650putStatus :: Putter StatusUpdate
620putStatus su = putInt 1 >> S.putWord8 (fromIntegral (fromEnum su)) 651putStatus su = putInt 1 >> S.putWord8 (statusUpdateId su)
621 652
622putRegular :: Putter RegularMessage 653putRegular :: Putter RegularMessage
623putRegular (Have i) = putInt 5 >> S.putWord8 0x04 >> putInt i 654putRegular (Have i) = putInt 5 >> S.putWord8 0x04 >> putInt i