]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: 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>
Thu, 31 Oct 2024 14:35:31 +0000 (15:35 +0100)
include/haproxy/quic_pacing-t.h
include/haproxy/quic_pacing.h
include/haproxy/quic_tx-t.h
include/haproxy/quic_tx.h
src/mux_quic.c
src/quic_pacing.c
src/quic_tx.c

index 220066994b1bcd935ae2e9e23e90deed0cad381b..25e6eecdba56c705575e414537eff9d0150654db 100644 (file)
@@ -7,6 +7,7 @@
 struct quic_pacer {
        struct list frms;
        const struct quic_cc_path *path;
+       ullong next;
 };
 
 #endif /* _HAPROXY_QUIC_PACING_T_H */
index f58c3a34029c60053c1511164bb12c71111676dc..e760d475ca784a4e8014d650e3bd8cab34fd6ce0 100644 (file)
@@ -11,6 +11,7 @@ static inline void quic_pacing_init(struct quic_pacer *pacer,
 {
        LIST_INIT(&pacer->frms);
        pacer->path = path;
+       pacer->next = 0;
 }
 
 static inline void quic_pacing_reset(struct quic_pacer *pacer)
@@ -29,4 +30,13 @@ static inline struct list *quic_pacing_frms(struct quic_pacer *pacer)
        return &pacer->frms;
 }
 
+static inline ullong quic_pacing_ns_pkt(const struct quic_pacer *pacer)
+{
+       return pacer->path->loss.srtt * 1000000 / (pacer->path->cwnd / pacer->path->mtu + 1);
+}
+
+int quic_pacing_expired(const struct quic_pacer *pacer);
+
+void quic_pacing_sent_done(struct quic_pacer *pacer, int sent);
+
 #endif /* _HAPROXY_QUIC_PACING_H */
index 359869a314270e81c680513ca73ec33ead2541ba..5f7e2342260672de3d08a23e548d38c1fc6058f4 100644 (file)
@@ -66,6 +66,7 @@ enum qc_build_pkt_err {
 
 enum quic_tx_err {
        QUIC_TX_ERR_NONE,
+       QUIC_TX_ERR_AGAIN,
        QUIC_TX_ERR_FATAL,
 };
 
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 23aa00559fe508fc75c9794264d101617d43825b..fd3c10365f72b392a1969378aa1e5cd90a786473 100644 (file)
@@ -2084,7 +2084,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 faee5e81c21b7eca59f020348058c6762acbe05e..df3fedb585248ef7e3556f734dbb8f8f06bbd06f 100644 (file)
@@ -1 +1,15 @@
 #include <haproxy/quic_pacing.h>
+
+#include <haproxy/quic_tx.h>
+
+struct quic_conn;
+
+int quic_pacing_expired(const struct quic_pacer *pacer)
+{
+       return !pacer->next || pacer->next <= now_mono_time();
+}
+
+void quic_pacing_sent_done(struct quic_pacer *pacer, int sent)
+{
+       pacer->next = now_mono_time() + quic_pacing_ns_pkt(pacer) * sent;
+}
index 654cc688f307ee4232105a51880a3fc4ccb3b26e..e33d74dc368f5853082d2e96fa20ffa9a3512084 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,20 @@ 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) {
+               if (max_dgram && max_dgram == sent && !LIST_ISEMPTY(frms))
+                       ret = QUIC_TX_ERR_AGAIN;
+               quic_pacing_sent_done(pacer, sent);
+       }
 
        TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc);
        return ret;