]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Dynamic allocation for negotiated Initial TLS cipher context.
authorFrédéric Lécaille <flecaille@haproxy.com>
Tue, 4 Jul 2023 05:55:58 +0000 (07:55 +0200)
committerFrédéric Lécaille <flecaille@haproxy.com>
Fri, 21 Jul 2023 12:27:10 +0000 (14:27 +0200)
Shorten ->negotiated_ictx quic_conn struct member (->nictx).
This variable is used during version negotiation. Indeed, a connection
may have to support support several QUIC versions of paquets during
the handshake. ->nictx is the QUIC TLS cipher context used for the negotiated
QUIC version.

This patch allows a connection to dynamically allocate this TLS cipher context.

Add a new pool (pool_head_quic_tls_ctx) for such QUIC TLS cipher context object.
Modify qc_new_conn() to initialize ->nictx to NULL value.
quic_tls_ctx_secs_free() frees all the secrets attached to a QUIC TLS cipher context.
Modify it to do nothing if it is called with a NULL TLS cipher context.
Modify to allocate ->nictx from qc_conn_finalize() just before initializing
its secrets. qc_conn_finalize() allocates -nictx only if needed (if a new QUIC
version was negotiated).
Modify qc_conn_release() which release a QUIC connection (quic_conn struct) to
release ->nictx TLS cipher context.

include/haproxy/quic_conn-t.h
include/haproxy/quic_tls-t.h
include/haproxy/quic_tls.h
src/quic_conn.c
src/quic_tls.c

index 3d830ebbc3e34a1b482c28c25156029576ec17e8..5b71ae8e58be191e79004979b95d1356cf27f93d 100644 (file)
@@ -581,7 +581,7 @@ struct quic_conn {
        const struct quic_version *original_version;
        const struct quic_version *negotiated_version;
        /* Negotiated version Initial TLS context */
-       struct quic_tls_ctx negotiated_ictx;
+       struct quic_tls_ctx *nictx;
        /* Connection owned socket FD. */
        int fd;
        /* QUIC transport parameters TLS extension */
index 1e146ae8a7cbf52189d87e18ebb88b655b9f535f..b36505f88f7e689f724cf47ec43c5bcf90f8cbfa 100644 (file)
@@ -54,6 +54,7 @@
 
 extern struct pool_head *pool_head_quic_pktns;
 extern struct pool_head *pool_head_quic_enc_level;
+extern struct pool_head *pool_head_quic_tls_ctx;
 extern struct pool_head *pool_head_quic_tls_secret;
 extern struct pool_head *pool_head_quic_tls_iv;
 extern struct pool_head *pool_head_quic_tls_key;
index 4d1af10fe05b099b908bf874357ebeb33b0dcf91..d433fff3d4dc07d61792c61df09bc4ade1aee5d3 100644 (file)
@@ -648,6 +648,9 @@ static inline void quic_tls_ctx_reset(struct quic_tls_ctx *ctx)
  */
 static inline void quic_tls_ctx_secs_free(struct quic_tls_ctx *ctx)
 {
+       if (!ctx)
+               return;
+
        if (ctx->rx.iv) {
                memset(ctx->rx.iv, 0, ctx->rx.ivlen);
                ctx->rx.ivlen = 0;
index 8885b7655d9df107992fb8c0d48c0fe136b92618..da471bb818707af6e95aefb3d9fb39f9fb63cf61 100644 (file)
@@ -1582,7 +1582,7 @@ static inline struct quic_tls_ctx *qc_select_tls_ctx(struct quic_conn *qc,
                                                      struct quic_rx_packet *pkt)
 {
        return pkt->type != QUIC_PACKET_TYPE_INITIAL ? &qel->tls_ctx :
-               pkt->version == qc->negotiated_version ? &qc->negotiated_ictx : &qel->tls_ctx;
+               pkt->version == qc->negotiated_version ? qc->nictx : &qel->tls_ctx;
 }
 
 /* Decrypt <pkt> packet using encryption level <qel> for <qc> connection.
@@ -2385,10 +2385,16 @@ static int qc_conn_finalize(struct quic_conn *qc, int server)
        if (qc->flags & QUIC_FL_CONN_FINALIZED)
                goto finalized;
 
-       if (qc->negotiated_version &&
-           !qc_new_isecs(qc, &qc->negotiated_ictx, qc->negotiated_version,
-                         qc->odcid.data, qc->odcid.len, server))
-               goto out;
+       if (qc->negotiated_version) {
+               qc->nictx = pool_alloc(pool_head_quic_tls_ctx);
+               if (!qc->nictx)
+                       goto out;
+
+               quic_tls_ctx_reset(qc->nictx);
+               if (!qc_new_isecs(qc, qc->nictx, qc->negotiated_version,
+                                 qc->odcid.data, qc->odcid.len, server))
+                       goto out;
+       }
 
        /* This connection is functional (ready to send/receive) */
        qc->flags |= QUIC_FL_CONN_FINALIZED;
@@ -3641,7 +3647,7 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf,
                if (qc->negotiated_version) {
                        ver = qc->negotiated_version;
                        if (qel == qc->iel)
-                               tls_ctx = &qc->negotiated_ictx;
+                               tls_ctx = qc->nictx;
                        else
                                tls_ctx = &qel->tls_ctx;
                }
@@ -5466,7 +5472,7 @@ static struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
        }
 
        /* Initialize in priority qc members required for a safe dealloc. */
-
+       qc->nictx = NULL;
        /* Prevents these CID to be dumped by TRACE() calls */
        qc->scid.len = qc->odcid.len = qc->dcid.len = 0;
        /* required to use MTLIST_IN_LIST */
@@ -5509,8 +5515,6 @@ static struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
        qc->ipktns = qc->hpktns = qc->apktns = NULL;
        LIST_INIT(&qc->pktns_list);
 
-       quic_tls_ctx_reset(&qc->negotiated_ictx);
-
        /* Required to safely call quic_conn_prx_cntrs_update() from quic_conn_release(). */
        qc->prx_counters = NULL;
 
@@ -5762,7 +5766,9 @@ void quic_conn_release(struct quic_conn *qc)
        qc_enc_level_free(qc, &qc->hel);
        qc_enc_level_free(qc, &qc->ael);
 
-       quic_tls_ctx_secs_free(&qc->negotiated_ictx);
+       quic_tls_ctx_secs_free(qc->nictx);
+       pool_free(pool_head_quic_tls_ctx, qc->nictx);
+       qc->nictx = NULL;
 
        quic_pktns_release(qc, &qc->ipktns);
        quic_pktns_release(qc, &qc->hpktns);
index 6eda50f2f4d833fbf8d5755962e24560b1f6883c..ba5009939888f43184902fa5ed12b57434ee5947 100644 (file)
@@ -14,6 +14,7 @@
 
 DECLARE_POOL(pool_head_quic_enc_level,  "quic_enc_level",  sizeof(struct quic_enc_level));
 DECLARE_POOL(pool_head_quic_pktns,      "quic_pktns",      sizeof(struct quic_pktns));
+DECLARE_POOL(pool_head_quic_tls_ctx,    "quic_tls_ctx",    sizeof(struct quic_tls_ctx));
 DECLARE_POOL(pool_head_quic_tls_secret, "quic_tls_secret", QUIC_TLS_SECRET_LEN);
 DECLARE_POOL(pool_head_quic_tls_iv,     "quic_tls_iv",     QUIC_TLS_IV_LEN);
 DECLARE_POOL(pool_head_quic_tls_key,    "quic_tls_key",    QUIC_TLS_KEY_LEN);