Opened 6 years ago

Closed 6 years ago

Last modified 2 years ago

#2121 closed feature-request (Duplicate)

Rework Deluge towards static incoming port

Reported by: bmnot Owned by:
Priority: critical Milestone: 2.0
Component: Core Version: other (please specify)
Keywords: Cc:

Description

This will sadly require libtorrent 0.16 in order to work (because that release adds port-reusing and forced ports http://code.google.com/p/libtorrent/issues/detail?id=305), but it would be a MAJOR improvement to Deluge, for multiple reasons:

  • A static port is best for DHT, because old clients will be lookng for you at your last-known IP and port, which is why clients like uTorrent have a single port setting.
  • Your router will be getting requests to old ports and will fill its logs with "UDP blocked" messages, similar to a Denial of Service attack, which can actually crash lower specced routers.

Once Deluge works well with libtorrent 0.16, it really would be worth looking into defaulting to a single, static port, randomly selected on config file generation.

Requesting a single port is easy in 0.16; see the libtorrent bug tracker link above. You just pass in two flags to tell it to re-use the port even if it's in TIME_WAIT state (the state just before it is freed by the system) and to disallow the system from choosing another port at random. It'll also require a small check that says "the only port we wanted is in use? okay, don't start the daemon, instead log a fatal error"

Change History (3)

comment:1 Changed 6 years ago by bmnot

  • Priority changed from major to critical

This is actually way more important than I made it out to be.

DHT works by all peers you encounter (whether that's via torrents or DHT or any other method) building lists of each other's IPs and ports.

These lists get populated as you encounter peers, and then they get shared around to other peers asking for DHT peer lists, for bootstrapping purposes.

So, what happens when you have a bad torrent client that uses a dynamic incoming port? Well, you break DHT quite badly.

What happens is that you will pollute the peer tables of *all* other peers you ever met, with false port numbers that you are no longer listening to.

Meanwhile, those peers will be trying to connect to your now-invalid port, as well as sharing this information with other peers.

The end result is that you keep polluting DHT with invalid IP:port pairs, and peers in turn will be hammering your router on invalid ports, causing it a great deal of load (particularly to generate all the failure/blocked log messages).

So, it's best to (as a user) set Deluge to "Use Random Port: No", and set the Incoming Port Range From/To? values to the same port, to enforce a single port and ensure clean DHT behavior.

There's only one issue with this workaround, and that's the fact that re-binding the same port will fail if you start the Daemon immediately after you last shut it down (i.e. with a daemon restart script). You'll have to stop the daemon, wait like 10 seconds, and start it again to ensure that the port will be properly available, or you'll once again end up in "random port" territory.

Sadly a proper fix to this behavior and a move to a single-port model would kind of require libtorrent 0.16, which finally includes support for fast re-binding and forcing a certain requested port.

There is *one* workaround that could be done even with libtorrent 0.15, and it's as follows: First, instantiate libtorrent using the requested single port you want (such as 54321), next, query libtorrent to see what port it actually assigned to. If it wasn't 54321, do NOT proceed, do NOT start DHT, just immediately close the daemon and log a "port was in use" error message. Alternatively, a re-try could possibly be implemented too, such as "port not the same as we requested? un-load libtorrent, load it again, wait 5 seconds, try to bind to that port one last time and see if we got it this time".

comment:2 Changed 6 years ago by bmnot

  • Resolution set to duplicate
  • Status changed from new to closed

comment:3 Changed 2 years ago by Cas

  • Milestone changed from 2.0.x to 2.0
Note: See TracTickets for help on using tickets.