10/10/2016

Torrent-tracking across networks

I have never given lots of thought to torrents, mostly it has for me been a thing to use to get hold of linux distro images. Although at the end of a small video production project (for Var GladSpexarna), and given the very modest server means available, the size of the file, and the number of potential recipients, BitTorrent, with its decentralized distribution seemed to be the right method.

Earlier years, before I was in charge, DVDs were burned, but the availability of newer cameras with higher resolutions have obsoleted that method, and even if bluray could possibly be used, my personal opinion is that, in the age of streaming and digital storefronts, optical media is on the way out. I am also not a fan of the prospect of being the one burning all these discs.

Torrents were given the OK from above, and a friend set up a small tracker. Since the aim is internal distribution, that was opted for, rather than using one of the various public trackers. The torrent is private as well, and the files are encrypted. I would have run a tracker myself, if not for the fact that I seemed to be unable to set up any sort of external visibility on my machines. I wrote that off as being yet another dimension of failure of the cheap 3G modem that is my connection to the internet. Other things required my focus.

Except it wasn't, or something changed. I don't know, but for some reason I had another go at it, and found out about hairpinning, and how routers may or may not support it. So I'm back in the running-my-own-server game at last.

The server now includes a torrent tracker. Because I want to run torrent tracker. The tracker is opentracker, the same as my friend uses, with a few modifications by yours truly, and those are the reasons I'm writing this post.

The problem I ran into with the tracker is that if I run the client with the initial seed of a torrent on the same host as the tracker itself, the address associated with that client will be 127.0.0.1, localhost. When another client asks for peers, the tracker will respond that there is one at 127.0.0.1.
This will of course not work.
The same thing goes for when there are clients running on the same local net as the tracker, say 10.0.0.0/8, and a client on a machine somewhere on the internet asks for peers.

At some point in time, the clients on local addresses will update their peer list, and thus ask the tracker again, and the tracker may inform them of the data-starved machine on the internet and initiate a connection.

The problem is succinctly put: "A machine cannot be the initiator of a connection between it and a machine on a local net behind a gateway, by addressing that machine by its local address." Kind of obvious when put that way.

Some of these problems can in some cases be fixed by having the tracker and client support setting a chosen IP address, rather than use the address from the connection between client and tracker. This was not a viable solution for me for two reasons:

  1. The torrent client I use, especially for running as a daemon is transmission, which does not support setting a custom IP field.
  2. If I could set an IP address, and I set it to the external address of my modem/gateway, I would not be able to connect to that client from my local network, due to lack of support for hairpinning.
The solution I opted for, partially to see if I could do it, partially since it seemed to me to be the easiest way to have everything I wanted without compromise, was to modify the tracker.
I present to you, my variant of opentracker. The modifications I have done, amount to doing an address translation of the peer list based on from where the request comes. The translations are rule-based so any translation expressible by the config file format should be possible, but the assumed use case is to e.g. translate local addresses to the gateway's external address when a machine outside the local net is asking.