]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: notify the mux on CONNECTION_CLOSE
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 8 Dec 2021 13:51:04 +0000 (14:51 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 8 Dec 2021 14:26:16 +0000 (15:26 +0100)
The xprt layer is reponsible to notify the mux of a CONNECTION_CLOSE
reception. In this case the flag QC_CF_CC_RECV is positionned on the
qcc and the mux tasklet is waken up.

One of the notable effect of the QC_CF_CC_RECV is that each qcs will be
released even if they have remaining data in their send buffers.

include/haproxy/mux_quic-t.h
src/mux_quic.c
src/xprt_quic.c

index f41918da9f3eb23a0d7c4a24f1ed8173682f41d4..eb3d6e902a92918a510c2f78bf6ebf43f3ec8a07 100644 (file)
@@ -22,9 +22,11 @@ enum qcs_type {
        QCS_MAX_TYPES
 };
 
+#define QC_CF_CC_RECV 0x00000001
+
 struct qcc {
        struct connection *conn;
-       uint32_t flags;
+       uint32_t flags; /* QC_CF_* */
 
        struct {
                uint64_t max_streams; /* maximum number of concurrent streams */
index 9111901c4230848c6fadfc7ff8c05a675096b773..89d7875e86acd98ee389966554551165444fd197 100644 (file)
@@ -275,7 +275,8 @@ static int qc_release_detached_streams(struct qcc *qcc)
                node = eb64_next(node);
 
                if (qcs->flags & QC_SF_DETACH) {
-                       if (!b_data(&qcs->tx.buf) && !b_data(&qcs->tx.xprt_buf)) {
+                       if ((!b_data(&qcs->tx.buf) && !b_data(&qcs->tx.xprt_buf)) ||
+                           qcc->flags & QC_CF_CC_RECV) {
                                qcs_destroy(qcs);
                                release = 1;
                        }
@@ -360,7 +361,8 @@ static void qc_detach(struct conn_stream *cs)
        fprintf(stderr, "%s: leaving with tx.buf.data=%lu, tx.xprt_buf.data=%lu\n",
                __func__, b_data(&qcs->tx.buf), b_data(&qcs->tx.xprt_buf));
 
-       if (b_data(&qcs->tx.buf) || b_data(&qcs->tx.xprt_buf)) {
+       if ((b_data(&qcs->tx.buf) || b_data(&qcs->tx.xprt_buf)) &&
+           !(qcc->flags & QC_CF_CC_RECV)) {
                qcs->flags |= QC_SF_DETACH;
                return;
        }
index 250c2b80a6b0654e570011e26c349c47feecb8a4..6556f77fa650247096d2605a4691828d55760b23 100644 (file)
@@ -2326,7 +2326,9 @@ static int qc_parse_pkt_frms(struct quic_rx_packet *pkt, struct ssl_sock_ctx *ct
                        break;
                case QUIC_FT_CONNECTION_CLOSE:
                case QUIC_FT_CONNECTION_CLOSE_APP:
-                       /* TODO warn the mux to close the connection */
+                       /* warn the mux to close the connection */
+                       conn->qcc->flags |= QC_CF_CC_RECV;
+                       tasklet_wakeup(conn->qcc->wait_event.tasklet);
                        break;
                case QUIC_FT_HANDSHAKE_DONE:
                        if (objt_listener(ctx->conn->target))