summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/DHT
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2013-12-27 05:36:45 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2013-12-27 05:36:45 +0400
commite06b3dbd76a0a76c872ca27b4ea33b4465d14da3 (patch)
treef797719a25bce95a95a3b30e02b50af7a7e7520a /src/Network/BitTorrent/DHT
parent89151d4315631243840fcae54244c144ff42329d (diff)
Fix get_peers response encoding
Diffstat (limited to 'src/Network/BitTorrent/DHT')
-rw-r--r--src/Network/BitTorrent/DHT/Message.hs38
1 files changed, 24 insertions, 14 deletions
diff --git a/src/Network/BitTorrent/DHT/Message.hs b/src/Network/BitTorrent/DHT/Message.hs
index 0733a85d..15d1099c 100644
--- a/src/Network/BitTorrent/DHT/Message.hs
+++ b/src/Network/BitTorrent/DHT/Message.hs
@@ -31,6 +31,7 @@ import Control.Applicative
31import Data.BEncode as BE 31import Data.BEncode as BE
32import Data.BEncode.BDict 32import Data.BEncode.BDict
33import Data.ByteString as BS 33import Data.ByteString as BS
34import Data.List as L
34import Data.Monoid 35import Data.Monoid
35import Data.Serialize as S 36import Data.Serialize as S
36import Data.Typeable 37import Data.Typeable
@@ -138,7 +139,7 @@ binary k = field (req k) >>= either (fail . format) return .
138 139
139instance (Typeable ip, Serialize ip) => BEncode (NodeFound ip) where 140instance (Typeable ip, Serialize ip) => BEncode (NodeFound ip) where
140 toBEncode (NodeFound ns) = toDict $ 141 toBEncode (NodeFound ns) = toDict $
141 nodes_key .=! S.encode ns 142 nodes_key .=! runPut (mapM_ put ns)
142 .: endDict 143 .: endDict
143 144
144 fromBEncode = fromDict $ NodeFound <$> binary nodes_key 145 fromBEncode = fromDict $ NodeFound <$> binary nodes_key
@@ -154,7 +155,7 @@ instance (Serialize ip, Typeable ip)
154 155
155-- | Get peers associated with a torrent infohash. 156-- | Get peers associated with a torrent infohash.
156newtype GetPeers = GetPeers InfoHash 157newtype GetPeers = GetPeers InfoHash
157 deriving Typeable 158 deriving (Show, Eq, Typeable)
158 159
159info_hash_key :: BKey 160info_hash_key :: BKey
160info_hash_key = "info_hash" 161info_hash_key = "info_hash"
@@ -172,7 +173,7 @@ data GotPeers ip = GotPeers
172 -- | The token value is a required argument for a future 173 -- | The token value is a required argument for a future
173 -- announce_peer query. 174 -- announce_peer query.
174 , grantedToken :: Token 175 , grantedToken :: Token
175 } deriving Typeable 176 } deriving (Show, Eq, Typeable)
176 177
177peers_key :: BKey 178peers_key :: BKey
178peers_key = "values" 179peers_key = "values"
@@ -182,17 +183,25 @@ token_key = "token"
182 183
183instance (Typeable ip, Serialize ip) => BEncode (GotPeers ip) where 184instance (Typeable ip, Serialize ip) => BEncode (GotPeers ip) where
184 toBEncode GotPeers {..} = toDict $ 185 toBEncode GotPeers {..} = toDict $
185 putPeerList peers 186 case peers of
186 .: token_key .=! grantedToken 187 Left ns ->
187 .: endDict 188 nodes_key .=! runPut (mapM_ put ns)
188 where 189 .: token_key .=! grantedToken
189 putPeerList (Right ps) = peers_key .=! S.encode ps 190 .: endDict
190 putPeerList (Left ns) = nodes_key .=! S.encode ns 191 Right ps ->
192 token_key .=! grantedToken
193 .: peers_key .=! L.map S.encode ps
194 .: endDict
191 195
192 fromBEncode = fromDict $ GotPeers <$> getPeerList <*>! token_key 196 fromBEncode = fromDict $ do
193 where 197 mns <- optional (binary nodes_key) -- "nodes"
194 getPeerList = Right <$> binary peers_key 198 tok <- field (req token_key) -- "token"
195 <|> Left <$> binary nodes_key 199 mps <- optional (field (req peers_key) >>= decodePeers) -- "values"
200 case (Right <$> mps) <|> (Left <$> mns) of
201 Nothing -> fail "get_peers: neihter peers nor nodes key is valid"
202 Just xs -> pure $ GotPeers xs tok
203 where
204 decodePeers = either fail pure . mapM S.decode
196 205
197instance (Typeable ip, Serialize ip) => 206instance (Typeable ip, Serialize ip) =>
198 KRPC (Query GetPeers) (Response (GotPeers ip)) where 207 KRPC (Query GetPeers) (Response (GotPeers ip)) where
@@ -213,7 +222,7 @@ data Announce = Announce
213 222
214 -- | received in response to a previous get_peers query. 223 -- | received in response to a previous get_peers query.
215 , sessionToken :: Token 224 , sessionToken :: Token
216 } deriving Typeable 225 } deriving (Show, Eq, Typeable)
217 226
218port_key :: BKey 227port_key :: BKey
219port_key = "port" 228port_key = "port"
@@ -235,6 +244,7 @@ instance BEncode Announce where
235-- port number under the infohash in its store of peer contact 244-- port number under the infohash in its store of peer contact
236-- information. 245-- information.
237data Announced = Announced 246data Announced = Announced
247 deriving (Show, Eq, Typeable)
238 248
239instance BEncode Announced where 249instance BEncode Announced where
240 toBEncode _ = toBEncode Ping 250 toBEncode _ = toBEncode Ping