]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Add a fake congestion control algorithm named "nocc"
authorFrédéric Lécaille <flecaille@haproxy.com>
Fri, 31 Mar 2023 13:21:55 +0000 (15:21 +0200)
committerFrédéric Lécaille <flecaille@haproxy.com>
Fri, 31 Mar 2023 15:09:03 +0000 (17:09 +0200)
This algorithm does nothing except initializing the congestion control window
to a fixed value. Very smart!

Modify the QUIC congestion control configuration parser to support this new
algorithm. The congestion control algorithm must be set as follows:

     quic-cc-algo nocc-<cc window size(KB))

For instance if "nocc-15" is provided as quic-cc-algo keyword value, this
will set a fixed window of 15KB.

Makefile
include/haproxy/quic_cc-t.h
src/cfgparse-quic.c
src/quic_cc_nocc.c [new file with mode: 0644]

index b5d160251c86961173f9d10d0837886ede909e9a..1f1de6d4645aa345889ee81bfaed5434085893fb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -607,7 +607,7 @@ OPTIONS_OBJS += src/quic_conn.o src/mux_quic.o src/h3.o src/xprt_quic.o    \
                 src/quic_cc_newreno.o src/quic_cc_cubic.o src/qpack-tbl.o  \
                 src/qpack-dec.o src/hq_interop.o src/quic_stream.o         \
                 src/h3_stats.o src/qmux_http.o src/cfgparse-quic.o         \
-                src/cbuf.o src/quic_cc.o
+                src/cbuf.o src/quic_cc.o src/quic_cc_nocc.o
 endif
 
 ifneq ($(USE_LUA),)
index f646c73d8ad54c9a8aea29cb4dec90e103478a45..35996d721f1dbb46e8aea70e1c71fd51e3799760 100644 (file)
@@ -37,6 +37,10 @@ extern struct quic_cc_algo quic_cc_algo_nr;
 extern struct quic_cc_algo quic_cc_algo_cubic;
 extern struct quic_cc_algo *default_quic_cc_algo;
 
+/* Fake algorithm with its fixed window */
+extern struct quic_cc_algo quic_cc_algo_nocc;
+extern unsigned int quic_cc_nocc_fixed_cwnd;
+
 extern unsigned long long last_ts;
 
 enum quic_cc_algo_state_type {
@@ -73,6 +77,7 @@ struct quic_cc_event {
 enum quic_cc_algo_type {
        QUIC_CC_ALGO_TP_NEWRENO,
        QUIC_CC_ALGO_TP_CUBIC,
+       QUIC_CC_ALGO_TP_NOCC,
 };
 
 struct quic_cc {
index 35548d36bd968fa0d46f68bde120cfc0f3a9c6ce..c8cb7d9630c133d863bb111bea5b056d48b212c5 100644 (file)
@@ -20,16 +20,27 @@ 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;
+       char *arg;
 
        if (!*args[cur_arg + 1]) {
                memprintf(err, "'%s' : missing control congestion algorithm", args[cur_arg]);
                return ERR_ALERT | ERR_FATAL;
        }
 
-       if (strcmp(args[cur_arg + 1], "newreno") == 0)
+       arg = args[cur_arg + 1];
+       if (strcmp(arg, "newreno") == 0)
            cc_algo = &quic_cc_algo_nr;
-       else if (strcmp(args[cur_arg + 1], "cubic") == 0)
+       else if (strcmp(arg, "cubic") == 0)
            cc_algo = &quic_cc_algo_cubic;
+       else if (strlen(arg) >= 6 && strncmp(arg, "nocc-", 5) == 0) {
+               if (!experimental_directives_allowed) {
+                       ha_alert("'%s' algo is experimental, must be allowed via a global 'expose-experimental-directives'\n", arg);
+                       return ERR_ALERT | ERR_FATAL;
+               }
+
+           cc_algo = &quic_cc_algo_nocc;
+           quic_cc_nocc_fixed_cwnd = atoi(arg + 5);
+       }
        else {
                memprintf(err, "'%s' : unknown control congestion algorithm", args[cur_arg]);
                return ERR_ALERT | ERR_FATAL;
diff --git a/src/quic_cc_nocc.c b/src/quic_cc_nocc.c
new file mode 100644 (file)
index 0000000..27db350
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Fake congestion control algorithm which does nothing except initializing
+ * the congestion control window to a fixed value.
+ *
+ */
+
+#include <haproxy/api-t.h>
+#include <haproxy/quic_conn-t.h>
+#include <haproxy/trace.h>
+
+#define TRACE_SOURCE    &trace_quic
+
+unsigned int quic_cc_nocc_fixed_cwnd;
+
+static int quic_cc_nocc_init(struct quic_cc *cc)
+{
+       struct quic_path *path;
+
+       path = container_of(cc, struct quic_path, cc);
+       path->cwnd = quic_cc_nocc_fixed_cwnd << 10;
+       return 1;
+}
+
+static void quic_cc_nocc_slow_start(struct quic_cc *cc)
+{
+}
+
+/* Slow start callback. */
+static void quic_cc_nocc_ss_cb(struct quic_cc *cc, struct quic_cc_event *ev)
+{
+       TRACE_ENTER(QUIC_EV_CONN_CC, cc->qc);
+       TRACE_PROTO("CC nocc", QUIC_EV_CONN_CC, cc->qc, ev, cc);
+       TRACE_LEAVE(QUIC_EV_CONN_CC, cc->qc);
+}
+
+/* Congestion avoidance callback. */
+static void quic_cc_nocc_ca_cb(struct quic_cc *cc, struct quic_cc_event *ev)
+{
+       TRACE_ENTER(QUIC_EV_CONN_CC, cc->qc);
+       TRACE_PROTO("CC nocc", QUIC_EV_CONN_CC, cc->qc, ev, cc);
+       TRACE_LEAVE(QUIC_EV_CONN_CC, cc->qc);
+}
+
+/*  Recovery period callback. */
+static void quic_cc_nocc_rp_cb(struct quic_cc *cc, struct quic_cc_event *ev)
+{
+       TRACE_ENTER(QUIC_EV_CONN_CC, cc->qc);
+       TRACE_PROTO("CC nocc", QUIC_EV_CONN_CC, cc->qc, ev, cc);
+       TRACE_LEAVE(QUIC_EV_CONN_CC, cc->qc);
+}
+
+static void quic_cc_nocc_state_trace(struct buffer *buf, const struct quic_cc *cc)
+{
+       struct quic_path *path;
+
+       path = container_of(cc, struct quic_path, cc);
+       chunk_appendf(buf, " cwnd=%llu", (unsigned long long)path->cwnd);
+}
+
+static void (*quic_cc_nocc_state_cbs[])(struct quic_cc *cc,
+                                      struct quic_cc_event *ev) = {
+       [QUIC_CC_ST_SS] = quic_cc_nocc_ss_cb,
+       [QUIC_CC_ST_CA] = quic_cc_nocc_ca_cb,
+       [QUIC_CC_ST_RP] = quic_cc_nocc_rp_cb,
+};
+
+static void quic_cc_nocc_event(struct quic_cc *cc, struct quic_cc_event *ev)
+{
+       return quic_cc_nocc_state_cbs[cc->algo->state](cc, ev);
+}
+
+struct quic_cc_algo quic_cc_algo_nocc = {
+       .type        = QUIC_CC_ALGO_TP_NOCC,
+       .init        = quic_cc_nocc_init,
+       .event       = quic_cc_nocc_event,
+       .slow_start  = quic_cc_nocc_slow_start,
+       .state_trace = quic_cc_nocc_state_trace,
+};
+