-
Notifications
You must be signed in to change notification settings - Fork 874
fix: connection flow control updates with STOP_SENDING and RESET_STREAM #2158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
165159b
to
5bdd02c
Compare
I'm not sure this sullfy satisfies RFC 9000 requirements when using stop_sending because, IIUC, you're accounting for bytes in the connection-level flow control before receiving the final size
I might be wrong but worth double checking. If im right, then data in-flight that increased the final size before the stopper received it, could result in the endpoints getting out of sync with connection-level FC |
I think my logic is correct. When sending the STOP_SENDING frame, we drop all currently received bytes and I return FC credit based on the highest offset received. This is correct IMHO, it's like the application had read the full buffer (the difference is that we don't about gaps in the STOP_SENDING case). Since whatever final size we later receive MUST be larger or equal than this offest, otherwise we close due to protocol violation. We also mark the send-buffer as "draining" (that is existing code): any additional stream data we receive with a higher offset we record in the buffer's max_off and in the connection level rx_data counter. And we also immediately mark it as read to the connection level FC too (since we are not buffering it, like the app had read it). Eventually we will receive a FIN or a RESET_STREAM for this stream. At this time we know the final size and verify it's >= than the highest received offset. If the final size is larger than highest received, we update the conn's rx_data and FC accordingly. One thing to note: the current code doesn't do a sanity check with the final size. It keeps a running count of received data and just verifies that the final size is consistent with what has been received previously. |
Thanks for the details. Can we add a test case for the scenario where data arrives after one of the endpoints has stopped reading to ensure that the connection FC counters are tracked appropriately (or confirm that one of the existing tests does it) please? |
5bdd02c
to
c838581
Compare
I've updated the test |
da7426d
to
87fde90
Compare
gentle ping @LPardue |
…ET_STREAM This fixes issues in quiche, where quiche does not properly update connection level flow control when sending STOP_SENDING or receiving RESET_STREAM frames. On calling `shutdown_stream(id, Shutdown::Read)`, quiche drops the receive buffer (correct) but it should also mark these bytes as "consumed" to the connection-level flow-control. On receiving a RESET_STREAM frame, quiche drops the receive buffer but it should also mark these dropped bytes as "consumed" to the connection-level flow-control. Quiche should also check if needs to send a MAX_DATA frame after updating "consumed"
87fde90
to
c7aff6e
Compare
This fixes issues in quiche, where quiche does not properly update connection level flow control when sending STOP_SENDING or receiving RESET_STREAM frames.
On calling
shutdown_stream(id, Shutdown::Read)
, quiche drops the receive buffer (correct) but it should also mark these bytes as "consumed" to the connection-level flow-control.On receiving a
RESET_STREAM
frame, quiche drops the receive buffer but it should also mark these dropped bytes as "consumed" to the connection-level flow-control.When Quiche updates "consumed" in the two above cases, it should also check if needs to send a MAX_DATA frame after updating "consumed".
Note, the two added
quiche::h3
tests are not directly related but I started there because I first suspected streams not getting collected. I did add tests to quiche itself that test my changes though.