diff options
Diffstat (limited to 'src/Network/BitTorrent/PeerWire/Handshake.hs')
-rw-r--r-- | src/Network/BitTorrent/PeerWire/Handshake.hs | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/src/Network/BitTorrent/PeerWire/Handshake.hs b/src/Network/BitTorrent/PeerWire/Handshake.hs index e0d1672b..62d7d7f4 100644 --- a/src/Network/BitTorrent/PeerWire/Handshake.hs +++ b/src/Network/BitTorrent/PeerWire/Handshake.hs | |||
@@ -12,7 +12,7 @@ | |||
12 | -- | 12 | -- |
13 | {-# LANGUAGE OverloadedStrings #-} | 13 | {-# LANGUAGE OverloadedStrings #-} |
14 | module Network.BitTorrent.PeerWire.Handshake | 14 | module Network.BitTorrent.PeerWire.Handshake |
15 | ( Handshake | 15 | ( Handshake, handshakeCaps |
16 | , handshake | 16 | , handshake |
17 | , ppHandshake | 17 | , ppHandshake |
18 | , defaultHandshake, defaultBTProtocol, defaultReserved | 18 | , defaultHandshake, defaultBTProtocol, defaultReserved |
@@ -29,6 +29,7 @@ import Data.Torrent.InfoHash | |||
29 | import Network | 29 | import Network |
30 | import Network.Socket.ByteString | 30 | import Network.Socket.ByteString |
31 | 31 | ||
32 | import Network.BitTorrent.Extension | ||
32 | import Network.BitTorrent.Peer.ID | 33 | import Network.BitTorrent.Peer.ID |
33 | import Network.BitTorrent.Peer.ClientInfo | 34 | import Network.BitTorrent.Peer.ClientInfo |
34 | 35 | ||
@@ -69,6 +70,10 @@ instance Serialize Handshake where | |||
69 | <*> get | 70 | <*> get |
70 | <*> get | 71 | <*> get |
71 | 72 | ||
73 | |||
74 | handshakeCaps :: Handshake -> Capabilities | ||
75 | handshakeCaps = hsReserved | ||
76 | |||
72 | -- TODO add reserved bits info | 77 | -- TODO add reserved bits info |
73 | -- | Format handshake in human readable form. | 78 | -- | Format handshake in human readable form. |
74 | ppHandshake :: Handshake -> String | 79 | ppHandshake :: Handshake -> String |
@@ -95,7 +100,7 @@ defaultReserved = 0 | |||
95 | defaultHandshake :: InfoHash -> PeerID -> Handshake | 100 | defaultHandshake :: InfoHash -> PeerID -> Handshake |
96 | defaultHandshake = Handshake defaultBTProtocol defaultReserved | 101 | defaultHandshake = Handshake defaultBTProtocol defaultReserved |
97 | 102 | ||
98 | 103 | -- TODO exceptions instead of Either | |
99 | -- | Handshaking with a peer specified by the second argument. | 104 | -- | Handshaking with a peer specified by the second argument. |
100 | -- | 105 | -- |
101 | handshake :: Socket -> Handshake -> IO (Either String Handshake) | 106 | handshake :: Socket -> Handshake -> IO (Either String Handshake) |
@@ -103,12 +108,15 @@ handshake sock hs = do | |||
103 | sendAll sock (S.encode hs) | 108 | sendAll sock (S.encode hs) |
104 | 109 | ||
105 | header <- recv sock 1 | 110 | header <- recv sock 1 |
106 | let protocolLen = B.head header | 111 | if B.length header == 0 then |
107 | let restLen = handshakeSize protocolLen - 1 | 112 | return $ Left "" |
108 | body <- recv sock restLen | 113 | else do |
109 | let resp = B.cons protocolLen body | 114 | let protocolLen = B.head header |
110 | 115 | let restLen = handshakeSize protocolLen - 1 | |
111 | return (checkIH (S.decode resp)) | 116 | body <- recv sock restLen |
117 | let resp = B.cons protocolLen body | ||
118 | |||
119 | return (checkIH (S.decode resp)) | ||
112 | where | 120 | where |
113 | checkIH (Right hs') | 121 | checkIH (Right hs') |
114 | | hsInfoHash hs /= hsInfoHash hs' = Left "Handshake info hash do not match." | 122 | | hsInfoHash hs /= hsInfoHash hs' = Left "Handshake info hash do not match." |