Understanding the Role of gVisor in OpenFlux: Architecture and Implementation

gVisor serves as the in-process, userspace TCP/IP stack engine in OpenFlux, enabling secure network isolation through virtual NICs while supporting both proxy-mode TCP termination and raw-socket IP forwarding across multiple platforms.

OpenFlux leverages gVisor to create a self-contained networking layer that operates independently of the host kernel. By implementing a complete TCP/IP stack in userspace, the project eliminates dependency on privileged raw sockets on Windows, macOS, and iOS, while still offering high-performance raw-socket capabilities on Linux through specialized virtual network interfaces.

Core Architecture of gVisor in OpenFlux

The Userspace Stack Implementation

At the heart of OpenFlux's networking layer sits a gVisor stack.Stack instance created via stack.New(). This object represents a fully functional TCP/IP implementation that runs entirely within the application process, intercepting packets before they reach the host operating system. According to the source code in tunnel/tunnel.go, the initialization sequence attaches a custom link endpoint and configures TCP forwarding mechanisms that determine how traffic exits the node.

The stack initialization occurs in the tunnel constructor, where tcp.NewForwarder establishes a forwarder that converts gVisor's internal TCP connections into standard Go net.Conn objects. This design allows OpenFlux to terminate incoming TCP connections inside the process and re-originate them through standard library calls, creating a transparent proxy architecture.

Virtual Network Interface Cards

OpenFlux implements two distinct virtual NIC types depending on the operating mode:

  • TunnelLinkEndpoint – The default virtual NIC used in proxy mode, defined in tunnel/endpoint.go. This component bridges the gVisor stack with OpenFlux's transport layer (Yandex, MAX, Cup-online), injecting packets into the encrypted tunnel and extracting incoming packets for the stack to process.

  • RawSocketEndpoint – A Linux-specific implementation found in tunnel/rawsocket_linux.go that interfaces directly with host raw sockets through syscall.Socket. This NIC allows the gVisor stack to read and write raw IP packets to the wire, bypassing the kernel's TCP implementation entirely.

Operating Modes: Proxy vs. Raw Socket

Proxy Mode (Default)

In the default configuration, OpenFlux operates as a userspace TCP proxy using gVisor's forwarding capabilities. When a client connects to the exit node, the gVisor stack accepts the connection through tcp.NewForwarder and hands it to handleExitTCP, which performs a standard net.Dial to the destination (see tunnel/tunnel.go:46-78).

This mode provides several advantages:

  • Cross-platform compatibility – Works identically on Linux, Windows, macOS, and iOS without requiring administrative privileges or raw socket access
  • Process isolation – All TCP state remains within the OpenFlux process, preventing host kernel interference
  • Flexible transport integration – The virtual NIC can route traffic through arbitrary transport implementations (WebSocket, QUIC, or custom obfuscation layers)

The proxy mode initialization creates the stack and attaches the TunnelLinkEndpoint between lines 91-99 of tunnel.go, then starts the TCP forwarder listener that accepts incoming connections on the configured ports.

Raw-Socket Mode (Linux Only)

When launched with the --mode raw flag, OpenFlux utilizes gVisor's routing capabilities to forward raw IP packets directly through the host network interface. The setupExitNodeRaw function (tunnel.go:87-110) instantiates a RawSocketEndpoint that reads raw packets in a readLoop (rawsocket_linux.go:74-99) and injects them into the gVisor stack.

In this configuration:

  1. The gVisor stack handles TCP state and congestion control
  2. Finished IP packets route to the RawSocketEndpoint NIC
  3. The endpoint rewrites source addresses to match the --local-ip parameter
  4. Packets transmit directly via raw socket syscalls

This mode offers lower overhead for high-throughput scenarios but requires root privileges or CAP_NET_RAW capabilities on Linux systems.

Key Implementation Files and Components

The gVisor integration spans several critical files in the OpenFlux repository:

File Purpose
tunnel/tunnel.go Core stack management, NIC configuration, and mode-specific setup functions (setupExitNodeProxy, setupExitNodeRaw)
tunnel/endpoint.go TunnelLinkEndpoint implementation for transport-layer packet injection
tunnel/rawsocket_linux.go RawSocketEndpoint and Linux-specific raw socket handling
network/checksum.go IP/TCP checksum recomputation utilities required for raw-socket packet integrity

