I had a 300 Mbps connection, but my YouTube videos were buffering like crazy.
The culprit? A massive file downloading in the background that was happily consuming every ounce of bandwidth. I had both Wi-Fi and an Ethernet cable plugged in, and it hit me: Why can’t I just force my download client to use the Ethernet, and keep Firefox strictly on Wi-Fi?
Surprisingly, there wasn't a simple, GUI-friendly way to do this. So, I built InterMux—an open-source utility that lets you bind any application to a specific network interface.
Here is how I built the native Linux version, and the massive technical headache of trying to port it to Windows.
The Linux Approach: Network Namespaces (Done Right)
Linux has an incredibly powerful feature called Network Namespaces (ip netns). It allows you to create isolated network stacks, complete with their own routing tables and interfaces.
A lot of people write quick bash scripts to throw an app into a namespace, but they almost always make one fatal UX mistake: they run the application as root. If you launch Firefox as root via a namespace script, it creates a brand new, empty profile. Your bookmarks, cookies, and extensions are gone.
For InterMux, I wanted it to feel seamless. The core architecture uses Python to handle the heavy lifting:
It creates the namespace and configures the veth pairs, custom routing tables, and NAT/IP forwarding as root.
It handles DNS resolution inside the namespace (working around pesky systemd-resolved stubs).
The trick: It immediately drops privileges using sudo -u, launching the target application as your regular user.
The result? You click a button in the Tkinter GUI, and Firefox opens on your Wi-Fi interface with all your tabs and profiles perfectly intact, while your terminal runs a ping command isolated on your mobile tether.
The Windows Problem: Faking Namespaces
Once the Linux version was stable, I wanted to bring it to Windows. I quickly realized Windows doesn't have an equivalent to kernel network namespaces. You can't just isolate a process's network stack easily.
I had to get creative. If I couldn't isolate the network at the OS level, I had to intercept the traffic.
For Phase 1 (currently in pre-release), I built a workaround using a local asyncio SOCKS5 proxy server. Here is how it works:
InterMux uses psutil to detect all active physical adapters and their IP addresses.
It spins up a local SOCKS5 proxy on 127.0.0.1.
Here is the magic: whenever the proxy server makes an outbound connection on behalf of the app, it binds the socket explicitly to the target adapter's IP using local_addr=(adapter_ip, 0). This forces the Windows networking stack to route the traffic out of that specific physical NIC.
InterMux then launches the target application (like Firefox or Chrome) and injects proxy environment variables (ALL_PROXY, etc.) or writes directly to their config files to force them through the local proxy.
It works great for web browsers and basic TCP download tools, but it’s still a hack.
The Call for Contributors (Phase 2)
The SOCKS5 approach on Windows has two major flaws: it doesn't support UDP traffic (so no gaming or VoIP), and some applications completely ignore system proxy variables.
This is where I need help.
For Phase 2 on Windows, the goal is to replace the SOCKS5 proxy with DLL-based socket injection. We need to hook the connect() and bind() calls at the application level and force them to bind to the specific adapter's IP before the traffic ever hits the OS routing table.
If you are a C++ or Systems developer who loves digging into Windows internals, DLL hooking, or network programming, I would love your help.
Even if you just want to use the stable Linux version to manage your bandwidth (or isolate your security testing tools), check it out!
Let me know what you think of the architecture, or if you have better ideas for tackling the Windows networking stack!
Top comments (0)