Wednesday 16 May 2018

Go-dispatch-proxy: A load balancing proxy written in Go

This will be my first post of 2018. I've been very busy these days and didn't have the time to devote to this blog, that was the reason for the prolonged absence of activity. Anyway, in this post, I want to present a tool which I've been working on for some days. It's not related to RE or something fancy. It's just a tool to load balance network connections across multiple interfaces.

To cut a long story short, I have multiple internet connections on my Windows desktop. I needed a tool which would help to utilise all those connections effectively to give an improved speed. In case if multiple connections (i.e. routes) are available, the default behaviour of Windows is to select the one which has a lower metric. If all routes have the same metric, Windows will select one and ignore the rest. [To change the interface metric manually have a look here]

To workaround this problem we can use a load balancer proxy. The purpose of the proxy would be to distribute our connections across the available interfaces leading to increased throughput. There is a project on GitHub - dispatch-proxy which is based on the same idea. It works but I dislike the fact that its written in Node.js. A seemingly innocuous command npm install can wreak havoc on the hard disk by creating tons of tiny files and fragmenting the file system in the process. Naturally, I have an aversion towards desktop apps which are written using node and friends.

Based on the idea I've written SOCKS5 load balancing proxy in pure Go with no additional dependencies.


The binary consists of just a single file which you can get from the appveyor CI server. It works on Windows and fulfils my purpose. It has not been tested on macOS but will likely work. However, it won't work on Linux. This is because the tool works by changing the source IP address for the outgoing packets. On Windows changing the source IP makes the outgoing packet to use the corresponding interface. On Linux, the packet is transmitted according to the kernels routing table and specifying the source IP has no effect.

To conclude this short post, here are a couple of screenshots showing the tool in action.

Listing the available interfaces
Listing the available interfaces

SOCKS proxy at work
SOCKS proxy at work