13 Jan 2012: Messing around dealing with random packet loss

One of my interests recently has been around network quality and how well protocols such as TCP cope with noise. Having just spent a week trying to use internet in various backpackers, network quality has come to the front of my brain again.

When a router can’t forward traffic as quickly as it’s getting it, it starts dropping packets. TCP takes advantage of this to measure link capacity – it increases the amount of traffic being sent until it starts losing packets then reduces the speed again. This generally works very well, but has an issue with packet loss not related to the data being sent. Many networks just have noise or lose packets randomly, and TCP will tend to back right off to a trickle when this happens completely unnecessarily.

I’ve been having a play with some simple erasure correction over networks. The result so far is a messy ruby script which will set up a tunnel with some erasure tolerance between linux boxes. EDIT: script updated. Was insanely buggy and kept losing link when client changed source port. Now repairs connection when that happens, editing this now over the link.. It breaks each packet it gets on the tun interface in to 3 UDP packets, and can reassemble any 2 of those in to the original. It takes just over half as much again traffic (adds some headers) but is a bit more resilient to random packet loss.

You can set up a server instance like:

you@server$ sudo ruby fectun.rb 0.0.0.0 4943 server PASSWORD

It will bind to the IP and port given and wait for a client to connect. The word “server” is magic – no decent command line options yet. The password should be chosen and kept the same between them – the server can only handle one client at once and any client with the password can take over the connection.

To connect with a client:

you@client$ sudo ruby fectun.rb 0.0.0.0 9000 my.other.computer 4943 PASSWORD

If all goes well, the server end should tell you it’s switching its destination to the client that just connected. The port may be mangled if the client is behind a NAT router.

Each end now has a “tun” interface connected to each other. These need to be given IP addresses:

you@server$ sudo ifconfig tun0 10.93.0.1/24

you@client$ sudo ifconfig tun0 10.93.0.2/24

Then from the client you should be able to:

you@client$ ping 10.93.0.1

or set up a SOCKS proxy by running SSH over the link:

you@client$ ssh you@10.0.0.1 -D 8080

It’s all a little sketchy at the moment but have managed to get a link to my server going from home. I hope to extend this to batch packets together within the erasure code so that it doesn’t send 3 times as many packets.

P.S. Please use this nicely. Could be quite anti-social on busy networks if you sent a lot of traffic over it.

blog comments powered by Disqus