MINOR: quic: duplicate glitches FE option on BE side

Previously, QUIC glitches support was only implemented for frontend
side. Extend this so that the option can be specified separately both on
frontend and backend sides. Function _qcc_report_glitch() now retrieves
the relevant max value based on connection side.

In addition to this, option has been renamed to use "fe/be" prefixes.
This is part of the current serie of commits which unify QUIC settings.
Older options are deprecated and will be removed on 3.5 release.
This commit is contained in:
Amaury Denoyelle 2025-07-31 16:48:57 +02:00
parent b34cd0b506
commit 7640e9a9ee
5 changed files with 49 additions and 24 deletions

View File

@ -1888,11 +1888,13 @@ The following keywords are supported in the "global" section :
- tune.pool-high-fd-ratio
- tune.pool-low-fd-ratio
- tune.pt.zero-copy-forwarding
- tune.quic.be.sec.glitches-threshold
- tune.quic.cc-hystart
- tune.quic.cc.cubic.min-losses
- tune.quic.disable-tx-pacing
- tune.quic.disable-udp-gso
- tune.quic.frontend.glitches-threshold
- tune.quic.fe.sec.glitches-threshold
- tune.quic.frontend.glitches-threshold (deprecated)
- tune.quic.frontend.max-data-size
- tune.quic.frontend.max-idle-timeout
- tune.quic.frontend.max-streams-bidi
@ -4079,8 +4081,8 @@ tune.glitches.kill.cpu-usage <number>
twice the usually observed CPU usage, or the commonly observed CPU usage plus
half the idle one (i.e. if CPU commonly reaches 60%, setting 80 here can make
sense). This parameter has no effect without tune.h2.fe.glitches-threshold or
tune.quic.frontend.glitches-threshold. See also the global parameters
"tune.h2.fe.glitches-threshold" and "tune.quic.frontend.glitches-threshold".
tune.quic.fe.sec.glitches-threshold. See also the global parameters
"tune.h2.fe.glitches-threshold" and "tune.quic.fe.sec.glitches-threshold".
tune.h1.zero-copy-fwd-recv { on | off }
Enables ('on') of disabled ('off') the zero-copy receives of data for the H1
@ -4727,20 +4729,26 @@ tune.quic.disable-udp-gso
transfer. It may be useful to disable it on developers suggestion when
suspecting an issue on emission.
tune.quic.frontend.glitches-threshold <number>
Sets the threshold for the number of glitches on a frontend connection, where
that connection will automatically be killed. This allows to automatically
kill misbehaving connections without having to write explicit rules for them.
The default value is zero, indicating that no threshold is set so that no
event will cause a connection to be closed. Beware that some QUIC clients may
occasionally cause a few glitches over long lasting connection, so any non-
zero value here should probably be in the hundreds or thousands to be
effective without affecting slightly bogus clients. It is also possible to
only kill connections when the CPU usage crosses a certain level, by using
"tune.glitches.kill.cpu-usage".
tune.quic.be.sec.glitches-threshold <number>
tune.quic.fe.sec.glitches-threshold <number>
Sets the threshold for the number of glitches per connection either on
frontend or backend side, where that connection will automatically be killed.
This allows to automatically kill misbehaving connections without having to
write explicit rules for them. The default value is zero, indicating that no
threshold is set so that no event will cause a connection to be closed.
Beware that some QUIC clients may occasionally cause a few glitches over long
lasting connection, so any non- zero value here should probably be in the
hundreds or thousands to be effective without affecting slightly bogus
clients. It is also possible to only kill connections when the CPU usage
crosses a certain level, by using "tune.glitches.kill.cpu-usage".
See also: fc_glitches, tune.glitches.kill.cpu-usage
tune.quic.frontend.glitches-threshold <number> (deprecated)
This keyword has been deprecated in 3.3 and will be removed in 3.5. It is
part of the streamlining process apply on QUIC configuration. If used, this
setting will only be applied on frontend connections.
tune.quic.frontend.max-data-size <size>
This setting is the hard limit for the number of data bytes in flight over a
QUIC frontend connection. It is reused as the value for the initial_max_data

View File

