diff --git a/include/haproxy/quic_conn-t.h b/include/haproxy/quic_conn-t.h index d05a7b96f..b5ca429c9 100644 --- a/include/haproxy/quic_conn-t.h +++ b/include/haproxy/quic_conn-t.h @@ -566,6 +566,8 @@ struct quic_conn_cntrs { #define QUIC_FL_CONN_HANDSHAKE_SPEED_UP (1U << 12) /* Handshake speeding up was done */ #define QUIC_FL_CONN_ACK_TIMER_FIRED (1U << 13) /* idle timer triggered for acknowledgements */ #define QUIC_FL_CONN_IO_TO_REQUEUE (1U << 14) /* IO handler must be requeued on new thread after connection migration */ +#define QUIC_FL_CONN_IPKTNS_DCD (1U << 15) /* Initial packet number space discarded */ +#define QUIC_FL_CONN_HPKTNS_DCD (1U << 16) /* Handshake packet number space discarded */ #define QUIC_FL_CONN_TO_KILL (1U << 24) /* Unusable connection, to be killed */ #define QUIC_FL_CONN_TX_TP_RECEIVED (1U << 25) /* Peer transport parameters have been received (used for the transmitting part) */ #define QUIC_FL_CONN_FINALIZED (1U << 26) /* QUIC connection finalized (functional, ready to send/receive) */ diff --git a/include/haproxy/quic_tls-t.h b/include/haproxy/quic_tls-t.h index b13e4f8bc..1e146ae8a 100644 --- a/include/haproxy/quic_tls-t.h +++ b/include/haproxy/quic_tls-t.h @@ -185,8 +185,6 @@ struct quic_tls_kp { /* Key update phase bit */ #define QUIC_FL_TLS_KP_BIT_SET (1 << 0) -/* Flag to be used when TLS secrets have been discarded. */ -#define QUIC_FL_TLS_SECRETS_DCD (1 << 1) struct quic_tls_secrets { EVP_CIPHER_CTX *ctx; diff --git a/include/haproxy/quic_tls.h b/include/haproxy/quic_tls.h index 9927044b4..ac0dd7cfc 100644 --- a/include/haproxy/quic_tls.h +++ b/include/haproxy/quic_tls.h @@ -498,6 +498,10 @@ static inline void quic_pktns_tx_pkts_release(struct quic_pktns *pktns, struct q static inline void quic_pktns_discard(struct quic_pktns *pktns, struct quic_conn *qc) { + if (pktns == qc->ipktns) + qc->flags |= QUIC_FL_CONN_IPKTNS_DCD; + else if (pktns == qc->hpktns) + qc->flags |= QUIC_FL_CONN_HPKTNS_DCD; qc->path->in_flight -= pktns->tx.in_flight; qc->path->prep_in_flight -= pktns->tx.in_flight; qc->path->loss.pto_count = 0; @@ -584,6 +588,21 @@ static inline enum quic_tls_pktns quic_tls_pktns(enum quic_tls_enc_level level) } } +/* Return 1 if packet number space attached to connection has been discarded, + * 0 if not. + */ +static inline int quic_tls_pktns_is_dcd(struct quic_conn *qc, struct quic_pktns *pktns) +{ + if (pktns == qc->apktns) + return 0; + + if ((pktns == qc->ipktns && (qc->flags & QUIC_FL_CONN_IPKTNS_DCD)) || + (pktns == qc->hpktns && (qc->flags & QUIC_FL_CONN_HPKTNS_DCD))) + return 1; + + return 0; +} + /* Reset all members of to default values, ->hp_key[] excepted */ static inline void quic_tls_ctx_reset(struct quic_tls_ctx *ctx) { @@ -787,14 +806,6 @@ static inline int quic_get_tls_enc_levels(enum quic_tls_enc_level *level, return ret; } -/* Flag the keys at encryption level as discarded. - * Note that this function is called only for Initial or Handshake encryption levels. - */ -static inline void quic_tls_discard_keys(struct quic_enc_level *qel) -{ - qel->tls_ctx.flags |= QUIC_FL_TLS_SECRETS_DCD; -} - /* Derive the initial secrets with as QUIC TLS context which is the * cryptographic context for the first encryption level (Initial) from * connection ID with as length (in bytes) for a server or not diff --git a/src/quic_conn.c b/src/quic_conn.c index a3b4d3ffe..2a694a699 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -3343,13 +3343,13 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt, */ if (pkt->type == QUIC_PACKET_TYPE_HANDSHAKE && qc_is_listener(qc)) { if (qc->state >= QUIC_HS_ST_SERVER_INITIAL) { - if (qc->iel && !(qc->iel->tls_ctx.flags & QUIC_FL_TLS_SECRETS_DCD)) { - quic_tls_discard_keys(qc->iel); + if (qc->ipktns && !quic_tls_pktns_is_dcd(qc, qc->ipktns)) { + /* Discard the handshake packet number space. */ TRACE_PROTO("discarding Initial pktns", QUIC_EV_CONN_PRSHPKT, qc); - quic_pktns_discard(qc->iel->pktns, qc); + quic_pktns_discard(qc->ipktns, qc); qc_set_timer(qc); qc_el_rx_pkts_del(qc->iel); - qc_release_pktns_frms(qc, qc->iel->pktns); + qc_release_pktns_frms(qc, qc->ipktns); } if (qc->state < QUIC_HS_ST_SERVER_HANDSHAKE) qc->state = QUIC_HS_ST_SERVER_HANDSHAKE; @@ -4543,7 +4543,7 @@ static int qc_qel_may_rm_hp(struct quic_conn *qc, struct quic_enc_level *qel) goto cant_rm_hp; /* check if tls secrets are available */ - if (qel->tls_ctx.flags & QUIC_FL_TLS_SECRETS_DCD) { + if (quic_tls_pktns_is_dcd(qc, qel->pktns)) { TRACE_PROTO("Discarded keys", QUIC_EV_CONN_TRMHP, qc); goto cant_rm_hp; } @@ -4649,7 +4649,7 @@ int qc_treat_rx_pkts(struct quic_conn *qc) } /* Release the Initial encryption level and packet number space. */ - if (qel->tls_ctx.flags & QUIC_FL_TLS_SECRETS_DCD && qel == qc->iel) { + if ((qc->flags & QUIC_FL_CONN_IPKTNS_DCD) && qel == qc->iel) { qc_enc_level_free(qc, &qc->iel); quic_pktns_release(qc, &qc->ipktns); } @@ -5129,9 +5129,8 @@ struct task *quic_conn_io_cb(struct task *t, void *context, unsigned int state) st = qc->state; if (st >= QUIC_HS_ST_COMPLETE) { - if (!(qc->hel->tls_ctx.flags & QUIC_FL_TLS_SECRETS_DCD)) { - /* Discard the Handshake keys. */ - quic_tls_discard_keys(qc->hel); + if (!(qc->flags & QUIC_FL_CONN_HPKTNS_DCD)) { + /* Discard the Handshake packet number space. */ TRACE_PROTO("discarding Handshake pktns", QUIC_EV_CONN_PHPKTS, qc); quic_pktns_discard(qc->hel->pktns, qc); qc_set_timer(qc); @@ -5202,7 +5201,7 @@ struct task *quic_conn_io_cb(struct task *t, void *context, unsigned int state) * the Handshake is confirmed and if there is no need to send * anymore Handshake packets. */ - if ((qc->hel->tls_ctx.flags & QUIC_FL_TLS_SECRETS_DCD) && + if (quic_tls_pktns_is_dcd(qc, qc->hpktns) && !qc_need_sending(qc, qc->hel)) { /* Ensure Initial packet encryption level and packet number space have * been released. @@ -6077,7 +6076,7 @@ static inline int qc_try_rm_hp(struct quic_conn *qc, TRACE_PROTO("RX hp removed", QUIC_EV_CONN_TRMHP, qc, pkt); } else { - if (qel->tls_ctx.flags & QUIC_FL_TLS_SECRETS_DCD) { + if (quic_tls_pktns_is_dcd(qc, qel->pktns)) { /* If the packet number space has been discarded, this packet * will be not parsed. */