MEDIUM: tcpcheck/backend: Get the connection SNI before initializing SSL ctx

The SNI of a new connection is now retrieved earlier, before the
initialization of the SSL context. So, concretely, it is now performed
before calling conn_prepare(). The SNI is then set just after.
This commit is contained in:
Christopher Faulet 2025-12-05 11:10:53 +01:00
parent 28654f3c9b
commit 7e9d921141
2 changed files with 35 additions and 26 deletions

View File

@ -2037,11 +2037,31 @@ int connect_server(struct stream *s)
if (srv) {
struct protocol *proto = protocol_lookup(srv_conn->dst->ss_family, srv->addr_type.proto_type, srv->alt_proto);
#ifdef USE_OPENSSL
struct sample *sni_smp = NULL;
struct ist sni = IST_NULL;
/* Set socket SNI */
if (srv->xprt && srv->xprt->get_ssl_sock_ctx && 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 = ist2(b_orig(&sni_smp->data.u.str), b_data(&sni_smp->data.u.str));
srv_conn->sni_hash = ssl_sock_sni_hash(sni);
}
}
#endif /* USE_OPENSSL */
if (conn_prepare(srv_conn, proto, srv->xprt)) {
conn_free(srv_conn);
return SF_ERR_INTERNAL;
}
#ifdef USE_OPENSSL
if (isttest(sni))
ssl_sock_set_servername(srv_conn, istptr(sni));
#endif
} else if (obj_type(s->target) == OBJ_TYPE_PROXY) {
int ret;
@ -2154,22 +2174,6 @@ int connect_server(struct stream *s)
if (err != SF_ERR_NONE)
return err;
#ifdef USE_OPENSSL
/* Set socket SNI unless connection is reused. */
if (conn_is_ssl(srv_conn) && 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)) {
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 */
/* The CO_FL_SEND_PROXY flag may have been set by the connect method,
* if so, add our handshake pseudo-XPRT now.
*/

View File

@ -1459,6 +1459,20 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
? xprt_get(XPRT_SSL)
: ((connect->options & TCPCHK_OPT_DEFAULT_CONNECT) ? check->xprt : xprt_get(XPRT_RAW)));
#ifdef USE_OPENSSL
if (xprt && xprt->get_ssl_sock_ctx) {
if (connect->sni)
sni = ist(connect->sni);
else if ((connect->options & TCPCHK_OPT_DEFAULT_CONNECT) && s && s->check.sni)
sni = ist(s->check.sni);
else if (auto_sni)
sni = ist2(b_orig(auto_sni), b_data(auto_sni));
if (isttest(sni))
conn->sni_hash = ssl_sock_sni_hash(sni);
}
#endif
if (conn_prepare(conn, proto, xprt) < 0) {
TRACE_ERROR("xprt allocation error", CHK_EV_TCPCHK_CONN|CHK_EV_TCPCHK_ERR, check);
status = SF_ERR_RESOURCE;
@ -1506,17 +1520,8 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
#ifdef USE_OPENSSL
if (conn_is_ssl(conn)) {
if (connect->sni)
sni = ist(connect->sni);
else if ((connect->options & TCPCHK_OPT_DEFAULT_CONNECT) && s && s->check.sni)
sni = ist(s->check.sni);
else if (auto_sni)
sni = ist2(b_orig(auto_sni), b_data(auto_sni));
if (isttest(sni)) {
conn->sni_hash = ssl_sock_sni_hash(sni);
if (isttest(sni))
ssl_sock_set_servername(conn, istptr(sni));
}
if (connect->alpn)
ssl_sock_set_alpn(conn, (unsigned char *)connect->alpn, connect->alpn_len);