]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: handle app data according to mux/connection layer status
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 26 Jan 2022 08:51:28 +0000 (09:51 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 26 Jan 2022 09:57:17 +0000 (10:57 +0100)
Define a new enum to represent the status of the mux/connection layer
above a quic_conn. This is important to know if it's possible to handle
application data, or if it should be buffered or dropped.

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

index bb75cee1f7c80393ce76b3f167636455cc22b927..562d22cab2110617dccdb5cd1054fbf593379f59 100644 (file)
@@ -614,6 +614,17 @@ struct rxbuf {
        struct mt_list mt_list;
 };
 
+/* Status of the connection/mux layer. This defines how to handle app data.
+ *
+ * During a standard quic_conn lifetime it transitions like this :
+ * QC_MUX_NULL -> QC_MUX_READY -> QC_MUX_RELEASED
+ */
+enum qc_mux_state {
+       QC_MUX_NULL,     /* not allocated, data should be buffered */
+       QC_MUX_READY,    /* allocated, ready to handle data */
+       QC_MUX_RELEASED, /* released, data can be dropped */
+};
+
 /* The number of buffers for outgoing packets (must be a power of two). */
 #define QUIC_CONN_TX_BUFS_NB 8
 #define QUIC_CONN_TX_BUF_SZ  QUIC_PACKET_MAXLEN
@@ -647,6 +658,7 @@ struct quic_conn {
        /* Thread ID this connection is attached to */
        int tid;
        int state;
+       enum qc_mux_state mux_state; /* status of the connection/mux layer */
        uint64_t err_code;
        unsigned char enc_params[QUIC_TP_MAX_ENCLEN]; /* encoded QUIC transport parameters */
        size_t enc_params_len;
index ec09170b174e47e2f2ec87aa79f09a512c7885e7..3683350a5cf734e9ec4919a3534ab32794ea1101 100644 (file)
@@ -1058,6 +1058,9 @@ int quic_set_app_ops(struct quic_conn *qc, const unsigned char *alpn, size_t alp
        if (app_ops->finalize)
                app_ops->finalize(qc->qcc->ctx);
 
+       /* mux-quic can now be considered ready. */
+       qc->mux_state = QC_MUX_READY;
+
        return 1;
 }
 
@@ -3203,12 +3206,9 @@ static int qc_qel_may_rm_hp(struct quic_conn *qc, struct quic_enc_level *qel)
        if (!(qel->tls_ctx.rx.flags & QUIC_FL_TLS_SECRETS_SET))
                return 0;
 
-       /* do not decrypt application level until handshake completion */
-       if (tel == QUIC_TLS_ENC_LEVEL_APP &&
-           HA_ATOMIC_LOAD(&qc->state) < QUIC_HS_ST_COMPLETE) {
+       /* check if the connection layer is ready before using app level */
+       if (tel == QUIC_TLS_ENC_LEVEL_APP && qc->mux_state != QC_MUX_READY)
                return 0;
-       }
-
 
        return 1;
 }
@@ -3475,6 +3475,9 @@ void quic_close(struct connection *conn, void *xprt_ctx)
                qc->timer_task = NULL;
        }
 
+       /* Next application data can be dropped. */
+       qc->mux_state = QC_MUX_RELEASED;
+
        TRACE_LEAVE(QUIC_EV_CONN_CLOSE, qc);
 
        /* TODO for now release the quic_conn on notification by the upper
@@ -3608,6 +3611,7 @@ static struct quic_conn *qc_new_conn(unsigned int version, int ipv4,
                        memcpy(qc->dcid.data, dcid, dcid_len);
                qc->dcid.len = dcid_len;
        }
+       qc->mux_state = QC_MUX_NULL;
 
        /* Initialize the output buffer */
        qc->obuf.pos = qc->obuf.data;