MINOR: protocol: define new callback set_affinity
Define a new protocol callback set_affinity. This function is used
during listener_accept() to notify about a rebind on a new thread just
before pushing the connection on the selected thread queue. If the
callback fails, accept is done locally.
This change will be useful for protocols with state allocated before
accept is done. For the moment, only QUIC protocol is concerned. This
will allow to rebind the quic_conn to a new thread depending on its
load.
This should be backported up to 2.7 after a period of observation.
diff --git a/include/haproxy/protocol-t.h b/include/haproxy/protocol-t.h
index b0765cf..e49a239 100644
--- a/include/haproxy/protocol-t.h
+++ b/include/haproxy/protocol-t.h
@@ -113,6 +113,7 @@
void (*ignore_events)(struct connection *conn, int event_type); /* unsubscribe from socket events */
int (*get_src)(struct connection *conn, struct sockaddr *, socklen_t); /* retrieve connection's source address; -1=fail */
int (*get_dst)(struct connection *conn, struct sockaddr *, socklen_t); /* retrieve connection's dest address; -1=fail */
+ int (*set_affinity)(struct connection *conn, int new_tid);
/* functions acting on the receiver */
int (*rx_suspend)(struct receiver *rx); /* temporarily suspend this receiver for a soft restart */
diff --git a/src/listener.c b/src/listener.c
index 5fe714b..07c7f92 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -1194,6 +1194,13 @@
t1 += (t2 << 16);
} while (unlikely(!_HA_ATOMIC_CAS(&l->thr_idx, &t0, t1)));
+ if (l->rx.proto && l->rx.proto->set_affinity) {
+ if (l->rx.proto->set_affinity(cli_conn, base + t)) {
+ /* Failed migration, stay on the same thread. */
+ goto local_accept;
+ }
+ }
+
/* We successfully selected the best thread "t" for this
* connection. We use deferred accepts even if it's the
* local thread because tests show that it's the best