BitTorrent DHT find_node Query Explained
The find_node query is a fundamental remote procedure
call (RPC) used in the BitTorrent Distributed Hash Table (DHT) to
discover other nodes and maintain an up-to-date routing table. This
article explains the purpose of the find_node message
within the Kademlia-based Mainline DHT (MLDHT) protocol, how the query
functions, and the specific binary data returned in its response.
What Is the find_node Query?
In BitTorrent’s trackerless DHT network, nodes store routing
information about each other rather than relying on a central server.
The find_node query is used by a client to search the DHT
for contact details of a specific 20-byte target node ID.
Unlike the get_peers query, which searches for peers
downloading or seeding a specific torrent info-hash,
find_node is strictly used for network maintenance,
bootstrapping new nodes into the network, and locating the closest
active nodes to a specific target identifier.
How the Query Works
Communication in the BitTorrent DHT relies on the Kademlia RPC (KRPC)
protocol, which uses Bencoded UDP packets. When a node sends a
find_node request, it includes the following parameters in
the query dictionary:
id: The 20-byte Node ID of the querying node.target: The 20-byte Node ID of the node being searched for.
What Information Does find_node Return?
When a node receives a find_node query, it searches its
own routing table for the \(K\) closest
nodes (typically \(K = 8\)) to the
requested target ID according to the XOR metric. It then
returns a Bencoded response containing a return dictionary
(r) with two key fields:
id: A 20-byte string representing the Node ID of the responding node.nodes: A compact binary string containing contact information for the 8 closest nodes known to the responder.
Format of the Compact Node Info
The nodes field encodes contact information in a
concatenated binary format to minimize network overhead:
- For IPv4: Each node entry takes up 26 bytes:
- Node ID: 20 bytes
- IP Address: 4 bytes (IPv4 address in network byte order)
- Port: 2 bytes (port number in network byte order)
- For IPv6: In extensions supporting IPv6 (such as
BEP 32), an alternate
nodes6field is used, where each node entry takes up 38 bytes (20 bytes for Node ID, 16 bytes for IPv6, and 2 bytes for the port).
If the responding node itself has the exact Node ID requested in the
target parameter, its own contact information and ID are
included among the returned list. The querying node then parses these
entries, updates its own routing table with the newly discovered nodes,
and can iteratively query those closer nodes to continue traversing the
DHT.