]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: quic: release BE quic_conn on connect failure
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 25 Nov 2025 13:37:50 +0000 (14:37 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 25 Nov 2025 13:50:23 +0000 (14:50 +0100)
If quic_connect_server() fails, quic_conn FD will remain unopened as set
to -1. Backend connections do not have a fallback socket for future
exchange, contrary to frontend one which can use the listener FD. As
such, it is better to release these connections early.

This patch adjusts such failure by extending quic_close(). This function
is called by the upper layer immediately after a connect issue. In this
case, release immediately a quic_conn backend instance if the FD is
unset, which means that connect has previously failed.

Also, quic_conn_release() is extended to ensure that such faulty
connections are immediately freed and not converted into a
quic_conn_closed instance.

Prior to this patch, a backend quic_conn without any FD would remain
allocated and possibly active. If its tasklet is executed, this resulted
in a crash due to access to an invalid FD.

No need to backport.

src/quic_conn.c
src/xprt_quic.c

index ea9a55b9797dba9a0580641a5a893d434deffdcb..f13f474d06fd52b51a58c423b01e635c8f358d75 100644 (file)
@@ -1548,9 +1548,16 @@ int quic_conn_release(struct quic_conn *qc)
        BUG_ON(qc->conn);
 
        cc_qc = NULL;
+       /* Convert to quic_conn_closed if entering in CLOSING state, except in
+        * the following case :
+        * - idle timeout already expired
+        * - no FD available for a backend connection (after connect() failure)
+        */
        if ((qc->flags & QUIC_FL_CONN_CLOSING) && !(qc->flags & QUIC_FL_CONN_EXP_TIMER) &&
-           qc->tx.cc_buf_area)
+           qc->tx.cc_buf_area &&
+           (!qc_is_back(qc) || qc_test_fd(qc))) {
                cc_qc = qc_new_cc_conn(qc);
+       }
 
        if (!cc_qc) {
                task_destroy(qc->idle_timer_task);
index c21b1b551f35def82eb2ef5137563335bef0557b..e6ca5a361821c15996c8c9317f8ce00812250549 100644 (file)
@@ -14,6 +14,7 @@
 #include <haproxy/buf.h>
 #include <haproxy/connection.h>
 #include <haproxy/quic_conn.h>
+#include <haproxy/quic_sock.h>
 #include <haproxy/quic_ssl.h>
 #include <haproxy/ssl_sock.h>
 #include <haproxy/quic_trace.h>
@@ -42,10 +43,13 @@ static void quic_close(struct connection *conn, void *xprt_ctx)
        qc->flags |= QUIC_FL_CONN_XPRT_CLOSED;
        qc->conn = NULL;
 
-       /* If the quic-conn timer has already expired or if already in "connection close"
-        * state, free the quic-conn.
+       /* Immediately release the connection in the following cases :
+        * - idle timeout already expired
+        * - connection in closing state
+        * - backend conn with no FD avail (after connect() failure)
         */
-       if (qc->flags & (QUIC_FL_CONN_EXP_TIMER|QUIC_FL_CONN_CLOSING)) {
+       if (qc->flags & (QUIC_FL_CONN_EXP_TIMER|QUIC_FL_CONN_CLOSING) ||
+           (qc_is_back(qc) && !qc_test_fd(qc))) {
                quic_conn_release(qc);
                qc = NULL;
                goto leave;