Search code examples
pythonsocketsudpbittorrentdht

UDP socket connected to DHT node, not recieving data


I'm attempting to implement the DHT protocol using python, but having troubles getting a response from a public DHT node (router.bittorrent.com:6881). Interestingly, the Node JS variant that I wrote works fine and I was able to get a response from the server. I'm using windows and added a UDP port rule in the inbound connections of the firewall settings that opened all UDP ports. I also tried disabling the entire firewall all together, but to no avail. I would appreciate any input.

#info_hash is a byte string parameter 

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(3)

network_info = (socket.gethostbyname('router.bittorrent.com'), 6881)
sock.connect(network_info)



rand = lambda: ''.join([chr(random.randint(0, 255)) for _ in range(20)])
my_id = rand()
get_peers = {b"t":b'aa', b"y":b"q", b"q":b"get_peers",
            b"a": {b"id":my_id,
                  b"info_hash": info_hash}}

encoded_data = bencoding.encode(get_peers)
sock.send(encoded_data)
res = sock.recv(1024) #Always times out here       

I added a firewall rule (and disabled all firewall protection measures in windows' settings), tried to bind the socket to (0.0.0.0), and attempted to use linux (kali linux virtual machine)


Solution

    • for routing table maintenance/bootstrapping you should use find_node, not get_peers
    • use wireshark to see what's being sent over the network and compare that with the working implementation
    • check the firewall on your router
    • use a bound UDP socket, not a connected one, you want local-to-any communication. This shouldn't be relevant for the first request but it's how a DHT node should be implemented
    • bind to a single address, not 0.0.0.0. This is mostly relevant for multi-homed hosts but still good practice in general