diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8595ff0..2251fe0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,8 +34,8 @@ variables: &default-variables .haproxy_stable: &haproxy-stable HAPROXY_GITREPO: "https://git.haproxy.org/?p=haproxy-2.7.git" HAPROXY_VERSION: 2.7-stable - # https://git.haproxy.org/?p=haproxy-2.7.git;a=commit;h=8d230219e15295a3c4757f94916aafcf540a7337 - HAPROXY_GITREF: "8d230219e15295a3c4757f94916aafcf540a7337" + # https://git.haproxy.org/?p=haproxy-2.7.git;a=commit;h=4dadaaafb20106619510fd3fc6f2819f47777729 + HAPROXY_GITREF: "4dadaaafb20106619510fd3fc6f2819f47777729" BUILD_PATCHES_DIR: "patches-stable" .haproxy_dev: &haproxy-dev diff --git a/haproxy/Makefile b/haproxy/Makefile index 18a3853..4eab44a 100644 --- a/haproxy/Makefile +++ b/haproxy/Makefile @@ -1,6 +1,6 @@ HAPROXY_GITREPO = https://git.haproxy.org/?p=haproxy-2.7.git HAPROXY_VERSION = 2.7-stable -HAPROXY_GITREF = 8d230219e15295a3c4757f94916aafcf540a7337 +HAPROXY_GITREF = 4dadaaafb20106619510fd3fc6f2819f47777729 HAPROXY_SHORTSHA = $(shell echo "$(HAPROXY_GITREF)" | grep -Eo '^.{7}' || echo "$(HAPROXY_GITREF)") HAPROXY_VERSION_MINOR = $(shell echo "$(HAPROXY_VERSION)" | cut -d'.' -f1-2) diff --git a/haproxy/patches-stable/1-MINOR-mux-quic-release-data-from-conn-flow-control-on-qsc-reset.patch b/haproxy/patches-stable/1-MINOR-mux-quic-release-data-from-conn-flow-control-on-qsc-reset.patch deleted file mode 100644 index d9d1722..0000000 --- a/haproxy/patches-stable/1-MINOR-mux-quic-release-data-from-conn-flow-control-on-qsc-reset.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 178fbffda1bad5396f34caefd1a3a75e117b1596 Mon Sep 17 00:00:00 2001 -From: Amaury Denoyelle -Date: Wed, 22 Mar 2023 11:17:59 +0100 -Subject: [PATCH] BUG/MEDIUM: mux-quic: release data from conn flow-control on - qcs reset - -Connection flow-control level calculation is a bit complicated. To -ensure it is never exceeded, each time a transfer occurs from a -qcs.tx.buf to its qc_stream_desc buffer it is accounted in -qcc.tx.offsets at the connection level. This value is not decremented -even if the corresponding STREAM frame is rejected by the quic-conn -layer as its emission will be retried later. - -In normal cases this works as expected. However there is an issue if a -qcs instance is removed with prepared data left. In this case, its data -is still accounted in qcc.tx.offsets despite being removed which may -block other streams. This happens every time a qcs is reset with -remaining data which will be discarded in favor of a RESET_STREAM frame. - -To fix this, if a stream has prepared data in qcc_reset_stream(), it is -decremented from qcc.tx.offsets. A BUG_ON() has been added to ensure -qcs_destroy() is never called for a stream with prepared data left. - -This bug can cause two issues : -* transfer freeze as data unsent from closed streams still count on the - connection flow-control limit and will block other streams. Note that - this issue was not reproduced so it's unsure if this really happens - without the following issue first. -* a crash on a BUG_ON() statement in qc_send() loop over - qc_send_frames(). Streams may remained in the send list with nothing - to send due to connection flow-control limit. However, limit is never - reached through qcc_streams_sent_done() so QC_CF_BLK_MFCTL flag is not - set which will allow the loop to continue. - -The last case was reproduced after several minutes of testing using the -following command : - -$ ngtcp2-client --exit-on-all-streams-close -t 0.1 -r 0.1 \ - --max-data=100K -n32 \ - 127.0.0.1 20443 "https://127.0.0.1:20443/?s=1g" 2>/dev/null - -This should fix github issues #2049 and #2074. ---- - src/mux_quic.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/src/mux_quic.c b/src/mux_quic.c -index c2364bfac30f..c14b9f25b2c2 100644 ---- a/src/mux_quic.c -+++ b/src/mux_quic.c -@@ -857,6 +857,15 @@ void qcc_reset_stream(struct qcs *qcs, int err) - qcs->flags |= QC_SF_TO_RESET; - qcs->err = err; - -+ /* Remove prepared stream data from connection flow-control calcul. */ -+ if (qcs->tx.offset > qcs->tx.sent_offset) { -+ const uint64_t diff = qcs->tx.offset - qcs->tx.sent_offset; -+ BUG_ON(qcc->tx.offsets - diff < qcc->tx.sent_offsets); -+ qcc->tx.offsets -= diff; -+ /* Reset qcs offset to prevent BUG_ON() on qcs_destroy(). */ -+ qcs->tx.offset = qcs->tx.sent_offset; -+ } -+ - qcc_send_stream(qcs, 1); - tasklet_wakeup(qcc->wait_event.tasklet); - } -@@ -1356,6 +1365,11 @@ static void qcs_destroy(struct qcs *qcs) - - TRACE_ENTER(QMUX_EV_QCS_END, conn, qcs); - -+ /* MUST not removed a stream with sending prepared data left. This is -+ * to ensure consistency on connection flow-control calculation. -+ */ -+ BUG_ON(qcs->tx.offset < qcs->tx.sent_offset); -+ - if (quic_stream_is_remote(qcs->qcc, id)) - qcc_release_remote_stream(qcs->qcc, id); - diff --git a/haproxy/patches-stable/2-MINOR-quic-missing-STREAM-frame-type-updated.patch b/haproxy/patches-stable/2-MINOR-quic-missing-STREAM-frame-type-updated.patch deleted file mode 100644 index ff25bfc..0000000 --- a/haproxy/patches-stable/2-MINOR-quic-missing-STREAM-frame-type-updated.patch +++ /dev/null @@ -1,75 +0,0 @@ -From c425e03b28168d96c32afcd9bfb86bcb66b733be Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= -Date: Mon, 20 Mar 2023 14:32:59 +0100 -Subject: [PATCH] BUG/MINOR: quic: Missing STREAM frame type updated - -This patch follows this commit which was not sufficient: - BUG/MINOR: quic: Missing STREAM frame data pointer updates - -Indeed, after updating the ->offset field, the bit which informs the -frame builder of its presence must be systematically set. - -This bug was revealed by the following BUG_ON() from -quic_build_stream_frame() : - bug condition "!!(frm->type & 0x04) != !!stream->offset.key" matched at src/quic_frame.c:515 - -This should fix the last crash occured on github issue #2074. - -Must be backported to 2.6 and 2.7. ---- - include/haproxy/quic_frame.h | 6 +++++- - src/quic_conn.c | 6 +++--- - 2 files changed, 8 insertions(+), 4 deletions(-) - -diff --git a/include/haproxy/quic_frame.h b/include/haproxy/quic_frame.h -index f75d7e65fcb8..cf489f759ba4 100644 ---- a/include/haproxy/quic_frame.h -+++ b/include/haproxy/quic_frame.h -@@ -255,11 +255,15 @@ static inline void qc_frm_free(struct quic_frame **frm) - } - - /* Move forward STREAM frame by bytes. */ --static inline void qc_stream_frm_mv_fwd(struct quic_stream *strm, uint64_t data) -+static inline void qc_stream_frm_mv_fwd(struct quic_frame *frm, uint64_t data) - { -+ struct quic_stream *strm = &frm->stream; - struct buffer cf_buf; - -+ /* Set offset bit if not already there. */ - strm->offset.key += data; -+ frm->type |= QUIC_STREAM_FRAME_TYPE_OFF_BIT; -+ - strm->len -= data; - cf_buf = b_make(b_orig(strm->buf), - b_size(strm->buf), -diff --git a/src/quic_conn.c b/src/quic_conn.c -index f4a36f0e4ad8..25ece803909d 100644 ---- a/src/quic_conn.c -+++ b/src/quic_conn.c -@@ -1905,7 +1905,7 @@ static inline int qc_requeue_nacked_pkt_tx_frms(struct quic_conn *qc, - else if (strm_frm->offset.key < stream_desc->ack_offset) { - uint64_t diff = stream_desc->ack_offset - strm_frm->offset.key; - -- qc_stream_frm_mv_fwd(strm_frm, diff); -+ qc_stream_frm_mv_fwd(frm, diff); - TRACE_DEVEL("updated partially acked frame", - QUIC_EV_CONN_PRSAFRM, qc, frm); - } -@@ -2562,7 +2562,7 @@ static void qc_dup_pkt_frms(struct quic_conn *qc, - else if (strm_frm->offset.key < stream_desc->ack_offset) { - uint64_t diff = stream_desc->ack_offset - strm_frm->offset.key; - -- qc_stream_frm_mv_fwd(strm_frm, diff); -+ qc_stream_frm_mv_fwd(frm, diff); - TRACE_DEVEL("updated partially acked frame", - QUIC_EV_CONN_PRSAFRM, qc, frm); - } -@@ -7301,7 +7301,7 @@ static inline int qc_build_frms(struct list *outlist, struct list *inlist, - else if (strm->offset.key < stream_desc->ack_offset) { - uint64_t diff = stream_desc->ack_offset - strm->offset.key; - -- qc_stream_frm_mv_fwd(strm, diff); -+ qc_stream_frm_mv_fwd(cf, diff); - TRACE_DEVEL("updated partially acked frame", - QUIC_EV_CONN_PRSAFRM, qc, cf); - }