/* tether_split.c - Micro-interceptor for per-app network routing.
* Forces SO_BINDTODEVICE on application sockets with 1MB WAN-jitter buffers.
*/
#define _GNU_SOURCE
#include <dlfcn.h>
#include <string.h>
#include <sys/socket.h>
#include <stdio.h>
// Define the interface just like a global state
// ADJUST NETWORK DEVICE HERE
static const char* IPHONE_IFACE = "enp0s24g0u5e4h2"; // <-- HERE
static int tether_initialized = 0;
// Intercept all OS socket creations
int socket(int domain, int type, int protocol) {
// 1. Grab the real OS socket function
int (*orig_socket)(int, int, int) = dlsym(RTLD_NEXT, "socket");
int fd = orig_socket(domain, type, protocol);
// 2. Only intercept valid IPv4/IPv6 sockets (Ignore local UNIX sockets)
if (fd >= 0 && (domain == AF_INET || domain == AF_INET6)) {
if (!tether_initialized) {
printf("[VX_NET] Intercepting OBS Sockets -> Forcing to %s\n", IPHONE_IFACE);
tether_initialized = 1;
}
// 3. Bind strictly to the iPhone interface
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, IPHONE_IFACE, strlen(IPHONE_IFACE));
// 4. [CRITICAL WAN PATCH]
// Force a 1MB Send Buffer for OBS to survive cellular jitter spikes
int buf_size = 1024 * 1024;
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const char*)&buf_size, sizeof(buf_size));
}
return fd;
}
gcc -fPIC -shared -o tether_split.so tether_split.c -ldl
Sometimes you want a specific application to use a specific network device, without changing the routing rules for the rest of your operating system. Instead of installing heavy networking daemons, container runtimes, or bloated user-space wrappers, this solves it with a few lines of clean C and zero dependencies.
It is designed with a minimalist, suckless-adjacent philosophy: one tiny tool that does exactly one job at the socket layer. The Setup:
The Problem: You have two internet connections. You want a high-stability fixed line (like Ethernet) to handle latency-sensitive traffic, but you want to offload a heavy data stream (like OBS Studio or massive uploads) to a secondary high-bandwidth line (like cellular data).
The Solution: This micro-interceptor binds target applications strictly to your chosen interface, while leaving your system's default network routing entirely untouched.
First, plug in both your Ethernet cable and your tethered phone. Run this to find their interface names:
ip link
- Look for your Ethernet: Usually starts with
enp...oreno...(e.g.,eno1). - Look for your Phone Tether: Usually starts with
enp...orenx...(e.g.,enp0s46g0u7c1h2).
By default, Linux gets confused when two internet connections are plugged in at the same time. We need to force the OS to prioritize your Ethernet so your games automatically get the best ping without any extra configuration.
Find the exact names of your connections:
nmcli connection show
Now, assign "Metrics" (priorities). A lower metric means higher priority.
# 1. Make your real Ethernet the absolute priority (Metric 10)
# Replace "Wired connection 1" with your actual Ethernet connection name
nmcli connection modify "Wired connection 1" ipv4.route-metric 10
# 2. Push the iPhone down so the system ignores it by default (Metric 100)
# Replace "Wired connection 2" with your actual Phone connection name
nmcli connection modify "Wired connection 2" ipv4.route-metric 100
# 3. Bounce NetworkManager to apply the rules permanently
sudo systemctl restart NetworkManager
(When to do this: You only need to run these nmcli commands once. NetworkManager will remember these priorities forever.)
Now, take the tether_split.c file and compile it into a shared object (.so) library. We use standard gcc, which is native to almost all Linux distributions.
gcc -fPIC -shared -o tether_split.so tether_split.c -ldl
(Why this is safe: You are compiling the code locally on your own machine. There are no downloaded binaries, no AUR packages, and no hidden dependencies.)
To force an application to use your phone's internet, simply prepend the LD_PRELOAD environment variable to its launch command.
This tells the Linux kernel: "Inject our compiled C script into this app the moment it boots."
For OBS Studio:
LD_PRELOAD=./tether_split.so obs
For Discord (or any other app):
LD_PRELOAD=./tether_split.so discord
Here is exactly what the code is doing, line by line:
#include <dlfcn.h>
#include <string.h>
#include <sys/socket.h>
#include <stdio.h>We are only including the foundational, built-in Linux headers.
<sys/socket.h>gives us the vocabulary to talk to the network.<dlfcn.h>gives us the ability to temporarily intercept function calls.
When you launch an app with LD_PRELOAD=./vx_obs_tether.so, you are telling the Linux operating system: "Before you load the normal networking rules for this app, load my tiny script first."
int (*orig_socket)(int, int, int) = dlsym(RTLD_NEXT, "socket");
int fd = orig_socket(domain, type, protocol);When the app asks the system to open a network connection (a socket), our script steps in. The very first thing it does is use dlsym(RTLD_NEXT... to find the real, original system socket function and pass the request right back to the OS. We aren't building a custom network stack; we are just tapping the OS on the shoulder.
If the connection is a standard internet connection (IPv4 or IPv6), our script flips two native Linux settings before handing the connection back to the app:
SO_BINDTODEVICE: It tells the kernel, "Force this specific connection to use the iPhone's network interface instead of the default Ethernet."SO_SNDBUF: It tells the kernel, "Give this connection a 1MB buffer." This is a critical stability patch. Cellular connections jitter. Expanding the buffer ensures the app doesn't drop frames or packets when the cell tower hiccups.
- It cannot read your files: There is no file I/O (
fopen,read,write) anywhere in the code. - It cannot execute commands: There are no
system()orexec()calls. - It cannot steal data: It never actually touches the contents of your network packets; it only tells the system which wire to send them down.
Because it compiles locally on your own machine using your own standard compiler (gcc), you are in complete control of the supply chain. You can read the whole file in 10 seconds and verify it does exactly what it claims to do, and nothing else.
How to verify it's working:
When you hit enter, you should immediately see [VX_NET] Intercepting OBS Sockets -> Forcing to... print in your terminal. You can now stream massive bitrates via your phone, while your system (and your games) remain happily locked to your low-latency Ethernet!