diff options
Diffstat (limited to 'src/Network/BitTorrent/DHT/Message.hs')
-rw-r--r-- | src/Network/BitTorrent/DHT/Message.hs | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/src/Network/BitTorrent/DHT/Message.hs b/src/Network/BitTorrent/DHT/Message.hs index 15d1099c..49629755 100644 --- a/src/Network/BitTorrent/DHT/Message.hs +++ b/src/Network/BitTorrent/DHT/Message.hs | |||
@@ -214,8 +214,15 @@ instance (Typeable ip, Serialize ip) => | |||
214 | -- | Announce that the peer, controlling the querying node, is | 214 | -- | Announce that the peer, controlling the querying node, is |
215 | -- downloading a torrent on a port. | 215 | -- downloading a torrent on a port. |
216 | data Announce = Announce | 216 | data Announce = Announce |
217 | { -- | infohash of the torrent; | 217 | { -- | If set, the 'port' field should be ignored and the source |
218 | topic :: InfoHash | 218 | -- port of the UDP packet should be used as the peer's port |
219 | -- instead. This is useful for peers behind a NAT that may not | ||
220 | -- know their external port, and supporting uTP, they accept | ||
221 | -- incoming connections on the same port as the DHT port. | ||
222 | impliedPort :: Bool | ||
223 | |||
224 | -- | infohash of the torrent; | ||
225 | , topic :: InfoHash | ||
219 | 226 | ||
220 | -- | the port /this/ peer is listening; | 227 | -- | the port /this/ peer is listening; |
221 | , port :: PortNumber | 228 | , port :: PortNumber |
@@ -227,16 +234,26 @@ data Announce = Announce | |||
227 | port_key :: BKey | 234 | port_key :: BKey |
228 | port_key = "port" | 235 | port_key = "port" |
229 | 236 | ||
237 | implied_port_key :: BKey | ||
238 | implied_port_key = "implied_port" | ||
239 | |||
230 | instance BEncode Announce where | 240 | instance BEncode Announce where |
231 | toBEncode Announce {..} = toDict $ | 241 | toBEncode Announce {..} = toDict $ |
232 | info_hash_key .=! topic | 242 | implied_port_key .=? flagField impliedPort |
233 | .: port_key .=! port | 243 | .: info_hash_key .=! topic |
234 | .: token_key .=! sessionToken | 244 | .: port_key .=! port |
245 | .: token_key .=! sessionToken | ||
235 | .: endDict | 246 | .: endDict |
247 | where | ||
248 | flagField flag = if flag then Just (1 :: Int) else Nothing | ||
249 | |||
236 | fromBEncode = fromDict $ do | 250 | fromBEncode = fromDict $ do |
237 | Announce <$>! info_hash_key | 251 | Announce <$> (boolField <$> optional (field (req implied_port_key))) |
252 | <*>! info_hash_key | ||
238 | <*>! port_key | 253 | <*>! port_key |
239 | <*>! token_key | 254 | <*>! token_key |
255 | where | ||
256 | boolField = maybe False (/= (0 :: Int)) | ||
240 | 257 | ||
241 | -- | The queried node must verify that the token was previously sent | 258 | -- | The queried node must verify that the token was previously sent |
242 | -- to the same IP address as the querying node. Then the queried node | 259 | -- to the same IP address as the querying node. Then the queried node |