fix: stabilize tunnel downloads (deadlock, stuck-consumer eviction, real diagnostics)
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>
This commit is contained in:
@@ -35,6 +35,10 @@ pub(crate) enum FrameType {
|
||||
/// путь: едет по контрольному каналу, сервер сохраняет его в пер-сессионный
|
||||
/// файл. Никогда не маршрутизируется в локальные сокеты.
|
||||
Diag = 0x06,
|
||||
/// Кредит потока для сквозного flow-control (payload — `u32` BE, "можешь
|
||||
/// прислать ещё N байт"). Отправляется приёмной стороной по мере
|
||||
/// освобождения локального буфера — см. `Muxer::grant_credit`/`consume_credit`.
|
||||
Credit = 0x07,
|
||||
}
|
||||
|
||||
/// Разобранный заголовок кадра (25 байт). Поля идут в том же порядке, что и в wire.
|
||||
@@ -170,6 +174,7 @@ impl Parser for FrameHeader {
|
||||
0x04 => FrameType::UdpConnect,
|
||||
0x05 => FrameType::UdpData,
|
||||
0x06 => FrameType::Diag,
|
||||
0x07 => FrameType::Credit,
|
||||
unknown => {
|
||||
// After successful AEAD decryption an unknown frame type means a
|
||||
// protocol version mismatch or data corruption that the cipher
|
||||
|
||||
Reference in New Issue
Block a user