ITADN

qmux: StreamTransport recv is not cancellation-safe

#192Openkixelated 创建于 2026-03-13
K
kixelatedcommented
## Problem `SessionState::run()` uses `tokio::select!` which can cancel the `transport.recv()` future mid-read. For `StreamTransport` (TCP/TLS), this drops partially-consumed bytes from the underlying reader, desynchronizing the stream on the next `recv()` call. WebSocket transport is unaffected since each message is atomic. ## Fix Buffer reads internally in `StreamTransport` using a `BytesMut`. Instead of reading directly from the TCP stream with `read_u8()`/`read_exact()` (which consume bytes on cancel), use `reader.read_buf(&mut self.buf)` to fill the buffer, then parse complete frames from it. If the future is cancelled between reads, the buffer retains partial data. The frame delimiter logic (`try_frame_len`) would peek at the buffer without consuming, and only split off bytes when a complete frame is found. ## Current mitigation The `select!` is `biased` so `recv` is polled first, but other branches can still win when `recv` is pending on I/O.
1 条评论