From: Christopher Faulet Date: Fri, 5 Dec 2025 10:10:53 +0000 (+0100) Subject: MEDIUM: tcpcheck/backend: Get the connection SNI before initializing SSL ctx X-Git-Tag: v3.4-dev1~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e9d921141e03e99131364e8c70e85109ab06de3;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/src/backend.c b/src/backend.c index d84a5f524..9722b71b9 100644 --- a/src/backend.c +++ b/src/backend.c @@ -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. */ diff --git a/src/tcpcheck.c b/src/tcpcheck.c index d0fd31cfe..97b909ea6 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -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);