From cc130473646f5b86be879fd78e0be5581c784ddc Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Wed, 17 Aug 2022 10:08:16 +0200 Subject: [PATCH] MINOR: quic: refactor application send Adjust qc_send_app_pkts function : remove arg and provide a new wrapper function qc_send_app_probing() which should be used instead when probing with old data. This simplifies the interface of the default function, most notably for the MUX which does not interfer with retransmission. QUIC_FL_CONN_RETRANS_OLD_DATA flag is set/unset directly in the wrapper qc_send_app_probing(). At the same time, function documentation has been updated to clarified arguments and return values. This commit will be useful for the next patch to differentiate MUX and retransmission send context. As a consequence, the current patch should be backported wherever the next one will be. --- include/haproxy/xprt_quic.h | 2 +- src/mux_quic.c | 2 +- src/xprt_quic.c | 49 ++++++++++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/include/haproxy/xprt_quic.h b/include/haproxy/xprt_quic.h index 4f85be876..1d11c6a27 100644 --- a/include/haproxy/xprt_quic.h +++ b/include/haproxy/xprt_quic.h @@ -769,7 +769,7 @@ int quic_set_app_ops(struct quic_conn *qc, const unsigned char *alpn, size_t alp struct task *quic_lstnr_dghdlr(struct task *t, void *ctx, unsigned int state); int quic_get_dgram_dcid(unsigned char *buf, const unsigned char *end, unsigned char **dcid, size_t *dcid_len); -int qc_send_app_pkts(struct quic_conn *qc, int old_data, struct list *frms); +int qc_send_app_pkts(struct quic_conn *qc, struct list *frms); void qc_notify_close(struct quic_conn *qc); diff --git a/src/mux_quic.c b/src/mux_quic.c index 699ad2cee..b48add9c7 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -1460,7 +1460,7 @@ static int qc_send_frames(struct qcc *qcc, struct list *frms) LIST_INIT(&qcc->send_retry_list); - qc_send_app_pkts(qcc->conn->handle.qc, 0, frms); + qc_send_app_pkts(qcc->conn->handle.qc, frms); /* If there is frames left at this stage, transport layer is blocked. * Subscribe on it to retry later. diff --git a/src/xprt_quic.c b/src/xprt_quic.c index e366e2049..55001e8f4 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -3882,8 +3882,19 @@ static int qc_qel_may_rm_hp(struct quic_conn *qc, struct quic_enc_level *qel) return ret; } -/* Sends application level packets from QUIC connection */ -int qc_send_app_pkts(struct quic_conn *qc, int old_data, struct list *frms) +/* Try to send application frames from list on connection . + * + * Use qc_send_app_probing wrapper when probing with old data. + * + * Returns 1 on success. Some data might not have been sent due to congestion, + * in this case they are left in input list. The caller may subscribe on + * quic-conn to retry later. + * + * Returns 0 on critical error. + * TODO review and classify more distinctly transient from definitive errors to + * allow callers to properly handle it. + */ +int qc_send_app_pkts(struct quic_conn *qc, struct list *frms) { int status = 0; struct buffer *buf; @@ -3896,11 +3907,6 @@ int qc_send_app_pkts(struct quic_conn *qc, int old_data, struct list *frms) goto leave; } - if (old_data) { - TRACE_STATE("preparing old data (probing)", QUIC_EV_CONN_TXPKT, qc); - qc->flags |= QUIC_FL_CONN_RETRANS_OLD_DATA; - } - /* Prepare and send packets until we could not further prepare packets. */ while (1) { int ret; @@ -3924,18 +3930,37 @@ int qc_send_app_pkts(struct quic_conn *qc, int old_data, struct list *frms) out: status = 1; - qc->flags &= ~QUIC_FL_CONN_RETRANS_OLD_DATA; qc_txb_release(qc); leave: TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc); return status; err: - qc->flags &= ~QUIC_FL_CONN_RETRANS_OLD_DATA; qc_txb_release(qc); goto leave; } +/* Try to send application frames from list on connection . Use this + * function when probing is required. + * + * Returns the result from qc_send_app_pkts function. + */ +static forceinline int qc_send_app_probing(struct quic_conn *qc, + struct list *frms) +{ + int ret; + + TRACE_ENTER(QUIC_EV_CONN_TXPKT, qc); + + TRACE_STATE("preparing old data (probing)", QUIC_EV_CONN_TXPKT, qc); + qc->flags |= QUIC_FL_CONN_RETRANS_OLD_DATA; + ret = qc_send_app_pkts(qc, frms); + qc->flags &= ~QUIC_FL_CONN_RETRANS_OLD_DATA; + + TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc); + return ret; +} + /* Sends handshake packets from up to two encryption levels and * with and as frame list respectively for * QUIC connection. is used as boolean to send data already sent but @@ -4055,11 +4080,11 @@ static void qc_dgrams_retransmit(struct quic_conn *qc) TRACE_PROTO("Avail. ack eliciting frames", QUIC_EV_CONN_FRMLIST, qc, &frms2); if (!LIST_ISEMPTY(&frms1)) { aqel->pktns->tx.pto_probe = 1; - qc_send_app_pkts(qc, 1, &frms1); + qc_send_app_probing(qc, &frms1); } if (!LIST_ISEMPTY(&frms2)) { aqel->pktns->tx.pto_probe = 1; - qc_send_app_pkts(qc, 1, &frms2); + qc_send_app_probing(qc, &frms2); } TRACE_STATE("no more need to probe 01RTT packet number space", QUIC_EV_CONN_TXPKT, qc); @@ -4106,7 +4131,7 @@ static struct task *quic_conn_app_io_cb(struct task *t, void *context, unsigned } /* XXX TODO: how to limit the list frames to send */ - if (!qc_send_app_pkts(qc, 0, &qel->pktns->tx.frms)) { + if (!qc_send_app_pkts(qc, &qel->pktns->tx.frms)) { TRACE_DEVEL("qc_send_app_pkts() failed", QUIC_EV_CONN_IO_CB, qc); goto out; }