From b7fa502360acc757aa96010359cea6efb2112902 Mon Sep 17 00:00:00 2001 From: Vishal Kumar Singh Date: Sat, 16 May 2026 12:34:33 +0530 Subject: [PATCH] feat(tls): add SNI to SslDigest This adds the SNI (Server Name Indication) to the SslDigest struct, making it accessible in the HTTP filter context via session.digest(). The SNI is extracted during TLS handshake for the boringssl/openssl backend. The rustls and s2n backends pass None for now and can be extended in future work. Users can now access the SNI in their request_filter callback: if let Some(digest) = session.digest() { if let Some(ssl_digest) = &digest.ssl_digest { if let Some(sni) = &ssl_digest.sni { // Use SNI for routing/validation logic } } } Fixes #547 --- pingora-core/src/protocols/tls/boringssl_openssl/stream.rs | 6 +++++- pingora-core/src/protocols/tls/digest.rs | 4 ++++ pingora-core/src/protocols/tls/rustls/stream.rs | 5 ++++- pingora-core/src/protocols/tls/s2n/stream.rs | 4 ++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/pingora-core/src/protocols/tls/boringssl_openssl/stream.rs b/pingora-core/src/protocols/tls/boringssl_openssl/stream.rs index 894244c0..bb021926 100644 --- a/pingora-core/src/protocols/tls/boringssl_openssl/stream.rs +++ b/pingora-core/src/protocols/tls/boringssl_openssl/stream.rs @@ -209,7 +209,11 @@ impl SslDigest { None => (Vec::new(), None, None), }; - SslDigest::new(cipher, ssl.version_str(), org, sn, cert_digest) + let sni = ssl + .servername(ssl::NameType::HOST_NAME) + .map(ToOwned::to_owned); + + SslDigest::new(cipher, ssl.version_str(), org, sn, cert_digest, sni) } } diff --git a/pingora-core/src/protocols/tls/digest.rs b/pingora-core/src/protocols/tls/digest.rs index 58ecf3b6..709d19fe 100644 --- a/pingora-core/src/protocols/tls/digest.rs +++ b/pingora-core/src/protocols/tls/digest.rs @@ -31,6 +31,8 @@ pub struct SslDigest { pub serial_number: Option, /// The digest of the peer's certificate pub cert_digest: Vec, + /// The SNI used during the TLS handshake + pub sni: Option, /// The user-defined TLS data pub extension: SslDigestExtension, } @@ -43,6 +45,7 @@ impl SslDigest { organization: Option, serial_number: Option, cert_digest: Vec, + sni: Option, ) -> Self where S: Into>, @@ -53,6 +56,7 @@ impl SslDigest { organization, serial_number, cert_digest, + sni, extension: SslDigestExtension::default(), } } diff --git a/pingora-core/src/protocols/tls/rustls/stream.rs b/pingora-core/src/protocols/tls/rustls/stream.rs index f2a0ddae..92d34889 100644 --- a/pingora-core/src/protocols/tls/rustls/stream.rs +++ b/pingora-core/src/protocols/tls/rustls/stream.rs @@ -390,7 +390,10 @@ impl SslDigest { .map(|(organization, serial)| (organization, Some(serial))) .unwrap_or_default(); - SslDigest::new(cipher, version, organization, serial_number, cert_digest) + // SNI extraction not yet implemented for rustls + let sni = None; + + SslDigest::new(cipher, version, organization, serial_number, cert_digest, sni) } } diff --git a/pingora-core/src/protocols/tls/s2n/stream.rs b/pingora-core/src/protocols/tls/s2n/stream.rs index 3f12ea44..be1cb119 100644 --- a/pingora-core/src/protocols/tls/s2n/stream.rs +++ b/pingora-core/src/protocols/tls/s2n/stream.rs @@ -307,12 +307,16 @@ impl SslDigest { } } + // SNI extraction not yet implemented for s2n + let sni = None; + SslDigest::new( cipher, version, organization, serial_number, cert_digest.unwrap_or_default(), + sni, ) } }