From 0ed617ac2ff377ce60bd9c8fd97fd9da32d43971 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 20 Sep 2022 14:46:40 +0200 Subject: [PATCH] BUG/MEDIUM: mux-quic: properly trim HTX buffer on snd_buf reset MUX QUIC snd_buf operation whill return early if a qcs instance is resetted. In this case, HTX is left untouched and the callback returns the whole bufer size. This lead to an undefined behavior as the stream layer is notified about a transfer but does not see its HTX buffer emptied. In the end, the transfer may stall which will lead to a leak on session. To fix this, HTX buffer is now resetted when snd_buf is short-circuited. This should fix the issue as now the stream layer can continue the transfer until its completion. This patch has already been tested by Tristan and is reported to solve the github issue #1801. This should be backported up to 2.6. --- include/haproxy/qmux_http.h | 1 + src/mux_quic.c | 2 +- src/qmux_http.c | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/include/haproxy/qmux_http.h b/include/haproxy/qmux_http.h index 4a7711401..a7dbe7cc3 100644 --- a/include/haproxy/qmux_http.h +++ b/include/haproxy/qmux_http.h @@ -10,6 +10,7 @@ size_t qcs_http_rcv_buf(struct qcs *qcs, struct buffer *buf, size_t count, char *fin); size_t qcs_http_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count, char *fin); +size_t qcs_http_reset_buf(struct qcs *qcs, struct buffer *buf, size_t count); #endif /* USE_QUIC */ diff --git a/src/mux_quic.c b/src/mux_quic.c index a396e340d..1c615f4e1 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -2110,7 +2110,7 @@ static size_t qc_snd_buf(struct stconn *sc, struct buffer *buf, BUG_ON_HOT(qcs->flags & QC_SF_DETACH); if (qcs_is_close_local(qcs) || (qcs->flags & QC_SF_TO_RESET)) { - ret = count; + ret = qcs_http_reset_buf(qcs, buf, count); goto end; } diff --git a/src/qmux_http.c b/src/qmux_http.c index c77707460..3ce4a3438 100644 --- a/src/qmux_http.c +++ b/src/qmux_http.c @@ -87,3 +87,23 @@ size_t qcs_http_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count, return ret; } + +/* QUIC MUX snd_buf reset. HTX data stored in of length will be + * cleared. This can be used when data should not be transmitted any longer. + * + * Return the size in bytes of cleared data. + */ +size_t qcs_http_reset_buf(struct qcs *qcs, struct buffer *buf, size_t count) +{ + struct htx *htx; + + TRACE_ENTER(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs); + + htx = htx_from_buf(buf); + htx_reset(htx); + htx_to_buf(htx, buf); + + TRACE_LEAVE(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs); + + return count; +}