From 1723e21af21e9f1f53f890b4fe999f1e83b3d448 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 22 Aug 2023 16:58:55 +0200 Subject: [PATCH] MINOR: connection: use attach-srv name as SNI reuse parameter on reverse On connection passive reverse from frontend to backend, its hash node is calculated to be able to select it from the idle server pool. If attach-srv rule defined an associated name, reuse it as the value for SNI prehash. This change allows a client to select a reverse connection by its name by configuring its server line with a SNI to permit this. --- include/haproxy/connection-t.h | 3 ++- src/connection.c | 15 +++++++++++++++ src/tcp_act.c | 19 +++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/include/haproxy/connection-t.h b/include/haproxy/connection-t.h index 98a010e..cf4ec5a 100644 --- a/include/haproxy/connection-t.h +++ b/include/haproxy/connection-t.h @@ -546,7 +546,8 @@ struct connection { /* Members used if connection must be reversed. */ struct { - enum obj_type *target; /* Server for passive reverse. */ + enum obj_type *target; /* Listener for active reverse, server for passive. */ + struct buffer name; /* Only used for passive reverse. Used as SNI when connection added to server idle pool. */ } reverse; }; diff --git a/src/connection.c b/src/connection.c index f6ac7db..6363ff7 100644 --- a/src/connection.c +++ b/src/connection.c @@ -436,6 +436,7 @@ void conn_init(struct connection *conn, void *target) conn->hash_node = NULL; conn->xprt = NULL; conn->reverse.target = NULL; + conn->reverse.name = BUF_NULL; } /* Initialize members used for backend connections. @@ -531,6 +532,8 @@ void conn_free(struct connection *conn) pool_free(pool_head_uniqueid, istptr(conn->proxy_unique_id)); conn->proxy_unique_id = IST_NULL; + ha_free(&conn->reverse.name.area); + conn_force_unsubscribe(conn); pool_free(pool_head_connection, conn); } @@ -2461,6 +2464,15 @@ int conn_reverse(struct connection *conn) memset(&hash_params, 0, sizeof(hash_params)); hash_params.target = srv; + if (b_data(&conn->reverse.name)) { + /* data cannot wrap else prehash usage is incorrect */ + BUG_ON(b_data(&conn->reverse.name) != b_contig_data(&conn->reverse.name, 0)); + + hash_params.sni_prehash = + conn_hash_prehash(b_head(&conn->reverse.name), + b_data(&conn->reverse.name)); + } + hash = conn_calculate_hash(&hash_params); conn->hash_node->node.key = hash; @@ -2481,6 +2493,9 @@ int conn_reverse(struct connection *conn) SWAP(conn->src, conn->dst); conn->reverse.target = NULL; + ha_free(&conn->reverse.name.area); + conn->reverse.name = BUF_NULL; + return 0; } diff --git a/src/tcp_act.c b/src/tcp_act.c index ab06499..291f704 100644 --- a/src/tcp_act.c +++ b/src/tcp_act.c @@ -44,11 +44,30 @@ static enum act_return tcp_action_attach_srv(struct act_rule *rule, struct proxy struct session *sess, struct stream *s, int flags) { struct server *srv = rule->arg.attach_srv.srv; + struct sample *name_smp; struct connection *conn = objt_conn(sess->origin); if (!conn) return ACT_RET_ABRT; conn_set_reverse(conn, &srv->obj_type); + + if (rule->arg.attach_srv.name) { + name_smp = sample_fetch_as_type(sess->fe, sess, s, + SMP_OPT_DIR_REQ | SMP_OPT_FINAL, + rule->arg.attach_srv.name, SMP_T_STR); + /* TODO strdup du buffer du sample */ + if (name_smp) { + struct buffer *buf = &name_smp->data.u.str; + char *area = malloc(b_data(buf)); + + if (!area) + return ACT_RET_ERR; + + conn->reverse.name = b_make(area, b_data(buf), 0, 0); + b_ncat(&conn->reverse.name, buf, b_data(buf)); + } + } + return ACT_RET_CONT; } -- 1.7.10.4