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 <[email protected]>
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()
{