mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-09 16:47:18 +02:00
MINOR: quic: Add a max window parameter to congestion control algorithms
Add a new ->max_cwnd member to bind_conf struct to store the maximum congestion control window value for each QUIC binding. Modify the "quic-cc-algo" keyword parsing to add an optional parameter to its value: the maximum congestion window value between parentheses as follows: ex: quic-cc-algo cubic(10m) This value must be bounded, greater than 10k and smaller than 1g.
This commit is contained in:
parent
840af0928b
commit
028a55a1d0
@ -186,6 +186,7 @@ struct bind_conf {
|
|||||||
#ifdef USE_QUIC
|
#ifdef USE_QUIC
|
||||||
struct quic_transport_params quic_params; /* QUIC transport parameters. */
|
struct quic_transport_params quic_params; /* QUIC transport parameters. */
|
||||||
struct quic_cc_algo *quic_cc_algo; /* QUIC control congestion algorithm */
|
struct quic_cc_algo *quic_cc_algo; /* QUIC control congestion algorithm */
|
||||||
|
size_t max_cwnd; /* QUIC maximumu congestion control window size (kB) */
|
||||||
enum quic_sock_mode quic_mode; /* QUIC socket allocation strategy */
|
enum quic_sock_mode quic_mode; /* QUIC socket allocation strategy */
|
||||||
#endif
|
#endif
|
||||||
struct proxy *frontend; /* the frontend all these listeners belong to, or NULL */
|
struct proxy *frontend; /* the frontend all these listeners belong to, or NULL */
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
@ -20,34 +21,89 @@ static int bind_parse_quic_cc_algo(char **args, int cur_arg, struct proxy *px,
|
|||||||
struct bind_conf *conf, char **err)
|
struct bind_conf *conf, char **err)
|
||||||
{
|
{
|
||||||
struct quic_cc_algo *cc_algo;
|
struct quic_cc_algo *cc_algo;
|
||||||
|
const char *newreno = "newrno";
|
||||||
|
const char *cubic = "cubic";
|
||||||
|
const char *nocc = "nocc";
|
||||||
|
const char *algo = NULL;
|
||||||
char *arg;
|
char *arg;
|
||||||
|
|
||||||
if (!*args[cur_arg + 1]) {
|
if (!*args[cur_arg + 1]) {
|
||||||
memprintf(err, "'%s' : missing control congestion algorithm", args[cur_arg]);
|
memprintf(err, "'%s' : missing control congestion algorithm", args[cur_arg]);
|
||||||
return ERR_ALERT | ERR_FATAL;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg = args[cur_arg + 1];
|
arg = args[cur_arg + 1];
|
||||||
if (strcmp(arg, "newreno") == 0)
|
if (strncmp(arg, newreno, strlen(newreno)) == 0) {
|
||||||
cc_algo = &quic_cc_algo_nr;
|
/* newreno */
|
||||||
else if (strcmp(arg, "cubic") == 0)
|
algo = newreno;
|
||||||
cc_algo = &quic_cc_algo_cubic;
|
cc_algo = &quic_cc_algo_nr;
|
||||||
else if (strlen(arg) >= 6 && strncmp(arg, "nocc-", 5) == 0) {
|
arg += strlen(newreno);
|
||||||
|
}
|
||||||
|
else if (strncmp(arg, cubic, strlen(cubic)) == 0) {
|
||||||
|
/* cubic */
|
||||||
|
algo = cubic;
|
||||||
|
cc_algo = &quic_cc_algo_cubic;
|
||||||
|
arg += strlen(cubic);
|
||||||
|
}
|
||||||
|
else if (strncmp(arg, nocc, strlen(nocc)) == 0) {
|
||||||
|
/* nocc */
|
||||||
if (!experimental_directives_allowed) {
|
if (!experimental_directives_allowed) {
|
||||||
ha_alert("'%s' algo is experimental, must be allowed via a global 'expose-experimental-directives'\n", arg);
|
ha_alert("'%s' algo is experimental, must be allowed via a global "
|
||||||
return ERR_ALERT | ERR_FATAL;
|
"'expose-experimental-directives'\n", arg);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_algo = &quic_cc_algo_nocc;
|
algo = nocc;
|
||||||
quic_cc_nocc_fixed_cwnd = atoi(arg + 5);
|
cc_algo = &quic_cc_algo_nocc;
|
||||||
|
arg += strlen(nocc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memprintf(err, "'%s' : unknown control congestion algorithm", args[cur_arg]);
|
memprintf(err, "'%s' : unknown control congestion algorithm", args[cur_arg + 1]);
|
||||||
return ERR_ALERT | ERR_FATAL;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*arg++ == '(') {
|
||||||
|
unsigned long cwnd;
|
||||||
|
char *end_opt;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
cwnd = strtoul(arg, &end_opt, 0);
|
||||||
|
if (end_opt == arg || errno != 0) {
|
||||||
|
memprintf(err, "'%s' : could not parse congestion window value", args[cur_arg + 1]);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*end_opt == 'k') {
|
||||||
|
cwnd <<= 10;
|
||||||
|
end_opt++;
|
||||||
|
}
|
||||||
|
else if (*end_opt == 'm') {
|
||||||
|
cwnd <<= 20;
|
||||||
|
end_opt++;
|
||||||
|
}
|
||||||
|
else if (*end_opt == 'g') {
|
||||||
|
memprintf(err, "'%s' : should be smaller than 1g", args[cur_arg + 1]);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*end_opt != ')') {
|
||||||
|
memprintf(err, "'%s' : expects %s(<max window>)", args[cur_arg + 1], algo);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cwnd < 10240 || cwnd >= (4UL << 30)) {
|
||||||
|
memprintf(err, "'%s' : should be greater than 10k and smaller than 4g", args[cur_arg + 1]);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf->max_cwnd = cwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
conf->quic_cc_algo = cc_algo;
|
conf->quic_cc_algo = cc_algo;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return ERR_ALERT | ERR_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bind_parse_quic_socket(char **args, int cur_arg, struct proxy *px,
|
static int bind_parse_quic_socket(char **args, int cur_arg, struct proxy *px,
|
||||||
|
@ -1954,6 +1954,8 @@ struct bind_conf *bind_conf_alloc(struct proxy *fe, const char *file,
|
|||||||
#ifdef USE_QUIC
|
#ifdef USE_QUIC
|
||||||
/* Use connection socket for QUIC by default. */
|
/* Use connection socket for QUIC by default. */
|
||||||
bind_conf->quic_mode = QUIC_SOCK_MODE_CONN;
|
bind_conf->quic_mode = QUIC_SOCK_MODE_CONN;
|
||||||
|
bind_conf->max_cwnd =
|
||||||
|
global.tune.bufsize * global.tune.quic_streams_buf;
|
||||||
#endif
|
#endif
|
||||||
LIST_INIT(&bind_conf->listeners);
|
LIST_INIT(&bind_conf->listeners);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user