Skip to content

Commit 2e44d41

Browse files
committed
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 AGAIN value and QUIC MUX will then be responsible to retry emission when the timer is reached.
1 parent 13e3713 commit 2e44d41

File tree

6 files changed

+37
-6
lines changed

6 files changed

+37
-6
lines changed

include/haproxy/quic_pacing.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ static inline void quic_pacing_init(struct quic_pacer *pacer,
1717

1818
int quic_pacing_expired(const struct quic_pacer *pacer);
1919

20+
2021
void quic_pacing_sent_done(struct quic_pacer *pacer);
2122

23+
enum quic_tx_err quic_pacing_send(struct quic_pacer *pacer, struct quic_conn *qc);
24+
2225
#endif /* _HAPROXY_QUIC_PACING_H */

include/haproxy/quic_tx-t.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ enum qc_build_pkt_err {
6666

6767
enum quic_tx_err {
6868
QUIC_TX_ERR_NONE,
69+
QUIC_TX_ERR_AGAIN,
6970
QUIC_TX_ERR_FATAL,
7071
};
7172

include/haproxy/quic_tx.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <haproxy/list-t.h>
2626
#include <haproxy/quic_conn-t.h>
2727
#include <haproxy/quic_tls-t.h>
28+
#include <haproxy/quic_pacing-t.h>
2829
#include <haproxy/quic_rx-t.h>
2930
#include <haproxy/quic_tx-t.h>
3031

@@ -33,7 +34,8 @@ void qc_txb_release(struct quic_conn *qc);
3334
int qc_purge_txbuf(struct quic_conn *qc, struct buffer *buf);
3435
struct buffer *qc_get_txb(struct quic_conn *qc);
3536

36-
enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms);
37+
enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms,
38+
struct quic_pacer *pacer);
3739

3840
void qel_register_send(struct list *send_list, struct quic_enc_level *qel,
3941
struct list *frms);

src/mux_quic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2091,7 +2091,7 @@ static int qcc_send_frames(struct qcc *qcc, struct list *frms)
20912091
return 1;
20922092
}
20932093

2094-
ret = qc_send_mux(qcc->conn->handle.qc, frms);
2094+
ret = qc_send_mux(qcc->conn->handle.qc, frms, NULL);
20952095
if (ret == QUIC_TX_ERR_FATAL) {
20962096
TRACE_DEVEL("error on sending", QMUX_EV_QCC_SEND, qcc->conn);
20972097
qcc_subscribe_send(qcc);

src/quic_pacing.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,16 @@ void quic_pacing_sent_done(struct quic_pacer *pacer)
1313
{
1414
pacer->next = now_mono_time() + pacer->cc->algo->pacing_rate(pacer->cc);
1515
}
16+
17+
/* Restart emission after <pacer> has delayed some frames on <qc> connection.
18+
*
19+
* Returns the value of qc_send_mux() call.
20+
*/
21+
enum quic_tx_err quic_pacing_send(struct quic_pacer *pacer, struct quic_conn *qc)
22+
{
23+
if (!quic_pacing_expired(pacer))
24+
return QUIC_TX_ERR_AGAIN;
25+
26+
BUG_ON(LIST_ISEMPTY(pacer->frms));
27+
return qc_send_mux(qc, pacer->frms, pacer);
28+
}

src/quic_tx.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <haproxy/trace.h>
2121
#include <haproxy/quic_cid.h>
2222
#include <haproxy/quic_conn.h>
23+
#include <haproxy/quic_pacing.h>
2324
#include <haproxy/quic_retransmit.h>
2425
#include <haproxy/quic_retry.h>
2526
#include <haproxy/quic_sock.h>
@@ -469,11 +470,12 @@ int qc_purge_txbuf(struct quic_conn *qc, struct buffer *buf)
469470
*
470471
* Returns the result from qc_send() function.
471472
*/
472-
enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms)
473+
enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms,
474+
struct quic_pacer *pacer)
473475
{
474476
struct list send_list = LIST_HEAD_INIT(send_list);
475477
enum quic_tx_err ret = QUIC_TX_ERR_NONE;
476-
int sent;
478+
int max_dgram = 0, sent;
477479

478480
TRACE_ENTER(QUIC_EV_CONN_TXPKT, qc);
479481
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)
492494
qc_send(qc, 0, &send_list, 0);
493495
}
494496

497+
if (pacer)
498+
max_dgram = 1;
499+
495500
TRACE_STATE("preparing data (from MUX)", QUIC_EV_CONN_TXPKT, qc);
496501
qel_register_send(&send_list, qc->ael, frms);
497-
sent = qc_send(qc, 0, &send_list, 0);
498-
if (sent <= 0)
502+
sent = qc_send(qc, 0, &send_list, max_dgram);
503+
if (sent <= 0) {
499504
ret = QUIC_TX_ERR_FATAL;
505+
}
506+
else if (pacer) {
507+
BUG_ON(sent > 1); /* burst not yet supported for pacing */
508+
if (!LIST_ISEMPTY(frms))
509+
ret = QUIC_TX_ERR_AGAIN;
510+
quic_pacing_sent_done(pacer);
511+
}
500512

501513
TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc);
502514
return ret;

0 commit comments

Comments
 (0)