From eb2a2da67cd47ec0604834846c523948cc2ebc31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Fri, 1 Apr 2022 12:15:24 +0200 Subject: [PATCH] BUG/MINOR: quic: Missing TX packet deallocations Ensure all TX packets are deallocated. There may be remaining ones which will never be acknowledged or deemed lost. --- include/haproxy/xprt_quic.h | 40 ++++++++++++++++++++----------------- src/xprt_quic.c | 4 +++- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/include/haproxy/xprt_quic.h b/include/haproxy/xprt_quic.h index 09c19ce38..9bf71e906 100644 --- a/include/haproxy/xprt_quic.h +++ b/include/haproxy/xprt_quic.h @@ -1018,27 +1018,10 @@ static inline void quic_tx_packet_refdec(struct quic_tx_packet *pkt) } } -/* Discard packet number space attached to QUIC connection. - * Its loss information are reset. Deduce the outstanding bytes for this - * packet number space from the outstanding bytes for the path of this - * connection. - * Note that all the non acknowledged TX packets and their frames are freed. - * Always succeeds. - */ -static inline void quic_pktns_discard(struct quic_pktns *pktns, - struct quic_conn *qc) +static inline void quic_pktns_tx_pkts_release(struct quic_pktns *pktns) { struct eb64_node *node; - qc->path->in_flight -= pktns->tx.in_flight; - qc->path->prep_in_flight -= pktns->tx.in_flight; - qc->path->loss.pto_count = 0; - - pktns->tx.time_of_last_eliciting = 0; - pktns->tx.loss_time = TICK_ETERNITY; - pktns->tx.pto_probe = 0; - pktns->tx.in_flight = 0; - node = eb64_first(&pktns->tx.pkts); while (node) { struct quic_tx_packet *pkt; @@ -1056,6 +1039,27 @@ static inline void quic_pktns_discard(struct quic_pktns *pktns, } } +/* Discard packet number space attached to QUIC connection. + * Its loss information are reset. Deduce the outstanding bytes for this + * packet number space from the outstanding bytes for the path of this + * connection. + * Note that all the non acknowledged TX packets and their frames are freed. + * Always succeeds. + */ +static inline void quic_pktns_discard(struct quic_pktns *pktns, + struct quic_conn *qc) +{ + qc->path->in_flight -= pktns->tx.in_flight; + qc->path->prep_in_flight -= pktns->tx.in_flight; + qc->path->loss.pto_count = 0; + + pktns->tx.time_of_last_eliciting = 0; + pktns->tx.loss_time = TICK_ETERNITY; + pktns->tx.pto_probe = 0; + pktns->tx.in_flight = 0; + quic_pktns_tx_pkts_release(pktns); +} + /* Initialize

QUIC network path depending on boolean * which is true for an IPv4 path, if not false for an IPv6 path. */ diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 32e293f64..10d3285d2 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -3802,8 +3802,10 @@ static void quic_conn_release(struct quic_conn *qc) pool_free(pool_head_quic_tls_secret, app_tls_ctx->rx.secret); pool_free(pool_head_quic_tls_secret, app_tls_ctx->tx.secret); - for (i = 0; i < QUIC_TLS_PKTNS_MAX; i++) + for (i = 0; i < QUIC_TLS_PKTNS_MAX; i++) { + quic_pktns_tx_pkts_release(&qc->pktns[i]); quic_free_arngs(&qc->pktns[i].rx.arngs); + } pool_free(pool_head_quic_conn_rxbuf, qc->rx.buf.area); pool_free(pool_head_quic_conn, qc);