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

masaori 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 c811aea  Cleanup: Separate SSLStats and SSLDiags from SSLUtils
c811aea is described below

commit c811aea9e0484433fbdd63e0fa6b9fbab87085eb
Author: Masaori Koshiba <masa...@apache.org>
AuthorDate: Thu Feb 21 15:43:58 2019 +0900

    Cleanup: Separate SSLStats and SSLDiags from SSLUtils
---
 iocore/net/Makefile.am          |   2 +
 iocore/net/OCSPStapling.cc      |   1 +
 iocore/net/P_SSLUtils.h         | 104 ----------
 iocore/net/SSLClientUtils.cc    |   2 +
 iocore/net/SSLConfig.cc         |  16 +-
 iocore/net/SSLDiags.cc          | 224 +++++++++++++++++++++
 iocore/net/SSLDiags.h           |  43 ++++
 iocore/net/SSLNetProcessor.cc   |   1 +
 iocore/net/SSLNetVConnection.cc |  16 +-
 iocore/net/SSLSessionCache.cc   |   2 +
 iocore/net/SSLStats.cc          | 239 +++++++++++++++++++++++
 iocore/net/SSLStats.h           | 115 +++++++++++
 iocore/net/SSLUtils.cc          | 420 ++--------------------------------------
 13 files changed, 660 insertions(+), 525 deletions(-)

diff --git a/iocore/net/Makefile.am b/iocore/net/Makefile.am
index 9eb9396..0971d5f 100644
--- a/iocore/net/Makefile.am
+++ b/iocore/net/Makefile.am
@@ -136,6 +136,7 @@ libinknet_a_SOURCES = \
        SSLCertLookup.cc \
        SSLSessionCache.cc \
        SSLConfig.cc \
+       SSLDiags.cc \
        SSLInternal.cc \
        SSLNetAccept.cc \
        SSLNetProcessor.cc \
@@ -143,6 +144,7 @@ libinknet_a_SOURCES = \
        SSLNextProtocolAccept.cc \
        SSLNextProtocolSet.cc \
        SSLSNIConfig.cc \
+       SSLStats.cc \
        SSLUtils.cc \
        SSLClientUtils.cc \
        OCSPStapling.cc \
diff --git a/iocore/net/OCSPStapling.cc b/iocore/net/OCSPStapling.cc
index b4fcd77..26316ce 100644
--- a/iocore/net/OCSPStapling.cc
+++ b/iocore/net/OCSPStapling.cc
@@ -27,6 +27,7 @@
 #include "P_Net.h"
 #include "P_SSLConfig.h"
 #include "P_SSLUtils.h"
+#include "SSLStats.h"
 
 // Maxiumum OCSP stapling response size.
 // This should be the response for a single certificate and will typically 
include the responder certificate chain,
diff --git a/iocore/net/P_SSLUtils.h b/iocore/net/P_SSLUtils.h
index e70dbc5..a61d8bc 100644
--- a/iocore/net/P_SSLUtils.h
+++ b/iocore/net/P_SSLUtils.h
@@ -33,92 +33,12 @@
 #endif
 #include <openssl/ssl.h>
 
-#include <unordered_map>
-
 struct SSLConfigParams;
 struct SSLCertLookup;
 class SSLNetVConnection;
-struct RecRawStatBlock;
 
 typedef int ssl_error_t;
 
-enum SSL_Stats {
-  ssl_origin_server_expired_cert_stat,
-  ssl_user_agent_expired_cert_stat,
-  ssl_origin_server_revoked_cert_stat,
-  ssl_user_agent_revoked_cert_stat,
-  ssl_origin_server_unknown_cert_stat,
-  ssl_user_agent_unknown_cert_stat,
-  ssl_origin_server_cert_verify_failed_stat,
-  ssl_user_agent_cert_verify_failed_stat,
-  ssl_origin_server_bad_cert_stat,
-  ssl_user_agent_bad_cert_stat,
-  ssl_origin_server_decryption_failed_stat,
-  ssl_user_agent_decryption_failed_stat,
-  ssl_origin_server_wrong_version_stat,
-  ssl_user_agent_wrong_version_stat,
-  ssl_origin_server_other_errors_stat,
-  ssl_user_agent_other_errors_stat,
-  ssl_origin_server_unknown_ca_stat,
-  ssl_user_agent_unknown_ca_stat,
-  ssl_user_agent_sessions_stat,
-  ssl_user_agent_session_hit_stat,
-  ssl_user_agent_session_miss_stat,
-  ssl_user_agent_session_timeout_stat,
-  ssl_total_handshake_time_stat,
-  ssl_total_success_handshake_count_in_stat,
-  ssl_total_tickets_created_stat,
-  ssl_total_tickets_verified_stat,
-  ssl_total_tickets_verified_old_key_stat, // verified with old key.
-  ssl_total_ticket_keys_renewed_stat,      // number of keys renewed.
-  ssl_total_tickets_not_found_stat,
-  ssl_total_tickets_renewed_stat,
-  ssl_total_dyn_def_tls_record_count,
-  ssl_total_dyn_max_tls_record_count,
-  ssl_total_dyn_redo_tls_record_count,
-  ssl_session_cache_hit,
-  ssl_session_cache_miss,
-  ssl_session_cache_eviction,
-  ssl_session_cache_lock_contention,
-  ssl_session_cache_new_session,
-
-  /* error stats */
-  ssl_error_want_write,
-  ssl_error_want_read,
-  ssl_error_want_client_hello_cb,
-  ssl_error_want_x509_lookup,
-  ssl_error_syscall,
-  ssl_error_read_eos,
-  ssl_error_zero_return,
-  ssl_error_ssl,
-  ssl_sni_name_set_failure,
-  ssl_total_success_handshake_count_out_stat,
-
-  /* ocsp stapling stats */
-  ssl_ocsp_revoked_cert_stat,
-  ssl_ocsp_unknown_cert_stat,
-  ssl_ocsp_refreshed_cert_stat,
-  ssl_ocsp_refresh_cert_failure_stat,
-
-  ssl_cipher_stats_start = 100,
-  ssl_cipher_stats_end   = 300,
-
-  Ssl_Stat_Count
-};
-
-extern RecRawStatBlock *ssl_rsb;
-
-/* Stats should only be accessed using these macros */
-#define SSL_INCREMENT_DYN_STAT(x) RecIncrRawStat(ssl_rsb, nullptr, (int)x, 1)
-#define SSL_DECREMENT_DYN_STAT(x) RecIncrRawStat(ssl_rsb, nullptr, (int)x, -1)
-#define SSL_SET_COUNT_DYN_STAT(x, count) RecSetRawStatCount(ssl_rsb, x, count)
-#define SSL_INCREMENT_DYN_STAT_EX(x, y) RecIncrRawStat(ssl_rsb, nullptr, 
(int)x, y)
-#define SSL_CLEAR_DYN_STAT(x)            \
-  do {                                   \
-    RecSetRawStatSum(ssl_rsb, (x), 0);   \
-    RecSetRawStatCount(ssl_rsb, (x), 0); \
-  } while (0)
-
 // Create a default SSL server context.
 SSL_CTX *SSLDefaultServerContext();
 
