summaryrefslogtreecommitdiff
path: root/src
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
parent7f63b5554fcf31d9b71c79fa9d0ee66d2ef95c94 (diff)
~ Fix message length bug in handshake.
Diffstat (limited to 'src')
-rw-r--r--src/Network/BitTorrent/PeerWire/Handshake.hs16
-rw-r--r--src/Network/BitTorrent/PeerWire/Message.hs5
2 files changed, 17 insertions, 4 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."
diff --git a/src/Network/BitTorrent/PeerWire/Message.hs b/src/Network/BitTorrent/PeerWire/Message.hs
index 39102eed..1c520221 100644
--- a/src/Network/BitTorrent/PeerWire/Message.hs
+++ b/src/Network/BitTorrent/PeerWire/Message.hs
@@ -99,7 +99,10 @@ instance Serialize Message where
99 0x0D -> SuggestPiece <$> getInt 99 0x0D -> SuggestPiece <$> getInt
100 0x10 -> RejectRequest <$> get 100 0x10 -> RejectRequest <$> get
101 0x11 -> AllowedFast <$> getInt 101 0x11 -> AllowedFast <$> getInt
102 _ -> fail $ "unknown message ID: " ++ show mid 102 _ -> do
103 rm <- remaining >>= getBytes
104 fail $ "unknown message ID: " ++ show mid ++ "\n"
105 ++ "remaining available bytes: " ++ show rm
103 106
104 where 107 where
105 getBlock :: Int -> Get Block 108 getBlock :: Int -> Get Block