Skip to content

Commit 375ffaa

Browse files
committed
BUG/MINOR: quic: fix rxbuf settings on backend side
QUIC flow control on bidirectional streams ensure that the peer cannot emit more than what haproxy has allowed, which guarantees that buffering is under controlled on the receiver side. This limit is first announced on the transport parameter via initial_max_stream_data_bidi_remote which is derived from configuration value. QUIC MUX calculation for its streams is then directly based on the transport parameter. This mechanism works as expected on the frontend side, as in this case all exchanges occur on remote streams opened by the opposite side. However, this is not working as expected on the backend side, as in this case transfers occur on streams opened locally by haproxy as the client. Thus, configuration has no impact on backend side rxbuf which remains set to a single buffer, causing important latency when retrieving large objects. This patch removes this limitation on the backend side by adjusting quic_transport_params_init(). If <server> parameter is false, limitation is set for initial_max_stream_data_bidi_local TP. This must be backported up to 3.3.
1 parent 5530f50 commit 375ffaa

1 file changed

Lines changed: 20 additions & 10 deletions

File tree

src/quic_tp.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ void quic_transport_params_init(struct quic_transport_params *p, int server)
5858
server ? quic_tune.fe.stream_max_concurrent : quic_tune.be.stream_max_concurrent;
5959
/* TODO value used to conform with HTTP/3, should be derived from app_ops */
6060
const int max_streams_uni = 3;
61+
uint64_t max_stream_data_bidi;
6162

6263
/* Set RFC default values for unspecified parameters. */
6364
quic_dflt_transport_params_cpy(p);
@@ -81,21 +82,30 @@ void quic_transport_params_init(struct quic_transport_params *p, int server)
8182
p->initial_max_data = stream_rxbuf ?
8283
stream_rxbuf : max_streams_bidi * stream_rx_bufsz;
8384

84-
/* Set remote streams flow-control data limit. This is calculated as a
85-
* ratio from max-data, then rounded up to bufsize.
85+
/* Calculate the limit for the Rx capability of bidirectional streams.
86+
* This is a ratio from max-data rounded up to bufsize.
8687
*/
87-
p->initial_max_stream_data_bidi_remote = server ?
88+
max_stream_data_bidi = server ?
8889
p->initial_max_data * quic_tune.fe.stream_data_ratio / 100 :
8990
p->initial_max_data * quic_tune.be.stream_data_ratio / 100;
90-
p->initial_max_stream_data_bidi_remote =
91-
stream_rx_bufsz * ((p->initial_max_stream_data_bidi_remote + (stream_rx_bufsz - 1)) / stream_rx_bufsz);
91+
max_stream_data_bidi =
92+
stream_rx_bufsz * ((max_stream_data_bidi + (stream_rx_bufsz - 1)) / stream_rx_bufsz);
9293

93-
/* Set remaining flow-control data limit. Local bidi streams are unused
94-
* on server side. Uni streams are only used for control exchange, so
95-
* only a single buffer for in flight data should be enough.
94+
/* Apply bidirectional streams Rx cap. This depends on the connection
95+
* side. On FE side, exchange will occur on remote streams; on BE side,
96+
* exchange will occur on local streams.
9697
*/
97-
p->initial_max_stream_data_bidi_local = stream_rx_bufsz;
98-
p->initial_max_stream_data_uni = stream_rx_bufsz;
98+
if (server) {
99+
p->initial_max_stream_data_bidi_remote = max_stream_data_bidi;
100+
p->initial_max_stream_data_bidi_local = stream_rx_bufsz;
101+
}
102+
else {
103+
p->initial_max_stream_data_bidi_remote = stream_rx_bufsz;
104+
p->initial_max_stream_data_bidi_local = max_stream_data_bidi;
105+
}
106+
107+
/* Unidirectional streams exchange should be minimal. */
108+
p->initial_max_stream_data_uni = stream_rx_bufsz;
99109

100110
if (server) {
101111
p->with_stateless_reset_token = 1;

0 commit comments

Comments
 (0)