-
Notifications
You must be signed in to change notification settings - Fork 874
Description
If I understand the code below correctly, Quiche currently ignores incoming StreamDataBlocked
frames, i.e. ignores if a sender signals that it is blocked on the provided stream data flow control window:
Line 8003 in b3af644
frame::Frame::StreamDataBlocked { .. } => (), |
If that is correct, have you considered sending a stream flow control update instead? More specifically call FlowControl::max_data_next
and send a window update:
quiche/quiche/src/flowcontrol.rs
Lines 95 to 98 in b3af644
/// Returns the new max_data limit. | |
pub fn max_data_next(&self) -> u64 { | |
self.consumed + self.window | |
} |
Maybe additionally call FlowControl::autotune_window
in case the BDP is larger than the stream window.
As a sender Firefox's QUIC stack will send a STREAM_DATA_BLOCKED
when attempting to send more than the granted stream window allows. I.e. it will send notify the receiver ahead of time that it will be blocked soon.
As a receiver Firefox's QUIC stack will send a flow control update when it receives a STREAM_DATA_BLOCKED
:
Before sending it will auto-tune the window:
This showed up while benchmarking Firefox's QUIC stack using h3.speed.cloudflare.com.
Throughout a transfer, not just during the initial BDP auto tuning ramp up, Firefox is repeatedly blocked on the stream flow control limit. Example:
$ RUST_LOG=neqo_bin=info cargo run --bin neqo-client -- -m=POST --stats --upload-size=100000000 https://h3.speed.cloudflare.com/__up?measId=XXX
6.193 INFO stats for Client ...
rx: 14582 drop 3 dup 0 saved 3
tx: 73061 lost 172 lateack 0 ptoack 0 unackdrop 0
pmtud: 6 sent 3 acked 3 lost 0 change 1500 iface_mtu 1470 pmtu
resumed: false
frames rx:
crypto 6 done 1 token 0 close 0
ack 14567 (max 73051) ping 569 padding 0
stream 5 reset 0 stop 0
max: stream 0 data 14 stream_data 24
blocked: stream 0 data 0 stream_data 0
datagram 0
ncid 0 rcid 0 pchallenge 0 presponse 0
ack_frequency 0
frames tx:
crypto 4 done 0 token 0 close 1
ack 590 (max 14842) ping 7 padding 6
stream 72950 reset 0 stop 0
max: stream 1 data 0 stream_data 0
blocked: stream 0 data 0 stream_data 21
datagram 0
ncid 0 rcid 0 pchallenge 0 presponse 0
ack_frequency 0
ecn:
tx:
Initial Count({NotEct: 4, Ect1: 0, Ect0: 0, Ce: 0})
Handshake Count({NotEct: 2, Ect1: 0, Ect0: 0, Ce: 0})
Short Count({NotEct: 73036, Ect1: 0, Ect0: 19, Ce: 0})
acked:
rx:
Initial Count({NotEct: 4, Ect1: 0, Ect0: 0, Ce: 0})
Handshake Count({NotEct: 3, Ect1: 0, Ect0: 0, Ce: 0})
Short Count({NotEct: 14572, Ect1: 0, Ect0: 0, Ce: 0})
path validation outcomes: ValidationCount({Capable: 0, NotCapable(BlackHole): 0, NotCapable(Bleaching): 1, NotCapable(ReceivedUnsentECT1): 0})
mark transitions:
dscp: Cs0: 14585
Note the blocked: stream 0 data 0 stream_data 21
, which means that Firefox has been blocked 21 times on stream flow control. Also note the low number of stream window updates sent by Cloudflare max: stream 0 data 14 stream_data 24
, i.e. 24
.
Caught by @larseggert 🙏
Related: #1384
Side note: Thank you for h3.speed.cloudflare.com! Very helpful.