[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  

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