This is an automated email from the ASF dual-hosted git repository.

cmcfarlen pushed a commit to branch 10.2.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit ddc283c280b99965cc9b44a611d8acc6b987f181
Author: Mo Chen <[email protected]>
AuthorDate: Fri Jun 19 17:45:42 2026 -0500

    TLS: count handshake signatures by key type (#13289)
    
    A full TLS handshake runs an asymmetric signature whose cost depends on the
    server key type -- RSA being far heavier than ECDSA.  Count those signatures
    by key type to make that work visible; resumed handshakes skip the 
signature.
    
    Also add proxy.process.ssl.connections_closed, incremented once per 
SSL_free,
    to track TLS connection teardown volume.
    
    New counters:
      * proxy.process.ssl.handshake_sign_rsa / _ecdsa / _other
      * proxy.process.ssl.connections_closed
    
    (cherry picked from commit 7766ce2cc9a8e58a247201d6a3ce7b1d3e895a59)
---
 src/iocore/net/SSLNetVConnection.cc |  6 ++++++
 src/iocore/net/SSLStats.cc          |  4 ++++
 src/iocore/net/SSLStats.h           |  4 ++++
 src/iocore/net/TLSBasicSupport.cc   | 22 ++++++++++++++++++++++
 4 files changed, 36 insertions(+)

diff --git a/src/iocore/net/SSLNetVConnection.cc 
b/src/iocore/net/SSLNetVConnection.cc
index f92d29528f..b14462a4da 100644
--- a/src/iocore/net/SSLNetVConnection.cc
+++ b/src/iocore/net/SSLNetVConnection.cc
@@ -990,6 +990,12 @@ SSLNetVConnection::clear()
   client_sess.reset();
 
   if (ssl != nullptr) {
+    // clear() runs from free() once per VC recycle, so this is the single 
chokepoint where a TLS
+    // connection's SSL object is torn down -- count it as one connection 
close here. Blind-tunnel
+    // conversions free their SSL earlier (before any data) and continue as a 
tunnel rather than a
+    // close, so by here ssl is already null for them and they are not counted 
(they are tracked by
+    // the tunnel metrics instead).
+    Metrics::Counter::increment(ssl_rsb.connections_closed);
     SSL_free(ssl);
     ssl = nullptr;
   }
diff --git a/src/iocore/net/SSLStats.cc b/src/iocore/net/SSLStats.cc
index 0b9b94343d..20ddb97e85 100644
--- a/src/iocore/net/SSLStats.cc
+++ b/src/iocore/net/SSLStats.cc
@@ -262,6 +262,10 @@ SSLInitializeStatistics()
   ssl_rsb.total_sslv3                        = 
Metrics::Counter::createPtr("proxy.process.ssl.ssl_total_sslv3");
   ssl_rsb.total_success_handshake_count_in   = 
Metrics::Counter::createPtr("proxy.process.ssl.total_success_handshake_count_in");
   ssl_rsb.total_success_handshake_count_out  = 
Metrics::Counter::createPtr("proxy.process.ssl.total_success_handshake_count_out");
+  ssl_rsb.handshake_sign_rsa                 = 
Metrics::Counter::createPtr("proxy.process.ssl.handshake_sign_rsa");
+  ssl_rsb.handshake_sign_ecdsa               = 
Metrics::Counter::createPtr("proxy.process.ssl.handshake_sign_ecdsa");
+  ssl_rsb.handshake_sign_other               = 
Metrics::Counter::createPtr("proxy.process.ssl.handshake_sign_other");
+  ssl_rsb.connections_closed                 = 
Metrics::Counter::createPtr("proxy.process.ssl.connections_closed");
   ssl_rsb.total_ticket_keys_renewed          = 
Metrics::Counter::createPtr("proxy.process.ssl.total_ticket_keys_renewed");
   ssl_rsb.total_tickets_created              = 
Metrics::Counter::createPtr("proxy.process.ssl.total_tickets_created");
   ssl_rsb.total_tickets_not_found            = 
Metrics::Counter::createPtr("proxy.process.ssl.total_tickets_not_found");
diff --git a/src/iocore/net/SSLStats.h b/src/iocore/net/SSLStats.h
index 495092b7fb..c6a3b32bce 100644
--- a/src/iocore/net/SSLStats.h
+++ b/src/iocore/net/SSLStats.h
@@ -86,6 +86,10 @@ struct SSLStatsBlock {
   Metrics::Counter::AtomicType *total_sslv3                                    
= nullptr;
   Metrics::Counter::AtomicType *total_success_handshake_count_in               
= nullptr;
   Metrics::Counter::AtomicType *total_success_handshake_count_out              
= nullptr;
+  Metrics::Counter::AtomicType *handshake_sign_rsa                             
= nullptr;
+  Metrics::Counter::AtomicType *handshake_sign_ecdsa                           
= nullptr;
+  Metrics::Counter::AtomicType *handshake_sign_other                           
= nullptr;
+  Metrics::Counter::AtomicType *connections_closed                             
= nullptr;
   Metrics::Counter::AtomicType *total_ticket_keys_renewed                      
= nullptr;
   Metrics::Counter::AtomicType *total_tickets_created                          
= nullptr;
   Metrics::Counter::AtomicType *total_tickets_not_found                        
= nullptr;
diff --git a/src/iocore/net/TLSBasicSupport.cc 
b/src/iocore/net/TLSBasicSupport.cc
index 5d7187da4a..897e406741 100644
--- a/src/iocore/net/TLSBasicSupport.cc
+++ b/src/iocore/net/TLSBasicSupport.cc
@@ -319,6 +319,28 @@ TLSBasicSupport::_update_end_of_handshake_stats()
 {
   Metrics::Counter::increment(ssl_rsb.total_success_handshake_count_in);
 
+  // Only a full handshake runs the asymmetric signature (a resumed one skips 
it); count those
+  // signatures by the server private-key type.
+  {
+    const SSL *ssl = this->_get_ssl_object();
+    if (ssl != nullptr && !SSL_session_reused(ssl)) {
+      if (EVP_PKEY *pkey = SSL_get_privatekey(ssl); pkey != nullptr) {
+        switch (EVP_PKEY_id(pkey)) {
+        case EVP_PKEY_RSA:
+        case EVP_PKEY_RSA_PSS:
+          Metrics::Counter::increment(ssl_rsb.handshake_sign_rsa);
+          break;
+        case EVP_PKEY_EC:
+          Metrics::Counter::increment(ssl_rsb.handshake_sign_ecdsa);
+          break;
+        default:
+          Metrics::Counter::increment(ssl_rsb.handshake_sign_other);
+          break;
+        }
+      }
+    }
+  }
+
 #if defined(OPENSSL_IS_BORINGSSL)
   SSL     *ssl      = this->_get_ssl_object();
   uint16_t group_id = SSL_get_group_id(ssl);

Reply via email to