diff --git a/include/haproxy/connection-t.h b/include/haproxy/connection-t.h index a8239b43f..9ee00819b 100644 --- a/include/haproxy/connection-t.h +++ b/include/haproxy/connection-t.h @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -471,8 +472,7 @@ struct conn_stream { * CAUTION! Always update CONN_HASH_PARAMS_TYPE_COUNT when adding a new entry. */ enum conn_hash_params_t { - /* to remove as soon as one useful parameter is present */ - CONN_HASH_DUMMY_PARAM, + CONN_HASH_PARAMS_TYPE_SNI = 0x1, }; #define CONN_HASH_PARAMS_TYPE_COUNT 1 @@ -488,6 +488,7 @@ enum conn_hash_params_t { */ struct conn_hash_params { struct server *srv; + XXH64_hash_t *sni_prehash; }; /* This structure describes a connection with its methods and data. diff --git a/src/backend.c b/src/backend.c index fed177c9b..d9d5c97e1 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1246,8 +1246,10 @@ int connect_server(struct stream *s) int reuse = 0; int init_mux = 0; int err; + struct sample *sni_smp = NULL; int64_t hash = 0; struct conn_hash_params hash_params; + XXH64_hash_t sni_hash; /* first, set unique connection parameters and then calculate hash */ memset(&hash_params, 0, sizeof(hash_params)); @@ -1255,6 +1257,20 @@ int connect_server(struct stream *s) srv = objt_server(s->target); hash_params.srv = srv; +#ifdef USE_OPENSSL + /* 1. sni */ + 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 (smp_make_safe(sni_smp)) { + sni_hash = conn_hash_prehash(sni_smp->data.u.str.area, + sni_smp->data.u.str.data); + hash_params.sni_prehash = &sni_hash; + } + } +#endif /* USE_OPENSSL */ + if (srv) hash = conn_calculate_hash(&hash_params); @@ -1547,19 +1563,8 @@ skip_reuse: return err; #ifdef USE_OPENSSL - if (srv && srv->ssl_ctx.sni) { - struct sample *smp; - - 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(smp)) { - ssl_sock_set_servername(srv_conn, smp->data.u.str.area); - if (!(srv->ssl_ctx.sni->fetch->use & SMP_USE_INTRN) || - smp->flags & SMP_F_VOLATILE) { - conn_set_private(srv_conn); - } - } - } + if (smp_make_safe(sni_smp)) + ssl_sock_set_servername(srv_conn, sni_smp->data.u.str.area); #endif /* USE_OPENSSL */ /* The CO_FL_SEND_PROXY flag may have been set by the connect method, diff --git a/src/connection.c b/src/connection.c index 3656b3636..6126dd180 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1423,6 +1423,12 @@ XXH64_hash_t conn_calculate_hash(const struct conn_hash_params *params) conn_hash_update(buf, &idx, ¶ms->srv, sizeof(params->srv), &hash_flags, 0); + if (params->sni_prehash) { + conn_hash_update(buf, &idx, + params->sni_prehash, sizeof(*params->sni_prehash), + &hash_flags, CONN_HASH_PARAMS_TYPE_SNI); + } + hash = conn_hash_digest(buf, idx, hash_flags); return hash; }