MINOR: quic: Tunable "max_idle_timeout" transport parameter

Add two tunable settings both for backends and frontends "max_idle_timeout"
QUIC transport parameter, "tune.quic.frontend.max-idle-timeout" and
"tune.quic.backend.max-idle-timeout" respectively.
cfg_parse_quic_time() has been implemented to parse a time value thanks
to parse_time_err(). It should be reused for any tunable time value to be
parsed.
Add the documentation for this tunable setting only for frontend.
This commit is contained in:
Frédéric Lécaille 2022-05-23 16:38:14 +02:00 committed by Amaury Denoyelle
parent aa8daed335
commit 1d96d6e024
6 changed files with 76 additions and 1 deletions

View File

@ -1119,6 +1119,7 @@ The following keywords are supported in the "global" section :
- tune.pool-high-fd-ratio
- tune.pool-low-fd-ratio
- tune.quic.conn-buf-limit
- tune.quic.frontend.max-idle-timeout
- tune.quic.retry-threshold
- tune.rcvbuf.client
- tune.rcvbuf.server
@ -2939,6 +2940,20 @@ tune.quic.conn-buf-limit <number>
and memory consumption and can be adjusted according to an estimated round
time-trip.
tune.quic.frontend.max-idle-timeout <timeout>
Warning: QUIC support in HAProxy is currently experimental. Configuration may
change without deprecation in the future.
Sets the QUIC max_idle_timeout transport parameters in milliseconds for
frontends which determines the period of time after which a connection silently
closes if it has remained inactive during an effective period of time deduced
from the two max_idle_timeout values announced by the two endpoints:
- the minimum of the two values if both are not null,
- the maximum if only one of them is not null,
- if both values are null, this feature is disabled.
The default value is 30000.
tune.quic.retry-threshold <number>
Warning: QUIC support in HAProxy is currently experimental. Configuration may
change without deprecation in the future.

View File

@ -158,6 +158,8 @@ struct global {
int pool_high_count; /* max number of opened fd before we start killing idle connections when creating new connections */
unsigned short idle_timer; /* how long before an empty buffer is considered idle (ms) */
#ifdef USE_QUIC
unsigned int quic_backend_max_idle_timeout;
unsigned int quic_frontend_max_idle_timeout;
unsigned int quic_retry_threshold;
unsigned int quic_streams_buf;
#endif /* USE_QUIC */

View File

@ -30,6 +30,8 @@ struct tp_preferred_address {
#define QUIC_DFLT_MAX_UDP_PAYLOAD_SIZE 65527 /* bytes */
#define QUIC_DFLT_ACK_DELAY_COMPONENT 3 /* milliseconds */
#define QUIC_DFLT_MAX_ACK_DELAY 25 /* milliseconds */
#define QUIC_DFLT_FRONT_MAX_IDLE_TIMEOUT 30000 /* milliseconds */
#define QUIC_DFLT_BACK_MAX_IDLE_TIMEOUT 30000 /* milliseconds */
#define QUIC_ACTIVE_CONNECTION_ID_LIMIT 2 /* number of connections */
/* Types of QUIC transport parameters */

View File

@ -1,3 +1,5 @@
#include <string.h>
#include <haproxy/api.h>
#include <haproxy/cfgparse.h>
#include <haproxy/global-t.h>
@ -18,6 +20,52 @@ static struct bind_kw_list bind_kws = { "QUIC", { }, {
INITCALL1(STG_REGISTER, bind_register_keywords, &bind_kws);
/* Must be used to parse tune.quic.* setting which requires a time
* as value.
* Return -1 on alert, or 0 if succeeded.
*/
static int cfg_parse_quic_time(char **args, int section_type,
struct proxy *curpx,
const struct proxy *defpx,
const char *file, int line, char **err)
{
unsigned int time;
const char *res, *name, *value;
int prefix_len = strlen("tune.quic.");
if (too_many_args(1, args, err, NULL))
return -1;
name = args[0];
value = args[1];
res = parse_time_err(value, &time, TIME_UNIT_MS);
if (res == PARSE_TIME_OVER) {
memprintf(err, "timer overflow in argument '%s' to '%s' "
"(maximum value is 2147483647 ms or ~24.8 days)", value, name);
return -1;
}
else if (res == PARSE_TIME_UNDER) {
memprintf(err, "timer underflow in argument '%s' to '%s' "
"(minimum non-null value is 1 ms)", value, name);
return -1;
}
else if (res) {
memprintf(err, "unexpected character '%c' in '%s'", *res, name);
return -1;
}
if (strcmp(name + prefix_len, "frontend.max-idle-timeout") == 0)
global.tune.quic_frontend_max_idle_timeout = time;
else if (strcmp(name + prefix_len, "backend.max-idle-timeout") == 0)
global.tune.quic_backend_max_idle_timeout = time;
else {
memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
return -1;
}
return 0;
}
/* Parse any tune.quic.* setting with strictly positive integer values.
* Return -1 on alert, or 0 if succeeded.
*/
@ -53,7 +101,9 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type,
}
static struct cfg_kw_list cfg_kws = {ILH, {
{ CFG_GLOBAL, "tune.quic.backend.max-idle-timeou", cfg_parse_quic_time },
{ CFG_GLOBAL, "tune.quic.conn-buf-limit", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.frontend.max-idle-timeout", cfg_parse_quic_time },
{ CFG_GLOBAL, "tune.quic.retry-threshold", cfg_parse_quic_tune_setting },
{ 0, NULL, NULL }
}};

View File

@ -115,6 +115,7 @@
#include <haproxy/namespace.h>
#include <haproxy/net_helper.h>
#include <haproxy/openssl-compat.h>
#include <haproxy/quic_tp-t.h>
#include <haproxy/pattern.h>
#include <haproxy/peers.h>
#include <haproxy/pool.h>
@ -205,6 +206,8 @@ struct global global = {
.idle_timer = 1000, /* 1 second */
#endif
#ifdef USE_QUIC
.quic_backend_max_idle_timeout = QUIC_DFLT_BACK_MAX_IDLE_TIMEOUT,
.quic_frontend_max_idle_timeout = QUIC_DFLT_FRONT_MAX_IDLE_TIMEOUT,
.quic_retry_threshold = QUIC_DFLT_RETRY_THRESHOLD,
.quic_streams_buf = 30,
#endif /* USE_QUIC */

View File

@ -51,7 +51,10 @@ void quic_transport_params_init(struct quic_transport_params *p, int server)
/* Set RFC default values for unspecified parameters. */
quic_dflt_transport_params_cpy(p);
p->max_idle_timeout = 30000;
if (server)
p->max_idle_timeout = global.tune.quic_frontend_max_idle_timeout;
else
p->max_idle_timeout = global.tune.quic_backend_max_idle_timeout;
p->initial_max_streams_bidi = max_streams_bidi;
p->initial_max_streams_uni = max_streams_uni;