diff --git a/src/quic_conn.c b/src/quic_conn.c index ea9a55b97..f13f474d0 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -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); diff --git a/src/xprt_quic.c b/src/xprt_quic.c index c21b1b551..e6ca5a361 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -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;