Opened 12 years ago

Closed 7 years ago

Last modified 6 years ago

#2133 closed bug (Fixed)

Remove port randomization to avoid polluting DHT

Reported by: bmnot Owned by: Cas
Priority: major Milestone: 2.0.0
Component: Core Version: 1.3-stable
Keywords: Cc:


To quote hydri (libtorrent author) regarding Deluge's port randomization: "<hydri> yeah, you should tell them not to do that.."

Try this: Start Deluge, connect to DHT, wait about half an hour, then disconnect again and re-start Deluge, letting it pick a new random port. Then go watch your router logs. About 2000 blocked connections per minute in my case. That's all the DHT peers trying to send you queries at your last known port.

Now, what happened? Well, when you meet other peers on torrents, you each exchange lists of all the DHT peers you know about. They add you to their list in this format: IP:PORT:FINGERPRINT. Then when THEY meet other peers, they keep passing this on, further and further. Suddenly, thousands or tens of thousands of peers know about your IP and port.

So, what happens when you change port all the time? Well, all those peers will be hammering your router at ports that are closed. At best, it means your DHT works much worse and that you're polluting the worldwide DHT tables. At worst, the DDoS-like "attack" might a crash a router that can't keep up with the thousands of blocked port messages per minute (it takes a bit of CPU and RAM to generate the text string for each blocked attempt in its internal logs; I've seen routers crash from this, mostly ones 8+ years old).

It also harms regular torrenting (TCP), because of peer discovery mechanisms. In that case, peers build lists of the IP and TCP port of all other peers, and then share these lists with each other. If your port has changed, you won't get connected to by those peers anymore. So, it's bad all around to have random ports on *every* launch.

The solution is so simple: Remove the "random port" checkbox, and change the dual incoming port "range" fields to a single port field instead. Next, on the first startup of the Deluge daemon, generate a port at random, and then stick to it. Allow the user to change the port if they want to, but using that single field to enter *one* port in. The process is as follows: "Install > first launch (rand() 49152-65535) == 53838 > every other launch = 53838". That way every user will still have a unique port, but it won't change on every launch, thus not harming DHT/getting your router DDoS'd. The port might still change occasionally due to being in use, but at least it will no longer happen on *every* launch, thus doing far less damage. Now, the OUTGOING ports on the other hand, should stay random (a port range); they have nothing to do with the torrent protocol. It's only the incoming port that needs to be static, for you to be connectable by other peers that know about you.

Finally: I spoke to Johnny, trying to figure out why this behavior was even in Deluge in the first place. Neither of us can see a reason. There is no benefit to having a random incoming port on every launch. Hiding traffic from the ISP by changing ports? No, your client still runs 24/7 for the most part and uses a single port all that time. If you really wanted to avoid any chance of ISPs detecting a lot of traffic on a single port, then the current feature is not gonna do it; the only way to combat traffic detection is to make a user-plugin that disables DHT, and then changes the libtorrent port every X minutes.

So, the current feature has no value and just harms the torrent protocol.

Lastly; libtorrent 16 has added a flag to "never let the OS pick a random port" (if port in use) for this exact reason, but it's not getting backported to lt15 so it cannot be used here. Here it is anyway for completion: "added session::listen_no_system_port flag to prevent libtorrent from ever binding the listen socket to port 0"

Change History (9)

comment:1 Changed 12 years ago by bmnot

PS: I'm already safe since I've disabled the randomization checkbox and put a single port in both range fields, resulting in it trying the same single port on every launch, so for me it doesn't matter if this gets fixed, but a fix would benefit all the other users. That's why I reported this.

comment:2 Changed 11 years ago by Cas

  • Milestone changed from Future to 1.4.0

comment:3 Changed 11 years ago by bmnot

Related ticket:

The "never let the system pick a random port" feature in libtorrent 1.6 is perfect, but something similar can be done for older clients too:

  • Start an instance of libtorrent.
  • Query the port.
  • Is it the port you wanted? No? Kill the libtorrent instance.
  • Wait X seconds.
  • Start an instance of libtorrent again.
  • Is it the port you wanted? No? Die with "unable to bind to desired port."

This allows people that have bound a static port in their router (not using UPnP) to have a working torrent daemon since it will never try to bind to the wrong port.

comment:4 Changed 10 years ago by Cas

  • Milestone changed from 1.4.0 to 2.0.0
  • Owner set to Cas
  • Status changed from new to assigned

comment:6 Changed 9 years ago by Doadin

I think provide a single port with no randomization and just give a popup if it cant bind to the specified port saying the port is in use or what is fairly common(imo) in other programs. Then optionally we can try and add something like other programs have that tells you what is using that port. I know i have a http server program on windows and it does this i tell it a port and for example ill say use port 80 and if i have skype open it uses 80 so the http server says something like "unable to bind to port 80, in use by skype.exe". Not sure how easy that last part would be to implement cross platform though.

Also maybe instead of a random port just pick one from the range 6881-6889 which is common for bittorrent and therefore should be open unless the user has many bittorrent clients open or for some random reason some other app decided to also ignore common defaults and picked a random port in this range.

Last edited 9 years ago by Doadin (previous) (diff)

comment:7 Changed 7 years ago by Cas

Fixed in develop for core, console and GTKUI: [5978b433d] and [175534787]

Outstanding WebUI preferences issue:

comment:8 Changed 7 years ago by Cas

  • Resolution set to Fixed
  • Status changed from assigned to closed

WebUI fixed: [20bae1bf90]

comment:9 Changed 6 years ago by Cas

  • Milestone changed from 2.0 to 2.0.0

Milestone renamed

Note: See TracTickets for help on using tickets.