diff options
Diffstat (limited to 'src/Network/Torrent/PeerWire/Handshake.hs')
-rw-r--r-- | src/Network/Torrent/PeerWire/Handshake.hs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/Network/Torrent/PeerWire/Handshake.hs b/src/Network/Torrent/PeerWire/Handshake.hs new file mode 100644 index 00000000..7bdb7fef --- /dev/null +++ b/src/Network/Torrent/PeerWire/Handshake.hs | |||
@@ -0,0 +1,54 @@ | |||
1 | {-# LANGUAGE OverloadedStrings #-} | ||
2 | module Network.Torrent.PeerWire.Handshake | ||
3 | ( Handshake | ||
4 | , defaultProtocol, defaultReserved, defaultHandshake | ||
5 | ) where | ||
6 | |||
7 | import Control.Applicative | ||
8 | import Data.Word | ||
9 | import Data.ByteString (ByteString) | ||
10 | import qualified Data.ByteString as B | ||
11 | import Data.Serialize | ||
12 | |||
13 | import Network.Torrent.PeerID | ||
14 | |||
15 | -- | In order to establish the connection between peers we should send 'Handshake' | ||
16 | -- message. The 'Handshake' is a required message and must be the first message | ||
17 | -- transmitted by the peer to the another peer. | ||
18 | data Handshake = Handshake { | ||
19 | hsProtocol :: ByteString -- ^ Identifier of the protocol. | ||
20 | , hsReserved :: Word64 -- ^ Reserved bytes, rarely used. | ||
21 | , hsInfoHash :: ByteString -- ^ Hash from the metainfo file. | ||
22 | -- This /should be/ same hash that is transmitted in tracker requests. | ||
23 | , hsPeerID :: PeerID -- ^ Peer id of the initiator. | ||
24 | -- This is /usually the same peer id that is transmitted in tracker requests. | ||
25 | } deriving (Show, Eq) | ||
26 | |||
27 | instance Serialize Handshake where | ||
28 | put hs = do | ||
29 | putWord8 (fromIntegral (B.length (hsProtocol hs))) | ||
30 | putByteString (hsProtocol hs) | ||
31 | putWord64be (hsReserved hs) | ||
32 | putByteString (hsInfoHash hs) | ||
33 | put (hsPeerID hs) | ||
34 | |||
35 | get = do | ||
36 | len <- getWord8 | ||
37 | Handshake <$> getBytes (fromIntegral len) | ||
38 | <*> getWord64be | ||
39 | <*> getBytes 20 | ||
40 | <*> get | ||
41 | |||
42 | -- | Default protocol string "BitTorrent protocol" as is. | ||
43 | defaultProtocol :: ByteString | ||
44 | defaultProtocol = "BitTorrent protocol" | ||
45 | |||
46 | -- | Default reserved word is 0. | ||
47 | defaultReserved :: Word64 | ||
48 | defaultReserved = 0 | ||
49 | |||
50 | -- | Length of info hash and peer id is unchecked, so it /should/ be equal 20. | ||
51 | defaultHandshake :: ByteString -- ^ Info hash string. | ||
52 | -> PeerID | ||
53 | -> Handshake | ||
54 | defaultHandshake hash pid = Handshake defaultProtocol defaultReserved hash pid \ No newline at end of file | ||