diff --git a/doc/configuration.txt b/doc/configuration.txt index c348a08de..36046d569 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -14457,6 +14457,15 @@ proto instance, it is possible to force the http/2 on clear TCP by specifying "proto h2" on the bind line. +quic-cc-algo [ cubic | newreno ] + Warning: QUIC support in HAProxy is currently experimental. Configuration may + + 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. + + Default value: cubic + quic-force-retry Warning: QUIC support in HAProxy is currently experimental. Configuration may change without deprecation in the future. diff --git a/include/haproxy/listener-t.h b/include/haproxy/listener-t.h index c712504c4..c8e4b74c0 100644 --- a/include/haproxy/listener-t.h +++ b/include/haproxy/listener-t.h @@ -181,6 +181,7 @@ struct bind_conf { #endif #ifdef USE_QUIC struct quic_transport_params quic_params; /* QUIC transport parameters. */ + struct quic_cc_algo *quic_cc_algo; /* QUIC control congestion algorithm */ #endif struct proxy *frontend; /* the frontend all these listeners belong to, or NULL */ const struct mux_proto_list *mux_proto; /* the mux to use for all incoming connections (specified by the "proto" keyword) */ diff --git a/src/cfgparse-quic.c b/src/cfgparse-quic.c index 8ccb83bab..5268e9ada 100644 --- a/src/cfgparse-quic.c +++ b/src/cfgparse-quic.c @@ -2,9 +2,11 @@ #include #include +#include #include #include #include +#include #include static int bind_parse_quic_force_retry(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err) @@ -13,8 +15,33 @@ static int bind_parse_quic_force_retry(char **args, int cur_arg, struct proxy *p return 0; } +/* parse "quic-cc-algo" bind keyword */ +static int bind_parse_quic_cc_algo(char **args, int cur_arg, struct proxy *px, + struct bind_conf *conf, char **err) +{ + struct quic_cc_algo *cc_algo; + + if (!*args[cur_arg + 1]) { + memprintf(err, "'%s' : missing control congestion algorith", args[cur_arg]); + return ERR_ALERT | ERR_FATAL; + } + + if (!strcmp(args[cur_arg + 1], "newreno")) + cc_algo = &quic_cc_algo_nr; + else if (!strcmp(args[cur_arg + 1], "cubic")) + cc_algo = &quic_cc_algo_cubic; + else { + memprintf(err, "'%s' : unknown control congestion algorithm", args[cur_arg]); + return ERR_ALERT | ERR_FATAL; + } + + conf->quic_cc_algo = cc_algo; + return 0; +} + static struct bind_kw_list bind_kws = { "QUIC", { }, { { "quic-force-retry", bind_parse_quic_force_retry, 0 }, + { "quic-cc-algo", bind_parse_quic_cc_algo, 1 }, { NULL, NULL, 0 }, }}; diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 57c1e6bf2..2c6605873 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -4293,6 +4293,7 @@ static struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4, struct quic_connection_id *icid; char *buf_area = NULL; struct listener *l = NULL; + struct quic_cc_algo *cc_algo = NULL; TRACE_ENTER(QUIC_EV_CONN_INIT); qc = pool_zalloc(pool_head_quic_conn); @@ -4314,6 +4315,7 @@ static struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4, l = owner; prx = l->bind_conf->frontend; + cc_algo = l->bind_conf->quic_cc_algo; qc->prx_counters = EXTRA_COUNTERS_GET(prx->extra_counters_fe, &quic_stats_module); @@ -4393,7 +4395,7 @@ static struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4, /* XXX TO DO: Only one path at this time. */ qc->path = &qc->paths[0]; - quic_path_init(qc->path, ipv4, default_quic_cc_algo, qc); + quic_path_init(qc->path, ipv4, cc_algo ? cc_algo : default_quic_cc_algo, qc); /* required to use MTLIST_IN_LIST */ MT_LIST_INIT(&qc->accept_list);