Skip to content

Commit

Permalink
Introduce TLSBasicSupport interface (#7556)
Browse files Browse the repository at this point in the history
* Introduce TLSBasicSupport interface

This introduces an abstract interface to support QUICNetVC where we
currently only supports SSLNetVC.

* Run clang-format
  • Loading branch information
maskit authored Mar 5, 2021
1 parent 664b3ad commit f3dcbd8
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 72 deletions.
1 change: 1 addition & 0 deletions iocore/net/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ libinknet_a_SOURCES = \
SSLSessionTicket.cc \
SSLUtils.cc \
OCSPStapling.cc \
TLSBasicSupport.cc \
TLSSessionResumptionSupport.cc \
TLSSNISupport.cc \
UDPIOEvent.cc \
Expand Down
63 changes: 18 additions & 45 deletions iocore/net/P_SSLNetVConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "P_ALPNSupport.h"
#include "TLSSessionResumptionSupport.h"
#include "TLSSNISupport.h"
#include "TLSBasicSupport.h"
#include "P_SSLUtils.h"
#include "P_SSLConfig.h"

Expand Down Expand Up @@ -94,7 +95,11 @@ enum SSLHandshakeStatus { SSL_HANDSHAKE_ONGOING, SSL_HANDSHAKE_DONE, SSL_HANDSHA
// A VConnection for a network socket.
//
//////////////////////////////////////////////////////////////////
class SSLNetVConnection : public UnixNetVConnection, public ALPNSupport, public TLSSessionResumptionSupport, public TLSSNISupport
class SSLNetVConnection : public UnixNetVConnection,
public ALPNSupport,
public TLSSessionResumptionSupport,
public TLSSNISupport,
public TLSBasicSupport
{
typedef UnixNetVConnection super; ///< Parent type.

Expand All @@ -106,9 +111,9 @@ class SSLNetVConnection : public UnixNetVConnection, public ALPNSupport, public
bool
trackFirstHandshake() override
{
bool retval = sslHandshakeBeginTime == 0;
bool retval = this->get_tls_handshake_begin_time() == 0;
if (retval) {
sslHandshakeBeginTime = Thread::get_hrtime();
this->_record_tls_handshake_begin_time();
}
return retval;
}
Expand Down Expand Up @@ -275,43 +280,6 @@ class SSLNetVConnection : public UnixNetVConnection, public ALPNSupport, public
return retval;
}

const char *
getSSLProtocol() const
{
return ssl ? SSL_get_version(ssl) : nullptr;
}

const char *
getSSLCipherSuite() const
{
return ssl ? SSL_get_cipher_name(ssl) : nullptr;
}

const char *
getSSLCurve() const
{
if (!ssl) {
return nullptr;
}
ssl_curve_id curve;
if (getSSLSessionCacheHit()) {
curve = getSSLCurveNID();
} else {
curve = SSLGetCurveNID(ssl);
}
#ifndef OPENSSL_IS_BORINGSSL
if (curve == NID_undef) {
return nullptr;
}
return OBJ_nid2sn(curve);
#else
if (curve == 0) {
return nullptr;
}
return SSL_get_curve_name(curve);
#endif
}

bool
has_tunnel_destination() const
{
Expand Down Expand Up @@ -362,11 +330,9 @@ class SSLNetVConnection : public UnixNetVConnection, public ALPNSupport, public
*/
int populate(Connection &con, Continuation *c, void *arg) override;

SSL *ssl = nullptr;
ink_hrtime sslHandshakeBeginTime = 0;
ink_hrtime sslHandshakeEndTime = 0;
ink_hrtime sslLastWriteTime = 0;
int64_t sslTotalBytesSent = 0;
SSL *ssl = nullptr;
ink_hrtime sslLastWriteTime = 0;
int64_t sslTotalBytesSent = 0;

// The serverName is either a pointer to the (null-terminated) name fetched from the
// SSL object or the empty string.
Expand Down Expand Up @@ -468,6 +434,13 @@ class SSLNetVConnection : public UnixNetVConnection, public ALPNSupport, public
}

protected:
SSL *
_get_ssl_object() const override
{
return this->ssl;
}
ssl_curve_id _get_tls_curve() const override;

const IpEndpoint &
_getLocalEndpoint() override
{
Expand Down
34 changes: 21 additions & 13 deletions iocore/net/SSLNetVConnection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ void
SSLNetVConnection::_bindSSLObject()
{
SSLNetVCAttach(this->ssl, this);
TLSBasicSupport::bind(this->ssl, this);
TLSSessionResumptionSupport::bind(this->ssl, this);
TLSSNISupport::bind(this->ssl, this);
}
Expand All @@ -222,6 +223,7 @@ void
SSLNetVConnection::_unbindSSLObject()
{
SSLNetVCDetach(this->ssl);
TLSBasicSupport::unbind(this->ssl);
TLSSessionResumptionSupport::unbind(this->ssl);
TLSSNISupport::unbind(this->ssl);
}
Expand Down Expand Up @@ -610,7 +612,7 @@ SSLNetVConnection::net_read_io(NetHandler *nh, EThread *lthread)
readSignalError(nh, err);
} else if (ret == SSL_HANDSHAKE_WANT_READ || ret == SSL_HANDSHAKE_WANT_ACCEPT) {
if (SSLConfigParams::ssl_handshake_timeout_in > 0) {
double handshake_time = (static_cast<double>(Thread::get_hrtime() - sslHandshakeBeginTime) / 1000000000);
double handshake_time = (static_cast<double>(Thread::get_hrtime() - this->get_tls_handshake_begin_time()) / 1000000000);
Debug("ssl", "ssl handshake for vc %p, took %.3f seconds, configured handshake_timer: %d", this, handshake_time,
SSLConfigParams::ssl_handshake_timeout_in);
if (handshake_time > SSLConfigParams::ssl_handshake_timeout_in) {
Expand Down Expand Up @@ -938,11 +940,11 @@ SSLNetVConnection::clear()
ssl = nullptr;
}
ALPNSupport::clear();
TLSBasicSupport::clear();
TLSSessionResumptionSupport::clear();
TLSSNISupport::_clear();

sslHandshakeStatus = SSL_HANDSHAKE_ONGOING;
sslHandshakeBeginTime = 0;
sslLastWriteTime = 0;
sslTotalBytesSent = 0;
sslClientRenegotiationAbort = false;
Expand Down Expand Up @@ -999,8 +1001,8 @@ SSLNetVConnection::sslStartHandShake(int event, int &err)
Debug("ssl", "Stopping handshake due to server shutting down.");
return EVENT_ERROR;
}
if (sslHandshakeBeginTime == 0) {
sslHandshakeBeginTime = Thread::get_hrtime();
if (this->get_tls_handshake_begin_time() == 0) {
this->_record_tls_handshake_begin_time();
// net_activity will not be triggered until after the handshake
set_inactivity_timeout(HRTIME_SECONDS(SSLConfigParams::ssl_handshake_timeout_in));
}
Expand Down Expand Up @@ -1309,12 +1311,8 @@ SSLNetVConnection::sslServerHandShakeEvent(int &err)

sslHandshakeStatus = SSL_HANDSHAKE_DONE;

if (sslHandshakeBeginTime) {
sslHandshakeEndTime = Thread::get_hrtime();
const ink_hrtime ssl_handshake_time = sslHandshakeEndTime - sslHandshakeBeginTime;

Debug("ssl", "ssl handshake time:%" PRId64, ssl_handshake_time);
SSL_INCREMENT_DYN_STAT_EX(ssl_total_handshake_time_stat, ssl_handshake_time);
if (this->get_tls_handshake_begin_time()) {
this->_record_tls_handshake_end_time();
SSL_INCREMENT_DYN_STAT(ssl_total_success_handshake_count_in_stat);
}

Expand Down Expand Up @@ -1423,7 +1421,7 @@ SSLNetVConnection::sslClientHandShakeEvent(int &err)
{
ssl_error_t ssl_error;

ink_assert(SSLNetVCAccess(ssl) == this);
ink_assert(TLSBasicSupport::getInstance(ssl) == this);

// Initialize properly for a client connection
if (sslHandshakeHookState == HANDSHAKE_HOOKS_PRE) {
Expand Down Expand Up @@ -1947,7 +1945,7 @@ SSLNetVConnection::populate_protocol(std::string_view *results, int n) const
{
int retval = 0;
if (n > retval) {
results[retval] = map_tls_protocol_to_tag(getSSLProtocol());
results[retval] = map_tls_protocol_to_tag(this->get_tls_protocol_name());
if (!results[retval].empty()) {
++retval;
}
Expand All @@ -1962,7 +1960,7 @@ const char *
SSLNetVConnection::protocol_contains(std::string_view prefix) const
{
const char *retval = nullptr;
std::string_view tag = map_tls_protocol_to_tag(getSSLProtocol());
std::string_view tag = map_tls_protocol_to_tag(this->get_tls_protocol_name());
if (prefix.size() <= tag.size() && strncmp(tag.data(), prefix.data(), prefix.size()) == 0) {
retval = tag.data();
} else {
Expand Down Expand Up @@ -2010,3 +2008,13 @@ SSLNetVConnection::_getNetProcessor()
{
return &sslNetProcessor;
}

ssl_curve_id
SSLNetVConnection::_get_tls_curve() const
{
if (getSSLSessionCacheHit()) {
return getSSLCurveNID();
} else {
return SSLGetCurveNID(ssl);
}
}
1 change: 1 addition & 0 deletions iocore/net/SSLUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,7 @@ SSLInitializeLibrary()
// the SSLNetVConnection to the SSL session.
ssl_vc_index = SSL_get_ex_new_index(0, (void *)"NetVC index", nullptr, nullptr, nullptr);

TLSBasicSupport::initialize();
TLSSessionResumptionSupport::initialize();
TLSSNISupport::initialize();

Expand Down
134 changes: 134 additions & 0 deletions iocore/net/TLSBasicSupport.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/** @file
TLSSBasicSupport.cc provides implmentations for
TLSBasicSupport methods
@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 "TLSBasicSupport.h"
#include "SSLStats.h"

int TLSBasicSupport::_ex_data_index = -1;

void
TLSBasicSupport::initialize()
{
ink_assert(_ex_data_index == -1);
if (_ex_data_index == -1) {
_ex_data_index = SSL_get_ex_new_index(0, (void *)"TLSBasicSupport index", nullptr, nullptr, nullptr);
}
}

TLSBasicSupport *
TLSBasicSupport::getInstance(SSL *ssl)
{
return static_cast<TLSBasicSupport *>(SSL_get_ex_data(ssl, _ex_data_index));
}

void
TLSBasicSupport::bind(SSL *ssl, TLSBasicSupport *srs)
{
SSL_set_ex_data(ssl, _ex_data_index, srs);
}

void
TLSBasicSupport::unbind(SSL *ssl)
{
SSL_set_ex_data(ssl, _ex_data_index, nullptr);
}

void
TLSBasicSupport::clear()
{
this->_tls_handshake_begin_time = 0;
this->_tls_handshake_end_time = 0;
}

const char *
TLSBasicSupport::get_tls_protocol_name() const
{
auto ssl = this->_get_ssl_object();
if (ssl) {
return SSL_get_version(ssl);
} else {
return nullptr;
}
}

const char *
TLSBasicSupport::get_tls_cipher_suite() const
{
auto ssl = this->_get_ssl_object();
if (ssl) {
return SSL_get_cipher_name(ssl);
} else {
return nullptr;
}
}

const char *
TLSBasicSupport::get_tls_curve() const
{
auto ssl = this->_get_ssl_object();

if (!ssl) {
return nullptr;
}
ssl_curve_id curve = this->_get_tls_curve();
#ifndef OPENSSL_IS_BORINGSSL
if (curve == NID_undef) {
return nullptr;
}
return OBJ_nid2sn(curve);
#else
if (curve == 0) {
return nullptr;
}
return SSL_get_curve_name(curve);
#endif
}

ink_hrtime
TLSBasicSupport::get_tls_handshake_begin_time() const
{
return this->_tls_handshake_begin_time;
}

ink_hrtime
TLSBasicSupport::get_tls_handshake_end_time() const
{
return this->_tls_handshake_end_time;
}

void
TLSBasicSupport::_record_tls_handshake_begin_time()
{
this->_tls_handshake_begin_time = Thread::get_hrtime();
}

void
TLSBasicSupport::_record_tls_handshake_end_time()
{
this->_tls_handshake_end_time = Thread::get_hrtime();
const ink_hrtime ssl_handshake_time = this->_tls_handshake_end_time - this->_tls_handshake_begin_time;

Debug("ssl", "ssl handshake time:%" PRId64, ssl_handshake_time);
SSL_INCREMENT_DYN_STAT_EX(ssl_total_handshake_time_stat, ssl_handshake_time);
}
Loading

0 comments on commit f3dcbd8

Please sign in to comment.