diff options
author | Sam T <pxqr.sta@gmail.com> | 2013-05-05 21:40:24 +0400 |
---|---|---|
committer | Sam T <pxqr.sta@gmail.com> | 2013-05-05 21:40:24 +0400 |
commit | 02890ad135b326d85aa5e7d188fce8fafec12fdb (patch) | |
tree | 6aa3e7f302495db8b042bfb851eaf434d5ff0ac8 /src | |
parent | 7f63b5554fcf31d9b71c79fa9d0ee66d2ef95c94 (diff) |
~ Fix message length bug in handshake.
Diffstat (limited to 'src')
-rw-r--r-- | src/Network/BitTorrent/PeerWire/Handshake.hs | 16 | ||||
-rw-r--r-- | src/Network/BitTorrent/PeerWire/Message.hs | 5 |
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 | |||
75 | ppHandshake hs = BC.unpack (hsProtocol hs) ++ " " | 75 | ppHandshake 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. | ||
79 | handshakeSize :: Word8 -> Int | ||
80 | handshakeSize n = 1 + fromIntegral n + 8 + 20 + 20 | ||
81 | |||
78 | -- | Maximum size of handshake message in bytes. | 82 | -- | Maximum size of handshake message in bytes. |
79 | handshakeMaxSize :: Int | 83 | handshakeMaxSize :: Int |
80 | handshakeMaxSize = 1 + 256 + 8 + 20 + 20 | 84 | handshakeMaxSize = handshakeSize 255 |
81 | 85 | ||
82 | -- | Default protocol string "BitTorrent protocol" as is. | 86 | -- | Default protocol string "BitTorrent protocol" as is. |
83 | defaultBTProtocol :: ByteString | 87 | defaultBTProtocol :: ByteString |
@@ -97,8 +101,14 @@ defaultHandshake = Handshake defaultBTProtocol defaultReserved | |||
97 | handshake :: Socket -> Handshake -> IO (Either String Handshake) | 101 | handshake :: Socket -> Handshake -> IO (Either String Handshake) |
98 | handshake sock hs = do | 102 | handshake 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 |