@@ -131,9 +51,6 @@ void SSLInitializeLibrary();
 // Initialize SSL library based on configuration settings
 void SSLPostConfigInitialize();
 
-// Initialize SSL statistics.
-void SSLInitializeStatistics();
-
 // Release SSL_CTX and the associated data. This works for both
 // client and server contexts and gracefully accepts nullptr.
 void SSLReleaseContext(SSL_CTX *ctx);
@@ -144,27 +61,6 @@ ssl_error_t SSLReadBuffer(SSL *ssl, void *buf, int64_t 
nbytes, int64_t &nread);
 ssl_error_t SSLAccept(SSL *ssl);
 ssl_error_t SSLConnect(SSL *ssl);
 
-// Log an SSL error.
-#define SSLError(fmt, ...) SSLDiagnostic(MakeSourceLocation(), false, nullptr, 
fmt, ##__VA_ARGS__)
-#define SSLErrorVC(vc, fmt, ...) SSLDiagnostic(MakeSourceLocation(), false, 
(vc), fmt, ##__VA_ARGS__)
-// Log a SSL diagnostic using the "ssl" diagnostic tag.
-#define SSLDebug(fmt, ...) SSLDiagnostic(MakeSourceLocation(), true, nullptr, 
fmt, ##__VA_ARGS__)
-#define SSLVCDebug(vc, fmt, ...) SSLDiagnostic(MakeSourceLocation(), true, 
(vc), fmt, ##__VA_ARGS__)
-
-#define SSL_CLR_ERR_INCR_DYN_STAT(vc, x, fmt, ...) \
-  do {                                             \
-    SSLVCDebug((vc), fmt, ##__VA_ARGS__);          \
-    RecIncrRawStat(ssl_rsb, nullptr, (int)x, 1);   \
-  } while (0)
-
-void SSLDiagnostic(const SourceLocation &loc, bool debug, SSLNetVConnection 
*vc, const char *fmt, ...) TS_PRINTFLIKE(4, 5);
-
-// Return a static string name for a SSL_ERROR constant.
-const char *SSLErrorName(int ssl_error);
-
-// Log a SSL network buffer.
-void SSLDebugBufferPrint(const char *tag, const char *buffer, unsigned buflen, 
const char *message);
-
 // Load the SSL certificate configuration.
 bool SSLParseCertificateConfiguration(const SSLConfigParams *params, 
SSLCertLookup *lookup);
 
diff --git a/iocore/net/SSLClientUtils.cc b/iocore/net/SSLClientUtils.cc
index 89842f5..dd67e88 100644
--- a/iocore/net/SSLClientUtils.cc
+++ b/iocore/net/SSLClientUtils.cc
@@ -23,9 +23,11 @@
 #include "records/I_RecHttp.h"
 #include "tscore/ink_platform.h"
 #include "tscore/X509HostnameValidator.h"
+
 #include "P_Net.h"
 #include "P_SSLClientUtils.h"
 #include "YamlSNIConfig.h"
+#include "SSLDiags.h"
 
 #include <openssl/err.h>
 #include <openssl/pem.h>
diff --git a/iocore/net/SSLConfig.cc b/iocore/net/SSLConfig.cc
index 2d67244..1fd1955 100644
--- a/iocore/net/SSLConfig.cc
+++ b/iocore/net/SSLConfig.cc
@@ -29,19 +29,23 @@
    SSL Configurations
  ****************************************************************************/
 
-#include "tscore/ink_platform.h"
-#include "tscore/I_Layout.h"
+#include "P_SSLConfig.h"
 
 #include <cstring>
 #include <cmath>
+
+#include "tscore/ink_platform.h"
+#include "tscore/I_Layout.h"
+#include "records/I_RecHttp.h"
+
+#include "HttpConfig.h"
+
 #include "P_Net.h"
-#include "P_SSLConfig.h"
-#include "YamlSNIConfig.h"
 #include "P_SSLUtils.h"
 #include "P_SSLCertLookup.h"
 #include "SSLSessionCache.h"
-#include <records/I_RecHttp.h>
-#include <HttpConfig.h>
+#include "SSLDiags.h"
+#include "YamlSNIConfig.h"
 
 int SSLConfig::configid                                     = 0;
 int SSLCertificateConfig::configid                          = 0;
diff --git a/iocore/net/SSLDiags.cc b/iocore/net/SSLDiags.cc
new file mode 100644
index 0000000..549a4d3
--- /dev/null
+++ b/iocore/net/SSLDiags.cc
@@ -0,0 +1,224 @@
+/** @file
+
+  Diags for TLS
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "SSLDiags.h"
+
+#include <openssl/err.h>
+
+#include "P_Net.h"
+#include "SSLStats.h"
+
+// return true if we have a stat for the error
+static bool
+increment_ssl_client_error(unsigned long err)
+{
+  // we only look for LIB_SSL errors atm
+  if (ERR_LIB_SSL != ERR_GET_LIB(err)) {
+    SSL_INCREMENT_DYN_STAT(ssl_user_agent_other_errors_stat);
+    return false;
+  }
+
+  // error was in LIB_SSL, now just switch on REASON
+  // (we ignore FUNCTION with the prejudice that we don't care what function
+  // the error came from, hope that's ok?)
+  switch (ERR_GET_REASON(err)) {
+#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED
+  case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED:
+    SSL_INCREMENT_DYN_STAT(ssl_user_agent_expired_cert_stat);
+    break;
+#endif
+#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED
+  case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:
+    SSL_INCREMENT_DYN_STAT(ssl_user_agent_revoked_cert_stat);
+    break;
+#endif
+#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
+  case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
+    SSL_INCREMENT_DYN_STAT(ssl_user_agent_unknown_cert_stat);
+    break;
+#endif
+  case SSL_R_CERTIFICATE_VERIFY_FAILED:
+    SSL_INCREMENT_DYN_STAT(ssl_user_agent_cert_verify_failed_stat);
+    break;
+#ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
+  case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
+    SSL_INCREMENT_DYN_STAT(ssl_user_agent_bad_cert_stat);
+    break;
+#endif
+#ifdef SSL_R_TLSV1_ALERT_DECRYPTION_FAILED
+  case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED:
+    SSL_INCREMENT_DYN_STAT(ssl_user_agent_decryption_failed_stat);
+    break;
+#endif
+  case SSL_R_WRONG_VERSION_NUMBER:
+    SSL_INCREMENT_DYN_STAT(ssl_user_agent_wrong_version_stat);
+    break;
+#ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA
+  case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
+    SSL_INCREMENT_DYN_STAT(ssl_user_agent_unknown_ca_stat);
+    break;
+#endif
+  default:
+    SSL_INCREMENT_DYN_STAT(ssl_user_agent_other_errors_stat);
+    return false;
+  }
+
+  return true;
+}
+
+// return true if we have a stat for the error
+
+static bool
+increment_ssl_server_error(unsigned long err)
+{
+  // we only look for LIB_SSL errors atm
+  if (ERR_LIB_SSL != ERR_GET_LIB(err)) {
+    SSL_INCREMENT_DYN_STAT(ssl_origin_server_other_errors_stat);
+    return false;
+  }
+
+  // error was in LIB_SSL, now just switch on REASON
+  // (we ignore FUNCTION with the prejudice that we don't care what function
+  // the error came from, hope that's ok?)
+  switch (ERR_GET_REASON(err)) {
+#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED
+  case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED:
+    SSL_INCREMENT_DYN_STAT(ssl_origin_server_expired_cert_stat);
+    break;
+#endif
+#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED
+  case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:
+    SSL_INCREMENT_DYN_STAT(ssl_origin_server_revoked_cert_stat);
+    break;
+#endif
+#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
+  case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
+    SSL_INCREMENT_DYN_STAT(ssl_origin_server_unknown_cert_stat);
+    break;
+#endif
+  case SSL_R_CERTIFICATE_VERIFY_FAILED:
+    SSL_INCREMENT_DYN_STAT(ssl_origin_server_cert_verify_failed_stat);
+    break;
+#ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
+  case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
+    SSL_INCREMENT_DYN_STAT(ssl_origin_server_bad_cert_stat);
+    break;
+#endif
+#ifdef SSL_R_TLSV1_ALERT_DECRYPTION_FAILED
+  case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED:
+    SSL_INCREMENT_DYN_STAT(ssl_origin_server_decryption_failed_stat);
+    break;
+#endif
+  case SSL_R_WRONG_VERSION_NUMBER:
+    SSL_INCREMENT_DYN_STAT(ssl_origin_server_wrong_version_stat);
+    break;
+#ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA
+  case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
+    SSL_INCREMENT_DYN_STAT(ssl_origin_server_unknown_ca_stat);
+    break;
+#endif
+  default:
+    SSL_INCREMENT_DYN_STAT(ssl_origin_server_other_errors_stat);
+    return false;
+  }
+
+  return true;
+}
+
+void
+SSLDiagnostic(const SourceLocation &loc, bool debug, SSLNetVConnection *vc, 
const char *fmt, ...)
+{
+  unsigned long l;
+  char buf[256];
+  const char *file, *data;
+  int line, flags;
+  unsigned long es;
+  va_list ap;
+  ip_text_buffer ip_buf = {'\0'};
+
+  if (vc) {
+    ats_ip_ntop(vc->get_remote_addr(), ip_buf, sizeof(ip_buf));
+  }
+
+  es = (unsigned long)pthread_self();
+  while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
+    if (debug) {
+      if (unlikely(diags->on())) {
+        diags->log("ssl-diag", DL_Debug, &loc, "SSL::%lu:%s:%s:%d%s%s%s%s", 
es, ERR_error_string(l, buf), file, line,
+                   (flags & ERR_TXT_STRING) ? ":" : "", (flags & 
ERR_TXT_STRING) ? data : "", vc ? ": peer address is " : "",
+                   ip_buf);
+      }
+    } else {
+      diags->error(DL_Error, &loc, "SSL::%lu:%s:%s:%d%s%s%s%s", es, 
ERR_error_string(l, buf), file, line,
+                   (flags & ERR_TXT_STRING) ? ":" : "", (flags & 
ERR_TXT_STRING) ? data : "", vc ? ": peer address is " : "",
+                   ip_buf);
+    }
+
+    // Tally desired stats (only client/server connection stats, not init
+    // issues where vc is nullptr)
+    if (vc) {
+      // get_context() == NET_VCONNECTION_OUT if ats is client (we update 
server stats)
+      if (vc->get_context() == NET_VCONNECTION_OUT) {
+        increment_ssl_server_error(l); // update server error stats
+      } else {
+        increment_ssl_client_error(l); // update client error stat
+      }
+    }
+  }
+
+  va_start(ap, fmt);
+  if (debug) {
+    diags->log_va("ssl-diag", DL_Debug, &loc, fmt, ap);
+  } else {
+    diags->error_va(DL_Error, &loc, fmt, ap);
+  }
+  va_end(ap);
+}
+
+const char *
+SSLErrorName(int ssl_error)
+{
+  static const char *names[] = {
+    "SSL_ERROR_NONE",    "SSL_ERROR_SSL",         "SSL_ERROR_WANT_READ",    
"SSL_ERROR_WANT_WRITE", "SSL_ERROR_WANT_X509_LOOKUP",
+    "SSL_ERROR_SYSCALL", "SSL_ERROR_ZERO_RETURN", "SSL_ERROR_WANT_CONNECT", 
"SSL_ERROR_WANT_ACCEPT"};
+
+  if (ssl_error < 0 || ssl_error >= (int)countof(names)) {
+    return "unknown SSL error";
+  }
+
+  return names[ssl_error];
+}
+
+void
+SSLDebugBufferPrint(const char *tag, const char *buffer, unsigned buflen, 
const char *message)
+{
+  if (is_debug_tag_set(tag)) {
+    if (message != nullptr) {
+      fprintf(stdout, "%s\n", message);
+    }
+    for (unsigned ii = 0; ii < buflen; ii++) {
+      putc(buffer[ii], stdout);
+    }
+    putc('\n', stdout);
+  }
+}
diff --git a/iocore/net/SSLDiags.h b/iocore/net/SSLDiags.h
new file mode 100644
index 0000000..52ccd08
--- /dev/null
+++ b/iocore/net/SSLDiags.h
@@ -0,0 +1,43 @@
+/** @file
+
+  Diags for TLS
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+
+#include "tscore/Diags.h"
+
+class SSLNetVConnection;
+
+// Log an SSL error.
+#define SSLError(fmt, ...) SSLDiagnostic(MakeSourceLocation(), false, nullptr, 
fmt, ##__VA_ARGS__)
+#define SSLErrorVC(vc, fmt, ...) SSLDiagnostic(MakeSourceLocation(), false, 
(vc), fmt, ##__VA_ARGS__)
+// Log a SSL diagnostic using the "ssl" diagnostic tag.
+#define SSLDebug(fmt, ...) SSLDiagnostic(MakeSourceLocation(), true, nullptr, 
fmt, ##__VA_ARGS__)
+#define SSLVCDebug(vc, fmt, ...) SSLDiagnostic(MakeSourceLocation(), true, 
(vc), fmt, ##__VA_ARGS__)
+
+void SSLDiagnostic(const SourceLocation &loc, bool debug, SSLNetVConnection 
*vc, const char *fmt, ...) TS_PRINTFLIKE(4, 5);
+
+// Return a static string name for a SSL_ERROR constant.
+const char *SSLErrorName(int ssl_error);
+
+// Log a SSL network buffer.
+void SSLDebugBufferPrint(const char *tag, const char *buffer, unsigned buflen, 
const char *message);
diff --git a/iocore/net/SSLNetProcessor.cc b/iocore/net/SSLNetProcessor.cc
index cff8992..90c7a4e 100644
--- a/iocore/net/SSLNetProcessor.cc
+++ b/iocore/net/SSLNetProcessor.cc
@@ -27,6 +27,7 @@
 #include "P_SSLUtils.h"
 #include "P_OCSPStapling.h"
 #include "P_SSLSNI.h"
+#include "SSLStats.h"
 
 //
 // Global Data
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index 5d08d3d..2c55571 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -20,22 +20,26 @@
   See the License for the specific language governing permissions and
   limitations under the License.
  */
+
 #include "tscore/ink_config.h"
 #include "tscore/EventNotify.h"
 #include "tscore/I_Layout.h"
 #include "records/I_RecHttp.h"
+
+#include "InkAPIInternal.h" // Added to include the ssl_hook definitions
+#include "Log.h"
+#include "HttpTunnel.h"
+#include "ProxyProtocol.h"
+#include "HttpConfig.h"
+
 #include "P_Net.h"
 #include "P_SSLNextProtocolSet.h"
 #include "P_SSLUtils.h"
-#include "InkAPIInternal.h" // Added to include the ssl_hook definitions
 #include "P_SSLConfig.h"
-#include "BIO_fastopen.h"
-#include "Log.h"
 #include "P_SSLClientUtils.h"
 #include "P_SSLSNI.h"
-#include "HttpTunnel.h"
-#include "ProxyProtocol.h"
-#include <HttpConfig.h>
+#include "BIO_fastopen.h"
+#include "SSLStats.h"
 
 #include <climits>
 #include <string>
diff --git a/iocore/net/SSLSessionCache.cc b/iocore/net/SSLSessionCache.cc
index bbe52a9..1238b4b 100644
--- a/iocore/net/SSLSessionCache.cc
+++ b/iocore/net/SSLSessionCache.cc
@@ -21,6 +21,8 @@
 
 #include "P_SSLConfig.h"
 #include "SSLSessionCache.h"
+#include "SSLStats.h"
+
 #include <cstring>
 
 #define SSLSESSIONCACHE_STRINGIFY0(x) #x
diff --git a/iocore/net/SSLStats.cc b/iocore/net/SSLStats.cc
new file mode 100644
index 0000000..c748b94
--- /dev/null
+++ b/iocore/net/SSLStats.cc
@@ -0,0 +1,239 @@
+/** @file
+
+  Stats of TLS
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "SSLStats.h"
+
+#include <openssl/err.h>
+
+#include "P_SSLConfig.h"
+
+RecRawStatBlock *ssl_rsb = nullptr;
+std::unordered_map<std::string, intptr_t> cipher_map;
+
+static int
+SSLRecRawStatSyncCount(const char *name, RecDataT data_type, RecData *data, 
RecRawStatBlock *rsb, int id)
+{
+  // Grab all the stats we want from OpenSSL and set the stats. This function 
only needs to be called by one of the
+  // involved stats, all others *must* call RecRawStatSyncSum.
+  SSLCertificateConfig::scoped_config certLookup;
+
+  int64_t sessions = 0;
+  int64_t hits     = 0;
+  int64_t misses   = 0;
+  int64_t timeouts = 0;
+
+  if (certLookup) {
+    const unsigned ctxCount = certLookup->count();
+    for (size_t i = 0; i < ctxCount; i++) {
+      SSLCertContext *cc = certLookup->get(i);
+      if (cc && cc->ctx) {
+        sessions += SSL_CTX_sess_accept_good(cc->ctx);
+        hits += SSL_CTX_sess_hits(cc->ctx);
+        misses += SSL_CTX_sess_misses(cc->ctx);
+        timeouts += SSL_CTX_sess_timeouts(cc->ctx);
+      }
+    }
+  }
+
+  SSL_SET_COUNT_DYN_STAT(ssl_user_agent_sessions_stat, sessions);
+  SSL_SET_COUNT_DYN_STAT(ssl_user_agent_session_hit_stat, hits);
+  SSL_SET_COUNT_DYN_STAT(ssl_user_agent_session_miss_stat, misses);
+  SSL_SET_COUNT_DYN_STAT(ssl_user_agent_session_timeout_stat, timeouts);
+
+  return RecRawStatSyncCount(name, data_type, data, rsb, id);
+}
+
+void
+SSLInitializeStatistics()
+{
+  SSL_CTX *ctx;
+  SSL *ssl;
+  STACK_OF(SSL_CIPHER) * ciphers;
+
+  // Allocate SSL statistics block.
+  ssl_rsb = RecAllocateRawStatBlock((int)Ssl_Stat_Count);
+  ink_assert(ssl_rsb != nullptr);
+
+  // SSL client errors.
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_other_errors", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_user_agent_other_errors_stat, RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_expired_cert", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_user_agent_expired_cert_stat, RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_revoked_cert", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_user_agent_revoked_cert_stat, RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_unknown_cert", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_user_agent_unknown_cert_stat, RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_cert_verify_failed", RECD_COUNTER, 
RECP_PERSISTENT,
+                     (int)ssl_user_agent_cert_verify_failed_stat, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_bad_cert", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_user_agent_bad_cert_stat, RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_decryption_failed", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_user_agent_decryption_failed_stat, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_wrong_version", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_user_agent_wrong_version_stat, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_unknown_ca", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_user_agent_unknown_ca_stat, RecRawStatSyncSum);
+
+  // Polled SSL context statistics.
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_sessions", RECD_COUNTER, RECP_NON_PERSISTENT,
+                     (int)ssl_user_agent_sessions_stat,
+                     SSLRecRawStatSyncCount); //<- only use this fn once
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_session_hit", RECD_COUNTER, RECP_NON_PERSISTENT,
+                     (int)ssl_user_agent_session_hit_stat, 
RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_session_miss", RECD_COUNTER, RECP_NON_PERSISTENT,
+                     (int)ssl_user_agent_session_miss_stat, 
RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_session_timeout", RECD_COUNTER, 
RECP_NON_PERSISTENT,
+                     (int)ssl_user_agent_session_timeout_stat, 
RecRawStatSyncCount);
+
+  // SSL server errors.
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_other_errors", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_origin_server_other_errors_stat, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_expired_cert", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_origin_server_expired_cert_stat, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_revoked_cert", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_origin_server_revoked_cert_stat, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_unknown_cert", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_origin_server_unknown_cert_stat, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_cert_verify_failed", RECD_COUNTER, 
RECP_PERSISTENT,
+                     (int)ssl_origin_server_cert_verify_failed_stat, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_bad_cert", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_origin_server_bad_cert_stat, RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_decryption_failed", RECD_COUNTER, 
RECP_PERSISTENT,
+                     (int)ssl_origin_server_decryption_failed_stat, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_wrong_version", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_origin_server_wrong_version_stat, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_unknown_ca", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_origin_server_unknown_ca_stat, 
RecRawStatSyncSum);
+
+  // SSL handshake time
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_handshake_time", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_total_handshake_time_stat, RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_success_handshake_count_in", RECD_COUNTER, 
RECP_PERSISTENT,
+                     (int)ssl_total_success_handshake_count_in_stat, 
RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_success_handshake_count_out", RECD_COUNTER, 
RECP_PERSISTENT,
+                     (int)ssl_total_success_handshake_count_out_stat, 
RecRawStatSyncCount);
+
+  // TLS tickets
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_tickets_created", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_total_tickets_created_stat, RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_tickets_verified", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_total_tickets_verified_stat, 
RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_tickets_not_found", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_total_tickets_not_found_stat, 
RecRawStatSyncCount);
+  // TODO: ticket renewal is not used right now.
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_tickets_renewed", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_total_tickets_renewed_stat, RecRawStatSyncCount);
+  // The number of session tickets verified with an "old" key.
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_tickets_verified_old_key", RECD_COUNTER, 
RECP_PERSISTENT,
+                     (int)ssl_total_tickets_verified_old_key_stat, 
RecRawStatSyncCount);
+  // The number of ticket keys renewed.
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_ticket_keys_renewed", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_total_ticket_keys_renewed_stat, 
RecRawStatSyncCount);
+
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_session_cache_hit", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_session_cache_hit, RecRawStatSyncCount);
+
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_session_cache_new_session", RECD_COUNTER, 
RECP_PERSISTENT,
+                     (int)ssl_session_cache_new_session, RecRawStatSyncCount);
+
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_session_cache_miss", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_session_cache_miss, RecRawStatSyncCount);
+
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_session_cache_eviction", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_session_cache_eviction, RecRawStatSyncCount);
+
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_session_cache_lock_contention", RECD_COUNTER, 
RECP_PERSISTENT,
+                     (int)ssl_session_cache_lock_contention, 
RecRawStatSyncCount);
+
+  /* Track dynamic record size */
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.default_record_size_count", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_total_dyn_def_tls_record_count, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.max_record_size_count", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_total_dyn_max_tls_record_count, 
RecRawStatSyncSum);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.redo_record_size_count", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_total_dyn_redo_tls_record_count, 
RecRawStatSyncCount);
+
+  /* error stats */
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_want_write", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_error_want_write, RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_want_read", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_error_want_read, RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_want_x509_lookup", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_error_want_x509_lookup, RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_syscall", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_error_syscall, RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_read_eos", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_error_read_eos, RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_zero_return", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_error_zero_return, RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.ssl_error_ssl", 
RECD_COUNTER, RECP_PERSISTENT, (int)ssl_error_ssl,
+                     RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_sni_name_set_failure", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_sni_name_set_failure, RecRawStatSyncCount);
+
+  /* ocsp stapling stats */
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_ocsp_revoked_cert_stat", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_ocsp_revoked_cert_stat, RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_ocsp_unknown_cert_stat", RECD_COUNTER, RECP_PERSISTENT,
+                     (int)ssl_ocsp_unknown_cert_stat, RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_ocsp_refreshed_cert", RECD_INT, RECP_PERSISTENT,
+                     (int)ssl_ocsp_refreshed_cert_stat, RecRawStatSyncCount);
+  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_ocsp_refresh_cert_failure", RECD_INT, RECP_PERSISTENT,
+                     (int)ssl_ocsp_refresh_cert_failure_stat, 
RecRawStatSyncCount);
+
+  // Get and register the SSL cipher stats. Note that we are using the default 
SSL context to obtain
+  // the cipher list. This means that the set of ciphers is fixed by the build 
configuration and not
+  // filtered by proxy.config.ssl.server.cipher_suite. This keeps the set of 
cipher suites stable across
+  // configuration reloads and works for the case where we honor the client 
cipher preference.
+
+  ctx     = SSLDefaultServerContext();
+  ssl     = SSL_new(ctx);
+  ciphers = SSL_get_ciphers(ssl);
+
+  // BoringSSL has sk_SSL_CIPHER_num() return a size_t (well, sk_num() is)
+  for (int index = 0; index < static_cast<int>(sk_SSL_CIPHER_num(ciphers)); 
index++) {
+    SSL_CIPHER *cipher     = const_cast<SSL_CIPHER 
*>(sk_SSL_CIPHER_value(ciphers, index));
+    const char *cipherName = SSL_CIPHER_get_name(cipher);
+    std::string statName   = "proxy.process.ssl.cipher.user_agent." + 
std::string(cipherName);
+
+    // If room in allocated space ...
+    if ((ssl_cipher_stats_start + index) > ssl_cipher_stats_end) {
+      // Too many ciphers, increase ssl_cipher_stats_end.
+      SSLError("too many ciphers to register metric '%s', increase 
SSL_Stats::ssl_cipher_stats_end", statName.c_str());
+      continue;
+    }
+
+    // If not already registered ...
+    if (cipherName && cipher_map.find(cipherName) == cipher_map.end()) {
+      cipher_map.emplace(cipherName, (intptr_t)(ssl_cipher_stats_start + 
index));
+      // Register as non-persistent since the order/index is dependent upon 
configuration.
+      RecRegisterRawStat(ssl_rsb, RECT_PROCESS, statName.c_str(), RECD_INT, 
RECP_NON_PERSISTENT,
+                         (int)ssl_cipher_stats_start + index, 
RecRawStatSyncSum);
+      SSL_CLEAR_DYN_STAT((int)ssl_cipher_stats_start + index);
+      Debug("ssl", "registering SSL cipher metric '%s'", statName.c_str());
+    }
+  }
+
+  SSL_free(ssl);
+  SSLReleaseContext(ctx);
+}
diff --git a/iocore/net/SSLStats.h b/iocore/net/SSLStats.h
new file mode 100644
index 0000000..ff38df0
--- /dev/null
+++ b/iocore/net/SSLStats.h
@@ -0,0 +1,115 @@
+/** @file
+
+  Stats of TLS
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#pragma once
+
+#include <unordered_map>
+
+#include "records/I_RecProcess.h"
+#include "SSLDiags.h"
+
+/* Stats should only be accessed using these macros */
+#define SSL_INCREMENT_DYN_STAT(x) RecIncrRawStat(ssl_rsb, nullptr, (int)x, 1)
+#define SSL_DECREMENT_DYN_STAT(x) RecIncrRawStat(ssl_rsb, nullptr, (int)x, -1)
+#define SSL_SET_COUNT_DYN_STAT(x, count) RecSetRawStatCount(ssl_rsb, x, count)
+#define SSL_INCREMENT_DYN_STAT_EX(x, y) RecIncrRawStat(ssl_rsb, nullptr, 
(int)x, y)
+#define SSL_CLEAR_DYN_STAT(x)            \
+  do {                                   \
+    RecSetRawStatSum(ssl_rsb, (x), 0);   \
+    RecSetRawStatCount(ssl_rsb, (x), 0); \
+  } while (0)
+#define SSL_CLR_ERR_INCR_DYN_STAT(vc, x, fmt, ...) \
+  do {                                             \
+    SSLVCDebug((vc), fmt, ##__VA_ARGS__);          \
+    RecIncrRawStat(ssl_rsb, nullptr, (int)x, 1);   \
+  } while (0)
+
+enum SSL_Stats {
+  ssl_origin_server_expired_cert_stat,
+  ssl_user_agent_expired_cert_stat,
+  ssl_origin_server_revoked_cert_stat,
+  ssl_user_agent_revoked_cert_stat,
+  ssl_origin_server_unknown_cert_stat,
+  ssl_user_agent_unknown_cert_stat,
+  ssl_origin_server_cert_verify_failed_stat,
+  ssl_user_agent_cert_verify_failed_stat,
+  ssl_origin_server_bad_cert_stat,
+  ssl_user_agent_bad_cert_stat,
+  ssl_origin_server_decryption_failed_stat,
+  ssl_user_agent_decryption_failed_stat,
+  ssl_origin_server_wrong_version_stat,
+  ssl_user_agent_wrong_version_stat,
+  ssl_origin_server_other_errors_stat,
+  ssl_user_agent_other_errors_stat,
+  ssl_origin_server_unknown_ca_stat,
+  ssl_user_agent_unknown_ca_stat,
+  ssl_user_agent_sessions_stat,
+  ssl_user_agent_session_hit_stat,
+  ssl_user_agent_session_miss_stat,
+  ssl_user_agent_session_timeout_stat,
+  ssl_total_handshake_time_stat,
+  ssl_total_success_handshake_count_in_stat,
+  ssl_total_tickets_created_stat,
+  ssl_total_tickets_verified_stat,
+  ssl_total_tickets_verified_old_key_stat, // verified with old key.
+  ssl_total_ticket_keys_renewed_stat,      // number of keys renewed.
+  ssl_total_tickets_not_found_stat,
+  ssl_total_tickets_renewed_stat,
+  ssl_total_dyn_def_tls_record_count,
+  ssl_total_dyn_max_tls_record_count,
+  ssl_total_dyn_redo_tls_record_count,
+  ssl_session_cache_hit,
+  ssl_session_cache_miss,
+  ssl_session_cache_eviction,
+  ssl_session_cache_lock_contention,
+  ssl_session_cache_new_session,
+
+  /* error stats */
+  ssl_error_want_write,
+  ssl_error_want_read,
+  ssl_error_want_client_hello_cb,
+  ssl_error_want_x509_lookup,
+  ssl_error_syscall,
+  ssl_error_read_eos,
+  ssl_error_zero_return,
+  ssl_error_ssl,
+  ssl_sni_name_set_failure,
+  ssl_total_success_handshake_count_out_stat,
+
+  /* ocsp stapling stats */
+  ssl_ocsp_revoked_cert_stat,
+  ssl_ocsp_unknown_cert_stat,
+  ssl_ocsp_refreshed_cert_stat,
+  ssl_ocsp_refresh_cert_failure_stat,
+
+  ssl_cipher_stats_start = 100,
+  ssl_cipher_stats_end   = 300,
+
+  Ssl_Stat_Count
+};
+
+extern RecRawStatBlock *ssl_rsb;
+extern std::unordered_map<std::string, intptr_t> cipher_map;
+
+// Initialize SSL statistics.
+void SSLInitializeStatistics();
diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc
index 111ec1b..ad20188 100644
--- a/iocore/net/SSLUtils.cc
+++ b/iocore/net/SSLUtils.cc
@@ -19,18 +19,25 @@
   limitations under the License.
  */
 
+#include "P_SSLUtils.h"
+
 #include "tscore/ink_platform.h"
 #include "tscore/SimpleTokenizer.h"
-#include "records/I_RecHttp.h"
 #include "tscore/I_Layout.h"
-#include "P_Net.h"
 #include "tscore/ink_cap.h"
 #include "tscore/ink_mutex.h"
+#include "records/I_RecHttp.h"
+
+#include "P_Net.h"
+#include "InkAPIInternal.h"
+
 #include "P_OCSPStapling.h"
+#include "P_SSLSNI.h"
+#include "P_SSLConfig.h"
 #include "SSLSessionCache.h"
-#include "InkAPIInternal.h"
 #include "SSLDynlock.h"
-#include "P_SSLSNI.h"
+#include "SSLDiags.h"
+#include "SSLStats.h"
 
 #include <string>
 #include <openssl/err.h>
@@ -138,9 +145,6 @@ static int ssl_vc_index = -1;
 static ink_mutex *mutex_buf      = nullptr;
 static bool open_ssl_initialized = false;
 
-RecRawStatBlock *ssl_rsb = nullptr;
-std::unordered_map<std::string, intptr_t> cipher_map;
-
 /* Using pthread thread ID and mutex functions directly, instead of
  * ATS this_ethread / ProxyMutex, so that other linked libraries
  * may use pthreads and openssl without confusing us here. (TS-2271).
@@ -904,38 +908,6 @@ ssl_private_key_validate_exec(const char *cmdLine)
   return bReturn;
 }
 
-static int
-SSLRecRawStatSyncCount(const char *name, RecDataT data_type, RecData *data, 
RecRawStatBlock *rsb, int id)
-{
-  // Grab all the stats we want from OpenSSL and set the stats. This function 
only needs to be called by one of the
-  // involved stats, all others *must* call RecRawStatSyncSum.
-  SSLCertificateConfig::scoped_config certLookup;
-
-  int64_t sessions = 0;
-  int64_t hits     = 0;
-  int64_t misses   = 0;
-  int64_t timeouts = 0;
-
-  if (certLookup) {
-    const unsigned ctxCount = certLookup->count();
-    for (size_t i = 0; i < ctxCount; i++) {
-      SSLCertContext *cc = certLookup->get(i);
-      if (cc && cc->ctx) {
-        sessions += SSL_CTX_sess_accept_good(cc->ctx);
-        hits += SSL_CTX_sess_hits(cc->ctx);
-        misses += SSL_CTX_sess_misses(cc->ctx);
-        timeouts += SSL_CTX_sess_timeouts(cc->ctx);
-      }
-    }
-  }
-
-  SSL_SET_COUNT_DYN_STAT(ssl_user_agent_sessions_stat, sessions);
-  SSL_SET_COUNT_DYN_STAT(ssl_user_agent_session_hit_stat, hits);
-  SSL_SET_COUNT_DYN_STAT(ssl_user_agent_session_miss_stat, misses);
-  SSL_SET_COUNT_DYN_STAT(ssl_user_agent_session_timeout_stat, timeouts);
-  return RecRawStatSyncCount(name, data_type, data, rsb, id);
-}
-
 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
 #define ssl_malloc(size, file, line) ssl_malloc(size)
 #define ssl_realloc(ptr, size, file, line) ssl_realloc(ptr, size)
@@ -1058,376 +1030,6 @@ SSLInitializeLibrary()
   open_ssl_initialized = true;
 }
 
-void
-SSLInitializeStatistics()
-{
-  SSL_CTX *ctx;
-  SSL *ssl;
-  STACK_OF(SSL_CIPHER) * ciphers;
-
-  // Allocate SSL statistics block.
-  ssl_rsb = RecAllocateRawStatBlock((int)Ssl_Stat_Count);
-  ink_assert(ssl_rsb != nullptr);
-
-  // SSL client errors.
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_other_errors", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_user_agent_other_errors_stat, RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_expired_cert", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_user_agent_expired_cert_stat, RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_revoked_cert", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_user_agent_revoked_cert_stat, RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_unknown_cert", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_user_agent_unknown_cert_stat, RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_cert_verify_failed", RECD_COUNTER, 
RECP_PERSISTENT,
-                     (int)ssl_user_agent_cert_verify_failed_stat, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_bad_cert", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_user_agent_bad_cert_stat, RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_decryption_failed", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_user_agent_decryption_failed_stat, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_wrong_version", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_user_agent_wrong_version_stat, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_unknown_ca", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_user_agent_unknown_ca_stat, RecRawStatSyncSum);
-
-  // Polled SSL context statistics.
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_sessions", RECD_COUNTER, RECP_NON_PERSISTENT,
-                     (int)ssl_user_agent_sessions_stat,
-                     SSLRecRawStatSyncCount); //<- only use this fn once
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_session_hit", RECD_COUNTER, RECP_NON_PERSISTENT,
-                     (int)ssl_user_agent_session_hit_stat, 
RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_session_miss", RECD_COUNTER, RECP_NON_PERSISTENT,
-                     (int)ssl_user_agent_session_miss_stat, 
RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.user_agent_session_timeout", RECD_COUNTER, 
RECP_NON_PERSISTENT,
-                     (int)ssl_user_agent_session_timeout_stat, 
RecRawStatSyncCount);
-
-  // SSL server errors.
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_other_errors", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_origin_server_other_errors_stat, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_expired_cert", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_origin_server_expired_cert_stat, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_revoked_cert", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_origin_server_revoked_cert_stat, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_unknown_cert", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_origin_server_unknown_cert_stat, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_cert_verify_failed", RECD_COUNTER, 
RECP_PERSISTENT,
-                     (int)ssl_origin_server_cert_verify_failed_stat, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_bad_cert", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_origin_server_bad_cert_stat, RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_decryption_failed", RECD_COUNTER, 
RECP_PERSISTENT,
-                     (int)ssl_origin_server_decryption_failed_stat, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_wrong_version", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_origin_server_wrong_version_stat, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.origin_server_unknown_ca", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_origin_server_unknown_ca_stat, 
RecRawStatSyncSum);
-
-  // SSL handshake time
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_handshake_time", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_total_handshake_time_stat, RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_success_handshake_count_in", RECD_COUNTER, 
RECP_PERSISTENT,
-                     (int)ssl_total_success_handshake_count_in_stat, 
RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_success_handshake_count_out", RECD_COUNTER, 
RECP_PERSISTENT,
-                     (int)ssl_total_success_handshake_count_out_stat, 
RecRawStatSyncCount);
-
-  // TLS tickets
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_tickets_created", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_total_tickets_created_stat, RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_tickets_verified", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_total_tickets_verified_stat, 
RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_tickets_not_found", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_total_tickets_not_found_stat, 
RecRawStatSyncCount);
-  // TODO: ticket renewal is not used right now.
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_tickets_renewed", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_total_tickets_renewed_stat, RecRawStatSyncCount);
-  // The number of session tickets verified with an "old" key.
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_tickets_verified_old_key", RECD_COUNTER, 
RECP_PERSISTENT,
-                     (int)ssl_total_tickets_verified_old_key_stat, 
RecRawStatSyncCount);
-  // The number of ticket keys renewed.
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.total_ticket_keys_renewed", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_total_ticket_keys_renewed_stat, 
RecRawStatSyncCount);
-
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_session_cache_hit", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_session_cache_hit, RecRawStatSyncCount);
-
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_session_cache_new_session", RECD_COUNTER, 
RECP_PERSISTENT,
-                     (int)ssl_session_cache_new_session, RecRawStatSyncCount);
-
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_session_cache_miss", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_session_cache_miss, RecRawStatSyncCount);
-
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_session_cache_eviction", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_session_cache_eviction, RecRawStatSyncCount);
-
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_session_cache_lock_contention", RECD_COUNTER, 
RECP_PERSISTENT,
-                     (int)ssl_session_cache_lock_contention, 
RecRawStatSyncCount);
-
-  /* Track dynamic record size */
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.default_record_size_count", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_total_dyn_def_tls_record_count, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.max_record_size_count", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_total_dyn_max_tls_record_count, 
RecRawStatSyncSum);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.redo_record_size_count", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_total_dyn_redo_tls_record_count, 
RecRawStatSyncCount);
-
-  /* error stats */
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_want_write", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_error_want_write, RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_want_read", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_error_want_read, RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_want_x509_lookup", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_error_want_x509_lookup, RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_syscall", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_error_syscall, RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_read_eos", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_error_read_eos, RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_error_zero_return", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_error_zero_return, RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, "proxy.process.ssl.ssl_error_ssl", 
RECD_COUNTER, RECP_PERSISTENT, (int)ssl_error_ssl,
-                     RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_sni_name_set_failure", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_sni_name_set_failure, RecRawStatSyncCount);
-
-  /* ocsp stapling stats */
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_ocsp_revoked_cert_stat", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_ocsp_revoked_cert_stat, RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_ocsp_unknown_cert_stat", RECD_COUNTER, RECP_PERSISTENT,
-                     (int)ssl_ocsp_unknown_cert_stat, RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_ocsp_refreshed_cert", RECD_INT, RECP_PERSISTENT,
-                     (int)ssl_ocsp_refreshed_cert_stat, RecRawStatSyncCount);
-  RecRegisterRawStat(ssl_rsb, RECT_PROCESS, 
"proxy.process.ssl.ssl_ocsp_refresh_cert_failure", RECD_INT, RECP_PERSISTENT,
-                     (int)ssl_ocsp_refresh_cert_failure_stat, 
RecRawStatSyncCount);
-
-  // Get and register the SSL cipher stats. Note that we are using the default 
SSL context to obtain
-  // the cipher list. This means that the set of ciphers is fixed by the build 
configuration and not
-  // filtered by proxy.config.ssl.server.cipher_suite. This keeps the set of 
cipher suites stable across
-  // configuration reloads and works for the case where we honor the client 
cipher preference.
-
-  ctx     = SSLDefaultServerContext();
-  ssl     = SSL_new(ctx);
-  ciphers = SSL_get_ciphers(ssl);
-
-  // BoringSSL has sk_SSL_CIPHER_num() return a size_t (well, sk_num() is)
-  for (int index = 0; index < static_cast<int>(sk_SSL_CIPHER_num(ciphers)); 
index++) {
-    SSL_CIPHER *cipher     = const_cast<SSL_CIPHER 
*>(sk_SSL_CIPHER_value(ciphers, index));
-    const char *cipherName = SSL_CIPHER_get_name(cipher);
-    std::string statName   = "proxy.process.ssl.cipher.user_agent." + 
std::string(cipherName);
-
-    // If room in allocated space ...
-    if ((ssl_cipher_stats_start + index) > ssl_cipher_stats_end) {
-      // Too many ciphers, increase ssl_cipher_stats_end.
-      SSLError("too many ciphers to register metric '%s', increase 
SSL_Stats::ssl_cipher_stats_end", statName.c_str());
-      continue;
-    }
-
-    // If not already registered ...
-    if (cipherName && cipher_map.find(cipherName) == cipher_map.end()) {
-      cipher_map.emplace(cipherName, (intptr_t)(ssl_cipher_stats_start + 
index));
-      // Register as non-persistent since the order/index is dependent upon 
configuration.
-      RecRegisterRawStat(ssl_rsb, RECT_PROCESS, statName.c_str(), RECD_INT, 
RECP_NON_PERSISTENT,
-                         (int)ssl_cipher_stats_start + index, 
RecRawStatSyncSum);
-      SSL_CLEAR_DYN_STAT((int)ssl_cipher_stats_start + index);
-      Debug("ssl", "registering SSL cipher metric '%s'", statName.c_str());
-    }
-  }
-
-  SSL_free(ssl);
-  SSLReleaseContext(ctx);
-}
-
-// return true if we have a stat for the error
-static bool
-increment_ssl_client_error(unsigned long err)
-{
-  // we only look for LIB_SSL errors atm
-  if (ERR_LIB_SSL != ERR_GET_LIB(err)) {
-    SSL_INCREMENT_DYN_STAT(ssl_user_agent_other_errors_stat);
-    return false;
-  }
-
-  // error was in LIB_SSL, now just switch on REASON
-  // (we ignore FUNCTION with the prejudice that we don't care what function
-  // the error came from, hope that's ok?)
-  switch (ERR_GET_REASON(err)) {
-#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED
-  case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED:
-    SSL_INCREMENT_DYN_STAT(ssl_user_agent_expired_cert_stat);
-    break;
-#endif
-#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED
-  case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:
-    SSL_INCREMENT_DYN_STAT(ssl_user_agent_revoked_cert_stat);
-    break;
-#endif
-#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
-  case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
-    SSL_INCREMENT_DYN_STAT(ssl_user_agent_unknown_cert_stat);
-    break;
-#endif
-  case SSL_R_CERTIFICATE_VERIFY_FAILED:
-    SSL_INCREMENT_DYN_STAT(ssl_user_agent_cert_verify_failed_stat);
-    break;
-#ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
-  case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
-    SSL_INCREMENT_DYN_STAT(ssl_user_agent_bad_cert_stat);
-    break;
-#endif
-#ifdef SSL_R_TLSV1_ALERT_DECRYPTION_FAILED
-  case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED:
-    SSL_INCREMENT_DYN_STAT(ssl_user_agent_decryption_failed_stat);
-    break;
-#endif
-  case SSL_R_WRONG_VERSION_NUMBER:
-    SSL_INCREMENT_DYN_STAT(ssl_user_agent_wrong_version_stat);
-    break;
-#ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA
-  case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
-    SSL_INCREMENT_DYN_STAT(ssl_user_agent_unknown_ca_stat);
-    break;
-#endif
-  default:
-    SSL_INCREMENT_DYN_STAT(ssl_user_agent_other_errors_stat);
-    return false;
-  }
-
-  return true;
-}
-
-// return true if we have a stat for the error
-
-static bool
-increment_ssl_server_error(unsigned long err)
-{
-  // we only look for LIB_SSL errors atm
-  if (ERR_LIB_SSL != ERR_GET_LIB(err)) {
-    SSL_INCREMENT_DYN_STAT(ssl_origin_server_other_errors_stat);
-    return false;
-  }
-
-  // error was in LIB_SSL, now just switch on REASON
-  // (we ignore FUNCTION with the prejudice that we don't care what function
-  // the error came from, hope that's ok?)
-  switch (ERR_GET_REASON(err)) {
-#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED
-  case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED:
-    SSL_INCREMENT_DYN_STAT(ssl_origin_server_expired_cert_stat);
-    break;
-#endif
-#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED
-  case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:
-    SSL_INCREMENT_DYN_STAT(ssl_origin_server_revoked_cert_stat);
-    break;
-#endif
-#ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
-  case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
-    SSL_INCREMENT_DYN_STAT(ssl_origin_server_unknown_cert_stat);
-    break;
-#endif
-  case SSL_R_CERTIFICATE_VERIFY_FAILED:
-    SSL_INCREMENT_DYN_STAT(ssl_origin_server_cert_verify_failed_stat);
-    break;
-#ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
-  case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
-    SSL_INCREMENT_DYN_STAT(ssl_origin_server_bad_cert_stat);
-    break;
-#endif
-#ifdef SSL_R_TLSV1_ALERT_DECRYPTION_FAILED
-  case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED:
-    SSL_INCREMENT_DYN_STAT(ssl_origin_server_decryption_failed_stat);
-    break;
-#endif
-  case SSL_R_WRONG_VERSION_NUMBER:
-    SSL_INCREMENT_DYN_STAT(ssl_origin_server_wrong_version_stat);
-    break;
-#ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA
-  case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
-    SSL_INCREMENT_DYN_STAT(ssl_origin_server_unknown_ca_stat);
-    break;
-#endif
-  default:
-    SSL_INCREMENT_DYN_STAT(ssl_origin_server_other_errors_stat);
-    return false;
-  }
-
-  return true;
-}
-
-void
-SSLDiagnostic(const SourceLocation &loc, bool debug, SSLNetVConnection *vc, 
const char *fmt, ...)
-{
-  unsigned long l;
-  char buf[256];
-  const char *file, *data;
-  int line, flags;
-  unsigned long es;
-  va_list ap;
-  ip_text_buffer ip_buf = {'\0'};
-
-  if (vc) {
-    ats_ip_ntop(vc->get_remote_addr(), ip_buf, sizeof(ip_buf));
-  }
-
-  es = (unsigned long)pthread_self();
-  while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
-    if (debug) {
-      if (unlikely(diags->on())) {
-        diags->log("ssl-diag", DL_Debug, &loc, "SSL::%lu:%s:%s:%d%s%s%s%s", 
es, ERR_error_string(l, buf), file, line,
-                   (flags & ERR_TXT_STRING) ? ":" : "", (flags & 
ERR_TXT_STRING) ? data : "", vc ? ": peer address is " : "",
-                   ip_buf);
-      }
-    } else {
-      diags->error(DL_Error, &loc, "SSL::%lu:%s:%s:%d%s%s%s%s", es, 
ERR_error_string(l, buf), file, line,
-                   (flags & ERR_TXT_STRING) ? ":" : "", (flags & 
ERR_TXT_STRING) ? data : "", vc ? ": peer address is " : "",
-                   ip_buf);
-    }
-
-    // Tally desired stats (only client/server connection stats, not init
-    // issues where vc is nullptr)
-    if (vc) {
-      // get_context() == NET_VCONNECTION_OUT if ats is client (we update 
server stats)
-      if (vc->get_context() == NET_VCONNECTION_OUT) {
-        increment_ssl_server_error(l); // update server error stats
-      } else {
-        increment_ssl_client_error(l); // update client error stat
-      }
-    }
-  }
-
-  va_start(ap, fmt);
-  if (debug) {
-    diags->log_va("ssl-diag", DL_Debug, &loc, fmt, ap);
-  } else {
-    diags->error_va(DL_Error, &loc, fmt, ap);
-  }
-  va_end(ap);
-}
-
-const char *
-SSLErrorName(int ssl_error)
-{
-  static const char *names[] = {
-    "SSL_ERROR_NONE",    "SSL_ERROR_SSL",         "SSL_ERROR_WANT_READ",    
"SSL_ERROR_WANT_WRITE", "SSL_ERROR_WANT_X509_LOOKUP",
-    "SSL_ERROR_SYSCALL", "SSL_ERROR_ZERO_RETURN", "SSL_ERROR_WANT_CONNECT", 
"SSL_ERROR_WANT_ACCEPT"};
-
-  if (ssl_error < 0 || ssl_error >= (int)countof(names)) {
-    return "unknown SSL error";
-  }
-
-  return names[ssl_error];
-}
-
-void
-SSLDebugBufferPrint(const char *tag, const char *buffer, unsigned buflen, 
const char *message)
-{
-  if (is_debug_tag_set(tag)) {
-    if (message != nullptr) {
-      fprintf(stdout, "%s\n", message);
-    }
-    for (unsigned ii = 0; ii < buflen; ii++) {
-      putc(buffer[ii], stdout);
-    }
-    putc('\n', stdout);
-  }
-}
-
 SSL_CTX *
 SSLDefaultServerContext()
 {

Reply via email to