From: Amaury Denoyelle Date: Mon, 23 May 2022 06:52:58 +0000 (+0200) Subject: BUG/MEDIUM: mux-quic: adjust buggy proxy closing support X-Git-Tag: v2.6-dev12~146 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d0c62328afe290e6009ae17e092b7df17d73c29b;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: mux-quic: adjust buggy proxy closing support 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. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index 4c240c8b22..c1cea6fa3c 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -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);