3b2296a6d9
Downloads were dying and stalling under real network conditions. Root causes fixed in the muxer's stream-delivery path: - dispatch_to_local held a DashMap Ref across a nested remove_stream call, self-deadlocking the leg's reader task whenever a stream's backlog needed eviction — permanently losing a tokio worker thread per occurrence. - Eviction now runs off the hot path entirely, in a periodic background reaper, and only fires when a stream is both over its byte budget AND has made no delivery progress for an RTT-adaptive grace window (was a flat 300ms then 5s, which killed merely-slow-but-alive consumers). - The server never told the client when a bridge ended normally (only on failed connect), leaving the client's virtual TCP socket stuck in CloseWait for a full idle timeout and slowing the whole engine loop. - The client's upload path silently dropped in-flight chunks when all tunnel legs were briefly down instead of pausing and retrying like the server bridge already did. - Tried end-to-end credit-based flow control for the download producer; reverted the enforcement (kept the dormant frame/API) after it proved worse than the pre-existing local channel backpressure — RTT-coupled pauses produced burst-then-stall downloads and jitter/ping spikes on the shared physical leg. - Server-side diagnostics snapshot was a stub (always-empty tunnel state, misleading placeholder trigger); now aggregates real per-session Muxer metrics from the SessionManager. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Блок rawcast — локальный протокол сокет ⇄ кадр
Промежуточный формат между «локальной» стороной клиента (реальные TCP/UDP сокеты
приложений) и протоколом туннеля nrxp. Когда трафик приходит не из
TUN напрямую, а из локальных соединений, его описывают компактным RawCastFrame,
а RawCastAdapter переводит это в кадры NRXP и обратно.
Детали — в rustdoc, модуль
rawcast.
Файлы
| Файл | Что внутри |
|---|---|
frame.rs |
RawCastFrame + enum'ы LocalProtocol/RawCastEvent, wire-формат. |
adapter.rs |
RawCastAdapter: трансляция RawCast ⇄ NRXP-Frame. |
Формат кадра
┌──────────┬───────┬───────────┬─────────┬──────────┬─────────────┬─────────┐
│ protocol │ event │ socket_id │ dst_ip │ dst_port │ payload_len │ payload │
│ 1 байт │ 1 б. │ 8 байт │ 4 байта │ 2 байта │ 2 байта │ N байт │
└──────────┴───────┴───────────┴─────────┴──────────┴─────────────┴─────────┘
└──────────────── LOCAL_HEADER_SIZE = 16 ────────────────┘
Ментальная модель
локальный сокет ─→ RawCastFrame ─to_nrxp──→ NRXP Frame ─→ туннель
туннель ─→ NRXP Frame ─from_nrxp─→ RawCastFrame ─→ локальный сокет
socket_id локальной стороны напрямую отображается в stream_id потока NRXP, так
что мультиплексирование «бесплатно» переносится между двумя протоколами. ICMP в
формате распознаётся, но ядром NRXP не проксируется.
Связи
Потребитель — клиентская точка входа ClientHandler::connect (net):
она гоняет RawCastFrame между локальными соединениями (client)
и туннелем.