summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/PeerWire/Handshake.hs
diff options
context:
space:
mode:
authorSam T <pxqr.sta@gmail.com>2013-05-05 21:40:24 +0400
committerSam T <pxqr.sta@gmail.com>2013-05-05 21:40:24 +0400
commit02890ad135b326d85aa5e7d188fce8fafec12fdb (patch)
tree6aa3e7f302495db8b042bfb851eaf434d5ff0ac8 /src/Network/BitTorrent/PeerWire/Handshake.hs
parent7f63b5554fcf31d9b71c79fa9d0ee66d2ef95c94 (diff)
~ Fix message length bug in handshake.
Diffstat (limited to 'src/Network/BitTorrent/PeerWire/Handshake.hs')
-rw-r--r--src/Network/BitTorrent/PeerWire/Handshake.hs16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/Network/BitTorrent/PeerWire/Handshake.hs b/src/Network/BitTorrent/PeerWire/Handshake.hs
index e4d27f75..e0d1672b 100644
--- a/src/Network/BitTorrent/PeerWire/Handshake.hs
+++ b/src/Network/BitTorrent/PeerWire/Handshake.hs
@@ -75,9 +75,13 @@ ppHandshake :: Handshake -> String
75ppHandshake hs = BC.unpack (hsProtocol hs) ++ " " 75ppHandshake hs = BC.unpack (hsProtocol hs) ++ " "
76 ++ ppClientInfo (clientInfo (hsPeerID hs)) 76 ++ ppClientInfo (clientInfo (hsPeerID hs))
77 77
78-- | Get handshake message size in bytes from the length of protocol string.
79handshakeSize :: Word8 -> Int
80handshakeSize n = 1 + fromIntegral n + 8 + 20 + 20
81
78-- | Maximum size of handshake message in bytes. 82-- | Maximum size of handshake message in bytes.
79handshakeMaxSize :: Int 83handshakeMaxSize :: Int
80handshakeMaxSize = 1 + 256 + 8 + 20 + 20 84handshakeMaxSize = handshakeSize 255
81 85
82-- | Default protocol string "BitTorrent protocol" as is. 86-- | Default protocol string "BitTorrent protocol" as is.
83defaultBTProtocol :: ByteString 87defaultBTProtocol :: ByteString
@@ -97,8 +101,14 @@ defaultHandshake = Handshake defaultBTProtocol defaultReserved
97handshake :: Socket -> Handshake -> IO (Either String Handshake) 101handshake :: Socket -> Handshake -> IO (Either String Handshake)
98handshake sock hs = do 102handshake sock hs = do
99 sendAll sock (S.encode hs) 103 sendAll sock (S.encode hs)
100 r <- recv sock handshakeMaxSize 104
101 return (checkIH (S.decode r)) 105 header <- recv sock 1
106 let protocolLen = B.head header
107 let restLen = handshakeSize protocolLen - 1
108 body <- recv sock restLen
109 let resp = B.cons protocolLen body
110
111 return (checkIH (S.decode resp))
102 where 112 where
103 checkIH (Right hs') 113 checkIH (Right hs')
104 | hsInfoHash hs /= hsInfoHash hs' = Left "Handshake info hash do not match." 114 | hsInfoHash hs /= hsInfoHash hs' = Left "Handshake info hash do not match."