MEDIUM: connection: use pool-conn-name instead of sni on reuse

Implement pool-conn-name support for idle connection reuse. It replaces
SNI as arbitrary identifier for connections in the idle pool. Thus,
every SNI reference in this context have been replaced.

Main change occurs in connect_server() where pool-conn-name sample fetch
is now prehash to generate idle connection identifier. SNI is now solely
used in the context of SSL for ssl_sock_set_servername().
This commit is contained in:
Amaury Denoyelle 2024-05-23 18:31:48 +02:00
parent be4f89f2b2
commit 47168e217a
4 changed files with 25 additions and 28 deletions

View File

@ -473,7 +473,7 @@ struct conn_src {
* CAUTION! Always update CONN_HASH_PARAMS_TYPE_COUNT when adding a new entry.
*/
enum conn_hash_params_t {
CONN_HASH_PARAMS_TYPE_SNI = 0x1,
CONN_HASH_PARAMS_TYPE_NAME = 0x1,
CONN_HASH_PARAMS_TYPE_DST_ADDR = 0x2,
CONN_HASH_PARAMS_TYPE_DST_PORT = 0x4,
CONN_HASH_PARAMS_TYPE_SRC_ADDR = 0x8,
@ -494,7 +494,7 @@ enum conn_hash_params_t {
* connection hash.
*/
struct conn_hash_params {
uint64_t sni_prehash;
uint64_t name_prehash;
uint64_t proxy_prehash;
uint64_t mark_tos_prehash;
void *target;

View File

@ -97,7 +97,7 @@ void sockaddr_free(struct sockaddr_storage **sap);
/* connection hash stuff */
uint64_t conn_calculate_hash(const struct conn_hash_params *params);
uint64_t conn_hash_prehash(char *buf, size_t size);
uint64_t conn_hash_prehash(const char *buf, size_t size);
int conn_reverse(struct connection *conn);

View File

@ -1349,9 +1349,7 @@ int connect_server(struct stream *s)
int reuse = 0;
int init_mux = 0;
int err;
#ifdef USE_OPENSSL
struct sample *sni_smp = NULL;
#endif
struct sample *name_smp = NULL;
struct sockaddr_storage *bind_addr = NULL;
int proxy_line_ret;
int64_t hash = 0;
@ -1373,13 +1371,11 @@ int connect_server(struct stream *s)
if (err != SRV_STATUS_OK)
return SF_ERR_INTERNAL;
#ifdef USE_OPENSSL
if (srv && srv->ssl_ctx.sni) {
sni_smp = sample_fetch_as_type(s->be, s->sess, s,
SMP_OPT_DIR_REQ | SMP_OPT_FINAL,
srv->ssl_ctx.sni, SMP_T_STR);
if (srv && srv->pool_conn_name_expr) {
name_smp = sample_fetch_as_type(s->be, s->sess, s,
SMP_OPT_DIR_REQ | SMP_OPT_FINAL,
srv->pool_conn_name_expr, SMP_T_STR);
}
#endif
/* do not reuse if mode is not http */
if (!IS_HTX_STRM(s)) {
@ -1403,17 +1399,12 @@ int connect_server(struct stream *s)
/* 1. target */
hash_params.target = s->target;
#ifdef USE_OPENSSL
/* 2. sni
* only test if the sample is not null as smp_make_safe (called before
* ssl_sock_set_servername) can only fails if this is not the case
*/
if (sni_smp) {
hash_params.sni_prehash =
conn_hash_prehash(sni_smp->data.u.str.area,
sni_smp->data.u.str.data);
/* 2. pool-conn-name */
if (name_smp) {
hash_params.name_prehash =
conn_hash_prehash(name_smp->data.u.str.area,
name_smp->data.u.str.data);
}
#endif /* USE_OPENSSL */
/* 3. destination address */
if (srv && srv_is_transparent(srv))
@ -1787,7 +1778,13 @@ int connect_server(struct stream *s)
return err;
#ifdef USE_OPENSSL
if (!(s->flags & SF_SRV_REUSED)) {
/* Set socket SNI unless connection is reused. */
if (srv && srv->ssl_ctx.sni && !(s->flags & SF_SRV_REUSED)) {
struct sample *sni_smp = NULL;
sni_smp = sample_fetch_as_type(s->be, s->sess, s,
SMP_OPT_DIR_REQ | SMP_OPT_FINAL,
srv->ssl_ctx.sni, SMP_T_STR);
if (smp_make_safe(sni_smp))
ssl_sock_set_servername(srv_conn, sni_smp->data.u.str.area);
}

View File

@ -2621,7 +2621,7 @@ INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
/* Generate the hash of a connection with params as input
* Each non-null field of params is taken into account for the hash calcul.
*/
uint64_t conn_hash_prehash(char *buf, size_t size)
uint64_t conn_hash_prehash(const char *buf, size_t size)
{
return XXH64(buf, size, 0);
}
@ -2699,10 +2699,10 @@ uint64_t conn_calculate_hash(const struct conn_hash_params *params)
conn_hash_update(&hash, &params->target, sizeof(params->target), &hash_flags, 0);
if (params->sni_prehash) {
if (params->name_prehash) {
conn_hash_update(&hash,
&params->sni_prehash, sizeof(params->sni_prehash),
&hash_flags, CONN_HASH_PARAMS_TYPE_SNI);
&params->name_prehash, sizeof(params->name_prehash),
&hash_flags, CONN_HASH_PARAMS_TYPE_NAME);
}
if (params->dst_addr) {
@ -2770,7 +2770,7 @@ int conn_reverse(struct connection *conn)
/* 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 =
hash_params.name_prehash =
conn_hash_prehash(b_head(&conn->reverse.name),
b_data(&conn->reverse.name));
}