]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: h1: h1_release() should return if it destroyed the connection
authorOlivier Houchard <ohouchard@haproxy.com>
Fri, 14 Nov 2025 11:33:33 +0000 (12:33 +0100)
committerOlivier Houchard <cognet@ci0.org>
Fri, 14 Nov 2025 11:49:35 +0000 (12:49 +0100)
h1_release() is called to destroy everything related to the mux h1,
usually even the connection. However, it handles upgrades to HTTP/2 too,
in which case the h1 mux will be destroyed, but the connection will
still be alive. So make it so it returns 0 if everything is destroyed,
and -1 if the connection is still alive.

This should be backported up to 2.8, as a future bugfix will depend on
it.

src/mux_h1.c

index 6163d42c2ed78a8c6664d2362f1d51dd2e7910fd..0b533d758c532a0434f94d53817d5527fcbf6e29 100644 (file)
@@ -339,7 +339,7 @@ DECLARE_STATIC_TYPED_POOL(pool_head_h1s, "h1s", struct h1s);
 static int h1_recv(struct h1c *h1c);
 static int h1_send(struct h1c *h1c);
 static int h1_process(struct h1c *h1c);
-static void h1_release(struct h1c *h1c);
+static int h1_release(struct h1c *h1c);
 
 /* h1_io_cb is exported to see it resolved in "show fd" */
 struct task *h1_io_cb(struct task *t, void *ctx, unsigned int state);
@@ -1371,8 +1371,10 @@ static int h1_init(struct connection *conn, struct proxy *proxy, struct session
 
 /* release function. This one should be called to free all resources allocated
  * to the mux.
+ * Returns 0 if everything was destroyed, -1 if an upgrade to h2 happened
+ * and the connection is still alive.
  */
-static void h1_release(struct h1c *h1c)
+static int h1_release(struct h1c *h1c)
 {
        struct connection *conn = NULL;
 
@@ -1391,7 +1393,7 @@ static void h1_release(struct h1c *h1c)
                if (conn_upgrade_mux_fe(conn, NULL, &h1c->ibuf, ist("h2"), PROTO_MODE_HTTP) != -1) {
                        /* connection successfully upgraded to H2, this
                         * mux was already released */
-                       return;
+                       return -1;
                }
                TRACE_ERROR("h2 upgrade failed", H1_EV_H1C_END|H1_EV_H1C_ERR, conn);
                sess_log(conn->owner); /* Log if the upgrade failed */
@@ -1437,6 +1439,7 @@ static void h1_release(struct h1c *h1c)
                        conn->destroy_cb(conn);
                conn_free(conn);
        }
+       return 0;
 }
 
 /******************************************************/