@ -217,7 +217,6 @@ struct global {
#ifdef USE_QUIC
unsigned int quic_backend_max_idle_timeout;
unsigned int quic_frontend_max_idle_timeout;
unsigned int quic_frontend_glitches_threshold;
unsigned int quic_frontend_max_data;
unsigned int quic_frontend_max_streams_bidi;
uint64_t quic_frontend_max_tx_mem;

View File

@ -15,11 +15,13 @@
struct quic_tune {
struct {
uint sec_glitches_threshold;
uint opts; /* QUIC_TUNE_FE_* options specific to FE side */
uint fb_opts; /* QUIC_TUNE_FB_* options shared by both side */
} fe;
struct {
uint sec_glitches_threshold;
uint fb_opts; /* QUIC_TUNE_FB_* options shared by both side */
} be;

View File

@ -281,6 +281,7 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type,
const struct proxy *defpx,
const char *file, int line, char **err)
{
int ret = 0;
unsigned int arg = 0;
int prefix_len = strlen("tune.quic.");
const char *suffix, *errptr;
@ -299,8 +300,12 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type,
suffix = args[0] + prefix_len;
if (strcmp(suffix, "cc.cubic.min-losses") == 0)
global.tune.quic_cubic_loss_tol = arg - 1;
else if (strcmp(suffix, "frontend.glitches-threshold") == 0)
global.tune.quic_frontend_glitches_threshold = arg;
else if (strcmp(suffix, "be.sec.glitches-threshold") == 0 ||
strcmp(suffix, "fe.sec.glitches-threshold") == 0) {
uint *ptr = (suffix[0] == 'b') ? &quic_tune.be.sec_glitches_threshold :
&quic_tune.fe.sec_glitches_threshold;
*ptr = arg;
}
else if (strcmp(suffix, "frontend.max-data-size") == 0) {
if ((errptr = parse_size_err(args[1], &arg))) {
memprintf(err, "'%s': unexpected character '%c' in size argument '%s'.",
@ -356,12 +361,20 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type,
}
else if (strcmp(suffix, "retry-threshold") == 0)
global.tune.quic_retry_threshold = arg;
/* legacy options */
else if (strcmp(suffix, "frontend.glitches-threshold") == 0) {
memprintf(err, "'%s' is deprecated in 3.3 and will be removed in 3.5. "
"Please use the newer keyword syntax 'tune.quic.fe.sec.glitches-threshold'.", args[0]);
quic_tune.fe.sec_glitches_threshold = arg;
ret = 1;
}
else {
memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
return -1;
}
return 0;
return ret;
}
static int cfg_parse_quic_tune_setting0(char **args, int section_type,
@ -439,7 +452,6 @@ static struct cfg_kw_list cfg_kws = {ILH, {
{ CFG_GLOBAL, "tune.quic.socket-owner", cfg_parse_quic_tune_socket_owner },
{ CFG_GLOBAL, "tune.quic.cc-hystart", cfg_parse_quic_tune_on_off },
{ CFG_GLOBAL, "tune.quic.cc.cubic.min-losses", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.frontend.glitches-threshold", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.frontend.max-data-size", 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 },
@ -452,6 +464,14 @@ static struct cfg_kw_list cfg_kws = {ILH, {
{ CFG_GLOBAL, "tune.quic.disable-tx-pacing", cfg_parse_quic_tune_setting0 },
{ CFG_GLOBAL, "tune.quic.disable-udp-gso", cfg_parse_quic_tune_setting0 },
{ CFG_GLOBAL, "tune.quic.zero-copy-fwd-send", cfg_parse_quic_tune_on_off },
{ CFG_GLOBAL, "tune.quic.fe.sec.glitches-threshold", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.be.sec.glitches-threshold", cfg_parse_quic_tune_setting },
/* legacy options */
{ CFG_GLOBAL, "tune.quic.frontend.glitches-threshold", cfg_parse_quic_tune_setting },
{ 0, NULL, NULL }
}};

View File

@ -759,11 +759,7 @@ void qcc_set_error(struct qcc *qcc, int err, int app)
*/
int _qcc_report_glitch(struct qcc *qcc, int inc)
{
const int max = global.tune.quic_frontend_glitches_threshold;
/* TODO add a BE limit for glitch counter */
if (qcc->flags & QC_CF_IS_BACK)
return 0;
const int max = QUIC_TUNE_FB_CONN_GET(sec_glitches_threshold, qcc->conn);
qcc->glitches += inc;
if (max && qcc->glitches >= max && !(qcc->flags & QC_CF_ERRL) &&