]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: mux-spop: do not enforce the timeout on connections with streams
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 10 Nov 2026 15:10:40 +0000 (16:10 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 12 Nov 2026 17:20:31 +0000 (18:20 +0100)
spop_conn_update_timeout() leaves the connection task unarmed while stream
connectors are attached, since the timeouts are then enforced by the upper
layer. But spop_attach() does not touch the task, so a connection which got
a timeout while it had no stream, for instance because of pending output
data or because of the default timeout applied to connections without
stream, keeps it once a new stream is attached. When it strikes,
spop_timeout_task() kills the connection and aborts the streams attached
to it, while nothing indicates that the agent is not responding.

As done for the H2 mux by commit c2ea47fb1 ("BUG/MEDIUM: mux-h2: do not
enforce timeout on long connections") and for the FCGI mux by commit
6e3bad2f3 ("BUG/MEDIUM: mux-fcgi: do not enforce the timeout on connections
with streams"), spop_timeout_task() now does not kill the connection when
stream connectors are still attached, it only disarms the timeout.

This should be backported to 3.1.

src/mux_spop.c

index 7d228b2bb5bbf29aea51da8ab012e13b459d387e..dc6b439e10e92d4fe90bde020c87fd4cd7005492 100644 (file)
@@ -2792,6 +2792,16 @@ static struct task *spop_timeout_task(struct task *t, void *context, unsigned in
                        return t;
                }
 
+               if (!spop_conn_may_expire(spop_conn)) {
+                       /* streams are still attached, they may be waiting for
+                        * the agent, so the timeout is not ours to enforce.
+                        */
+                       HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+                       t->expire = TICK_ETERNITY;
+                       TRACE_DEVEL("leaving (streams attached)", SPOP_EV_SPOP_CONN_WAKE, spop_conn->conn);
+                       return t;
+               }
+
                /* We're about to destroy the connection, so make sure nobody attempts
                 * to steal it from us.
                 */