Fine-grained control over TCP behavior is achieved through direct stack manipulation. Buffer sizes are tuned via SetTCPBuffers (tunnel.go:60-75), while routing tables are manipulated using AddRoute and promiscuous mode is enabled through SetPromiscuousMode (tunnel.go:35-41, 124-129).

Working with the gVisor Stack: Code Examples

Creating a TCP Tunnel with Proxy Mode

To instantiate a userspace TCP tunnel using the default proxy mode:

trans, _ := transport.NewYandexTransport(url) // Any Transport implementation
tunnel := tunnel.NewTCPTunnel(trans, true)    // true → exit node mode

This constructor builds the gVisor stack, attaches the TunnelLinkEndpoint, and initializes the TCP forwarder as implemented in tunnel.go:79-88 and tunnel.go:30-42.

Dialing Through the gVisor Stack

Applications can establish connections through the isolated stack using the tunnel's dial method:

conn, err := tunnel.DialTCP("example.com:443")
if err != nil {
    log.Fatalf("dial failed: %v", err)
}
defer conn.Close()

The DialTCP method utilizes gonet.DialTCP to open connections inside the gVisor network namespace, automatically selecting the correct NIC based on the current operating mode (tunnel.go:72-81).

Enabling Raw-Socket Mode

For Linux systems requiring raw packet forwarding:

sudo ./openflux --exit-node --mode raw --local-ip 203.0.113.10 --url "YOUR_URL"

Behind the scenes, this triggers setupExitNodeRaw, which creates the RawSocketEndpoint and wires it to the gVisor stack routing table (tunnel.go:87-110).

Configuring Custom Routes

OpenFlux allows dynamic routing configuration within the gVisor instance:

// Route 10.10.20.0/24 via NIC 1
tunnel.gvisorStack.AddRoute(tcpip.Route{
    Destination: tcpip.AddrFrom4([4]byte{10, 10, 20, 0}).Subnet(),
    NIC:         tcpip.NICID(1),
})

This capability enables complex networking scenarios where specific subnets traverse different transport mechanisms or exit interfaces.

Summary

  • gVisor provides a complete userspace TCP/IP stack that isolates OpenFlux networking from the host kernel, enabling consistent behavior across Linux, Windows, macOS, and iOS.
  • Two virtual NIC implementations (TunnelLinkEndpoint and RawSocketEndpoint) allow the project to switch between proxy mode (unprivileged, cross-platform) and raw-socket mode (Linux-only, high-performance).
  • Proxy mode terminates TCP connections in-process and re-originates them via net.Dial, while raw-socket mode forwards raw IP packets through Linux raw sockets with address rewriting.
  • Fine-grained control over TCP buffers, routing tables, and promiscuous mode is achieved through direct manipulation of the stack.Stack object.

Frequently Asked Questions

What is gVisor's primary function in OpenFlux?

gVisor acts as an in-process, userspace TCP/IP stack that replaces the host kernel's networking layer. It processes TCP connections, maintains protocol state, and routes packets through virtual NICs, allowing OpenFlux to intercept and control all network traffic without modifying system-level network configurations.

Does OpenFlux require root privileges to use gVisor?

No, gVisor's default proxy mode operates entirely in userspace without requiring elevated privileges. However, raw-socket mode (--mode raw) requires root or CAP_NET_RAW capabilities on Linux because it creates actual raw sockets to transmit packets directly to the network interface.

How does gVisor enable cross-platform support in OpenFlux?

By implementing the TCP/IP stack in userspace rather than relying on host kernel features, gVisor provides identical networking primitives across all supported platforms. Windows, macOS, and iOS use the proxy mode exclusively since they lack raw socket support in the RawSocketEndpoint implementation, while Linux can utilize both proxy and raw-socket modes with the same underlying gVisor architecture.

Can I tune TCP performance parameters in OpenFlux's gVisor stack?

Yes, OpenFlux exposes gVisor's TCP buffer configuration through SetTCPBuffers in tunnel/tunnel.go (lines 60-75). Additionally, you can modify routing behavior using AddRoute and enable promiscuous mode on virtual NICs via SetPromiscuousMode to support advanced networking scenarios requiring specific packet handling characteristics.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →