MINOR: connection/ssl: Store the SNI hash value in the connection itself

When a SNI is set on a new connection, its hash is now saved in the
connection itself. To do so, a dedicated field was added into the connection
strucutre, called sni_hash. For now, this value is only used when the TLS
session is cached.
This commit is contained in:
Christopher Faulet 2025-12-05 11:04:21 +01:00
parent 92f77cb3e6
commit 28654f3c9b
5 changed files with 20 additions and 9 deletions

View file

@ -660,6 +660,7 @@ struct connection {
struct buffer name; /* Only used for passive reverse. Used as SNI when connection added to server idle pool. */
} reverse;
uint64_t sni_hash; /* Hash of the SNI. Used to cache the TLS session and try to reuse it. set to 0 is there is no SNI */
uint32_t term_evts_log; /* Termination events log: first 4 events reported from fd, handshake or xprt */
uint32_t mark; /* set network mark, if CO_FL_OPT_MARK is set */
uint8_t tos; /* set ip tos, if CO_FL_OPT_TOS is set */

View file

@ -2162,8 +2162,11 @@ int connect_server(struct stream *s)
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))
if (smp_make_safe(sni_smp)) {
srv_conn->sni_hash = ssl_sock_sni_hash(ist2(b_orig(&sni_smp->data.u.str),
b_data(&sni_smp->data.u.str)));
ssl_sock_set_servername(srv_conn, sni_smp->data.u.str.area);
}
}
#endif /* USE_OPENSSL */

View file

@ -520,6 +520,7 @@ void conn_init(struct connection *conn, void *target)
conn->xprt = NULL;
conn->reverse.target = NULL;
conn->reverse.name = BUF_NULL;
conn->sni_hash = 0;
}
/* Initialize members used for backend connections.

View file

@ -4202,7 +4202,6 @@ static int ssl_sess_new_srv_cb(SSL *ssl, SSL_SESSION *sess)
int len;
unsigned char *ptr;
const char *sni;
uint64_t sni_hash;
#ifdef USE_QUIC
struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
#endif
@ -4247,11 +4246,10 @@ static int ssl_sess_new_srv_cb(SSL *ssl, SSL_SESSION *sess)
else if (s->ssl_ctx.reused_sess[tid].ptr && !old_tid)
HA_ATOMIC_CAS(&s->ssl_ctx.last_ssl_sess_tid, &old_tid, tid + 1);
sni_hash = (sni ? ssl_sock_sni_hash(ist(sni)) : 0);
if (s->ssl_ctx.reused_sess[tid].sni_hash != sni_hash) {
/* if the new sni hash isn' t the same as the old one */
s->ssl_ctx.reused_sess[tid].sni_hash = sni_hash;
if (s->ssl_ctx.reused_sess[tid].sni_hash != conn->sni_hash) {
/* if the new sni hash or isn' t the same as the old one */
ha_free(&s->ssl_ctx.reused_sess[tid].sni);
s->ssl_ctx.reused_sess[tid].sni_hash = conn->sni_hash;
if (sni)
s->ssl_ctx.reused_sess[tid].sni = strdup(sni);
}

View file

@ -1280,6 +1280,9 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
struct buffer *auto_sni = NULL;
int status, port;
int check_type;
#ifdef USE_OPENSSL
struct ist sni = IST_NULL;
#endif
TRACE_ENTER(CHK_EV_TCPCHK_CONN, check);
@ -1504,11 +1507,16 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
#ifdef USE_OPENSSL
if (conn_is_ssl(conn)) {
if (connect->sni)
ssl_sock_set_servername(conn, connect->sni);
sni = ist(connect->sni);
else if ((connect->options & TCPCHK_OPT_DEFAULT_CONNECT) && s && s->check.sni)
ssl_sock_set_servername(conn, s->check.sni);
sni = ist(s->check.sni);
else if (auto_sni)
ssl_sock_set_servername(conn, b_orig(auto_sni));
sni = ist2(b_orig(auto_sni), b_data(auto_sni));
if (isttest(sni)) {
conn->sni_hash = ssl_sock_sni_hash(sni);
ssl_sock_set_servername(conn, istptr(sni));
}
if (connect->alpn)
ssl_sock_set_alpn(conn, (unsigned char *)connect->alpn, connect->alpn_len);