]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: support migrating the listener as well
authorWilly Tarreau <w@1wt.eu>
Thu, 20 Apr 2023 17:03:49 +0000 (19:03 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 21 Apr 2023 15:41:26 +0000 (17:41 +0200)
When migrating a quic_conn to another thread, we may need to also
switch the listener if the thread belongs to another group. When
this happens, the freshly created connection will already have the
target listener, so let's just pick it from the connection and use
it in qc_set_tid_affinity(). Note that it will be the caller's
responsibility to guarantee this.

include/haproxy/quic_conn.h
src/proto_quic.c
src/quic_conn.c

index 3764dceb9cfe0b3207f5f7da1e4bc81ea94c801c..bfd66c47075f4fe7a109383b584565e81b28000d 100644 (file)
@@ -700,7 +700,7 @@ static inline void quic_handle_stopping(void)
        }
 }
 
-int qc_set_tid_affinity(struct quic_conn *qc, uint tid);
+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);
 
 #endif /* USE_QUIC */
index 8c263772dc142429df04024c0143807f91b4040c..76583298e43d0a8217b73f594d68d3290c27c9d7 100644 (file)
@@ -707,10 +707,14 @@ static void quic_disable_listener(struct listener *l)
                fd_stop_recv(l->rx.fd);
 }
 
+/* change the connection's thread to <new_tid>. For frontend connections, the
+ * target is a listener, and the caller is responsible for guaranteeing that
+ * the listener assigned to the connection is bound to the requested thread.
+ */
 static int quic_set_affinity(struct connection *conn, int new_tid)
 {
        struct quic_conn *qc = conn->handle.qc;
-       return qc_set_tid_affinity(qc, new_tid);
+       return qc_set_tid_affinity(qc, new_tid, objt_listener(conn->target));
 }
 
 static int quic_alloc_dghdlrs(void)
index 314c978c4eb505aa6a29bdb20b237f678da88684..b474e7209c20280a078c34e7f0e75b3dbf1bae4b 100644 (file)
@@ -8391,12 +8391,14 @@ int qc_notify_send(struct quic_conn *qc)
 }
 
 /* Move a <qc> QUIC connection and its resources from the current thread to the
- * new one <new_tid>. After this call, the connection cannot be dereferenced
- * anymore on the current thread.
+ * new one <new_tid> optionally in association with <new_li> (since it may need
+ * to change when migrating to a thread from a different group, otherwise leave
+ * it NULL). After this call, the connection cannot be dereferenced anymore on
+ * the current thread.
  *
  * Returns 0 on success else non-zero.
  */
-int qc_set_tid_affinity(struct quic_conn *qc, uint new_tid)
+int qc_set_tid_affinity(struct quic_conn *qc, uint new_tid, struct listener *new_li)
 {
        struct task *t1 = NULL, *t2 = NULL;
        struct tasklet *t3 = NULL;
@@ -8457,6 +8459,13 @@ int qc_set_tid_affinity(struct quic_conn *qc, uint new_tid)
        node = eb64_first(&qc->cids);
        BUG_ON(!node || eb64_next(node)); /* One and only one CID must be present before affinity rebind. */
        conn_id = eb64_entry(node, struct quic_connection_id, seq_num);
+
+       /* At this point no connection was accounted for yet on this
+        * listener so it's OK to just swap the pointer.
+        */
+       if (new_li && new_li != qc->li)
+               qc->li = new_li;
+
        /* Rebinding is considered done when CID points to the new thread. No
         * access should be done to quic-conn instance after it.
         */