This is an automated email from the ASF dual-hosted git repository. zwoop 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 cdcd881 Adds a new log tag for the MPTCP state of a connection cdcd881 is described below commit cdcd881e48bc25745d45f1c33a5f3ffc5d906d74 Author: Leif Hedstrom <zw...@apache.org> AuthorDate: Fri Mar 15 09:08:42 2019 -0600 Adds a new log tag for the MPTCP state of a connection Possible values are: -1 == MPTCP was not enabled on the listening port 0 == MPTCP was enabled, but not negotiated 1 == MPTCP was enabled, and succesfully negotiated --- doc/admin-guide/logging/formatting.en.rst | 13 +++++++++---- include/tscore/ink_platform.h | 9 +++++++++ iocore/net/I_NetProcessor.h | 6 ++++++ iocore/net/I_NetVConnection.h | 18 ++++++++++++++++-- iocore/net/P_UnixNetVConnection.h | 16 ++++++++++++++++ iocore/net/UnixNetAccept.cc | 10 ++++++++++ iocore/net/UnixNetProcessor.cc | 1 + mgmt/LocalManager.cc | 12 +++--------- proxy/PluginVC.cc | 6 ++++++ proxy/PluginVC.h | 1 + proxy/http/HttpProxyServerMain.cc | 1 + proxy/http/HttpSM.cc | 11 +++++++---- proxy/http/HttpSM.h | 30 +++++++++++++++--------------- proxy/logging/Log.cc | 5 +++++ proxy/logging/LogAccess.cc | 15 +++++++++++++++ proxy/logging/LogAccess.h | 1 + 16 files changed, 121 insertions(+), 34 deletions(-) diff --git a/doc/admin-guide/logging/formatting.en.rst b/doc/admin-guide/logging/formatting.en.rst index 1a4bce0..1217663 100644 --- a/doc/admin-guide/logging/formatting.en.rst +++ b/doc/admin-guide/logging/formatting.en.rst @@ -45,7 +45,7 @@ The return value from the ``format`` function is the log format object which may then be supplied to the appropriate ``log.*`` functions that define your logging destinations. -A very simple exampe, which contains only the timestamp of when the event began +A very simple example, which contains only the timestamp of when the event began and the canonical URL of the request, would look like: .. code:: yaml @@ -233,7 +233,7 @@ Error Code The log fields of error code which is triggered session close or transaction close. The first byte of this field indicates that the error code is session level (``S``) or transaction level (``T``). -When no error code is received or transmitted, these fileds are ``-``. +When no error code is received or transmitted, these fields are ``-``. For HTTP/2, error code are described in RFC 7540 section 7. ===== =============== ========================================================= @@ -660,6 +660,7 @@ TCP Details ~~~~~~~~~~~ .. _cqtr: +.. _cqmpt: The following logging fields reveal information about the TCP layer of client, proxy, and origin server connections. @@ -670,6 +671,10 @@ Field Source Description cqtr Client Request TCP reused status of the connection between the client and |TS| proxy, indicating whether the request was delivered through an already established connection. +cqmpt Client Request Indicates the MPTCP state of the connection. ``-1`` means + MPTCP was not enabled on the listening port, whereas ``0`` + and ``1`` indicates whether MPTCP was successfully + negotiated or not. ===== ============== ========================================================== .. _admin-logging-fields-time: @@ -698,7 +703,7 @@ The logging fields expose a variety of timing related information about client, proxy, and origin transactions. Variants of some of the fields provide timing resolution of the same underlying detail in milliseconds and seconds (both fractional and rounded-down integers). These variants are particularly useful -in accomodating the emulation of other HTTP proxy softwares' logging formats. +in accommodating the emulation of other HTTP proxy softwares' logging formats. Other fields in this category provide variously formatted timestamps of particular events within the current transaction (e.g. the time at which a @@ -731,7 +736,7 @@ ms Proxy Timestamp in milliseconds of a specific milestone which milestone to use. msdms Proxy Difference in milliseconds between the timestamps of two milestones. See note below about - specifying which miletones to use. + specifying which milestones to use. stms Proxy-Origin Connection Time (in milliseconds) spent accessing the origin server. Measured from the time the connection between proxy and origin is established to the diff --git a/include/tscore/ink_platform.h b/include/tscore/ink_platform.h index a7e0e8a..6bef79d 100644 --- a/include/tscore/ink_platform.h +++ b/include/tscore/ink_platform.h @@ -190,3 +190,12 @@ typedef unsigned int in_addr_t; // on various OSs (linux-4096,osx/bsd-1024, // windows-260,etc) #endif + +// This is a little bit of a hack for now, until MPTCP has landed upstream in Linux land. +#ifndef MPTCP_ENABLED +#if defined(linux) +#define MPTCP_ENABLED 42 +#else +#define MPTCP_ENABLED 0 +#endif +#endif diff --git a/iocore/net/I_NetProcessor.h b/iocore/net/I_NetProcessor.h index b8dee4e..570e7f3 100644 --- a/iocore/net/I_NetProcessor.h +++ b/iocore/net/I_NetProcessor.h @@ -97,6 +97,12 @@ public: */ bool f_inbound_transparent; + /** MPTCP enabled on listener. + @internal For logging and metrics purposes to know whether the + listener enabled MPTCP or not. + */ + bool f_mptcp; + /// Proxy Protocol enabled bool f_proxy_protocol; diff --git a/iocore/net/I_NetVConnection.h b/iocore/net/I_NetVConnection.h index e906568..e1e9504 100644 --- a/iocore/net/I_NetVConnection.h +++ b/iocore/net/I_NetVConnection.h @@ -21,9 +21,11 @@ limitations under the License. */ - #pragma once +#include <string_view> +#include <optional> + #include "tscore/ink_inet.h" #include "I_Action.h" #include "I_VConnection.h" @@ -32,7 +34,6 @@ #include "I_IOBuffer.h" #include "I_Socks.h" #include "ts/apidefs.h" -#include <string_view> #include "YamlSNIConfig.h" #include "tscpp/util/TextView.h" #include "tscore/IpMap.h" @@ -649,6 +650,9 @@ public: /** Set remote sock addr struct. */ virtual void set_remote_addr(const sockaddr *) = 0; + /** Set the MPTCP state for this connection */ + virtual void set_mptcp_state() = 0; + // for InkAPI bool get_is_internal_request() const @@ -668,6 +672,14 @@ public: { return is_transparent; } + + /// Get the MPTCP state of the VC. + std::optional<bool> + get_mptcp_state() const + { + return mptcp_state; + } + /// Set the transparency state. void set_is_transparent(bool state = true) @@ -823,6 +835,8 @@ protected: bool is_transparent = false; /// Set if proxy protocol is enabled bool is_proxy_protocol = false; + /// This is essentially a tri-state, we leave it undefined to mean no MPTCP support + std::optional<bool> mptcp_state; /// Set if the next write IO that empties the write buffer should generate an event. int write_buffer_empty_event = 0; /// NetVConnection Context. diff --git a/iocore/net/P_UnixNetVConnection.h b/iocore/net/P_UnixNetVConnection.h index f56a208..46111bc 100644 --- a/iocore/net/P_UnixNetVConnection.h +++ b/iocore/net/P_UnixNetVConnection.h @@ -292,6 +292,7 @@ public: ink_hrtime get_active_timeout() override; void set_local_addr() override; + void set_mptcp_state() override; void set_remote_addr() override; void set_remote_addr(const sockaddr *) override; int set_tcp_init_cwnd(int init_cwnd) override; @@ -347,6 +348,21 @@ UnixNetVConnection::set_local_addr() ATS_UNUSED_RETURN(safe_getsockname(con.fd, &local_addr.sa, &local_sa_size)); } +// Update the internal VC state variable for MPTCP +inline void +UnixNetVConnection::set_mptcp_state() +{ + int mptcp_enabled = -1; + int mptcp_enabled_size = sizeof(mptcp_enabled); + + if (0 == safe_getsockopt(con.fd, IPPROTO_TCP, MPTCP_ENABLED, (char *)&mptcp_enabled, &mptcp_enabled_size)) { + Debug("socket_mptcp", "MPTCP socket state: %d", mptcp_enabled); + mptcp_state = mptcp_enabled > 0 ? true : false; + } else { + Debug("socket_mptcp", "MPTCP failed getsockopt(): %s", strerror(errno)); + } +} + inline ink_hrtime UnixNetVConnection::get_active_timeout() { diff --git a/iocore/net/UnixNetAccept.cc b/iocore/net/UnixNetAccept.cc index 0164d64..a1141e4 100644 --- a/iocore/net/UnixNetAccept.cc +++ b/iocore/net/UnixNetAccept.cc @@ -117,6 +117,9 @@ net_accept(NetAccept *na, void *ep, bool blockable) vc->set_is_transparent(na->opt.f_inbound_transparent); vc->set_is_proxy_protocol(na->opt.f_proxy_protocol); vc->set_context(NET_VCONNECTION_IN); + if (na->opt.f_mptcp) { + vc->set_mptcp_state(); // Try to get the MPTCP state, and update accordingly + } #ifdef USE_EDGE_TRIGGER // Set the vc as triggered and place it in the read ready queue later in case there is already data on the socket. if (na->server.http_accept_filter) { @@ -354,6 +357,9 @@ NetAccept::do_blocking_accept(EThread *t) vc->options.ip_family = opt.ip_family; vc->apply_options(); vc->set_context(NET_VCONNECTION_IN); + if (opt.f_mptcp) { + vc->set_mptcp_state(); // Try to get the MPTCP state, and update accordingly + } vc->accept_object = this; #ifdef USE_EDGE_TRIGGER // Set the vc as triggered and place it in the read ready queue later in case there is already data on the socket. @@ -503,6 +509,10 @@ NetAccept::acceptFastEvent(int event, void *ep) vc->options.ip_family = opt.ip_family; vc->apply_options(); vc->set_context(NET_VCONNECTION_IN); + if (opt.f_mptcp) { + vc->set_mptcp_state(); // Try to get the MPTCP state, and update accordingly + } + #ifdef USE_EDGE_TRIGGER // Set the vc as triggered and place it in the read ready queue later in case there is already data on the socket. if (server.http_accept_filter) { diff --git a/iocore/net/UnixNetProcessor.cc b/iocore/net/UnixNetProcessor.cc index 436e6fa..e9896d5 100644 --- a/iocore/net/UnixNetProcessor.cc +++ b/iocore/net/UnixNetProcessor.cc @@ -51,6 +51,7 @@ NetProcessor::AcceptOptions::reset() packet_tos = 0; tfo_queue_length = 0; f_inbound_transparent = false; + f_mptcp = false; f_proxy_protocol = false; return *this; } diff --git a/mgmt/LocalManager.cc b/mgmt/LocalManager.cc index a9205be..8caf6f0 100644 --- a/mgmt/LocalManager.cc +++ b/mgmt/LocalManager.cc @@ -47,14 +47,6 @@ using namespace std::literals; static const std::string_view MGMT_OPT{"-M"}; static const std::string_view RUNROOT_OPT{"--run-root="}; -#ifndef MPTCP_ENABLED -#if defined(linux) -#define MPTCP_ENABLED 42 -#else -#define MPTCP_ENABLED 0 -#endif -#endif - void LocalManager::mgmtCleanup() { @@ -1043,11 +1035,13 @@ LocalManager::bindProxyPort(HttpProxyPort &port) err = setsockopt(port.m_fd, IPPROTO_TCP, MPTCP_ENABLED, &one, sizeof(one)); if (err < 0) { mgmt_log("[bindProxyPort] Unable to enable MPTCP: %s\n", strerror(errno)); + Debug("lm_mptcp", "[bindProxyPort] Unable to enable MPTCP: %s", strerror(errno)); } else { mgmt_log("[bindProxyPort] Successfully enabled MPTCP on %d\n", port.m_port); + Debug("lm_mptcp", "[bindProxyPort] Successfully enabled MPTCP on %d\n", port.m_port); } #else - Debug("lm", "[bindProxyPort] Multipath TCP requested but not configured on this host"); + Debug("lm_mptcp", "[bindProxyPort] Multipath TCP requested but not configured on this host"); #endif } diff --git a/proxy/PluginVC.cc b/proxy/PluginVC.cc index b4a62e5..79abc43 100644 --- a/proxy/PluginVC.cc +++ b/proxy/PluginVC.cc @@ -963,6 +963,12 @@ PluginVC::set_remote_addr(const sockaddr * /* new_sa ATS_UNUSED */) return; } +void +PluginVC::set_mptcp_state() +{ + return; +} + int PluginVC::set_tcp_init_cwnd(int /* init_cwnd ATS_UNUSED */) { diff --git a/proxy/PluginVC.h b/proxy/PluginVC.h index d620549..6ee6b4d 100644 --- a/proxy/PluginVC.h +++ b/proxy/PluginVC.h @@ -102,6 +102,7 @@ public: void set_local_addr() override; void set_remote_addr() override; void set_remote_addr(const sockaddr *) override; + void set_mptcp_state() override; int set_tcp_init_cwnd(int init_cwnd) override; int set_tcp_congestion_control(int) override; diff --git a/proxy/http/HttpProxyServerMain.cc b/proxy/http/HttpProxyServerMain.cc index 7863833..11abf90 100644 --- a/proxy/http/HttpProxyServerMain.cc +++ b/proxy/http/HttpProxyServerMain.cc @@ -158,6 +158,7 @@ make_net_accept_options(const HttpProxyPort *port, unsigned nthreads) if (port) { net.f_inbound_transparent = port->m_inbound_transparent_p; + net.f_mptcp = port->m_mptcp; net.ip_family = port->m_family; net.local_port = port->m_port; net.f_proxy_protocol = port->m_proxy_protocol; diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index 81ec27f..3b9ae71 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -465,12 +465,15 @@ HttpSM::attach_client_session(ProxyClientTransaction *client_vc, IOBufferReader _client_connection_id = p->connection_id(); } } - // We've already verified that the netvc is !nullptr above, and netvc == ua_txn->get_netvc() - is_internal = netvc->get_is_internal_request(); - // Collect log & stats information - client_tcp_reused = !(ua_txn->is_first_transaction()); + // Collect log & stats information. We've already verified that the netvc is !nullptr above, + // and netvc == ua_txn->get_netvc(). SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(netvc); + + is_internal = netvc->get_is_internal_request(); + mptcp_state = netvc->get_mptcp_state(); + client_tcp_reused = !(ua_txn->is_first_transaction()); + if (ssl_vc != nullptr) { client_connection_is_ssl = true; client_ssl_reused = ssl_vc->getSSLSessionCacheHit(); diff --git a/proxy/http/HttpSM.h b/proxy/http/HttpSM.h index 76a0d13..30ace9e 100644 --- a/proxy/http/HttpSM.h +++ b/proxy/http/HttpSM.h @@ -29,9 +29,11 @@ ****************************************************************************/ - #pragma once +#include <string_view> +#include <optional> + #include "tscore/ink_platform.h" #include "P_EventSystem.h" #include "HttpCacheSM.h" @@ -41,9 +43,7 @@ #include "InkAPIInternal.h" #include "../ProxyClientTransaction.h" #include "HdrUtils.h" -#include <string_view> #include "tscore/History.h" -//#include "AuthHttpAdapter.h" #define HTTP_API_CONTINUE (INK_API_EVENT_EVENTS_START + 0) #define HTTP_API_ERROR (INK_API_EVENT_EVENTS_START + 1) @@ -310,12 +310,12 @@ public: // YTS Team, yamsat Plugin bool enable_redirection = false; // To check if redirection is enabled + bool post_failed = false; // Added to identify post failure + bool debug_on = false; // Transaction specific debug flag char *redirect_url = nullptr; // url for force redirect (provide users a functionality to redirect to another url when needed) int redirect_url_len = 0; - int redirection_tries = 0; // To monitor number of redirections - int64_t transfered_bytes = 0; // Added to calculate POST data - bool post_failed = false; // Added to identify post failure - bool debug_on = false; // Transaction specific debug flag + int redirection_tries = 0; // To monitor number of redirections + int64_t transfered_bytes = 0; // Added to calculate POST data // Tunneling request to plugin HttpPluginTunnel_t plugin_tunnel_type = HTTP_NO_PLUGIN_TUNNEL; @@ -335,9 +335,9 @@ public: void postbuf_copy_partial_data(); void postbuf_init(IOBufferReader *ua_reader); void set_postbuf_done(bool done); + IOBufferReader *get_postbuf_clone_reader(); bool get_postbuf_done(); bool is_postbuf_valid(); - IOBufferReader *get_postbuf_clone_reader(); protected: int reentrancy_count = 0; @@ -536,17 +536,17 @@ public: int pushed_response_hdr_bytes = 0; int64_t pushed_response_body_bytes = 0; bool client_tcp_reused = false; - // Info about client's SSL connection. - bool client_ssl_reused = false; - bool client_connection_is_ssl = false; - bool is_internal = false; + bool client_ssl_reused = false; + bool client_connection_is_ssl = false; + bool is_internal = false; + bool server_connection_is_ssl = false; + bool is_waiting_for_full_body = false; + bool is_using_post_buffer = false; + std::optional<bool> mptcp_state; // Don't initialize, that marks it as "not defined". const char *client_protocol = "-"; const char *client_sec_protocol = "-"; const char *client_cipher_suite = "-"; int server_transact_count = 0; - bool server_connection_is_ssl = false; - bool is_waiting_for_full_body = false; - bool is_using_post_buffer = false; TransactionMilestones milestones; ink_hrtime api_timer = 0; diff --git a/proxy/logging/Log.cc b/proxy/logging/Log.cc index b3a2354..04038f1 100644 --- a/proxy/logging/Log.cc +++ b/proxy/logging/Log.cc @@ -502,6 +502,11 @@ Log::init_fields() global_field_list.add(field, false); field_symbol_hash.emplace("cqint", field); + field = new LogField("client_req_mptcp", "cqmpt", LogField::sINT, &LogAccess::marshal_client_req_mptcp_state, + &LogAccess::unmarshal_int_to_str); + global_field_list.add(field, false); + field_symbol_hash.emplace("cqmpt", field); + field = new LogField("client_sec_protocol", "cqssv", LogField::STRING, &LogAccess::marshal_client_security_protocol, (LogField::UnmarshalFunc)&LogAccess::unmarshal_str); global_field_list.add(field, false); diff --git a/proxy/logging/LogAccess.cc b/proxy/logging/LogAccess.cc index 4fc737b..202cfaa 100644 --- a/proxy/logging/LogAccess.cc +++ b/proxy/logging/LogAccess.cc @@ -1725,6 +1725,21 @@ LogAccess::marshal_client_req_is_internal(char *buf) return INK_MIN_ALIGN; } +int +LogAccess::marshal_client_req_mptcp_state(char *buf) +{ + if (buf) { + int val = -1; + + if (m_http_sm->mptcp_state.has_value()) { + val = m_http_sm->mptcp_state.value() ? 1 : 0; + } else { + } + marshal_int(buf, val); + } + return INK_MIN_ALIGN; +} + /*------------------------------------------------------------------------- -------------------------------------------------------------------------*/ diff --git a/proxy/logging/LogAccess.h b/proxy/logging/LogAccess.h index 1e05282..c915204 100644 --- a/proxy/logging/LogAccess.h +++ b/proxy/logging/LogAccess.h @@ -150,6 +150,7 @@ public: inkcoreapi int marshal_client_req_is_ssl(char *); // INT inkcoreapi int marshal_client_req_ssl_reused(char *); // INT inkcoreapi int marshal_client_req_is_internal(char *); // INT + inkcoreapi int marshal_client_req_mptcp_state(char *); // INT inkcoreapi int marshal_client_security_protocol(char *); // STR inkcoreapi int marshal_client_security_cipher_suite(char *); // STR inkcoreapi int marshal_client_finish_status_code(char *); // INT