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
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
51 lines
2.0 KiB
Markdown
51 lines
2.0 KiB
Markdown
# Framing protocol
|
|
|
|
The framing protocol in `src/framing.rs` defines the binary message format used after the HTTP auth handshake upgrades the connection to a persistent tunnel.
|
|
|
|
## Purpose
|
|
|
|
Carry multiple bidirectional streams over a single TLS connection with minimal overhead.
|
|
|
|
## Frame format
|
|
|
|
All multi-byte integers are big-endian.
|
|
|
|
```
|
|
+--------+----------+----------+-------+-----------+
|
|
| Type | StreamID | Len | Flags | Payload.. |
|
|
| 1 byte | 8 bytes | 4 bytes | 1 byte| variable |
|
|
+--------+----------+----------+-------+-----------+
|
|
```
|
|
|
|
- **Type** — 0x01 CONNECT, 0x02 CONNECT_REPLY, 0x03 DATA, 0x04 CLOSE, 0x05 ERROR
|
|
- **StreamID** — odd IDs for client-initiated streams, even reserved for server-initiated
|
|
- **Len** — payload length, max 4 MiB
|
|
- **Flags** — reserved for future use (currently always 0x00)
|
|
|
|
## Key abstractions
|
|
|
|
| Type | File | Description |
|
|
| ---- | ---- | ----------- |
|
|
| `Frame` | `src/framing.rs` | Struct holding frame_type, stream_id, flags, payload |
|
|
| `FrameReader` | `src/framing.rs` | Async reader with buffering that handles partial TCP reads |
|
|
| `FrameWriter` | `src/framing.rs` | Async writer that serializes and flushes frames |
|
|
| `encode_target` | `src/framing.rs` | Encode a `Socks5Target` into CONNECT frame payload |
|
|
| `decode_target` | `src/framing.rs` | Decode a `Socks5Target` from CONNECT frame payload |
|
|
|
|
## Partial read discipline
|
|
|
|
`FrameReader::read_frame` loops until a complete frame is available:
|
|
|
|
1. Attempt to deserialize from the buffer.
|
|
2. If the frame is incomplete (`FrameTooShort`), read more bytes from the underlying TCP stream into the buffer.
|
|
3. If the connection closes with a partial frame in the buffer, return an error.
|
|
4. Only consume bytes from the buffer once the full frame is present.
|
|
|
|
This prevents header corruption when TCP segments arrive in arbitrary sizes.
|
|
|
|
## Key source files
|
|
|
|
| File | Purpose |
|
|
| ---- | ------- |
|
|
| `src/framing.rs` | Frame format, serialization, async reader/writer, target encoding |
|