Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions doc/admin-guide/files/records.config.en.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3935,6 +3935,15 @@ TLS v1.3 0-RTT Configuration

Set to ``1`` to allow HTTP parameters on early data requests.

SNI Routing
-----------

.. ts:cv:: CONFIG proxy.config.tunnel.activity_check_period INT 0
:units: seconds

Frequency of checking the activity of SNI Routing Tunnel. Set to ``0`` to disable monitoring of the activity of the SNI tunnels.
The feature is disabled by default.

OCSP Stapling Configuration
===========================

Expand Down
5 changes: 5 additions & 0 deletions doc/admin-guide/monitoring/statistics/core/ssl.en.rst
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,8 @@ SSL/TLS

Incoming client SSL connections terminated due to an unsupported or disabled
version of SSL/TLS, since statistics collection began.

.. ts:stat:: global proxy.process.tunnel.current_active_connections integer
:type: gauge

A gauge of current active SNI Routing Tunnels.
8 changes: 8 additions & 0 deletions mgmt/RecordsConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,14 @@ static const RecordElement RecordsConfig[] =
,
{RECT_CONFIG, "proxy.config.hostdb.host_file.interval", RECD_INT, "86400", RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL}
,
//##########################################################################
//#
//# SNI Routing
//#
//##########################################################################
{RECT_CONFIG, "proxy.config.tunnel.activity_check_period", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_INT, "[0-100]", RECA_NULL}
,

//##########################################################################
//#
//# HTTP
Expand Down
9 changes: 9 additions & 0 deletions proxy/http/HttpConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@ register_stat_callbacks()
RecRegisterRawStat(http_rsb, RECT_PROCESS, "proxy.process.http.websocket.current_active_client_connections", RECD_INT,
RECP_NON_PERSISTENT, (int)http_websocket_current_active_client_connections_stat, RecRawStatSyncSum);
HTTP_CLEAR_DYN_STAT(http_websocket_current_active_client_connections_stat);

// Tunnel Stats
RecRegisterRawStat(http_rsb, RECT_PROCESS, "proxy.process.tunnel.current_active_connections", RECD_INT, RECP_NON_PERSISTENT,
(int)tunnel_current_active_connections_stat, RecRawStatSyncSum);
HTTP_CLEAR_DYN_STAT(tunnel_current_active_connections_stat);

// Current Transaction Stats
RecRegisterRawStat(http_rsb, RECT_PROCESS, "proxy.process.http.current_client_transactions", RECD_INT, RECP_NON_PERSISTENT,
(int)http_current_client_transactions_stat, RecRawStatSyncSum);
Expand Down Expand Up @@ -1146,6 +1152,8 @@ HttpConfig::startup()
HttpEstablishStaticConfigByte(c.oride.attach_server_session_to_client, "proxy.config.http.attach_server_session_to_client");
HttpEstablishStaticConfigLongLong(c.oride.max_proxy_cycles, "proxy.config.http.max_proxy_cycles");

HttpEstablishStaticConfigLongLong(c.oride.tunnel_activity_check_period, "proxy.config.tunnel.activity_check_period");

HttpEstablishStaticConfigLongLong(c.http_request_line_max_size, "proxy.config.http.request_line_max_size");
HttpEstablishStaticConfigLongLong(c.http_hdr_field_max_size, "proxy.config.http.header_field_max_size");

Expand Down Expand Up @@ -1447,6 +1455,7 @@ HttpConfig::reconfigure()
}
params->oride.attach_server_session_to_client = m_master.oride.attach_server_session_to_client;
params->oride.max_proxy_cycles = m_master.oride.max_proxy_cycles;
params->oride.tunnel_activity_check_period = m_master.oride.tunnel_activity_check_period;

