Architecture

The magic of onetun lies in its ability to perform network operations typically reserved for the OS kernel entirely in user-space. This is achieved by combining a user-space network stack with a user-space WireGuard implementation.

Core Components

  1. Tokio Runtime: Handles asynchronous I/O, allowing onetun to manage many connections concurrently on a single thread.
  2. Local Sockets: Standard TCP/UDP listeners bound to your local machine (e.g., 127.0.0.1:8080).
  3. Virtual Interface (smoltcp): A complete TCP/IP stack implementation in Rust. It maintains state machines for TCP connections and generates raw IP packets.
  4. BoringTun: Cloudflare's userspace WireGuard implementation. It handles the encryption and decryption of IP packets.
  5. Event Bus: A central broadcasting system (src/events.rs) that moves data between these components.

The Data Flow

Here is the lifecycle of a packet when you send a request to a forwarded port:

1. Client to Virtual Interface

  1. Your browser connects to 127.0.0.1:8080.
  2. onetun accepts the connection and assigns it a Virtual Port.
  3. Data sent by your browser is read by onetun and pushed onto the Event Bus as a LocalData event.
  4. The TcpVirtualInterface picks up this data. It mimics a network interface, "injecting" this data into a virtual TCP socket inside the smoltcp state machine.

2. IP Encapsulation

  1. smoltcp processes the data and decides it needs to send a TCP packet. It generates a raw IPv4/IPv6 packet.
  2. This raw packet is emitted to the Event Bus as an OutboundInternetPacket.

3. WireGuard Encryption

  1. The WireGuardTunnel component listens for OutboundInternetPacket events.
  2. It takes the raw IP packet and uses boringtun to encrypt it according to the WireGuard protocol.
  3. The encrypted payload is sent via a standard UDP socket to the configured WireGuard Endpoint.

4. The Return Trip

  1. The WireGuard endpoint responds with an encrypted UDP packet.
  2. WireGuardTunnel receives it, decrypts it using boringtun, and extracts the inner IP packet.
  3. This packet is published to the Event Bus as an InboundInternetPacket.
  4. The VirtualIpDevice feeds this packet back into smoltcp.
  5. smoltcp processes the TCP ACK/Data, and the virtual socket becomes readable.
  6. onetun reads the payload from the virtual socket and writes it back to your browser's real TCP connection.

UDP Virtualization

UDP is stateless, which presents a challenge for mapping "connections". onetun manages a pool of virtual ports (src/tunnel/udp.rs).

  • When a UDP datagram arrives from a new peer, onetun assigns it a virtual port from a pool.
  • This mapping is kept for a timeout period (default 60 seconds).
  • If the pool is exhausted, onetun attempts to reclaim the least-recently-used port.