cloudflare / cloudflare/quiche
`stream_send` / `dgram_send`: `tx_cap` accounting is inconsistent and can cause undocumented stream starvation
- Dominant language
- Rust
- Stars
- 11.8k
- Forks
- 1.1k
- Avg merge
- 21h 9m
- Merged PRs (30d)
- 6
Description
`stream_send` and `dgram_send` `tx_cap` accounting behavior for the congestion window and flow window, leading to two related problems:
1. Stream-send call order determines who gets capacity (starvation)
stream_send decrements `tx_cap` immediately when data is buffered (`tx_cap = min(cwnd_available, max_tx_data - tx_data)`). This means the order in which the application calls stream_send across streams determines which one gets the connection's send budget — not respecting the streams' declared priority. Calling stream_send on a low-priority stream first can exhaust `tx_cap` entirely, causing a subsequent `stream_send` on a high-priority stream to return `Error::Done`. Stream priority only controls wire scheduling of already-buffered data, not buffering admission.
Example: https://github.com/birneee/quiche/commit/da27e93b548aca94264580c1132fa3c8a9623490
2. `dgram_send` does not decrement `tx_cap`
`dgram_send` pushes datagrams to a queue without touching `tx_cap`. As a result, the same congestion window that blocks a second `stream_send` places no equivalent restriction on `dgram_send`. It is possible to simultaneously buffer more data than the congestion window allows:
The `tx_cap` used by `stream_send` does not reflect already-queued datagrams. The restriction only catches up on the next `recv()` cycle after `send()` puts the datagrams on the wire.
### Proposal
At minimum, the following functions should document their behavior in the function docs:
- `stream_send`
- `stream_send_zc`
- `dgram_send`
- `dgram_send_buf`
Applications relying on stream priority, operating near the congestion window limit, or assuming that all buffered data can be sent within one round-trip need to understand this behavior to avoid starving high-priority streams or buffering more data than the congestion window allows.
Contributor guide
Research direction
Start with the documentation for the named entry points: stream_send, stream_send_zc, dgram_send, and dgram_send_buf. Compare their descriptions with the issue's tx_cap accounting, stream-priority, congestion-window, and datagram-queue behavior. Done means each function documents the relevant buffering limits and possible starvation or excess buffering clearly for applications.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- documentation, networking
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 67/100