This is an automated email from the ASF dual-hosted git repository.
bneradt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new c9a433daf9 Update SNI for origin side connections (#12231)
c9a433daf9 is described below
commit c9a433daf94b28b653f3948ab1c856cce8a47d9b
Author: Brian Neradt <[email protected]>
AuthorDate: Mon May 12 17:21:52 2025 -0500
Update SNI for origin side connections (#12231)
Origin side connection pooling was not able to access the appropriate
SNI of those connections, resulting in those connections not being able
to be reused appropriately. This addresses that issue by setting the
internal SNI buffer for those connections to the appropriate SNI so that
the origin conection pooling feature has access to the SNI value.
This also populates the SNI buffer when an SSLNetVConnection is bound to
an SSL object.
Fixes: #12214
---
include/iocore/net/TLSSNISupport.h | 24 +++++++++++++++++++++++-
src/iocore/net/SSLNetVConnection.cc | 2 +-
src/iocore/net/TLSSNISupport.cc | 27 ++++++++++++++++++++++++---
3 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/include/iocore/net/TLSSNISupport.h
b/include/iocore/net/TLSSNISupport.h
index fbba3810d5..6897cce36a 100644
--- a/include/iocore/net/TLSSNISupport.h
+++ b/include/iocore/net/TLSSNISupport.h
@@ -58,9 +58,31 @@ public:
int perform_sni_action(SSL &ssl);
// Callback functions for OpenSSL libraries
+
+ /** Process a CLIENT_HELLO from a client.
+ *
+ * This is for client-side connections.
+ */
void on_client_hello(ClientHello &client_hello);
+
+ /** Process the servername extension when a client uses one in the TLS
handshake.
+ *
+ * This is for client-side connections.
+ */
void on_servername(SSL *ssl, int *al, void *arg);
+ /** Set the servername extension for server-side connections.
+ *
+ * This is for server-side connections.
+ * This calls SSL_set_tlsext_host_name() to set the servername extension.
+ *
+ * @param ssl The SSL object upon which the servername extension is set.
+ * @param name The servername to set. This is assumed to be a non-empty,
+ * null-terminated string.
+ * @return True if the servername was set successfully, false otherwise.
+ */
+ bool set_sni_server_name(SSL *ssl, char const *name);
+
/**
* Get the server name in SNI
*
@@ -92,5 +114,5 @@ private:
// Null-terminated string, or nullptr if there is no SNI server name.
std::unique_ptr<char[]> _sni_server_name;
- void _set_sni_server_name(std::string_view name);
+ void _set_sni_server_name_buffer(std::string_view name);
};
diff --git a/src/iocore/net/SSLNetVConnection.cc
b/src/iocore/net/SSLNetVConnection.cc
index 69ea874101..6b877b3fdb 100644
--- a/src/iocore/net/SSLNetVConnection.cc
+++ b/src/iocore/net/SSLNetVConnection.cc
@@ -1146,7 +1146,7 @@ SSLNetVConnection::sslStartHandShake(int event, int &err)
// SNI
ats_scoped_str &tlsext_host_name = this->options.sni_hostname ?
this->options.sni_hostname : this->options.sni_servername;
if (tlsext_host_name) {
- if (SSL_set_tlsext_host_name(this->ssl, tlsext_host_name)) {
+ if (this->set_sni_server_name(this->ssl, tlsext_host_name)) {
Dbg(dbg_ctl_ssl, "using SNI name '%s' for client handshake",
tlsext_host_name.get());
} else {
Dbg(dbg_ctl_ssl_error, "failed to set SNI name '%s' for client
handshake", tlsext_host_name.get());
diff --git a/src/iocore/net/TLSSNISupport.cc b/src/iocore/net/TLSSNISupport.cc
index 18c7d0deab..ee5e4a8c44 100644
--- a/src/iocore/net/TLSSNISupport.cc
+++ b/src/iocore/net/TLSSNISupport.cc
@@ -54,6 +54,12 @@ void
TLSSNISupport::bind(SSL *ssl, TLSSNISupport *snis)
{
SSL_set_ex_data(ssl, _ex_data_index, snis);
+ char const *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+ if (servername) {
+ snis->_set_sni_server_name_buffer(servername);
+ } else {
+ snis->_clear();
+ }
}
void
@@ -118,7 +124,7 @@ TLSSNISupport::on_client_hello(ClientHello &client_hello)
}
}
if (servername) {
- this->_set_sni_server_name(std::string_view(servername, len));
+ this->_set_sni_server_name_buffer(std::string_view(servername, len));
}
}
@@ -127,8 +133,23 @@ TLSSNISupport::on_servername(SSL *ssl, int * /* al
ATS_UNUSED */, void * /* arg
{
const char *name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
if (name) {
- this->_set_sni_server_name(name);
+ this->_set_sni_server_name_buffer(name);
+ }
+}
+
+bool
+TLSSNISupport::set_sni_server_name(SSL *ssl, char const *name)
+{
+ if (name == nullptr || strnlen(name, 256) == 0) {
+ Dbg(dbg_ctl_ssl_sni, "Empty servername provided, not setting SNI");
+ return false;
+ }
+ if (SSL_set_tlsext_host_name(ssl, name) != 1) {
+ Dbg(dbg_ctl_ssl_sni, "SSL_set_tlsext_host_name failed to set %s", name);
+ return false;
}
+ this->_set_sni_server_name_buffer(name);
+ return true;
}
void
@@ -144,7 +165,7 @@ TLSSNISupport::get_sni_server_name() const
}
void
-TLSSNISupport::_set_sni_server_name(std::string_view name)
+TLSSNISupport::_set_sni_server_name_buffer(std::string_view name)
{
if (name.size()) {
char *n = new char[name.size() + 1];