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
- Tokio Runtime: Handles asynchronous I/O, allowing
onetunto manage many connections concurrently on a single thread. - Local Sockets: Standard TCP/UDP listeners bound to your local machine (e.g.,
127.0.0.1:8080). - Virtual Interface (smoltcp): A complete TCP/IP stack implementation in Rust. It maintains state machines for TCP connections and generates raw IP packets.
- BoringTun: Cloudflare's userspace WireGuard implementation. It handles the encryption and decryption of IP packets.
- 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
- Your browser connects to
127.0.0.1:8080. onetunaccepts the connection and assigns it a Virtual Port.- Data sent by your browser is read by
onetunand pushed onto the Event Bus as aLocalDataevent. - The
TcpVirtualInterfacepicks up this data. It mimics a network interface, "injecting" this data into a virtual TCP socket inside thesmoltcpstate machine.
2. IP Encapsulation
smoltcpprocesses the data and decides it needs to send a TCP packet. It generates a raw IPv4/IPv6 packet.- This raw packet is emitted to the Event Bus as an
OutboundInternetPacket.
3. WireGuard Encryption
- The
WireGuardTunnelcomponent listens forOutboundInternetPacketevents. - It takes the raw IP packet and uses
boringtunto encrypt it according to the WireGuard protocol. - The encrypted payload is sent via a standard UDP socket to the configured WireGuard Endpoint.
4. The Return Trip
- The WireGuard endpoint responds with an encrypted UDP packet.
WireGuardTunnelreceives it, decrypts it usingboringtun, and extracts the inner IP packet.- This packet is published to the Event Bus as an
InboundInternetPacket. - The
VirtualIpDevicefeeds this packet back intosmoltcp. smoltcpprocesses the TCP ACK/Data, and the virtual socket becomes readable.onetunreads 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,
onetunassigns it a virtual port from a pool. - This mapping is kept for a timeout period (default 60 seconds).
- If the pool is exhausted,
onetunattempts to reclaim the least-recently-used port.