Skip to content

Commit 773bf78

Browse files
committed
MEDIUM: quic: define cubic-pacing congestion algorithm
1 parent 6d2a44e commit 773bf78

File tree

5 files changed

+52
-3
lines changed

5 files changed

+52
-3
lines changed

include/haproxy/listener-t.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ struct bind_conf {
185185
struct quic_cc_algo *quic_cc_algo; /* QUIC control congestion algorithm */
186186
size_t max_cwnd; /* QUIC maximumu congestion control window size (kB) */
187187
enum quic_sock_mode quic_mode; /* QUIC socket allocation strategy */
188+
int quic_pacing_burst; /* QUIC allowed pacing burst size */
188189
#endif
189190
struct proxy *frontend; /* the frontend all these listeners belong to, or NULL */
190191
const struct mux_proto_list *mux_proto; /* the mux to use for all incoming connections (specified by the "proto" keyword) */

include/haproxy/quic_cc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ static inline void *quic_cc_priv(const struct quic_cc *cc)
7878
* which is true for an IPv4 path, if not false for an IPv6 path.
7979
*/
8080
static inline void quic_cc_path_init(struct quic_cc_path *path, int ipv4, unsigned long max_cwnd,
81-
struct quic_cc_algo *algo, struct quic_conn *qc)
81+
struct quic_cc_algo *algo, int burst,
82+
struct quic_conn *qc)
8283
{
8384
unsigned int max_dgram_sz;
8485

@@ -92,6 +93,7 @@ static inline void quic_cc_path_init(struct quic_cc_path *path, int ipv4, unsign
9293
path->prep_in_flight = 0;
9394
path->in_flight = 0;
9495
path->ifae_pkts = 0;
96+
path->pacing_burst = burst;
9597
quic_cc_init(&path->cc, algo, qc);
9698
}
9799

src/cfgparse-quic.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include <haproxy/global.h>
1414
#include <haproxy/listener.h>
1515
#include <haproxy/proxy.h>
16-
#include <haproxy/quic_cc-t.h>
16+
#include <haproxy/quic_cc.h>
1717
#include <haproxy/quic_rules.h>
1818
#include <haproxy/tools.h>
1919

@@ -69,12 +69,31 @@ static unsigned long parse_window_size(const char *kw, char *value,
6969
return 0;
7070
}
7171

72+
static int parse_burst(const char *kw, char *value, char **end_opt, char **err)
73+
{
74+
int burst;
75+
76+
errno = 0;
77+
burst = strtoul(value, end_opt, 0);
78+
if (*end_opt == value || errno != 0) {
79+
memprintf(err, "'%s' : could not burst value", kw);
80+
goto fail;
81+
}
82+
83+
return burst;
84+
85+
fail:
86+
return -1;
87+
}
88+
7289
/* parse "quic-cc-algo" bind keyword */
7390
static int bind_parse_quic_cc_algo(char **args, int cur_arg, struct proxy *px,
7491
struct bind_conf *conf, char **err)
7592
{
93+
const char *pacing_pfx = "-pacing";
7694
struct quic_cc_algo *cc_algo;
7795
const char *algo = NULL;
96+
int pacing = 0;
7897
char *arg;
7998

8099
if (!*args[cur_arg + 1]) {
@@ -94,6 +113,19 @@ static int bind_parse_quic_cc_algo(char **args, int cur_arg, struct proxy *px,
94113
algo = QUIC_CC_CUBIC_STR;
95114
cc_algo = &quic_cc_algo_cubic;
96115
arg += strlen(QUIC_CC_CUBIC_STR);
116+
117+
if (strncmp(arg, pacing_pfx, strlen(pacing_pfx)) == 0) {
118+
if (!experimental_directives_allowed) {
119+
memprintf(err, "'%s' : support for pacing is experimental, must be allowed via a global "
120+
"'expose-experimental-directives'\n", args[cur_arg]);
121+
goto fail;
122+
}
123+
124+
cc_algo->pacing_rate = quic_cc_default_pacing_rate;
125+
cc_algo->pacing_burst = quic_cc_default_pacing_burst;
126+
pacing = 1;
127+
arg += strlen(pacing_pfx);
128+
}
97129
}
98130
else if (strncmp(arg, QUIC_CC_NO_CC_STR, strlen(QUIC_CC_NO_CC_STR)) == 0) {
99131
/* nocc */
@@ -127,6 +159,18 @@ static int bind_parse_quic_cc_algo(char **args, int cur_arg, struct proxy *px,
127159

128160
conf->max_cwnd = cwnd;
129161
}
162+
else if (pacing) {
163+
int burst = parse_burst(args[cur_arg], arg, &end_opt, err);
164+
if (burst < 0)
165+
goto fail;
166+
167+
if (*end_opt != ')') {
168+
memprintf(err, "'%s' : expects %s(<burst>)", args[cur_arg + 1], algo);
169+
goto fail;
170+
}
171+
172+
conf->quic_pacing_burst = burst;
173+
}
130174
else {
131175
if (*arg++ != ')') {
132176
memprintf(err, "'%s' : unexpected extra argument for '%s' algorithm", args[cur_arg], algo);

src/listener.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2040,6 +2040,7 @@ struct bind_conf *bind_conf_alloc(struct proxy *fe, const char *file,
20402040
/* Use connection socket for QUIC by default. */
20412041
bind_conf->quic_mode = QUIC_SOCK_MODE_CONN;
20422042
bind_conf->max_cwnd = global.tune.quic_frontend_max_window_size;
2043+
bind_conf->quic_pacing_burst = 0;
20432044
#endif
20442045
LIST_INIT(&bind_conf->listeners);
20452046

src/quic_conn.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1224,7 +1224,8 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
12241224
/* Only one path at this time (multipath not supported) */
12251225
qc->path = &qc->paths[0];
12261226
quic_cc_path_init(qc->path, ipv4, server ? l->bind_conf->max_cwnd : 0,
1227-
cc_algo ? cc_algo : default_quic_cc_algo, qc);
1227+
cc_algo ? cc_algo : default_quic_cc_algo,
1228+
l->bind_conf->quic_pacing_burst, qc);
12281229

12291230
memcpy(&qc->local_addr, local_addr, sizeof(qc->local_addr));
12301231
memcpy(&qc->peer_addr, peer_addr, sizeof qc->peer_addr);

0 commit comments

Comments
 (0)