diff --git a/doc/admin-guide/logging/formatting.en.rst b/doc/admin-guide/logging/formatting.en.rst index 583e999a923..d9dbc1b6792 100644 --- a/doc/admin-guide/logging/formatting.en.rst +++ b/doc/admin-guide/logging/formatting.en.rst @@ -604,6 +604,7 @@ SSL / Encryption .. _cqssv: .. _cqssc: .. _cqssu: +.. _cqssa: .. _pqssl: .. _pscert: @@ -628,6 +629,7 @@ cqssv Client Request SSL version used to communicate with the client. cqssc Client Request SSL Cipher used by |TS| to communicate with the client. cqssu Client Request SSL Elliptic Curve used by |TS| to communicate with the client when using an ECDHE cipher. +cqssa Client Request ALPN Protocol ID negotiated with the client. pqssl Proxy Request Indicates whether the connection from |TS| to the origin was over SSL or not. pscert Proxy Request 1 if origin requested certificate from |TS| during TLS diff --git a/iocore/net/P_ALPNSupport.h b/iocore/net/P_ALPNSupport.h index 75970da679f..e4031221733 100644 --- a/iocore/net/P_ALPNSupport.h +++ b/iocore/net/P_ALPNSupport.h @@ -61,6 +61,9 @@ class ALPNSupport return npnSet; } + void set_negotiated_protocol_id(const ts::TextView &proto); + int get_negotiated_protocol_id() const; + private: const SSLNextProtocolSet *npnSet = nullptr; SessionProtocolSet protoenabled; @@ -68,4 +71,21 @@ class ALPNSupport unsigned char *npn = nullptr; size_t npnsz = 0; Continuation *npnEndpoint = nullptr; + int _negotiated_proto_id = SessionProtocolNameRegistry::INVALID; }; + +// +// Inline functions +// + +inline void +ALPNSupport::set_negotiated_protocol_id(const ts::TextView &proto) +{ + _negotiated_proto_id = globalSessionProtocolNameRegistry.indexFor(proto); +} + +inline int +ALPNSupport::get_negotiated_protocol_id() const +{ + return _negotiated_proto_id; +} diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc index 666c028278a..fbba68439ff 100644 --- a/iocore/net/QUICNetVConnection.cc +++ b/iocore/net/QUICNetVConnection.cc @@ -2133,6 +2133,8 @@ QUICNetVConnection::_start_application() app_name_len = IP_PROTO_TAG_HTTP_QUIC.size(); } + this->set_negotiated_protocol_id({reinterpret_cast(app_name), static_cast(app_name_len)}); + if (netvc_context == NET_VCONNECTION_IN) { if (!this->setSelectedProtocol(app_name, app_name_len)) { this->_handle_error(std::make_unique(QUICTransErrorCode::PROTOCOL_VIOLATION)); diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc index f4eaaa840fa..b261274ef1f 100644 --- a/iocore/net/SSLNetVConnection.cc +++ b/iocore/net/SSLNetVConnection.cc @@ -1325,6 +1325,8 @@ SSLNetVConnection::sslServerHandShakeEvent(int &err) if (!this->setSelectedProtocol(proto, len)) { return EVENT_ERROR; } + this->set_negotiated_protocol_id({reinterpret_cast(proto), static_cast(len)}); + Debug("ssl", "client selected next protocol '%.*s'", len, proto); } else { Debug("ssl", "client did not select a next protocol"); diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index 0bc9621485c..976eaa41756 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -525,6 +525,8 @@ HttpSM::attach_client_session(ProxyTransaction *client_vc, IOBufferReader *buffe client_cipher_suite = cipher ? cipher : "-"; const char *curve = ssl_vc->getSSLCurve(); client_curve = curve ? curve : "-"; + client_alpn_id = ssl_vc->get_negotiated_protocol_id(); + if (!client_tcp_reused) { // Copy along the TLS handshake timings milestones[TS_MILESTONE_TLS_HANDSHAKE_START] = ssl_vc->sslHandshakeBeginTime; diff --git a/proxy/http/HttpSM.h b/proxy/http/HttpSM.h index c2d325c745f..da35e36bf1c 100644 --- a/proxy/http/HttpSM.h +++ b/proxy/http/HttpSM.h @@ -551,6 +551,7 @@ class HttpSM : public Continuation, public PluginUserArgs const char *client_sec_protocol = "-"; const char *client_cipher_suite = "-"; const char *client_curve = "-"; + int client_alpn_id = SessionProtocolNameRegistry::INVALID; int server_transact_count = 0; TransactionMilestones milestones; diff --git a/proxy/http/Makefile.am b/proxy/http/Makefile.am index 8f816d24d26..adfbe73cdc2 100644 --- a/proxy/http/Makefile.am +++ b/proxy/http/Makefile.am @@ -100,8 +100,8 @@ test_proxy_http_LDADD = \ $(top_builddir)/src/tscore/libtscore.la \ $(top_builddir)/proxy/hdrs/libhdrs.a \ $(top_builddir)/iocore/eventsystem/libinkevent.a \ - $(top_builddir)/lib/records/librecords_p.a \ $(top_builddir)/proxy/logging/liblogging.a \ + $(top_builddir)/lib/records/librecords_p.a \ $(top_builddir)/proxy/shared/libUglyLogStubs.a \ $(top_builddir)/mgmt/libmgmt_p.la \ $(top_builddir)/iocore/utils/libinkutils.a \ diff --git a/proxy/logging/Log.cc b/proxy/logging/Log.cc index 61307e0abc2..db430850b86 100644 --- a/proxy/logging/Log.cc +++ b/proxy/logging/Log.cc @@ -533,6 +533,11 @@ Log::init_fields() global_field_list.add(field, false); field_symbol_hash.emplace("cqssu", field); + field = new LogField("client_sec_alpn", "cqssa", LogField::STRING, &LogAccess::marshal_client_security_alpn, + reinterpret_cast(&LogAccess::unmarshal_str)); + global_field_list.add(field, false); + field_symbol_hash.emplace("cqssa", field); + Ptr finish_status_map = make_ptr(new LogFieldAliasTable); finish_status_map->init(N_LOG_FINISH_CODE_TYPES, LOG_FINISH_FIN, "FIN", LOG_FINISH_INTR, "INTR", LOG_FINISH_TIMEOUT, "TIMEOUT"); diff --git a/proxy/logging/LogAccess.cc b/proxy/logging/LogAccess.cc index 37849d2d273..02db557c700 100644 --- a/proxy/logging/LogAccess.cc +++ b/proxy/logging/LogAccess.cc @@ -2011,6 +2011,24 @@ LogAccess::marshal_client_security_curve(char *buf) return round_len; } +int +LogAccess::marshal_client_security_alpn(char *buf) +{ + const char *alpn = "-"; + if (const int alpn_id = m_http_sm->client_alpn_id; alpn_id != SessionProtocolNameRegistry::INVALID) { + ts::TextView client_sec_alpn = globalSessionProtocolNameRegistry.nameFor(alpn_id); + alpn = client_sec_alpn.data(); + } + + int round_len = LogAccess::strlen(alpn); + + if (buf) { + marshal_str(buf, alpn, round_len); + } + + return round_len; +} + /*------------------------------------------------------------------------- -------------------------------------------------------------------------*/ diff --git a/proxy/logging/LogAccess.h b/proxy/logging/LogAccess.h index 9b14644f3ec..ff650acb87e 100644 --- a/proxy/logging/LogAccess.h +++ b/proxy/logging/LogAccess.h @@ -154,6 +154,7 @@ class LogAccess inkcoreapi int marshal_client_security_protocol(char *); // STR inkcoreapi int marshal_client_security_cipher_suite(char *); // STR inkcoreapi int marshal_client_security_curve(char *); // STR + inkcoreapi int marshal_client_security_alpn(char *); // STR inkcoreapi int marshal_client_finish_status_code(char *); // INT inkcoreapi int marshal_client_req_id(char *); // INT inkcoreapi int marshal_client_req_uuid(char *); // STR