]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: use stream elasticity value for initial advertisement
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 18 May 2026 06:27:32 +0000 (08:27 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 20 May 2026 07:52:50 +0000 (09:52 +0200)
When stream elasticity is active, the maximum number of concurrent bidi
streams advertised via transport parameters is now reduced depending on
the connection load. This is implemented via conn_calc_max_streams()
which returns the value to use.

This is not applied on listeners with enabled 0-RTT. Indeed, for such
connections, clients are expected to reuse the previously seen transport
parameters. The server on the other hand must not decrease several
values on the newly advertised params, in particular for the maximum
number of concurrent bidi streams. The simplest way to prevent 0-RTT
failure is to not mix stream elasticity with it.

Note that the 0-RTT limitation is only applied for the initial value :
during the connection lifetime, stream elasticity can still be used by
the MUX to dynamically reduce the stream window. This will be
implemented in a future patch.

doc/configuration.txt
src/proxy.c
src/quic_tp.c

index 97cd580ea9c083830c96f302fa9684e4041b0556..ce9cadb958a4222edf28cce3157cac9d5cc30330 100644 (file)
@@ -5727,6 +5727,10 @@ tune.streams-elasticity <number>
   use lower values (120 to 200) to support 1.2 to 2 streams per connection on
   average at full load.
 
+  There is a limitation for QUIC listeners with enabled 0-RTT. In this case,
+  the initial value advertised to the peer will ignore stream elasticity and
+  instead rely solely on the "tune.quic.stream.max-concurrent" setting.
+
   Monitoring the total number of active streams on backends, including queues,
   provides a practical indicator of a sustainable target load and helps avoid
   over-provisioning.
index d328031ad50a60e0b0de7cc401fe01dd45aa69d1..033ba5090352e820304f7626c80b80af18713922 100644 (file)
@@ -1808,6 +1808,13 @@ int proxy_finalize(struct proxy *px, int *err_code)
                                           proxy_type_str(px), px->id);
                                *err_code |= ERR_WARN;
                        }
+
+                       if (bind_conf->ssl_conf.early_data && conn_calc_max_streams(1)) {
+                               ha_notice("Binding [%s:%d] for %s %s: "
+                                         "stream elasticity is ignored for initial connection settings as this is incompatible with 0-RTT.",
+                                          bind_conf->file, bind_conf->line,
+                                          proxy_type_str(px), px->id);
+                       }
                }
 #endif /* USE_QUIC */
 
index 1dc9df07a4820767f68e61e5e4a1e3d02e201e04..e85f8b58d0e0049f68d44da98965981611e33a85 100644 (file)
@@ -1,6 +1,7 @@
 #include <arpa/inet.h>
 #include <string.h>
 
+#include <haproxy/connection.h>
 #include <haproxy/global.h>
 #include <haproxy/ncbuf-t.h>
 #include <haproxy/net_helper.h>
@@ -862,6 +863,15 @@ int qc_lstnr_params_init(struct quic_conn *qc,
        rx_params->initial_source_connection_id.len = scidlen;
        TRACE_PROTO("\nRX(local) transp. params.", QUIC_EV_TRANSP_PARAMS, qc, rx_params);
 
+       /* Reduce max-streams-bidi if stream elasticity is active. This is
+        * ignored however if 0-RTT is configured as clients could reuse
+        * different transport parameters than the one advertised.
+        */
+       if (global.tune.streams_elasticity && !qc->li->bind_conf->ssl_conf.early_data) {
+               rx_params->initial_max_streams_bidi =
+                 conn_calc_max_streams(rx_params->initial_max_streams_bidi);
+       }
+
        return 1;
 }