From: Amaury Denoyelle Date: Thu, 24 Oct 2024 14:06:48 +0000 (+0200) Subject: MINOR: quic/pacing: support pacing emission on quic_conn layer X-Git-Tag: v3.1-dev14~86 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8039fe43e621dcb5c07c4b7fd3427ae0fd1efdd5;p=thirdparty%2Fhaproxy.git MINOR: quic/pacing: support pacing emission on quic_conn layer 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. --- diff --git a/include/haproxy/quic_pacing.h b/include/haproxy/quic_pacing.h index f6e9228f01..ba918267fc 100644 --- a/include/haproxy/quic_pacing.h +++ b/include/haproxy/quic_pacing.h @@ -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 */ diff --git a/include/haproxy/quic_tx-t.h b/include/haproxy/quic_tx-t.h index 359869a314..ef5617d47c 100644 --- a/include/haproxy/quic_tx-t.h +++ b/include/haproxy/quic_tx-t.h @@ -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 */ diff --git a/include/haproxy/quic_tx.h b/include/haproxy/quic_tx.h index 21f7eecf3a..970d8d598b 100644 --- a/include/haproxy/quic_tx.h +++ b/include/haproxy/quic_tx.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -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); diff --git a/src/mux_quic.c b/src/mux_quic.c index ffd53b9c54..9085859f0e 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -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); diff --git a/src/quic_tx.c b/src/quic_tx.c index a99b2c4b49..ef7668df9a 100644 --- a/src/quic_tx.c +++ b/src/quic_tx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -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;