Files
rustunnel/droid-wiki/features/stream-multiplexing.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

48 lines
2.1 KiB
Markdown

# Stream multiplexing
rustunnel carries multiple SOCKS5 connections over a single persistent TLS tunnel using stream IDs.
## Purpose
Avoid the overhead of establishing a new HTTPS connection for every SOCKS5 request. A single mTLS+auth session stays open, and multiple logical streams are interleaved via the binary framing protocol.
## How it works
### Connector side
1. A local SOCKS5 client connects to the connector's SOCKS5 proxy.
2. The connector's `StreamMux::open_stream` allocates the next odd stream ID.
3. It sends a CONNECT frame with the target address encoded in the payload.
4. It waits for a CONNECT_REPLY frame (status 0x00 = OK).
5. On success, it returns a `mpsc::Receiver<Bytes>` for tunnel-to-SOCKS5 data.
6. The connector spawns a task to read from the SOCKS5 client and send DATA frames to the tunnel.
7. Another path reads from the `data_rx` channel and writes raw bytes back to the SOCKS5 client.
### Listener side
1. The listener receives a CONNECT frame with a stream ID and target address.
2. It resolves the target address and opens a TCP connection.
3. It spawns a task to read from the target and send DATA frames back to the tunnel.
4. It sends a CONNECT_REPLY frame to acknowledge the stream.
5. Incoming DATA frames for that stream ID are written to the target connection.
6. CLOSE frames trigger shutdown of the target connection.
### Stream isolation
Each stream has its own ID. Data from one stream never mixes with another. The E2E test `e2e_concurrent_streams_isolation` verifies this by sending unique payloads through two concurrent streams and asserting each echo response matches its original payload.
## Key abstractions
| Type | File | Description |
| ---- | ---- | ----------- |
| `StreamMux` | `src/tunnel.rs` | Connector-side multiplexer |
| `ServerStreamEntry` | `src/tunnel.rs` | Listener-side per-stream target write half |
| `ConnectorStreamEntry` | `src/tunnel.rs` | Connector-side per-stream data channel and reply channel |
## Key source files
| File | Purpose |
| ---- | ------- |
| `src/tunnel.rs` | StreamMux, open_stream, dispatch_frame, framing loops |
| `src/framing.rs` | Frame types, CONNECT/DATA/CLOSE/ERROR encoding |