params->http_request_line_max_size = m_master.http_request_line_max_size;
params->http_hdr_field_max_size = m_master.http_hdr_field_max_size;
Expand Down
2 changes: 2 additions & 0 deletions proxy/http/HttpConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ enum {
http_current_client_connections_stat,
http_current_active_client_connections_stat,
http_websocket_current_active_client_connections_stat,
tunnel_current_active_connections_stat,
http_current_client_transactions_stat,
http_total_incoming_connections_stat,
http_current_server_transactions_stat,
Expand Down Expand Up @@ -507,6 +508,7 @@ struct OverridableHttpConfigParams {
MgmtByte uncacheable_requests_bypass_parent = 1;
MgmtByte attach_server_session_to_client = 0;
MgmtInt max_proxy_cycles = 0;
MgmtInt tunnel_activity_check_period = 0;

MgmtByte forward_connect_method = 0;

Expand Down
18 changes: 14 additions & 4 deletions proxy/http/HttpSM.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1236,8 +1236,7 @@ HttpSM::state_raw_http_server_open(int event, void *data)
do_http_server_open(true);
return 0;

case NET_EVENT_OPEN:

case NET_EVENT_OPEN: {
// Record the VC in our table
server_entry = vc_table.new_entry();
server_entry->vc = netvc = static_cast<NetVConnection *>(data);
Expand All @@ -1248,8 +1247,13 @@ HttpSM::state_raw_http_server_open(int event, void *data)
netvc->set_inactivity_timeout(get_server_inactivity_timeout());
netvc->set_active_timeout(get_server_active_timeout());
t_state.current.server->clear_connect_fail();
break;

if (get_tunnel_type() != SNIRoutingType::NONE) {
tunnel.mark_tls_tunnel_active();
}

break;
}
case VC_EVENT_ERROR:
case NET_EVENT_OPEN_FAILED:
t_state.current.state = HttpTransact::OPEN_RAW_ERROR;
Expand Down Expand Up @@ -5281,7 +5285,7 @@ HttpSM::do_http_server_open(bool raw)
SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(ua_txn->get_netvc());
if (ssl_vc && raw) {
tls_upstream = ssl_vc->upstream_tls();

_tunnel_type = ssl_vc->tunnel_type();
// ALPN on TLS Partial Blind Tunnel - set negotiated ALPN id
if (ssl_vc->tunnel_type() == SNIRoutingType::PARTIAL_BLIND) {
int pid = ssl_vc->get_negotiated_protocol_id();
Expand Down Expand Up @@ -8260,6 +8264,12 @@ HttpSM::is_redirect_required()
return redirect_required;
}

SNIRoutingType
HttpSM::get_tunnel_type() const
{
return _tunnel_type;
}

// Fill in the client protocols used. Return the number of entries populated.
int
HttpSM::populate_client_protocol(std::string_view *result, int n) const
Expand Down
4 changes: 3 additions & 1 deletion proxy/http/HttpSM.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ class HttpSM : public Continuation, public PluginUserArgs<TS_USER_ARGS_TXN>
// See if we should allow the transaction
// based on sni and host name header values
void check_sni_host();
SNIRoutingType get_tunnel_type() const;

protected:
int reentrancy_count = 0;
Expand Down Expand Up @@ -701,7 +702,8 @@ class HttpSM : public Continuation, public PluginUserArgs<TS_USER_ARGS_TXN>
PostDataBuffers _postbuf;
int _client_connection_id = -1, _client_transaction_id = -1;
int _client_transaction_priority_weight = -1, _client_transaction_priority_dependence = -1;
bool _from_early_data = false;
bool _from_early_data = false;
SNIRoutingType _tunnel_type = SNIRoutingType::NONE;
};

// Function to get the cache_sm object - YTS Team, yamsat
Expand Down
80 changes: 80 additions & 0 deletions proxy/http/HttpTunnel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ HttpTunnel::kill_tunnel()
ink_assert(producer.alive == false);
}
active = false;
this->mark_tls_tunnel_inactive();
this->deallocate_buffers();
this->reset();
}
Expand Down Expand Up @@ -1169,6 +1170,10 @@ HttpTunnel::producer_handler(int event, HttpTunnelProducer *p)

