]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: refactor quic CID association with threads
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 28 Jan 2022 15:02:13 +0000 (16:02 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 28 Jan 2022 15:29:27 +0000 (16:29 +0100)
Do not use an extra DCID parameter on new_quic_cid to be able to
associated a new generated CID to a thread ID. Simply do the computation
inside the function. The API is cleaner this way.

This also has the effects to improve the apparent randomness of CIDs.
With the previous version the first byte of all CIDs are identical for a
connection which could lead to privacy issue. This version may not be
totally perfect on this aspect but it improves the situation.

include/haproxy/xprt_quic.h
src/xprt_quic.c

index d8f23bd1ff1cd80fc42ca168a7ec79d02047e6cd..4107fbe8383fa24fd6594234f290563709073ee4 100644 (file)
@@ -132,12 +132,6 @@ static inline void quic_cid_dump(struct buffer *buf,
        chunk_appendf(buf, ")");
 }
 
-/* Simply compute a thread ID from a CID */
-static inline unsigned long quic_get_cid_tid(const unsigned char *cid)
-{
-       return *cid % global.nbthread;
-}
-
 /* Free the CIDs attached to <conn> QUIC connection. This must be called under
  * the CID lock.
  */
@@ -177,13 +171,32 @@ static inline void quic_connection_id_to_frm_cpy(struct quic_frame *dst,
        to->stateless_reset_token = src->stateless_reset_token;
 }
 
+/* Retrieve the associated thread ID for <cid>. */
+static inline unsigned long quic_get_cid_tid(const unsigned char *cid)
+{
+       return *cid % global.nbthread;
+}
+
+/* Modify <cid> to have a CID linked to the thread ID <target_tid>. This is
+ * based on quic_get_cid_tid.
+ */
+static inline void quic_pin_cid_to_tid(unsigned char *cid, int target_tid)
+{
+       cid[0] = cid[0] - (cid[0] % global.nbthread) + target_tid;
+}
+
 /* Allocate a new CID with <seq_num> as sequence number and attach it to <root>
  * ebtree.
+ *
+ * The CID is randomly generated in part with the result altered to be
+ * associated with the current thread ID. This means this function must only
+ * be called by the quic_conn thread.
+ *
  * Returns the new CID if succeeded, NULL if not.
  */
 static inline struct quic_connection_id *new_quic_cid(struct eb_root *root,
                                                       struct quic_conn *qc,
-                                                      int seq_num, unsigned char *dcid)
+                                                      int seq_num)
 {
        struct quic_connection_id *cid;
 
@@ -199,8 +212,7 @@ static inline struct quic_connection_id *new_quic_cid(struct eb_root *root,
                goto err;
        }
 
-       /* Set the same first octet from <dcid> */
-       cid->cid.data[0] = *dcid;
+       quic_pin_cid_to_tid(cid->cid.data, tid);
 
        cid->qc = qc;
 
index caea3e67c75aa95e39526b79a09a297c38f4871c..a1fa7dbdecdf918658c5e79b84a284c7f34e8369 100644 (file)
@@ -2806,7 +2806,7 @@ static int quic_build_post_handshake_frames(struct quic_conn *qc)
                if (!frm)
                        goto err;
 
-               cid = new_quic_cid(&qc->cids, qc, i, qc->scid.data);
+               cid = new_quic_cid(&qc->cids, qc, i);
                if (!cid)
                        goto err;
 
@@ -3605,7 +3605,7 @@ static struct quic_conn *qc_new_conn(unsigned int version, int ipv4,
        /* Initialize the output buffer */
        qc->obuf.pos = qc->obuf.data;
 
-       icid = new_quic_cid(&qc->cids, qc, 0, dcid);
+       icid = new_quic_cid(&qc->cids, qc, 0);
        if (!icid) {
                TRACE_PROTO("Could not allocate a new connection ID", QUIC_EV_CONN_INIT, qc);
                goto err;