]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-quic: adjust buggy proxy closing support
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 23 May 2022 06:52:58 +0000 (08:52 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 23 May 2022 09:05:52 +0000 (11:05 +0200)
The wake handler detects if the frontend is closed. This can happen if
the proxy has been disabled individually or even on process soft-stop.
Before this patch, in this condition QCS instances were freed before
being detached from the cs_endpoint. This clearly violates the haproxy
connection architecture and cause a BUG_ON statement crash in cs_free().

To handle this properly, cs_endpoint is notified by setting RD_SH|WR_SH
on connection flags. The cs_endpoint will thus use the detach operation
which allows the QCS instance to be freed.

This code allows the soft-stop process to complete as soon as possible.
However, the client is not notified about the connection closing. It
should be done by emitting a H3 GOAWAY + CONNECTION_CLOSE. Sadly, this
is impossible at this stage because the listener sockets are closed so
the quic-conn cannot use it to emit new frames. At this stage the client
will most probably detect connection closing on its idle timeout
expiration.

Thus, to completely support proxy closing/soft-stop, important
architecture changes are required in QUIC socket management. This is
also linked with the reload feature.

src/mux_quic.c

index 4c240c8b22dafd78f0dbf78ce94d1d9530254ac1..c1cea6fa3c9813ad5180f264f4550ecda2b142cc 100644 (file)
@@ -1566,12 +1566,15 @@ static int qc_wake(struct connection *conn)
        TRACE_ENTER(QMUX_EV_QCC_WAKE, conn);
 
        /* Check if a soft-stop is in progress.
-        * Release idling front connection if this is the case.
         *
         * TODO this is revelant for frontend connections only.
+        *
+        * TODO Client should be notified with a H3 GOAWAY and then a
+        * CONNECTION_CLOSE. However, quic-conn uses the listener socket for
+        * sending which at this stage is already closed.
         */
        if (unlikely(prx->flags & (PR_FL_DISABLED|PR_FL_STOPPED)))
-               goto release;
+               qcc->conn->flags |= (CO_FL_SOCK_RD_SH|CO_FL_SOCK_WR_SH);
 
        if (conn->handle.qc->flags & QUIC_FL_CONN_NOTIFY_CLOSE)
                qcc->conn->flags |= (CO_FL_SOCK_RD_SH|CO_FL_SOCK_WR_SH);