MINOR: quic: Dynamic allocation for negotiated Initial TLS cipher context.

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.
This commit is contained in:
Frédéric Lécaille 2023-07-04 07:55:58 +02:00
parent 642dba8c22
commit 90a63ae4fa
5 changed files with 22 additions and 11 deletions

View 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 */

View 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;

View 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;

View 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);

View 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);