Files
rustunnel/droid-wiki/overview/architecture.md
T
rootandfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> 0166fb6511
CI / cargo fmt (push) Has been cancelled
CI / cargo clippy (macos-latest) (push) Has been cancelled
CI / cargo clippy (ubuntu-latest) (push) Has been cancelled
CI / cargo clippy (windows-latest) (push) Has been cancelled
CI / cargo test (macos-latest) (push) Has been cancelled
CI / cargo test (ubuntu-latest) (push) Has been cancelled
CI / cargo test (windows-latest) (push) Has been cancelled
CI / cargo build (macos-latest) (push) Has been cancelled
CI / cargo build (ubuntu-latest) (push) Has been cancelled
CI / cargo build (windows-latest) (push) Has been cancelled
CI / cargo build --release (macos-latest) (push) Has been cancelled
CI / cargo build --release (ubuntu-latest) (push) Has been cancelled
CI / cargo build --release (windows-latest) (push) Has been cancelled
CI / CLI smoke (macos-latest) (push) Has been cancelled
CI / CLI smoke (ubuntu-latest) (push) Has been cancelled
CI / CLI smoke (windows-latest) (push) Has been cancelled
CI / Minimal E2E (macos-latest) (push) Has been cancelled
CI / Minimal E2E (ubuntu-latest) (push) Has been cancelled
CI / Minimal E2E (windows-latest) (push) Has been cancelled
docs: add comprehensive project wiki for v1.0
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-06-04 14:07:55 -06:00

4.0 KiB

Architecture

rustunnel is organized as a single Rust binary crate with a modular source tree. The architecture separates CLI parsing, credential generation, TLS configuration, SOCKS5 handling, binary framing, and the core tunnel engine into distinct modules.

Component diagram

graph TD
    A[CLI `src/cli.rs`] --> B[Main dispatch `src/main.rs`]
    B --> C[Credential generation `src/generate.rs`]
    B --> D[Tunnel engine `src/tunnel.rs`]
    B --> E[Connection keys `src/connkey.rs`]
    D --> F[TLS stack `src/tls.rs`]
    D --> G[SOCKS5 proxy `src/socks5.rs`]
    D --> H[Framing protocol `src/framing.rs`]
    D --> I[Signal handling `src/signal.rs`]
    F --> J[Rustls + ring]
    G --> K[Tokio TCP]
    H --> L[Bytes + tokio-util]
    C --> M[rcgen]

Data flow

A typical tunnel session flows like this:

  1. Listener binds a TCP socket and wraps it with tokio_rustls::TlsAcceptor.
  2. Connector initiates a TCP connection and upgrades it with tokio_rustls::TlsConnector.
  3. Both sides perform mTLS handshakes: the listener requires a client certificate signed by the shared CA; the connector validates the server certificate against the same CA.
  4. The connector sends an HTTP POST to /tunnel with an X-Rustunnel-Token header.
  5. The listener validates the token with a constant-time comparison (src/tunnel.rs).
  6. On success, both sides switch from HTTP/1.1 to a binary framing protocol (src/framing.rs).
  7. The connector's local SOCKS5 proxy accepts client connections and opens multiplexed streams over the single persistent tunnel.
  8. The listener decodes each stream's target address, opens a local TCP connection to that target, and forwards data bidirectionally.
sequenceDiagram
    participant Client as Local app
    participant Socks as SOCKS5 proxy
    participant Conn as Connector
    participant TLS as mTLS tunnel
    participant List as Listener
    participant Target as Target server

    Client->>Socks: SOCKS5 CONNECT
    Socks->>Conn: open stream
    Conn->>TLS: TLS handshake
    TLS->>List: accept + verify client cert
    Conn->>List: POST /tunnel + auth token
    List->>Conn: 200 OK
    Conn->>List: binary framing CONNECT frame
    List->>Target: TCP connect
    Target->>List: response
    List->>Conn: DATA frame
    Conn->>Socks: raw bytes
    Socks->>Client: response

Module responsibilities

Module Responsibility
src/cli.rs clap-based CLI definitions for all subcommands and arguments
src/main.rs Entry point, crypto provider installation, tracing init, command dispatch
src/tunnel.rs Core tunnel engine: listener accept loop, connector reconnect loop, SOCKS5 proxy, stream mux, HTTP auth handshake, framing loop
src/tls.rs rustls server and client config builders, certificate loading, identity validation, insecure verifier
src/socks5.rs SOCKS5 greeting, auth, CONNECT request parsing, target resolution
src/framing.rs Binary frame serialization/deserialization, FrameReader, FrameWriter
src/generate.rs Self-signed CA, server cert, client cert, and auth token generation with rcgen
src/connkey.rs ConnectionKey struct: encode/decode all material as a base64 string
src/redact.rs Redacted wrapper and helpers to prevent secrets from leaking into logs
src/errors.rs thiserror-based error enums for TLS, auth, tunnel, and host operations
src/config.rs JSON configuration file format for generated credential sets
src/signal.rs Cross-platform shutdown signal handler (SIGINT/SIGTERM on Unix, Ctrl+C on Windows)

Threading model

The project uses Tokio's multi-threaded runtime. Each side (listener and connector) spawns tasks for:

  • Accepting new TCP connections
  • TLS handshakes
  • Per-tunnel framing loops
  • Per-stream target forwarding
  • SOCKS5 client handling

The connector's SOCKS5 proxy stays bound permanently while a background reconnect loop maintains the tunnel. When the tunnel drops, existing streams receive EOF and new streams wait for the reconnect loop to re-establish the session.