From: Amaury Denoyelle Date: Mon, 19 Aug 2024 09:59:28 +0000 (+0200) Subject: MINOR: quic: define max-window-size config setting X-Git-Tag: v3.1-dev6~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c24c8667b28cf7f67df71b715eb52f519c190f4d;p=thirdparty%2Fhaproxy.git MINOR: quic: define max-window-size config setting 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. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index b2ea8dfda4..d7fbb46551 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -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 The default value is 100. +tune.quic.frontend.max-window-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 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 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 }() 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 diff --git a/include/haproxy/global-t.h b/include/haproxy/global-t.h index f4d87b7a12..16da286c41 100644 --- a/include/haproxy/global-t.h +++ b/include/haproxy/global-t.h @@ -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; diff --git a/include/haproxy/quic_conn-t.h b/include/haproxy/quic_conn-t.h index c7006450e8..ed5ec01c9e 100644 --- a/include/haproxy/quic_conn-t.h +++ b/include/haproxy/quic_conn-t.h @@ -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 diff --git a/src/cfgparse-quic.c b/src/cfgparse-quic.c index 85e5d294fc..e869da50d2 100644 --- a/src/cfgparse-quic.c +++ b/src/cfgparse-quic.c @@ -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 }, diff --git a/src/haproxy.c b/src/haproxy.c index 0c1aeacb78..7ab540e90e 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -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, diff --git a/src/listener.c b/src/listener.c index e004f8d85f..d5609086c6 100644 --- a/src/listener.c +++ b/src/listener.c @@ -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);