diff --git a/include/haproxy/protocol-t.h b/include/haproxy/protocol-t.h index b0765cf87..e49a239ce 100644 --- a/include/haproxy/protocol-t.h +++ b/include/haproxy/protocol-t.h @@ -113,6 +113,7 @@ struct protocol { 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 5fe714ba5..07c7f92ea 100644 --- a/src/listener.c +++ b/src/listener.c @@ -1194,6 +1194,13 @@ void listener_accept(struct listener *l) 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