QUIC RCIDM: Add counters to support RCID count enforcement
authorHugo Landau <hlandau@openssl.org>
Tue, 7 Nov 2023 15:31:30 +0000 (15:31 +0000)
committerTomas Mraz <tomas@openssl.org>
Thu, 11 Jan 2024 10:14:18 +0000 (11:14 +0100)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23022)

include/internal/quic_rcidm.h
ssl/quic/quic_rcidm.c

index cd90d0948105fe9659d69bbe81298baacbad15d8..4837fed480cf39a9e0e3ea67cd374984518d42c9 100644 (file)
@@ -166,6 +166,19 @@ int ossl_quic_rcidm_get_preferred_tx_dcid(QUIC_RCIDM *rcidm,
 int ossl_quic_rcidm_get_preferred_tx_dcid_changed(QUIC_RCIDM *rcidm,
                                                   int clear);
 
+/*
+ * Returns the number of active numbered RCIDs we have. Note that this includes
+ * RCIDs on the retir*ing* queue accessed via
+ * ossl_quic_rcidm_pop_retire_seq_num() as these are still active until actually
+ * retired.
+ */
+size_t ossl_quic_rcidm_get_num_active(const QUIC_RCIDM *rcidm);
+
+/*
+ * Returns the number of retir*ing* numbered RCIDs we have.
+ */
+size_t ossl_quic_rcidm_get_num_retiring(const QUIC_RCIDM *rcidm);
+
 # endif
 
 #endif
index 91391d6589a354f06fcf0ab4c743f45c39602da2..05cfa054c6acdac3b615b21955e20e176f711f9c 100644 (file)
@@ -207,6 +207,9 @@ struct quic_rcidm_st {
      */
     OSSL_LIST(retiring)         retiring_list;
 
+    /* Number of entries on the retiring_list. */
+    size_t                      num_retiring;
+
     /* preferred_rcid has been changed? */
     unsigned int    preferred_rcid_changed          : 1;
 
@@ -250,6 +253,8 @@ static void rcidm_check_rcid(QUIC_RCIDM *rcidm, RCID *rcid)
     assert(rcid->seq_num >= rcidm->retire_prior_to
             || rcid->state == RCID_STATE_RETIRING);
     assert(rcidm->num_changes == 0 || rcidm->handshake_complete);
+    assert(rcid->state != RCID_STATE_RETIRING || rcidm->num_retiring > 0);
+    assert(rcidm->num_retiring < SIZE_MAX / 2);
 }
 
 static int rcid_cmp(const RCID *a, const RCID *b)
@@ -355,6 +360,7 @@ static RCID *rcidm_create_rcid(QUIC_RCIDM *rcidm, uint64_t seq_num,
         rcid->state     = RCID_STATE_RETIRING;
         rcid->pq_idx    = SIZE_MAX;
         ossl_list_retiring_insert_tail(&rcidm->retiring_list, rcid);
+        ++rcidm->num_retiring;
     }
 
     rcidm_check_rcid(rcidm, rcid);
@@ -390,6 +396,7 @@ static void rcidm_transition_rcid(QUIC_RCIDM *rcidm, RCID *rcid,
             rcidm->cur_rcid = NULL;
 
         ossl_list_retiring_insert_tail(&rcidm->retiring_list, rcid);
+        ++rcidm->num_retiring;
     }
 
     rcidm_check_rcid(rcidm, rcid);
@@ -411,6 +418,7 @@ static void rcidm_free_rcid(QUIC_RCIDM *rcidm, RCID *rcid)
         break;
     case RCID_STATE_RETIRING:
         ossl_list_retiring_remove(&rcidm->retiring_list, rcid);
+        --rcidm->num_retiring;
         break;
     default:
         assert(0);
@@ -658,4 +666,14 @@ int ossl_quic_rcidm_get_preferred_tx_dcid_changed(QUIC_RCIDM *rcidm,
     return r;
 }
 
-// TODO expose counters for enforcement
+size_t ossl_quic_rcidm_get_num_active(const QUIC_RCIDM *rcidm)
+{
+    return ossl_pqueue_RCID_num(rcidm->rcids)
+        + (rcidm->cur_rcid != NULL ? 1 : 0)
+        + ossl_quic_rcidm_get_num_retiring(rcidm);
+}
+
+size_t ossl_quic_rcidm_get_num_retiring(const QUIC_RCIDM *rcidm)
+{
+    return rcidm->num_retiring;
+}