]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: handle external extra CIDs generator.
authorEmeric Brun <ebrun@haproxy.com>
Thu, 7 Sep 2023 08:08:29 +0000 (10:08 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 22 Sep 2023 08:32:14 +0000 (10:32 +0200)
This patch adds the ability to externalize and customize the code
of the computation of extra CIDs after the first one was derived from
the ODCID.

This is to prepare interoperability with extra components such as
different QUIC proxies or routers for instance.

To process the patch defines two function callbacks:
- the first one to compute a hash 64bits from the first generated CID
  (itself continues to be derived from ODCID). Resulting hash is stored
  into the 'quic_conn' and 64bits is chosen large enought to be able to
  store an entire haproxy's CID.
- the second callback re-uses the previoulsy computed hash to derive
  an extra CID using the custom algorithm. If not set haproxy will
  continue to choose a randomized CID value.

Those two functions have also the 'cluster_secret' passed as an argument:
this way, it is usable for obfuscation or ciphering.

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

index 5373d42f722bfbb5761389af9bb517a202d3bfb2..36e74431f633be6d366a8949fe1756567591d37b 100644 (file)
@@ -520,6 +520,10 @@ struct quic_conn {
 #endif
 
        uint64_t next_cid_seq_num;
+       /* Initial hash computed from first ID (derived from ODCID).
+        * it could be reused to derive extra CIDs from the same hash
+        */
+       uint64_t hash64;
 
        /* Initial encryption level */
        struct quic_enc_level *iel;
index 5353a5969b60165555e869d514cddae3bf416f00..5d2fbfa05b2d8f1cd92bee279f32948b84f937d8 100644 (file)
@@ -619,5 +619,10 @@ static inline void quic_handle_stopping(void)
 int qc_set_tid_affinity(struct quic_conn *qc, uint new_tid, struct listener *new_li);
 void qc_finalize_affinity_rebind(struct quic_conn *qc);
 
+/* Function pointer that can be used to compute a hash from first generated CID (derived from ODCID) */
+extern uint64_t (*quic_hash64_from_cid)(const unsigned char *cid, int size, const unsigned char *secret, size_t secretlen);
+/* Function pointer that can be used to derive a new CID from the previously computed hash */
+extern void (*quic_newcid_from_hash64)(unsigned char *cid, int size, uint64_t hash, const unsigned char *secret, size_t secretlen);
+
 #endif /* USE_QUIC */
 #endif /* _HAPROXY_QUIC_CONN_H */
index 23d1400950bff095f497e8333a31576c0f7f34e9..051c9da579eb42d46c696560dd8f119a455d04e5 100644 (file)
@@ -116,6 +116,10 @@ const struct quic_version quic_versions[] = {
        },
 };
 
+/* Function pointers, can be used to compute a hash from first generated CID and to derive new CIDs */
+uint64_t (*quic_hash64_from_cid)(const unsigned char *cid, int size, const unsigned char *secret, size_t secretlen) = NULL;
+void (*quic_newcid_from_hash64)(unsigned char *cid, int size, uint64_t hash, const unsigned char *secret, size_t secretlen) = NULL;
+
 /* The total number of supported versions */
 const size_t quic_versions_nb = sizeof quic_versions / sizeof *quic_versions;
 /* Listener only preferred version */
@@ -644,8 +648,11 @@ struct quic_connection_id *new_quic_cid(struct eb_root *root,
        conn_id->cid.len = QUIC_HAP_CID_LEN;
 
        if (!orig) {
-               /* TODO: RAND_bytes() should be replaced */
-               if (RAND_bytes(conn_id->cid.data, conn_id->cid.len) != 1) {
+               if (quic_newcid_from_hash64)
+                       quic_newcid_from_hash64(conn_id->cid.data, conn_id->cid.len, qc->hash64,
+                                               global.cluster_secret, sizeof(global.cluster_secret));
+               else if (RAND_bytes(conn_id->cid.data, conn_id->cid.len) != 1) {
+                       /* TODO: RAND_bytes() should be replaced */
                        TRACE_ERROR("RAND_bytes() failed", QUIC_EV_CONN_TXPKT, qc);
                        goto err;
                }
index 39271a0fd41d287be981ef9c75b1efa1fd05f9bb..7dbf94d808242f2775697c436e1de56fae905956 100644 (file)
@@ -1964,6 +1964,11 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
                                goto err;
                        }
 
+                       /* Compute and store into the quic_conn the hash used to compute extra CIDs */
+                       if (quic_hash64_from_cid)
+                               qc->hash64 = quic_hash64_from_cid(conn_id->cid.data, conn_id->cid.len,
+                                                                 global.cluster_secret, sizeof(global.cluster_secret));
+
                        tree = &quic_cid_trees[quic_cid_tree_idx(&conn_id->cid)];
                        HA_RWLOCK_WRLOCK(QC_CID_LOCK, &tree->lock);
                        node = ebmb_insert(&tree->root, &conn_id->node, conn_id->cid.len);