From: Amaury Denoyelle Date: Tue, 22 Jul 2025 13:44:17 +0000 (+0200) Subject: MINOR: mux-quic: correctly implement backend timeout X-Git-Tag: v3.3-dev4~45 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=89329b147dec6a7c2c11fc5badd4c1cde1f1eedd;p=thirdparty%2Fhaproxy.git MINOR: mux-quic: correctly implement backend timeout qcc_refresh_timeout() is the function called on QUIC MUX activity. Its purpose is to update the timeout by selecting the correct value depending on the connection state. Prior to this patch, backend connections were mostly ignored by the function. However, the default server timeout was selecting as a fallback. This is incompatible with backend connections reuse. This patch fixes timeout applied on backend connections. Only values specific to frontend which are http-request and http-keep-alive timeouts are now ignored for a backend connection. Also, fallback timeout is only used for frontend connections. This patch ensures that an idle backend connection won't be deleted due to server timeout. This is necessary for proper connection reuse which will be implemented in a future patch. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index e7ca77a89..74faaa493 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -315,26 +315,26 @@ static void qcc_refresh_timeout(struct qcc *qcc) goto leave; } - /* Frontend timeout management + /* Timeout management * - detached streams with data left to send -> default timeout * - shutdown done -> timeout client-fin - * - stream waiting on incomplete request or no stream yet activated -> timeout http-request - * - idle after stream processing -> timeout http-keep-alive + * - (FE only) stream waiting on incomplete request or no stream yet activated -> timeout http-request + * - (FE only) idle after stream processing -> timeout http-keep-alive * * If proxy stop-stop in progress, immediate or spread close will be * processed if shutdown already one or connection is idle. */ - if (!conn_is_back(qcc->conn)) { - if (!LIST_ISEMPTY(&qcc->send_list) || !LIST_ISEMPTY(&qcc->tx.frms)) { - TRACE_DEVEL("pending output data", QMUX_EV_QCC_WAKE, qcc->conn); - qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout); - } - else if (qcc->app_st >= QCC_APP_ST_SHUT) { - TRACE_DEVEL("connection in closing", QMUX_EV_QCC_WAKE, qcc->conn); - qcc->task->expire = tick_add_ifset(now_ms, - qcc->shut_timeout); - } - else if (!LIST_ISEMPTY(&qcc->opening_list) || unlikely(!qcc->largest_bidi_r)) { + if (!LIST_ISEMPTY(&qcc->send_list) || !LIST_ISEMPTY(&qcc->tx.frms)) { + TRACE_DEVEL("pending output data", QMUX_EV_QCC_WAKE, qcc->conn); + qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout); + } + else if (qcc->app_st >= QCC_APP_ST_SHUT) { + TRACE_DEVEL("connection in closing", QMUX_EV_QCC_WAKE, qcc->conn); + qcc->task->expire = tick_add_ifset(now_ms, + qcc->shut_timeout); + } + else if (!conn_is_back(qcc->conn)) { + if (!LIST_ISEMPTY(&qcc->opening_list) || unlikely(!qcc->largest_bidi_r)) { int timeout = px->timeout.httpreq; struct qcs *qcs = NULL; int base_time; @@ -356,6 +356,12 @@ static void qcc_refresh_timeout(struct qcc *qcc) TRACE_DEVEL("at least one request achieved but none currently in progress", QMUX_EV_QCC_WAKE, qcc->conn); qcc->task->expire = tick_add_ifset(qcc->idle_start, timeout); } + + /* Fallback to client timeout if specific value not set. */ + if (!tick_isset(qcc->task->expire)) { + TRACE_DEVEL("fallback to default timeout", QMUX_EV_QCC_WAKE, qcc->conn); + qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout); + } } /* If proxy soft-stop in progress and connection is inactive, @@ -392,14 +398,6 @@ static void qcc_refresh_timeout(struct qcc *qcc) } } - /* fallback to default timeout if frontend specific undefined or for - * backend connections. - */ - if (!tick_isset(qcc->task->expire)) { - TRACE_DEVEL("fallback to default timeout", QMUX_EV_QCC_WAKE, qcc->conn); - qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout); - } - task_queue(qcc->task); leave: