Skip to content

Commit

Permalink
Add TLSEventSupport (#11744)
Browse files Browse the repository at this point in the history
* Add TLSEventSupport

* Remove _fire_ssl_servername_event

* Refactoring for Clang-Analyzer

* const
  • Loading branch information
maskit authored Sep 20, 2024
1 parent 5ca08cf commit c9d557b
Show file tree
Hide file tree
Showing 13 changed files with 820 additions and 536 deletions.
15 changes: 15 additions & 0 deletions include/iocore/net/NetVConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ class NetVConnection : public VConnection, public PluginUserArgs<TS_USER_ARGS_VC
TLS_ALPN,
TLS_Basic,
TLS_CertSwitch,
TLS_Event,
TLS_EarlyData,
TLS_SNI,
TLS_SessionResumption,
Expand Down Expand Up @@ -594,6 +595,20 @@ NetVConnection::_set_service(TLSBasicSupport *instance)
this->_set_service(NetVConnection::Service::TLS_Basic, instance);
}

class TLSEventSupport;
template <>
inline TLSEventSupport *
NetVConnection::get_service() const
{
return static_cast<TLSEventSupport *>(this->_get_service(NetVConnection::Service::TLS_Event));
}
template <>
inline void
NetVConnection::_set_service(TLSEventSupport *instance)
{
this->_set_service(NetVConnection::Service::TLS_Event, instance);
}

class TLSEarlyDataSupport;
template <>
inline TLSEarlyDataSupport *
Expand Down
89 changes: 89 additions & 0 deletions include/iocore/net/TLSEventSupport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/** @file
TLSEventSupport implements common methods and members to
support TLS related events
@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 "iocore/eventsystem/Lock.h"

class Continuation;

class TLSEventSupport
{
public:
enum class SSLHandshakeHookState {
HANDSHAKE_HOOKS_PRE,
HANDSHAKE_HOOKS_PRE_INVOKE,
HANDSHAKE_HOOKS_CLIENT_HELLO,
HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE,
HANDSHAKE_HOOKS_SNI,
HANDSHAKE_HOOKS_CERT,
HANDSHAKE_HOOKS_CERT_INVOKE,
HANDSHAKE_HOOKS_CLIENT_CERT,
HANDSHAKE_HOOKS_CLIENT_CERT_INVOKE,
HANDSHAKE_HOOKS_OUTBOUND_PRE,
HANDSHAKE_HOOKS_OUTBOUND_PRE_INVOKE,
HANDSHAKE_HOOKS_VERIFY_SERVER,
HANDSHAKE_HOOKS_DONE
};

static char const *get_ssl_handshake_hook_state_name(SSLHandshakeHookState state);

virtual ~TLSEventSupport() = default;

static void initialize();
static TLSEventSupport *getInstance(SSL *ssl);
static void bind(SSL *ssl, TLSEventSupport *es);
static void unbind(SSL *ssl);

bool callHooks(TSEvent eventId);
bool calledHooks(TSEvent eventId) const;
virtual Continuation *getContinuationForTLSEvents() = 0;
virtual EThread *getThreadForTLSEvents() = 0;
virtual Ptr<ProxyMutex> getMutexForTLSEvents() = 0;
virtual void reenable(int event) = 0;

protected:
void clear();

SSLHandshakeHookState get_handshake_hook_state();
void set_handshake_hook_state(SSLHandshakeHookState state);
bool is_invoked_state() const;
int invoke_tls_event();
void resume_tls_event();

virtual bool _is_tunneling_requested() const = 0;
virtual void _switch_to_tunneling_mode() = 0;

private:
static int _ex_data_index;
SSL *_ssl;

bool _first_handshake_hooks_pre = true;
bool _first_handshake_hooks_outbound_pre = true;

/// The current hook.
/// @note For @C SSL_HOOKS_INVOKE, this is the hook to invoke.
class APIHook *curHook = nullptr;
SSLHandshakeHookState sslHandshakeHookState = SSLHandshakeHookState::HANDSHAKE_HOOKS_PRE;
};
2 changes: 0 additions & 2 deletions include/iocore/net/TLSSNISupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ class TLSSNISupport
} hints_from_sni;

protected:
virtual void _fire_ssl_servername_event() = 0;

virtual in_port_t _get_local_port() = 0;

void _clear();
Expand Down
24 changes: 12 additions & 12 deletions src/api/InkAPI.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7870,25 +7870,25 @@ TSHttpEventNameLookup(TSEvent event)
return HttpDebugNames::get_event_name(static_cast<int>(event));
}

/// Re-enable SSL VC.
/// Re-enable NetVC that has TLSEventSupport.
class TSSslCallback : public Continuation
{
public:
TSSslCallback(SSLNetVConnection *vc, TSEvent event) : Continuation(vc->nh->mutex), m_vc(vc), m_event(event)
TSSslCallback(TLSEventSupport *tes, TSEvent event) : Continuation(tes->getMutexForTLSEvents().get()), m_tes(tes), m_event(event)
{
SET_HANDLER(&TSSslCallback::event_handler);
}
int
event_handler(int /* event ATS_UNUSED */, void *)
{
m_vc->reenable(m_vc->nh, m_event);
m_tes->reenable(m_event);
delete this;
return 0;
}

