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.
This commit is contained in:
Amaury Denoyelle 2023-08-22 16:58:55 +02:00
parent 0b3758e18f
commit 1723e21af2
3 changed files with 36 additions and 1 deletions

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
}