]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux_h2: do not try to remove front conn from idle trees
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 19 Feb 2021 14:37:38 +0000 (15:37 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 19 Feb 2021 15:35:13 +0000 (16:35 +0100)
In h2_process there was two parts where the connection was removed from
the idle trees, without first checking if the connection is a backend
side.

This should not produce a crash as the node is properly zeroed on
conn_init. However, it is better to explicit the test as it is done on
all other places. Besides it will be mandatory if the node part is
dynamically allocated only for backend connections.

src/mux_h2.c

index c94615949df13874bc46bbe08cf60cf5d665f8f8..a6c167b5685a387afab18ce1cda341ae885280f9 100644 (file)
@@ -3904,15 +3904,19 @@ static int h2_process(struct h2c *h2c)
                }
 
                /* connections in error must be removed from the idle lists */
-               HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
-               conn_delete_from_tree(&conn->hash_node);
-               HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+               if (conn->flags & CO_FL_LIST_MASK) {
+                       HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+                       conn_delete_from_tree(&conn->hash_node);
+                       HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+               }
        }
        else if (h2c->st0 == H2_CS_ERROR) {
                /* connections in error must be removed from the idle lists */
-               HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
-               conn_delete_from_tree(&conn->hash_node);
-               HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+               if (conn->flags & CO_FL_LIST_MASK) {
+                       HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+                       conn_delete_from_tree(&conn->hash_node);
+                       HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+               }
        }
 
        if (!b_data(&h2c->dbuf))
@@ -4049,9 +4053,11 @@ do_leave:
        }
 
        /* in any case this connection must not be considered idle anymore */
-       HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
-       conn_delete_from_tree(&h2c->conn->hash_node);
-       HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+       if (h2c->conn->flags & CO_FL_LIST_MASK) {
+               HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+               conn_delete_from_tree(&h2c->conn->hash_node);
+               HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
+       }
 
        /* either we can release everything now or it will be done later once
         * the last stream closes.