]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: mux_quic: do not reset timeout after shut
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 28 Oct 2026 09:38:29 +0000 (10:38 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 28 Oct 2026 10:06:00 +0000 (11:06 +0100)
When a connection is shutting down, MUX QUIC uses shut-timeout if
defined as a final timeout value. However, the timer was reset every
time qcc_refresh_timeout() was called. In effect, a connection could
stay indefinitely due to repeated activity from the peer.

Fix this by ensuring shut-timeout is only set once in
qcc_refresh_timeout(). The value is not updated if QCC task timeout is
already set.

Note that shut-timeout could be completely ignored if set to a greater
value than the default client/server timeout. However, as the docs
imply, this is not expected, as it is used to ensure a closing
connection will quickly end.

This must be backported up to 2.8.

src/mux_quic.c

index bf538b3cb35007145e44a367507f0acb7b222d4d..67a90985235daadeb09605670fcc669a247fb584 100644 (file)
@@ -373,9 +373,13 @@ static void qcc_refresh_timeout(struct qcc *qcc)
                qcc->task->expire = tick_add_ifset(now_ms, qcc->timeout);
        }
        else if (qcc->app_st >= QCC_APP_ST_SHUT) {
+               /* Schedule shut-timeout once and do not reset it after. It is
+                * expected that if set this value is shorter than the default
+                * timeout, so that the connection will quickly end.
+                */
                TRACE_DEVEL("connection in closing", QMUX_EV_QCC_WAKE, qcc->conn);
-               qcc->task->expire = tick_add_ifset(now_ms,
-                                                  qcc->shut_timeout);
+               qcc->task->expire = tick_first(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)) {