Ticket #2133 (new bug)
Remove port randomization to avoid polluting DHT
|Reported by:||bmnot||Owned by:|
|Component:||core||Version:||1.3-stable (git branch)|
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: http://upstream-tracker.org/changelogs/libtorrent-rasterbar/0.16.1/changelog.html "added session::listen_no_system_port flag to prevent libtorrent from ever binding the listen socket to port 0"