]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Move the packet number space status at quic_conn level
authorFrédéric Lécaille <flecaille@haproxy.com>
Wed, 28 Jun 2023 16:41:42 +0000 (18:41 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 30 Jun 2023 14:20:55 +0000 (16:20 +0200)
As the packet number spaces and encryption level are dynamically allocated,
the information about the packet number space discarded status must be kept
somewhere else than in these objects.

quic_tls_discard_keys() is no more useful.
Modify quic_pktns_discard() to do the same job: flag the quic_conn object
has having discarded packet number space.
Implement quic_tls_pktns_is_disarded() to check if a packet number space is
discarded. Note the Application data packet number space is never discarded.

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

index d05a7b96f7cbd9f306c4b17f8c49703476f662e4..b5ca429c97e23b04ff2dc6f995d186a996b18343 100644 (file)
@@ -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) */
index b13e4f8bc28c586138dc05d1baefeb6cc06771a5..1e146ae8a7cbf52189d87e18ebb88b655b9f535f 100644 (file)
@@ -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;
index 9927044b479f573f1babdb7c9c5aa0088e9d35c0..ac0dd7cfc6588097ed474359dd6c5772822b6cdd 100644 (file)
@@ -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 <pktns> packet number space attached to <qc> 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 <ctx> 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 <qel> 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 <ctx> as QUIC TLS context which is the
  * cryptographic context for the first encryption level (Initial) from
  * <cid> connection ID with <cidlen> as length (in bytes) for a server or not
index a3b4d3ffebd2c7a3910723c8707208f87b915051..2a694a6995f7196eb5a9156d27751d7e687194b4 100644 (file)
@@ -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.
                         */