mirror of
https://github.com/therealaleph/MasterHttpRelayVPN-RUST.git
synced 2026-05-18 05:36:56 +03:00
54552bbdac
Performance refactor of full-tunnel mode hot path. No wire-protocol or
behavior changes — internal data flow only.
**1. Zero-copy reads via `Bytes`/`BytesMut`**
`tunnel_loop` and the SOCKS5 UDP receive loop drop their per-iteration
`Vec::to_vec()` copies. `MuxMsg::{ConnectData,Data,UdpOpen,UdpData}` now
carry `Bytes` instead of `Vec<u8>`/`Arc<Vec<u8>>`; the `Arc::try_unwrap`
dance for `pending_client_data` is gone (Bytes is already Arc-backed).
TCP path is threshold-based to avoid the obvious memory regression:
- n ≥ 32 KB: `BytesMut::split().freeze()` — saves the 64 KB memcpy on
hot downloads.
- n < 32 KB: `Bytes::copy_from_slice` + `buf.clear()` — payload-sized
retention. Without this split, a queued tiny TLS record would refcount-
pin the full 64 KB recv buffer (worst case ~96 MB on a backpressured
tunnel).
UDP path: fixed `Vec<u8>` recv buffer + `Bytes::copy_from_slice` after
the 9 KB MAX_UDP_PAYLOAD_BYTES guard. `parse_socks5_udp_packet` split
into `_offsets` + `&[u8]` wrapper so callers stay on the reusable buffer.
**2. Base64 encoding moved off the single mux thread**
New internal `PendingOp { data: Option<Bytes>, encode_empty: bool }`
flows through `mux_loop` with raw bytes. Actual `B64.encode(...)` runs
in `fire_batch`'s spawned task, after the per-deployment semaphore. Up
to ~3 MB of encoding per batch (50 ops × 64 KB) no longer serializes
the single mux task.
**3. Code quality**
- `BatchAccum::push_or_fire` collapses 4× ~25-line match arms → ~10 each.
- `should_fire(pending_len, payload_bytes, op_bytes)` extracted with
`saturating_add` for a self-contained contract.
- `encode_pending(p) -> BatchOp` extracted as a free function so the
encoding contract is directly testable.
**Tests:** 208/208 (was 200, +8 new):
- `encode_pending_*` × 4 — base64-encode contract per MuxMsg variant
- `should_fire_*` × 3 — first-op, MAX_BATCH_OPS boundary, payload cap
- `batch_accum_reindexes_after_flush` — regression test for post-flush
reply index lookup in `fire_batch`
**Public API:** `TunnelMux::udp_open` and `udp_data` now take
`data: impl Into<Bytes>` instead of `Vec<u8>`. Existing call sites
keep compiling.
Reviewed via Anthropic Claude.
Co-Authored-By: dazzling-no-more <noreply@github.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>