]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic/pacing: support pacing emission on quic_conn layer
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 24 Oct 2024 14:06:48 +0000 (16:06 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 19 Nov 2024 15:16:48 +0000 (16:16 +0100)
Pacing will be implemented for STREAM frames emission. As such,
qc_send_mux() API has been extended to add an argument to a quic_pacer
engine.

If non NULL, engine will be used to pace emission. In short, no more
than one datagram will be emitted for each qc_send_mux() invokation.
Pacer is then notified about the emission and a timer for a future
emission is calculated. qc_send_mux() will return PACING error value, to
inform QUIC MUX layer that it will be responsible to retry emission
after some delay.

include/haproxy/quic_pacing.h
include/haproxy/quic_tx-t.h
include/haproxy/quic_tx.h
src/mux_quic.c
src/quic_tx.c

index f6e9228f018ccc9f15c9200bdd5210de5966d198..ba918267fc9b6b02c3c88323d19e4cc0c9ef37f5 100644 (file)
@@ -15,6 +15,9 @@ static inline void quic_pacing_init(struct quic_pacer *pacer,
 
 int quic_pacing_expired(const struct quic_pacer *pacer);
 
+
 void quic_pacing_sent_done(struct quic_pacer *pacer);
 
+enum quic_tx_err quic_pacing_send(struct quic_pacer *pacer, struct quic_conn *qc);
+
 #endif /* _HAPROXY_QUIC_PACING_H */
index 359869a314270e81c680513ca73ec33ead2541ba..ef5617d47cba6129a0a276711cd9f0215eafa6f9 100644 (file)
@@ -67,6 +67,7 @@ enum qc_build_pkt_err {
 enum quic_tx_err {
        QUIC_TX_ERR_NONE,
        QUIC_TX_ERR_FATAL,
+       QUIC_TX_ERR_PACING,
 };
 
 #endif /* _HAPROXY_TX_T_H */
index 21f7eecf3a302b14ace27101c4d2adcfb7fc175a..970d8d598bf9100fcf72ad9e4ca842bf7019be33 100644 (file)
@@ -25,6 +25,7 @@
 #include <haproxy/list-t.h>
 #include <haproxy/quic_conn-t.h>
 #include <haproxy/quic_tls-t.h>
+#include <haproxy/quic_pacing-t.h>
 #include <haproxy/quic_rx-t.h>
 #include <haproxy/quic_tx-t.h>
 
@@ -33,7 +34,8 @@ void qc_txb_release(struct quic_conn *qc);
 int qc_purge_txbuf(struct quic_conn *qc, struct buffer *buf);
 struct buffer *qc_get_txb(struct quic_conn *qc);
 
-enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms);
+enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms,
+                             struct quic_pacer *pacer);
 
 void qel_register_send(struct list *send_list, struct quic_enc_level *qel,
                        struct list *frms);
index ffd53b9c543a1874909f52a15720f8e44a3d2b80..9085859f0ef4907ccd100c004af438e73766c3a7 100644 (file)
@@ -2083,7 +2083,7 @@ static int qcc_send_frames(struct qcc *qcc, struct list *frms)
                return 1;
        }
 
-       ret = qc_send_mux(qcc->conn->handle.qc, frms);
+       ret = qc_send_mux(qcc->conn->handle.qc, frms, NULL);
        if (ret == QUIC_TX_ERR_FATAL) {
                TRACE_DEVEL("error on sending", QMUX_EV_QCC_SEND, qcc->conn);
                qcc_subscribe_send(qcc);
index a99b2c4b490804719b7faa17faf6dc4d6bc3a677..ef7668df9a6b51e88d09e3d1b4c50ef9e56d21a2 100644 (file)
@@ -20,6 +20,7 @@
 #include <haproxy/trace.h>
 #include <haproxy/quic_cid.h>
 #include <haproxy/quic_conn.h>
+#include <haproxy/quic_pacing.h>
 #include <haproxy/quic_retransmit.h>
 #include <haproxy/quic_retry.h>
 #include <haproxy/quic_sock.h>
@@ -469,11 +470,12 @@ int qc_purge_txbuf(struct quic_conn *qc, struct buffer *buf)
  *
  * Returns the result from qc_send() function.
  */
-enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms)
+enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms,
+                             struct quic_pacer *pacer)
 {
        struct list send_list = LIST_HEAD_INIT(send_list);
        enum quic_tx_err ret = QUIC_TX_ERR_NONE;
-       int sent;
+       int max_dgram = 0, sent;
 
        TRACE_ENTER(QUIC_EV_CONN_TXPKT, qc);
        BUG_ON(qc->mux_state != QC_MUX_READY); /* Only MUX can uses this function so it must be ready. */
@@ -492,11 +494,21 @@ enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms)
                qc_send(qc, 0, &send_list, 0);
        }
 
+       if (pacer)
+               max_dgram = 1;
+
        TRACE_STATE("preparing data (from MUX)", QUIC_EV_CONN_TXPKT, qc);
        qel_register_send(&send_list, qc->ael, frms);
-       sent = qc_send(qc, 0, &send_list, 0);
-       if (sent <= 0)
+       sent = qc_send(qc, 0, &send_list, max_dgram);
+       if (sent <= 0) {
                ret = QUIC_TX_ERR_FATAL;
+       }
+       else if (pacer) {
+               BUG_ON(sent > 1); /* burst not yet supported for pacing */
+               if (!LIST_ISEMPTY(frms))
+                       ret = QUIC_TX_ERR_PACING;
+               quic_pacing_sent_done(pacer);
+       }
 
        TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc);
        return ret;