switch (event) {
case VC_EVENT_READ_READY:
if (sm->get_tunnel_type() != SNIRoutingType::NONE) {
mark_tls_tunnel_active();
}

// Data read from producer, reenable consumers
for (c = p->consumer_list.head; c; c = c->link.next) {
if (c->alive && c->write_vio) {
Expand Down Expand Up @@ -1629,6 +1634,14 @@ HttpTunnel::close_vc(HttpTunnelConsumer *c)
int
HttpTunnel::main_handler(int event, void *data)
{
if (event == HTTP_TUNNEL_EVENT_ACTIVITY_CHECK) {
if (!_is_tls_tunnel_active()) {
mark_tls_tunnel_inactive();
}

return EVENT_DONE;
}

HttpTunnelProducer *p = nullptr;
HttpTunnelConsumer *c = nullptr;
bool sm_callback = false;
Expand Down Expand Up @@ -1689,3 +1702,70 @@ void
HttpTunnel::internal_error()
{
}

void
HttpTunnel::mark_tls_tunnel_active()
{
_tls_tunnel_last_update = Thread::get_hrtime();

if (_tls_tunnel_active) {
return;
}

_tls_tunnel_active = true;
HTTP_INCREMENT_DYN_STAT(tunnel_current_active_connections_stat);

_schedule_tls_tunnel_activity_check_event();
}

void
HttpTunnel::mark_tls_tunnel_inactive()
{
if (!_tls_tunnel_active) {
return;
}

_tls_tunnel_active = false;
HTTP_DECREMENT_DYN_STAT(tunnel_current_active_connections_stat);

if (_tls_tunnel_activity_check_event) {
_tls_tunnel_activity_check_event->cancel();
_tls_tunnel_activity_check_event = nullptr;
}
}

void
HttpTunnel::_schedule_tls_tunnel_activity_check_event()
{
if (_tls_tunnel_activity_check_event) {
return;
}

ink_hrtime period = HRTIME_SECONDS(sm->t_state.txn_conf->tunnel_activity_check_period);

if (period > 0) {
EThread *ethread = this_ethread();
_tls_tunnel_activity_check_event = ethread->schedule_every_local(this, period, HTTP_TUNNEL_EVENT_ACTIVITY_CHECK);
}
}

bool
HttpTunnel::_is_tls_tunnel_active() const
{
ink_hrtime period = HRTIME_SECONDS(sm->t_state.txn_conf->tunnel_activity_check_period);

// This should not be called if period is 0
ink_release_assert(period > 0);

ink_hrtime now = Thread::get_hrtime();

Debug("http_tunnel", "now=%" PRId64 " last_update=%" PRId64, now, _tls_tunnel_last_update);

// In some cases, m_tls_tunnel_last_update could be larger than now, because it's using cached current time.
// - e.g. comparing Thread::cur_time of different threads.
if (_tls_tunnel_last_update >= now || now - _tls_tunnel_last_update <= period) {
return true;
}

return false;
}
12 changes: 12 additions & 0 deletions proxy/http/HttpTunnel.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#define HTTP_TUNNEL_EVENT_DONE (HTTP_TUNNEL_EVENTS_START + 1)
#define HTTP_TUNNEL_EVENT_PRECOMPLETE (HTTP_TUNNEL_EVENTS_START + 2)
#define HTTP_TUNNEL_EVENT_CONSUMER_DETACH (HTTP_TUNNEL_EVENTS_START + 3)
#define HTTP_TUNNEL_EVENT_ACTIVITY_CHECK (HTTP_TUNNEL_EVENTS_START + 4)

#define HTTP_TUNNEL_STATIC_PRODUCER (VConnection *)!0

Expand Down Expand Up @@ -284,6 +285,10 @@ class HttpTunnel : public Continuation
bool has_cache_writer() const;
bool has_consumer_besides_client() const;

// CAVEAT: This is different from the HttpTunnel::active flag
void mark_tls_tunnel_active();
void mark_tls_tunnel_inactive();

HttpTunnelProducer *add_producer(VConnection *vc, int64_t nbytes, IOBufferReader *reader_start, HttpProducerHandler sm_handler,
HttpTunnelType_t vc_type, const char *name);

Expand Down Expand Up @@ -334,6 +339,8 @@ class HttpTunnel : public Continuation
void finish_all_internal(HttpTunnelProducer *p, bool chain);
void update_stats_after_abort(HttpTunnelType_t t);
void producer_run(HttpTunnelProducer *p);
void _schedule_tls_tunnel_activity_check_event();
bool _is_tls_tunnel_active() const;

HttpTunnelProducer *get_producer(VIO *vio);
HttpTunnelConsumer *get_consumer(VIO *vio);
Expand All @@ -349,6 +356,11 @@ class HttpTunnel : public Continuation

bool active = false;

// Activity check for SNI Routing Tunnel
bool _tls_tunnel_active = false;
Event *_tls_tunnel_activity_check_event = nullptr;
ink_hrtime _tls_tunnel_last_update = 0;

/// State data about flow control.
FlowControl flow_state;

Expand Down