From 81eda41d5c7982a78ce357170acf607e4817bf7f Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 21 Apr 2026 17:58:27 +0200 Subject: [PATCH] MINOR: mux_quic: do not perform unnecessary timeout handling on BE side MUX implements a timeout for HTTP keep-alive which monitors the delay between two HTTP requests. This is only applicable for frontend connections, as on the backend side idle connections can be kept in the server pool. In QUIC mux, this timeout relies on QCC which is refresh when the last request is terminated. This patch modifies the refresh operation so that it is only performed for frontend connections. This is not strictly necessary but the timeout timeout management is now clearer and it eliminates an unnecessary operation for backend connections. Similarly, http-request timeout is also only applicable for frontend connections. This relies on qcs_wait_http_req() function. A request QCS is inserted in until the headers are received. This is unnecessary on the backend side so this is excluded as well. --- include/haproxy/mux_quic.h | 16 +++++++++------- src/mux_quic.c | 16 ++++++++-------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/include/haproxy/mux_quic.h b/include/haproxy/mux_quic.h index 6ba947785..232dfe7d2 100644 --- a/include/haproxy/mux_quic.h +++ b/include/haproxy/mux_quic.h @@ -109,14 +109,16 @@ static inline void qcs_wait_http_req(struct qcs *qcs) { struct qcc *qcc = qcs->qcc; - /* A stream cannot be registered several times. */ - BUG_ON_HOT(tick_isset(qcs->start)); - qcs->start = now_ms; + if (!conn_is_back(qcc->conn)) { + /* A stream cannot be registered several times. */ + BUG_ON_HOT(tick_isset(qcs->start)); + qcs->start = now_ms; - /* qcc.opening_list size is limited by flow-control so no custom - * restriction is needed here. - */ - LIST_APPEND(&qcc->opening_list, &qcs->el_opening); + /* qcc.opening_list size is limited by flow-control so no + * custom restriction is needed here. + */ + LIST_APPEND(&qcc->opening_list, &qcs->el_opening); + } } void qcc_show_quic(struct qcc *qcc); diff --git a/src/mux_quic.c b/src/mux_quic.c index 5300ca5f6..ac798e475 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -259,6 +259,12 @@ static forceinline void qcc_reset_idle_start(struct qcc *qcc) qcc->idle_start = now_ms; } +/* Return true if the mux timeout should be armed. */ +static inline int qcc_may_expire(struct qcc *qcc) +{ + return !qcc->nb_sc; +} + /* Decrement sc. */ static forceinline void qcc_rm_sc(struct qcc *qcc) { @@ -268,7 +274,7 @@ static forceinline void qcc_rm_sc(struct qcc *qcc) /* Reset qcc idle start for http-keep-alive timeout. Timeout will be * refreshed after this on stream detach. */ - if (!qcc->nb_sc && !qcc->nb_hreq) + if (!conn_is_back(qcc->conn) && qcc_may_expire(qcc) && !qcc->nb_hreq) qcc_reset_idle_start(qcc); } @@ -281,7 +287,7 @@ static forceinline void qcc_rm_hreq(struct qcc *qcc) /* Reset qcc idle start for http-keep-alive timeout. Timeout will be * refreshed after this on I/O handler. */ - if (!qcc->nb_sc && !qcc->nb_hreq) + if (!conn_is_back(qcc->conn) && qcc_may_expire(qcc) && !qcc->nb_hreq) qcc_reset_idle_start(qcc); } @@ -308,12 +314,6 @@ static inline int qcc_is_dead(const struct qcc *qcc) return 0; } -/* Return true if the mux timeout should be armed. */ -static inline int qcc_may_expire(struct qcc *qcc) -{ - return !qcc->nb_sc; -} - /* Refresh the timeout on if needed depending on its state. */ static void qcc_refresh_timeout(struct qcc *qcc) {