private:
SSLNetVConnection *m_vc;
TSEvent m_event;
TLSEventSupport *m_tes;
TSEvent m_event;
};

/// SSL Hooks
Expand Down Expand Up @@ -8372,19 +8372,19 @@ TSVConnReenable(TSVConn vconn)
void
TSVConnReenableEx(TSVConn vconn, TSEvent event)
{
NetVConnection *vc = reinterpret_cast<NetVConnection *>(vconn);
SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(vc);
// We really only deal with a SSLNetVConnection at the moment
if (ssl_vc != nullptr) {
NetVConnection *vc = reinterpret_cast<NetVConnection *>(vconn);

if (auto tes = vc->get_service<TLSEventSupport>(); tes) {
EThread *eth = this_ethread();

// We use the mutex of VC's NetHandler so we can put the VC into ready_list by reenable()
MUTEX_TRY_LOCK(trylock, ssl_vc->nh->mutex, eth);
Ptr<ProxyMutex> m = tes->getMutexForTLSEvents();
MUTEX_TRY_LOCK(trylock, m, eth);
if (trylock.is_locked()) {
ssl_vc->reenable(ssl_vc->nh, event);
tes->reenable(event);
} else {
// We schedule the reenable to the home thread of ssl_vc.
ssl_vc->thread->schedule_imm(new TSSslCallback(ssl_vc, event));
tes->getThreadForTLSEvents()->schedule_imm(new TSSslCallback(tes, event));
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/iocore/net/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ add_library(
SSLUtils.cc
OCSPStapling.cc
TLSBasicSupport.cc
TLSEventSupport.cc
TLSCertSwitchSupport.cc
TLSEarlyDataSupport.cc
TLSKeyLogger.cc
Expand Down
23 changes: 22 additions & 1 deletion src/iocore/net/P_QUICNetVConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "P_UDPNet.h"
#include "iocore/net/TLSALPNSupport.h"
#include "iocore/net/TLSBasicSupport.h"
#include "iocore/net/TLSEventSupport.h"
#include "iocore/net/TLSSessionResumptionSupport.h"
#include "iocore/net/TLSSNISupport.h"
#include "iocore/net/TLSCertSwitchSupport.h"
Expand All @@ -59,6 +60,7 @@
#include <netinet/in.h>
#include <quiche.h>

class EThread;
class QUICPacketHandler;
class QUICResetTokenTable;
class QUICConnectionTable;
Expand All @@ -70,6 +72,7 @@ class QUICNetVConnection : public UnixNetVConnection,
public TLSSNISupport,
public TLSSessionResumptionSupport,
public TLSCertSwitchSupport,
public TLSEventSupport,
public TLSBasicSupport,
public QUICSupport
{
Expand Down Expand Up @@ -142,6 +145,12 @@ class QUICNetVConnection : public UnixNetVConnection,
// QUICNetVConnection
int in_closed_queue = 0;

// TLSEventSupport
void reenable(int event) override;
Continuation *getContinuationForTLSEvents() override;
EThread *getThreadForTLSEvents() override;
Ptr<ProxyMutex> getMutexForTLSEvents() override;

bool shouldDestroy();
void destroy(EThread *t);
void remove_connection_ids();
Expand All @@ -158,7 +167,6 @@ class QUICNetVConnection : public UnixNetVConnection,
ssl_curve_id _get_tls_curve() const override;

// TLSSNISupport
void _fire_ssl_servername_event() override;
in_port_t _get_local_port() override;

// TLSSessionResumptionSupport
Expand All @@ -169,6 +177,19 @@ class QUICNetVConnection : public UnixNetVConnection,
shared_SSL_CTX _lookupContextByName(const std::string &servername, SSLCertContextType ctxType) override;
shared_SSL_CTX _lookupContextByIP() override;

// TLSEventSupport
bool
_is_tunneling_requested() const override
{
// FIXME Not Supported
return false;
}
void
_switch_to_tunneling_mode() override
{
// FIXME Not supported
}

private:
SSL *_ssl;
QUICConfig::scoped_config _quic_config;
Expand Down
Loading

0 comments on commit c9d557b

Please sign in to comment.