Skip to content

fix: connection level flow control accounting for empty, non-fin frames#2491

Open
gregor-cf wants to merge 1 commit into
cloudflare:masterfrom
gregor-cf:gregor/fix-flow-control-empty-stream-frame
Open

fix: connection level flow control accounting for empty, non-fin frames#2491
gregor-cf wants to merge 1 commit into
cloudflare:masterfrom
gregor-cf:gregor/fix-flow-control-empty-stream-frame

Conversation

@gregor-cf
Copy link
Copy Markdown
Contributor

This fixes a bug in connection level flow control accounting. When an empty STREAM frame without FIN is received, we calcuate the difference between the highest previously received offset and the frame's max_off and add that to connection level flow control. However, in RecvBuf::write() we return early and we do not update the highest received offset. On subsequent frames, we count the same bytes against conn level flow control again.

To fix this, we update the highest receive offset in RecvBuf::write(). The alternative would be to ignore such frames, but I think updating the high water mark is the right choice: It mimmicks what we do for empty FIN frames and https://datatracker.ietf.org/doc/html/rfc9000#section-19.8 also says

"When a Stream Data field has a length of 0, the offset in the STREAM frame is the offset of the next byte that would be sent."

@gregor-cf gregor-cf requested a review from a team as a code owner May 21, 2026 19:42
Copy link
Copy Markdown
Contributor

@antoniovicente antoniovicente left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix looks good.

Comment thread quiche/src/stream/recv_buf.rs
Comment thread quiche/src/stream/recv_buf.rs
Comment thread quiche/src/stream/recv_buf.rs
Comment thread quiche/src/stream/recv_buf.rs
@gregor-cf gregor-cf force-pushed the gregor/fix-flow-control-empty-stream-frame branch from b2549ad to 32d889b Compare May 26, 2026 19:58
@gregor-cf gregor-cf requested a review from ghedo May 26, 2026 20:01
@gregor-cf
Copy link
Copy Markdown
Contributor Author

addressed all review comments

This fixes a bug in connection level flow control accounting. When an empty
STREAM frame without FIN is received, we calcuate the difference between the
highest previously received offset and the frame's max_off and add that to
connection level flow control. However, in `RecvBuf::write()` we return early
and we do not update the highest received offset. On subsequent frames, we
count the same bytes against conn level flow control again.

To fix this, we update the highest receive offset in RecvBuf::write(). The
alternative would be to ignore such frames, but I think updating the high
water mark is the right choice: It mimmicks what we do for empty FIN frames
and https://datatracker.ietf.org/doc/html/rfc9000#section-19.8 also say

 > When a Stream Data field has a length of 0, the offset in the STREAM frame is the offset of the next byte that would be sent.
@gregor-cf gregor-cf force-pushed the gregor/fix-flow-control-empty-stream-frame branch from 32d889b to 8fc8d39 Compare May 27, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants