]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: mux-spop: don't add a closing connection to an idle list on detach
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 10 Nov 2026 15:16:25 +0000 (16:16 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 12 Nov 2026 17:20:31 +0000 (18:20 +0100)
In spop_detach(), the test deciding whether the connection may be moved to
an idle list checks SPOP_CF_RCVD_SHUT, SPOP_CF_ERR_PENDING and
SPOP_CF_ERROR, but not the connection state. A connection that already
switched to SPOP_CS_ERROR, SPOP_CS_CLOSING or SPOP_CS_CLOSED may thus be
inserted in the session server list or in the server's idle pool, while
spop_avail_streams() reports no available stream for it.

This can only happen with a private connection, since srv_add_to_idle_list()
already rejects connections without available streams. It is not harmful
either, since session_get_conn() also requires an available stream, so such
a connection is never reused. But it is still wrong to park it: it prevents
the session from dropping it and forces a useless idle counter increment.

This is the same fix as the one applied on mux-fcgi by commit 2acf116bf
("MINOR: mux-fcgi: don't add a closed connection to an idle list on
detach"). Unlike FCGI, all states from SPOP_CS_ERROR are excluded, which
matches the test performed by spop_avail_streams().

This may be backported to 3.1.

src/mux_spop.c

index a742c930ea0552a085c50452f7e6d9c31655e872..06daaa7b925a68868314447ccb639397594c1240 100644 (file)
@@ -3024,7 +3024,8 @@ static void spop_detach(struct sedesc *sd)
        /* A stream left, refresh the timeout if necessary. */
        spop_conn_update_timeout(spop_conn);
 
-       if (!(spop_conn->flags & (SPOP_CF_RCVD_SHUT|SPOP_CF_ERR_PENDING|SPOP_CF_ERROR))) {
+       if (!(spop_conn->flags & (SPOP_CF_RCVD_SHUT|SPOP_CF_ERR_PENDING|SPOP_CF_ERROR)) &&
+           (spop_conn->state < SPOP_CS_ERROR)) {
                if (spop_conn->conn->flags & CO_FL_PRIVATE) {
                        /* Add the connection in the session server list, if not already done */
                        session_add_conn(sess, spop_conn->conn);