[bittorrent] DHT and NAT
Josef Drexler
josef at ttdpatch.net
Fri Jun 29 15:17:41 EDT 2007
While implementing the Bittorrent DHT protocol for rtorrent, I've
noticed that the DHT specs do not provide a way for the node to tell
other nodes on what UDP port it should be contacted. I've looked
through the list archives and other message boards but it seems that
this never seems to have been discussed yet.
I've found that it is often the case that NAT routers will mangle the
source port of outgoing UDP packets. This means that I have no
control over the outgoing source port of the DHT packets, and while I
can properly forward any given port, that only works if the other
nodes already know to contact me there instead of the source port of
the packets they receive. Replies receives to the mangled port will
be forwarded automatically, so that sending queries and receiving
replies works well. However, the queries sent by other nodes will go
to the wrong port.
The mainline client adds the PORT message to the Bittorrent protocol,
which allows me to tell BT peers about the port to contact me on for
DHT. However, this only works while I have an active torrent, and not
if I want to run as a standalone DHT client.
Furthermore, it seems the mainline client is the only client that
implements this message, so when behind a NAT router I can only
actively join the DHT network if I am in fact connected to a recent
mainline client. Many other clients (such as uTorrent and Bitcomet)
claim to support DHT but do not support the message, or at least do
not indicate support for it in the options field.
Do these clients have other methods of letting nodes know the port?
I think ideally such an option would be part of the DHT protocol, so
that one does not have to have active torrents in order to join the
DHT network. On the other hand, running a standalone DHT node would
perhaps be unlikely behind a NAT router.
Nonetheless, there exists the need to exchange port numbers outside
of the current DHT specs. Possibilities include:
1) Adding the optional "p" key to the main KRPC dictionary, holding
the contact port.
This key might be added by a node if it notices no incoming queries,
indicating that other nodes cannot reach it on the source port of
outgoing messages. The receiving node should save the given port and
send all queries there instead of the packet's source port.
2) Adding support for the PORT message to all clients claiming to
support DHT.
Why don't they support the message anyway?
An alternative would be adding it as a field to the extension
protocol handshake that is also used for ut_pex for example.
3) A dedicated "try contacting me here" query type.
This might have {y="q", q="contact", a={port=<port>}}, and could
again be sent if the node notices a lack of incoming queries. This
should cause the receiving node to send a "ping" query to the given
port.
It might also be useful to add an "ip" key to support situations
where a router does multi-IP NAT and the source IP is not fixed
either. This could cause complications with properly identifying
incoming packets though, so I'm not sure if this is really a good idea.
--
Josef Drexler
josef at ttdpatch.net
More information about the BitTorrent
mailing list