]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: define max-window-size config setting
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 19 Aug 2024 09:59:28 +0000 (11:59 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 20 Aug 2024 15:02:29 +0000 (17:02 +0200)
Define a new global keyword tune.quic.frontend.max-window-size. This
allows to set globally the maximum congestion window size for each QUIC
frontend connections.

The default value is 0. It is a special value which automatically derive
the size from the configured QUIC connection buffer limit. This is
similar to the previous "quic-cc-algo" behavior, which can be used to
override the maximum window size per bind line.

doc/configuration.txt
include/haproxy/global-t.h
include/haproxy/quic_conn-t.h
src/cfgparse-quic.c
src/haproxy.c
src/listener.c

index b2ea8dfda485fc78262f35bb25746a29679045aa..d7fbb465514a0121372ace024ba432e2f362280e 100644 (file)
@@ -1509,6 +1509,7 @@ The following keywords are supported in the "global" section :
    - tune.quic.frontend.glitches-threshold
    - tune.quic.frontend.max-idle-timeout
    - tune.quic.frontend.max-streams-bidi
+   - tune.quic.frontend.max-window-size
    - tune.quic.max-frame-loss
    - tune.quic.reorder-ratio
    - tune.quic.retry-threshold
@@ -3934,6 +3935,17 @@ tune.quic.frontend.max-streams-bidi <number>
 
   The default value is 100.
 
+tune.quic.frontend.max-window-size <size>
+  Sets the default maximum window size for the congestion controller of a
+  single QUIC connection. The value must be written as an integer with an
+  optional suffix 'k', 'm' or 'g'. It must be between 10k and 4g. Alternatively,
+  the special value 0 can be used to automatically derive the value from
+  "quic.frontend.conn-tx-buffers.limit".
+
+  The default value is 0.
+
+  See also the "quic-cc-algo" bind option.
+
 tune.quic.max-frame-loss <number>
   Sets the limit for which a single QUIC frame can be marked as lost. If
   exceeded, the connection is considered as failing and is closed immediately.
@@ -16661,14 +16673,14 @@ proto <name>
   h2" on the bind line.
 
 quic-cc-algo { cubic | newreno | nocc }
-quic-cc-algo { cubic | newreno | nocc }(max_window)
+quic-cc-algo { cubic | newreno | nocc }(<max_window>)
   This is a QUIC specific setting to select the congestion control algorithm
   for any connection attempts to the configured QUIC listeners. They are similar
   to those used by TCP. An optional value in bytes may be used to specify the
   maximum window size. It must be greater than 10k and smaller than 4g.
 
   Default value: cubic
-  Default window value: tune.quic.frontend.conn-tx-buffers.limit * tune.bufsize
+  Default window value: "tune.quic.frontend.max-window-size"
 
   Example:
       # newreno congestion control algorithm
index f4d87b7a1282605b91e13fa32667e24127664362..16da286c41ed6d2ea8fbf64272420cf03d5185f0 100644 (file)
@@ -199,6 +199,7 @@ struct global {
                unsigned int quic_frontend_max_idle_timeout;
                unsigned int quic_frontend_glitches_threshold;
                unsigned int quic_frontend_max_streams_bidi;
+               size_t quic_frontend_max_window_size;
                unsigned int quic_retry_threshold;
                unsigned int quic_reorder_ratio;
                unsigned int quic_streams_buf;
index c7006450e8c73f5844fb69793c73b194f729f167..ed5ec01c9e5e043ba3dc44eb170eb3b4633e0374 100644 (file)
@@ -97,6 +97,8 @@ typedef unsigned long long ull;
 #define QUIC_DFLT_REORDER_RATIO        50 /* in percent */
 /* Default limit of loss detection on a single frame. If exceeded, connection is closed. */
 #define QUIC_DFLT_MAX_FRAME_LOSS       10
+/* Default congestion window size. 0 has a special value based on global.tune.quic_streams_buf */
+#define QUIC_DFLT_MAX_WINDOW_SIZE       0
 
 /*
  *  0                   1                   2                   3
index 85e5d294fc0e896be5566fa67d3cd080a2844fad..e869da50d20e6f216ea127d1c4d607f6a2f247e4 100644 (file)
@@ -285,6 +285,48 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type,
        return 0;
 }
 
+/* Parse any tune.quic.* setting accepting any integer values.
+ * Return -1 on alert, or 0 if succeeded.
+ */
+static int cfg_parse_quic_tune_setting1(char **args, int section_type,
+                                       struct proxy *curpx,
+                                       const struct proxy *defpx,
+                                       const char *file, int line, char **err)
+{
+       int prefix_len = strlen("tune.quic.");
+       const char *suffix;
+
+       if (too_many_args(1, args, err, NULL))
+               return -1;
+
+       suffix = args[0] + prefix_len;
+       if (strcmp(suffix, "frontend.max-window-size") == 0) {
+               unsigned long cwnd;
+               char *end_opt;
+
+               if (strcmp(args[1], "0") == 0) {
+                       /* 0 is a special value to set the limit based on quic_streams_buf */
+                       cwnd = 0;
+               }
+               else {
+                       cwnd = parse_window_size(args[0], args[1], &end_opt, err);
+                       if (!cwnd)
+                               return -1;
+                       if (*end_opt != '\0') {
+                               memprintf(err, "'%s' : expects an integer value with an optional suffix 'k', 'm' or 'g'", args[0]);
+                               return -1;
+                       }
+               }
+               global.tune.quic_frontend_max_window_size = cwnd;
+       }
+       else {
+               memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
+               return -1;
+       }
+
+       return 0;
+}
+
 static int cfg_parse_quic_tune_setting0(char **args, int section_type,
                                         struct proxy *curpx,
                                         const struct proxy *defpx,
@@ -354,6 +396,7 @@ static struct cfg_kw_list cfg_kws = {ILH, {
        { CFG_GLOBAL, "tune.quic.frontend.glitches-threshold", cfg_parse_quic_tune_setting },
        { CFG_GLOBAL, "tune.quic.frontend.max-streams-bidi", cfg_parse_quic_tune_setting },
        { CFG_GLOBAL, "tune.quic.frontend.max-idle-timeout", cfg_parse_quic_time },
+       { CFG_GLOBAL, "tune.quic.frontend.max-window-size", cfg_parse_quic_tune_setting1 },
        { CFG_GLOBAL, "tune.quic.max-frame-loss", cfg_parse_quic_tune_setting },
        { CFG_GLOBAL, "tune.quic.reorder-ratio", cfg_parse_quic_tune_setting },
        { CFG_GLOBAL, "tune.quic.retry-threshold", cfg_parse_quic_tune_setting },
index 0c1aeacb787d758db26a18df8adbe2733a520550..7ab540e90e96d758ac082454d05ae1b96231a7f4 100644 (file)
@@ -200,6 +200,7 @@ struct global global = {
                .quic_backend_max_idle_timeout = QUIC_TP_DFLT_BACK_MAX_IDLE_TIMEOUT,
                .quic_frontend_max_idle_timeout = QUIC_TP_DFLT_FRONT_MAX_IDLE_TIMEOUT,
                .quic_frontend_max_streams_bidi = QUIC_TP_DFLT_FRONT_MAX_STREAMS_BIDI,
+               .quic_frontend_max_window_size = QUIC_DFLT_MAX_WINDOW_SIZE,
                .quic_reorder_ratio = QUIC_DFLT_REORDER_RATIO,
                .quic_retry_threshold = QUIC_DFLT_RETRY_THRESHOLD,
                .quic_max_frame_loss = QUIC_DFLT_MAX_FRAME_LOSS,
index e004f8d85fd6bf0d1329b52ce56685277cf80fa5..d5609086c68bb62b290588021a10a5a7ceec1723 100644 (file)
@@ -2036,7 +2036,9 @@ struct bind_conf *bind_conf_alloc(struct proxy *fe, const char *file,
        /* Use connection socket for QUIC by default. */
        bind_conf->quic_mode = QUIC_SOCK_MODE_CONN;
        bind_conf->max_cwnd =
-               global.tune.bufsize * global.tune.quic_streams_buf;
+         global.tune.quic_frontend_max_window_size ?
+         global.tune.quic_frontend_max_window_size :
+         global.tune.bufsize * global.tune.quic_streams_buf;
 #endif
        LIST_INIT(&bind_conf->listeners);