From c977140b7ece59853b850bebd3440fc747a06864 Mon Sep 17 00:00:00 2001 From: Brian Neradt Date: Mon, 30 Oct 2023 20:33:57 +0000 Subject: [PATCH 1/3] HttpConnectionCount move to iocore/net This moves HttpConnectionCount to iocore/net from proxy/http in anticipation to using its functionality on the client accept connection side. While doing so, this also renames HttpConnectionCount to ConnectionTracker because it is no longer HTTP transaction specific. --- .../net/ConnectionTracker.h} | 90 +++++----- .../net/SessionSharingAPIEnums.h} | 0 include/proxy/PoolableSession.h | 7 +- include/proxy/http/Http1ServerSession.h | 4 +- include/proxy/http/HttpConfig.h | 8 +- include/proxy/http/HttpTransact.h | 4 +- include/shared/overridable_txn_vars.h | 2 +- src/api/InkAPI.cc | 13 +- src/iocore/net/CMakeLists.txt | 1 + .../net/ConnectionTracker.cc} | 168 ++++++++---------- src/iocore/net/Makefile.am | 1 + src/proxy/http/CMakeLists.txt | 1 - src/proxy/http/HttpConfig.cc | 13 +- src/proxy/http/HttpProxyServerMain.cc | 21 ++- src/proxy/http/HttpSM.cc | 23 +-- src/proxy/http/Makefile.am | 2 - src/shared/overridable_txn_vars.cc | 6 +- 17 files changed, 187 insertions(+), 177 deletions(-) rename include/{proxy/http/HttpConnectionCount.h => iocore/net/ConnectionTracker.h} (79%) rename include/{proxy/http/HttpProxyAPIEnums.h => iocore/net/SessionSharingAPIEnums.h} (100%) rename src/{proxy/http/HttpConnectionCount.cc => iocore/net/ConnectionTracker.cc} (64%) diff --git a/include/proxy/http/HttpConnectionCount.h b/include/iocore/net/ConnectionTracker.h similarity index 79% rename from include/proxy/http/HttpConnectionCount.h rename to include/iocore/net/ConnectionTracker.h index 25f24b1a051..b13f2b39760 100644 --- a/include/proxy/http/HttpConnectionCount.h +++ b/include/iocore/net/ConnectionTracker.h @@ -40,8 +40,7 @@ #include "swoc/bwf_fwd.h" #include "swoc/TextView.h" #include -#include "proxy/http/HttpProxyAPIEnums.h" -#include "proxy/Show.h" +#include "iocore/net/SessionSharingAPIEnums.h" /** * Singleton class to keep track of the number of outbound connections. @@ -49,13 +48,13 @@ * Outbound connections are divided in to equivalence classes (called "groups" here) based on the * session matching setting. Tracking data is stored for each group. */ -class OutboundConnTrack +class ConnectionTracker { - using self_type = OutboundConnTrack; ///< Self reference type. + using self_type = ConnectionTracker; ///< Self reference type. public: // Non-copyable. - OutboundConnTrack(const self_type &) = delete; + ConnectionTracker(const self_type &) = delete; self_type &operator=(const self_type &) = delete; /// Definition of an upstream server group equivalence class. @@ -71,23 +70,23 @@ class OutboundConnTrack /// Per transaction configuration values. struct TxnConfig { - int max{0}; ///< Maximum concurrent connections. - int min{0}; ///< Minimum keepalive connections. - MatchType match{MATCH_IP}; ///< Match type. + int server_max{0}; ///< Maximum concurrent server connections. + int server_min{0}; ///< Minimum keepalive server connections. + MatchType server_match{MATCH_IP}; ///< Server match type. }; /** Static configuration values. */ struct GlobalConfig { - std::chrono::seconds alert_delay{60}; ///< Alert delay in seconds. + std::chrono::seconds server_alert_delay{60}; ///< Alert delay in seconds. }; // The names of the configuration values. // Unfortunately these are not used in RecordsConfig.cc so that must be made consistent by hand. // Note: These need to be @c constexpr or there are static initialization ordering risks. - static constexpr std::string_view CONFIG_VAR_MAX{"proxy.config.http.per_server.connection.max"}; - static constexpr std::string_view CONFIG_VAR_MIN{"proxy.config.http.per_server.connection.min"}; - static constexpr std::string_view CONFIG_VAR_MATCH{"proxy.config.http.per_server.connection.match"}; - static constexpr std::string_view CONFIG_VAR_ALERT_DELAY{"proxy.config.http.per_server.connection.alert_delay"}; + static constexpr std::string_view CONFIG_SERVER_VAR_MAX{"proxy.config.http.per_server.connection.max"}; + static constexpr std::string_view CONFIG_SERVER_VAR_MIN{"proxy.config.http.per_server.connection.min"}; + static constexpr std::string_view CONFIG_SERVER_VAR_MATCH{"proxy.config.http.per_server.connection.match"}; + static constexpr std::string_view CONFIG_SERVER_VAR_ALERT_DELAY{"proxy.config.http.per_server.connection.alert_delay"}; /// A record for the outbound connection count. /// These are stored per outbound session equivalence class, as determined by the session matching. @@ -118,7 +117,7 @@ class OutboundConnTrack // Counting data. std::atomic _count{0}; ///< Number of outbound connections. std::atomic _count_max{0}; ///< largest observed @a count value. - std::atomic _blocked{0}; ///< Number of outbound connections blocked since last alert. + std::atomic _blocked{0}; ///< Number of connections blocked since last alert. std::atomic _in_queue{0}; ///< # of connections queued, waiting for a connection. std::atomic _last_alert{0}; ///< Absolute time of the last alert. @@ -130,6 +129,7 @@ class OutboundConnTrack * Construct from @c Key because the use cases do a table lookup first so the @c Key is already constructed. * @param key A populated @c Key structure - values are copied to the @c Group. * @param fqdn The full FQDN. + * @param min_keep_alive The minimum number of origin keep alive connections to maintain. */ Group(Key const &key, std::string_view fqdn, int min_keep_alive); /// Key equality checker. @@ -182,22 +182,22 @@ class OutboundConnTrack /** Generate a Warning that a connection was blocked. * - * @param config Transaction local configuration. - * @param sm_id State machine ID to display in Warning. + * @param max_connections The maximum configured number of connections for the group. + * @param sm_id ID to display in Warning. * @param count Count value to display in Warning. * @param addr IP address of the upstream. * @param debug_tag Tag to use for the debug message. If no debug message should be generated set this to @c nullptr. */ - void Warn_Blocked(const TxnConfig *config, int64_t sm_id, int count, const sockaddr *addr, const char *debug_tag = nullptr); + void Warn_Blocked(int max_connections, int64_t id, int count, const sockaddr *addr, const char *debug_tag = nullptr); }; - /** Get or create the @c Group for the specified session properties. + /** Get or create the @c Group for the specified outbound session properties. * @param txn_cnf The transaction local configuration. * @param fqdn The fully qualified domain name of the upstream. * @param addr The IP address of the upstream. * @return A @c Group for the arguments, existing if possible and created if not. */ - static TxnState obtain(TxnConfig const &txn_cnf, std::string_view fqdn, const IpEndpoint &addr); + static TxnState obtain_outbound(TxnConfig const &txn_cnf, std::string_view fqdn, IpEndpoint const &addr); /** Get the currently existing groups. * @param [out] groups parameter - pointers to the groups are pushed in to this container. @@ -244,9 +244,9 @@ class OutboundConnTrack static void Warning_Bad_Match_Type(std::string_view tag); // Converters for overridable values for use in the TS API. - static const MgmtConverter MIN_CONV; - static const MgmtConverter MAX_CONV; - static const MgmtConverter MATCH_CONV; + static const MgmtConverter MIN_SERVER_CONV; + static const MgmtConverter MAX_SERVER_CONV; + static const MgmtConverter SERVER_MATCH_CONV; protected: static GlobalConfig *_global_config; ///< Global configuration data. @@ -278,13 +278,13 @@ class OutboundConnTrack Imp &instance(); }; -inline OutboundConnTrack::Imp & -OutboundConnTrack::instance() +inline ConnectionTracker::Imp & +ConnectionTracker::instance() { return _imp; } -inline OutboundConnTrack::Group::Group(Key const &key, std::string_view fqdn, int min_keep_alive) +inline ConnectionTracker::Group::Group(Key const &key, std::string_view fqdn, int min_keep_alive) : _hash(key._hash), _match_type(key._match_type), min_keep_alive_conns(min_keep_alive), _key{_addr, _hash, _match_type} { // store the host name if relevant. @@ -300,7 +300,7 @@ inline OutboundConnTrack::Group::Group(Key const &key, std::string_view fqdn, in } inline uint64_t -OutboundConnTrack::Group::hash(const Key &key) +ConnectionTracker::Group::hash(const Key &key) { switch (key._match_type) { case MATCH_IP: @@ -317,20 +317,20 @@ OutboundConnTrack::Group::hash(const Key &key) } inline bool -OutboundConnTrack::TxnState::is_active() +ConnectionTracker::TxnState::is_active() { return nullptr != _g; } inline int -OutboundConnTrack::TxnState::reserve() +ConnectionTracker::TxnState::reserve() { _reserved_p = true; return ++_g->_count; } inline void -OutboundConnTrack::TxnState::release() +ConnectionTracker::TxnState::release() { if (_reserved_p) { _reserved_p = false; @@ -338,22 +338,22 @@ OutboundConnTrack::TxnState::release() } } -inline OutboundConnTrack::Group * -OutboundConnTrack::TxnState::drop() +inline ConnectionTracker::Group * +ConnectionTracker::TxnState::drop() { _reserved_p = false; return _g; } inline int -OutboundConnTrack::TxnState::enqueue() +ConnectionTracker::TxnState::enqueue() { _queued_p = true; return ++_g->_in_queue; } inline void -OutboundConnTrack::TxnState::dequeue() +ConnectionTracker::TxnState::dequeue() { if (_queued_p) { _queued_p = false; @@ -362,7 +362,7 @@ OutboundConnTrack::TxnState::dequeue() } inline void -OutboundConnTrack::TxnState::clear() +ConnectionTracker::TxnState::clear() { if (_g) { this->dequeue(); @@ -372,7 +372,7 @@ OutboundConnTrack::TxnState::clear() } inline void -OutboundConnTrack::TxnState::update_max_count(int count) +ConnectionTracker::TxnState::update_max_count(int count) { auto cmax = _g->_count_max.load(); if (count > cmax) { @@ -381,48 +381,46 @@ OutboundConnTrack::TxnState::update_max_count(int count) } inline void -OutboundConnTrack::TxnState::blocked() +ConnectionTracker::TxnState::blocked() { ++_g->_blocked; } /* === Linkage === */ inline auto -OutboundConnTrack::Linkage::next_ptr(value_type *value) -> value_type *& +ConnectionTracker::Linkage::next_ptr(value_type *value) -> value_type *& { return value->_next; } inline auto -OutboundConnTrack::Linkage::prev_ptr(value_type *value) -> value_type *& +ConnectionTracker::Linkage::prev_ptr(value_type *value) -> value_type *& { return value->_prev; } inline uint64_t -OutboundConnTrack::Linkage::hash_of(key_type key) +ConnectionTracker::Linkage::hash_of(key_type key) { return Group::hash(key); } inline auto -OutboundConnTrack::Linkage::key_of(value_type *value) -> key_type +ConnectionTracker::Linkage::key_of(value_type *value) -> key_type { return value->_key; } inline bool -OutboundConnTrack::Linkage::equal(key_type lhs, key_type rhs) +ConnectionTracker::Linkage::equal(key_type lhs, key_type rhs) { return Group::equal(lhs, rhs); } /* === */ -Action *register_ShowConnectionCount(Continuation *, HTTPHdr *); - namespace swoc { -BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, OutboundConnTrack::MatchType type); -BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, OutboundConnTrack::Group::Key const &key); -BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, OutboundConnTrack::Group const &g); +BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, ConnectionTracker::MatchType type); +BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, ConnectionTracker::Group::Key const &key); +BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, ConnectionTracker::Group const &g); } // namespace swoc diff --git a/include/proxy/http/HttpProxyAPIEnums.h b/include/iocore/net/SessionSharingAPIEnums.h similarity index 100% rename from include/proxy/http/HttpProxyAPIEnums.h rename to include/iocore/net/SessionSharingAPIEnums.h diff --git a/include/proxy/PoolableSession.h b/include/proxy/PoolableSession.h index 08179177698..3dcbace7dc6 100644 --- a/include/proxy/PoolableSession.h +++ b/include/proxy/PoolableSession.h @@ -23,6 +23,7 @@ #pragma once +#include "iocore/net/ConnectionTracker.h" #include "proxy/ProxySession.h" class PoolableSession : public ProxySession @@ -74,7 +75,7 @@ class PoolableSession : public ProxySession TSServerSessionSharingMatchMask sharing_match = TS_SERVER_SESSION_SHARING_MATCH_MASK_NONE; TSServerSessionSharingPoolType sharing_pool = TS_SERVER_SESSION_SHARING_POOL_GLOBAL; - void enable_outbound_connection_tracking(OutboundConnTrack::Group *group); + void enable_outbound_connection_tracking(ConnectionTracker::Group *group); void release_outbound_connection_tracking(); void attach_hostname(const char *hostname); @@ -89,7 +90,7 @@ class PoolableSession : public ProxySession // Keep track of connection limiting and a pointer to the // singleton that keeps track of the connection counts. - OutboundConnTrack::Group *conn_track_group = nullptr; + ConnectionTracker::Group *conn_track_group = nullptr; virtual IOBufferReader *get_remote_reader() = 0; @@ -209,7 +210,7 @@ PoolableSession::FQDNLinkage::equal(CryptoHash const &lhs, CryptoHash const &rhs } inline void -PoolableSession::enable_outbound_connection_tracking(OutboundConnTrack::Group *group) +PoolableSession::enable_outbound_connection_tracking(ConnectionTracker::Group *group) { ink_assert(nullptr == conn_track_group); conn_track_group = group; diff --git a/include/proxy/http/Http1ServerSession.h b/include/proxy/http/Http1ServerSession.h index 346a5e5b6e5..567fb1b6e6c 100644 --- a/include/proxy/http/Http1ServerSession.h +++ b/include/proxy/http/Http1ServerSession.h @@ -32,8 +32,8 @@ #pragma once -#include "proxy/http/HttpConnectionCount.h" -#include "proxy/http/HttpProxyAPIEnums.h" +#include "iocore/net/ConnectionTracker.h" +#include "iocore/net/SessionSharingAPIEnums.h" #include "proxy/PoolableSession.h" #include "proxy/http/Http1ServerTransaction.h" diff --git a/include/proxy/http/HttpConfig.h b/include/proxy/http/HttpConfig.h index 7e628dc4d52..da253a150fb 100644 --- a/include/proxy/http/HttpConfig.h +++ b/include/proxy/http/HttpConfig.h @@ -48,10 +48,10 @@ #include "tscore/ink_resolver.h" #include "tscore/Regex.h" #include "tscpp/util/ts_bw.h" -#include "proxy/http/HttpProxyAPIEnums.h" #include "iocore/eventsystem/ConfigProcessor.h" +#include "iocore/net/ConnectionTracker.h" +#include "iocore/net/SessionSharingAPIEnums.h" #include "records/RecProcess.h" -#include "proxy/http/HttpConnectionCount.h" #include "tscpp/util/ts_ip.h" #include "api/Metrics.h" @@ -638,7 +638,7 @@ struct OverridableHttpConfigParams { MgmtInt default_buffer_water_mark = 32768; MgmtInt slow_log_threshold = 0; - OutboundConnTrack::TxnConfig outbound_conntrack; + ConnectionTracker::TxnConfig connection_tracker_config; MgmtInt plugin_vc_default_buffer_index = BUFFER_SIZE_INDEX_32K; MgmtInt plugin_vc_default_buffer_water_mark = DEFAULT_PLUGIN_VC_BUFFER_WATER_MARK; @@ -771,7 +771,7 @@ struct HttpConfigParams : public ConfigInfo { MgmtByte server_session_sharing_pool = TS_SERVER_SESSION_SHARING_POOL_THREAD; - OutboundConnTrack::GlobalConfig global_outbound_conntrack; + ConnectionTracker::GlobalConfig global_connection_tracker_config; // bitset to hold the status codes that will BE cached with negative caching enabled HttpStatusBitset negative_caching_list; diff --git a/include/proxy/http/HttpTransact.h b/include/proxy/http/HttpTransact.h index 243ba4b6126..a22c1e554ca 100644 --- a/include/proxy/http/HttpTransact.h +++ b/include/proxy/http/HttpTransact.h @@ -76,8 +76,8 @@ using ink_time_t = time_t; struct HttpConfigParams; class HttpSM; +#include "iocore/net/ConnectionTracker.h" #include "tscore/InkErrno.h" -#include "proxy/http/HttpConnectionCount.h" #define UNKNOWN_INTERNAL_ERROR (INK_START_ERRNO - 1) @@ -717,7 +717,7 @@ class HttpTransact CacheLookupInfo cache_info; ResolveInfo dns_info; RedirectInfo redirect_info; - OutboundConnTrack::TxnState outbound_conn_track_state; + ConnectionTracker::TxnState outbound_conn_track_state; ConnectionAttributes client_info; ConnectionAttributes parent_info; ConnectionAttributes server_info; diff --git a/include/shared/overridable_txn_vars.h b/include/shared/overridable_txn_vars.h index 9f82691456c..6558ebfb967 100644 --- a/include/shared/overridable_txn_vars.h +++ b/include/shared/overridable_txn_vars.h @@ -24,8 +24,8 @@ #pragma once #include +#include "iocore/net/ConnectionTracker.h" #include "proxy/hdrs/HTTP.h" -#include "proxy/http/HttpConnectionCount.h" namespace ts { diff --git a/src/api/InkAPI.cc b/src/api/InkAPI.cc index aa6c9c6183b..6df05780535 100644 --- a/src/api/InkAPI.cc +++ b/src/api/InkAPI.cc @@ -56,6 +56,7 @@ #include "records/RecCore.h" #include "../iocore/net/P_SSLConfig.h" #include "../iocore/net/P_SSLClientUtils.h" +#include "iocore/net/ConnectionTracker.h" #include "iocore/net/SSLAPIHooks.h" #include "iocore/net/SSLDiags.h" #include "iocore/net/SSLInternal.h" @@ -8300,16 +8301,16 @@ _conf_to_memberp(TSOverridableConfigKey conf, OverridableHttpConfigParams *overr ret = _memberp_to_generic(&overridableHttpConfig->allow_half_open, conv); break; case TS_CONFIG_HTTP_PER_SERVER_CONNECTION_MAX: - ret = &overridableHttpConfig->outbound_conntrack.max; - conv = &OutboundConnTrack::MAX_CONV; + ret = &overridableHttpConfig->connection_tracker_config.server_max; + conv = &ConnectionTracker::MAX_SERVER_CONV; break; case TS_CONFIG_HTTP_SERVER_MIN_KEEP_ALIVE_CONNS: - ret = &overridableHttpConfig->outbound_conntrack.min; - conv = &OutboundConnTrack::MIN_CONV; + ret = &overridableHttpConfig->connection_tracker_config.server_min; + conv = &ConnectionTracker::MIN_SERVER_CONV; break; case TS_CONFIG_HTTP_PER_SERVER_CONNECTION_MATCH: - ret = &overridableHttpConfig->outbound_conntrack.match; - conv = &OutboundConnTrack::MATCH_CONV; + ret = &overridableHttpConfig->connection_tracker_config.server_match; + conv = &ConnectionTracker::SERVER_MATCH_CONV; break; case TS_CONFIG_HTTP_HOST_RESOLUTION_PREFERENCE: ret = &overridableHttpConfig->host_res_data; diff --git a/src/iocore/net/CMakeLists.txt b/src/iocore/net/CMakeLists.txt index 581f402351c..009c91f2fe9 100644 --- a/src/iocore/net/CMakeLists.txt +++ b/src/iocore/net/CMakeLists.txt @@ -22,6 +22,7 @@ add_library( BIO_fastopen.cc BoringSSLUtils.cc Connection.cc + ConnectionTracker.cc EventIO.cc Inline.cc YamlSNIConfig.cc diff --git a/src/proxy/http/HttpConnectionCount.cc b/src/iocore/net/ConnectionTracker.cc similarity index 64% rename from src/proxy/http/HttpConnectionCount.cc rename to src/iocore/net/ConnectionTracker.cc index 3b10292b178..698acacb835 100644 --- a/src/proxy/http/HttpConnectionCount.cc +++ b/src/iocore/net/ConnectionTracker.cc @@ -23,59 +23,63 @@ #include #include +#include "iocore/net/ConnectionTracker.h" #include "tscpp/util/ts_bw_format.h" #include "../../records/P_RecDefs.h" #include "proxy/http/HttpConfig.h" -#include "proxy/http/HttpConnectionCount.h" using namespace std::literals; extern void Enable_Config_Var(std::string_view const &name, bool (*cb)(const char *, RecDataT, RecData, void *), void *cookie); -OutboundConnTrack::Imp OutboundConnTrack::_imp; +ConnectionTracker::Imp ConnectionTracker::_imp; -OutboundConnTrack::GlobalConfig *OutboundConnTrack::_global_config{nullptr}; +ConnectionTracker::GlobalConfig *ConnectionTracker::_global_config{nullptr}; -const MgmtConverter OutboundConnTrack::MAX_CONV( - [](const void *data) -> MgmtInt { return static_cast(*static_cast(data)); }, - [](void *data, MgmtInt i) -> void { *static_cast(data) = static_cast(i); }); +const MgmtConverter ConnectionTracker::MAX_SERVER_CONV( + [](const void *data) -> MgmtInt { return static_cast(*static_cast(data)); }, + [](void *data, MgmtInt i) -> void { + *static_cast(data) = static_cast(i); + }); -const MgmtConverter OutboundConnTrack::MIN_CONV( - [](const void *data) -> MgmtInt { return static_cast(*static_cast(data)); }, - [](void *data, MgmtInt i) -> void { *static_cast(data) = static_cast(i); }); +const MgmtConverter ConnectionTracker::MIN_SERVER_CONV( + [](const void *data) -> MgmtInt { return static_cast(*static_cast(data)); }, + [](void *data, MgmtInt i) -> void { + *static_cast(data) = static_cast(i); + }); // Do integer and string conversions. -const MgmtConverter OutboundConnTrack::MATCH_CONV{ - [](const void *data) -> MgmtInt { return static_cast(*static_cast(data)); }, +const MgmtConverter ConnectionTracker::SERVER_MATCH_CONV{ + [](const void *data) -> MgmtInt { return static_cast(*static_cast(data)); }, [](void *data, MgmtInt i) -> void { // Problem - the InkAPITest requires being able to set an arbitrary value, so this can either // correctly clamp or pass the regression tests. Currently it passes the tests. // *static_cast(data) = std::clamp(static_cast(i), MATCH_IP, // MATCH_BOTH); - *static_cast(data) = static_cast(i); + *static_cast(data) = static_cast(i); }, nullptr, nullptr, [](const void *data) -> std::string_view { - auto t = *static_cast(data); - return t < 0 || t > OutboundConnTrack::MATCH_BOTH ? "Invalid"sv : OutboundConnTrack::MATCH_TYPE_NAME[t]; + auto t = *static_cast(data); + return t < 0 || t > ConnectionTracker::MATCH_BOTH ? "Invalid"sv : ConnectionTracker::MATCH_TYPE_NAME[t]; }, [](void *data, std::string_view src) -> void { - OutboundConnTrack::MatchType t; - if (OutboundConnTrack::lookup_match_type(src, t)) { - *static_cast(data) = t; + ConnectionTracker::MatchType t; + if (ConnectionTracker::lookup_match_type(src, t)) { + *static_cast(data) = t; } else { - OutboundConnTrack::Warning_Bad_Match_Type(src); + ConnectionTracker::Warning_Bad_Match_Type(src); } }}; -const std::array(OutboundConnTrack::MATCH_BOTH) + 1> OutboundConnTrack::MATCH_TYPE_NAME{ +const std::array(ConnectionTracker::MATCH_BOTH) + 1> ConnectionTracker::MATCH_TYPE_NAME{ {"ip"sv, "port"sv, "host"sv, "both"sv} }; // Make sure the clock is millisecond resolution or finer. -static_assert(OutboundConnTrack::Group::Clock::period::num == 1); -static_assert(OutboundConnTrack::Group::Clock::period::den >= 1000); +static_assert(ConnectionTracker::Group::Clock::period::num == 1); +static_assert(ConnectionTracker::Group::Clock::period::den >= 1000); // Configuration callback functions. namespace @@ -83,10 +87,10 @@ namespace bool Config_Update_Conntrack_Min(const char *name, RecDataT dtype, RecData data, void *cookie) { - auto config = static_cast(cookie); + auto config = static_cast(cookie); if (RECD_INT == dtype) { - config->min = data.rec_int; + config->server_min = data.rec_int; return true; } return false; @@ -95,10 +99,10 @@ Config_Update_Conntrack_Min(const char *name, RecDataT dtype, RecData data, void bool Config_Update_Conntrack_Max(const char *name, RecDataT dtype, RecData data, void *cookie) { - auto config = static_cast(cookie); + auto config = static_cast(cookie); if (RECD_INT == dtype) { - config->max = data.rec_int; + config->server_max = data.rec_int; return true; } return false; @@ -107,19 +111,19 @@ Config_Update_Conntrack_Max(const char *name, RecDataT dtype, RecData data, void bool Config_Update_Conntrack_Match(const char *name, RecDataT dtype, RecData data, void *cookie) { - auto config = static_cast(cookie); + auto config = static_cast(cookie); if (RECD_STRING == dtype) { - OutboundConnTrack::MatchType match_type; + ConnectionTracker::MatchType match_type; std::string_view tag{data.rec_string}; - if (OutboundConnTrack::lookup_match_type(tag, match_type)) { - config->match = match_type; + if (ConnectionTracker::lookup_match_type(tag, match_type)) { + config->server_match = match_type; return true; } else { - OutboundConnTrack::Warning_Bad_Match_Type(tag); + ConnectionTracker::Warning_Bad_Match_Type(tag); } } else { - Warning("Invalid type for '%s' - must be 'INT'", OutboundConnTrack::CONFIG_VAR_MATCH.data()); + Warning("Invalid type for '%s' - must be 'INT'", ConnectionTracker::CONFIG_SERVER_VAR_MATCH.data()); } return false; } @@ -127,10 +131,10 @@ Config_Update_Conntrack_Match(const char *name, RecDataT dtype, RecData data, vo bool Config_Update_Conntrack_Alert_Delay(const char *name, RecDataT dtype, RecData data, void *cookie) { - auto config = static_cast(cookie); + auto config = static_cast(cookie); if (RECD_INT == dtype && data.rec_int >= 0) { - config->alert_delay = std::chrono::seconds(data.rec_int); + config->server_alert_delay = std::chrono::seconds(data.rec_int); return true; } return false; @@ -139,37 +143,37 @@ Config_Update_Conntrack_Alert_Delay(const char *name, RecDataT dtype, RecData da } // namespace void -OutboundConnTrack::config_init(GlobalConfig *global, TxnConfig *txn) +ConnectionTracker::config_init(GlobalConfig *global, TxnConfig *txn) { _global_config = global; // remember this for later retrieval. // Per transaction lookup must be done at call time because it changes. - Enable_Config_Var(CONFIG_VAR_MIN, &Config_Update_Conntrack_Min, txn); - Enable_Config_Var(CONFIG_VAR_MAX, &Config_Update_Conntrack_Max, txn); - Enable_Config_Var(CONFIG_VAR_MATCH, &Config_Update_Conntrack_Match, txn); - Enable_Config_Var(CONFIG_VAR_ALERT_DELAY, &Config_Update_Conntrack_Alert_Delay, global); + Enable_Config_Var(CONFIG_SERVER_VAR_MIN, &Config_Update_Conntrack_Min, txn); + Enable_Config_Var(CONFIG_SERVER_VAR_MAX, &Config_Update_Conntrack_Max, txn); + Enable_Config_Var(CONFIG_SERVER_VAR_MATCH, &Config_Update_Conntrack_Match, txn); + Enable_Config_Var(CONFIG_SERVER_VAR_ALERT_DELAY, &Config_Update_Conntrack_Alert_Delay, global); } -OutboundConnTrack::TxnState -OutboundConnTrack::obtain(TxnConfig const &txn_cnf, std::string_view fqdn, IpEndpoint const &addr) +ConnectionTracker::TxnState +ConnectionTracker::obtain_outbound(TxnConfig const &txn_cnf, std::string_view fqdn, IpEndpoint const &addr) { TxnState zret; CryptoHash hash; CryptoContext().hash_immediate(hash, fqdn.data(), fqdn.size()); - Group::Key key{addr, hash, txn_cnf.match}; + Group::Key key{addr, hash, txn_cnf.server_match}; std::lock_guard lock(_imp._mutex); // Table lock auto loc = _imp._table.find(key); if (loc != _imp._table.end()) { zret._g = loc; } else { - zret._g = new Group(key, fqdn, txn_cnf.min); + zret._g = new Group(key, fqdn, txn_cnf.server_min); _imp._table.insert(zret._g); } return zret; } bool -OutboundConnTrack::Group::equal(const Key &lhs, const Key &rhs) +ConnectionTracker::Group::equal(const Key &lhs, const Key &rhs) { bool zret = false; if (lhs._match_type == rhs._match_type) { @@ -199,7 +203,7 @@ OutboundConnTrack::Group::equal(const Key &lhs, const Key &rhs) } bool -OutboundConnTrack::Group::should_alert(std::time_t *lat) +ConnectionTracker::Group::should_alert(std::time_t *lat) { bool zret = false; // This is a bit clunky because the goal is to store just the tick count as an atomic. @@ -207,7 +211,7 @@ OutboundConnTrack::Group::should_alert(std::time_t *lat) Ticker last_tick{_last_alert}; // Load the most recent alert time in ticks. TimePoint last{TimePoint::duration{last_tick}}; // Most recent alert time in a time_point. TimePoint now = Clock::now(); // Current time_point. - if (last + _global_config->alert_delay <= now) { + if (last + _global_config->server_alert_delay <= now) { // it's been long enough, swap out our time for the last time. The winner of this swap // does the actual alert, leaving its current time as the last alert time. zret = _last_alert.compare_exchange_strong(last_tick, now.time_since_epoch().count()); @@ -219,13 +223,13 @@ OutboundConnTrack::Group::should_alert(std::time_t *lat) } std::time_t -OutboundConnTrack::Group::get_last_alert_epoch_time() const +ConnectionTracker::Group::get_last_alert_epoch_time() const { return Clock::to_time_t(TimePoint{TimePoint::duration{Ticker{_last_alert}}}); } void -OutboundConnTrack::get(std::vector &groups) +ConnectionTracker::get(std::vector &groups) { std::lock_guard lock(_imp._mutex); // TABLE LOCK groups.resize(0); @@ -236,7 +240,7 @@ OutboundConnTrack::get(std::vector &groups) } std::string -OutboundConnTrack::to_json_string() +ConnectionTracker::to_json_string() { std::string text; size_t extent = 0; @@ -277,7 +281,7 @@ OutboundConnTrack::to_json_string() } void -OutboundConnTrack::dump(FILE *f) +ConnectionTracker::dump(FILE *f) { std::vector groups; @@ -298,30 +302,12 @@ OutboundConnTrack::dump(FILE *f) } } -struct ShowConnectionCount : public ShowCont { - ShowConnectionCount(Continuation *c, HTTPHdr *h) : ShowCont(c, h) { SET_HANDLER(&ShowConnectionCount::showHandler); } - int - showHandler(int event, Event *e) - { - CHECK_SHOW(show(OutboundConnTrack::to_json_string().c_str())); - return completeJson(event, e); - } -}; - -Action * -register_ShowConnectionCount(Continuation *c, HTTPHdr *h) -{ - ShowConnectionCount *s = new ShowConnectionCount(c, h); - this_ethread()->schedule_imm(s); - return &s->action; -} - bool -OutboundConnTrack::lookup_match_type(std::string_view tag, OutboundConnTrack::MatchType &type) +ConnectionTracker::lookup_match_type(std::string_view tag, ConnectionTracker::MatchType &type) { // Search the array for the tag. - for (OutboundConnTrack::MatchType idx : - {OutboundConnTrack::MATCH_IP, OutboundConnTrack::MATCH_PORT, OutboundConnTrack::MATCH_HOST, OutboundConnTrack::MATCH_BOTH}) { + for (ConnectionTracker::MatchType idx : + {ConnectionTracker::MATCH_IP, ConnectionTracker::MATCH_PORT, ConnectionTracker::MATCH_HOST, ConnectionTracker::MATCH_BOTH}) { if (tag == MATCH_TYPE_NAME[idx]) { type = idx; return true; @@ -331,10 +317,10 @@ OutboundConnTrack::lookup_match_type(std::string_view tag, OutboundConnTrack::Ma } void -OutboundConnTrack::Warning_Bad_Match_Type(std::string_view tag) +ConnectionTracker::Warning_Bad_Match_Type(std::string_view tag) { swoc::LocalBufferWriter<256> w; - w.print("Invalid value '{}' for '{}' - must be one of", tag, CONFIG_VAR_MATCH); + w.print("Invalid value '{}' for '{}' - must be one of", tag, CONFIG_SERVER_VAR_MATCH); for (auto n : MATCH_TYPE_NAME) { w.write(" '"sv); w.write(n); @@ -345,7 +331,7 @@ OutboundConnTrack::Warning_Bad_Match_Type(std::string_view tag) } void -OutboundConnTrack::TxnState::Note_Unblocked(const TxnConfig *config, int count, sockaddr const *addr) +ConnectionTracker::TxnState::Note_Unblocked(const TxnConfig *config, int count, sockaddr const *addr) { time_t lat; // last alert time (epoch seconds) @@ -353,23 +339,25 @@ OutboundConnTrack::TxnState::Note_Unblocked(const TxnConfig *config, int count, auto blocked = _g->_blocked.exchange(0); swoc::LocalBufferWriter<256> w; w.print("upstream unblocked: [{}] count={} limit={} group=({}) blocked={} upstream={}\0", - swoc::bwf::Date(lat, "%b %d %H:%M:%S"sv), count, config->max, *_g, blocked, addr); + swoc::bwf::Date(lat, "%b %d %H:%M:%S"sv), count, config->server_max, *_g, blocked, addr); Debug(DEBUG_TAG, "%s", w.data()); Note("%s", w.data()); } } void -OutboundConnTrack::TxnState::Warn_Blocked(const TxnConfig *config, int64_t sm_id, int count, sockaddr const *addr, - char const *debug_tag) +ConnectionTracker::TxnState::Warn_Blocked(int max_connections, int64_t id, int count, sockaddr const *addr, char const *debug_tag) { bool alert_p = _g->should_alert(); auto blocked = alert_p ? _g->_blocked.exchange(0) : _g->_blocked.load(); if (alert_p || debug_tag) { swoc::LocalBufferWriter<256> w; - w.print("[{}] too many connections: count={} limit={} group=({}) blocked={} upstream={}\0", sm_id, count, config->max, *_g, - blocked, addr); + if (id > 1) { + w.print("[{}] ", id); + } + w.print("too many connections: count={} limit={} group=({}) blocked={} upstream={}\0", count, max_connections, *_g, blocked, + addr); if (debug_tag) { Debug(debug_tag, "%s", w.data()); @@ -383,30 +371,30 @@ OutboundConnTrack::TxnState::Warn_Blocked(const TxnConfig *config, int64_t sm_id namespace swoc { BufferWriter & -bwformat(BufferWriter &w, bwf::Spec const &spec, OutboundConnTrack::MatchType type) +bwformat(BufferWriter &w, bwf::Spec const &spec, ConnectionTracker::MatchType type) { if (spec.has_numeric_type()) { bwformat(w, spec, static_cast(type)); } else { - bwformat(w, spec, OutboundConnTrack::MATCH_TYPE_NAME[type]); + bwformat(w, spec, ConnectionTracker::MATCH_TYPE_NAME[type]); } return w; } BufferWriter & -bwformat(BufferWriter &w, bwf::Spec const &spec, OutboundConnTrack::Group::Key const &key) +bwformat(BufferWriter &w, bwf::Spec const &spec, ConnectionTracker::Group::Key const &key) { switch (key._match_type) { - case OutboundConnTrack::MATCH_BOTH: + case ConnectionTracker::MATCH_BOTH: w.print("{:s} {},{}", key._match_type, key._addr, key._hash); break; - case OutboundConnTrack::MATCH_HOST: + case ConnectionTracker::MATCH_HOST: w.print("{:s} {}", key._match_type, key._hash); break; - case OutboundConnTrack::MATCH_PORT: + case ConnectionTracker::MATCH_PORT: w.print("{:s} {}", key._match_type, key._addr); break; - case OutboundConnTrack::MATCH_IP: + case ConnectionTracker::MATCH_IP: w.print("{:s} {::a}", key._match_type, key._addr); break; } @@ -414,19 +402,19 @@ bwformat(BufferWriter &w, bwf::Spec const &spec, OutboundConnTrack::Group::Key c } BufferWriter & -bwformat(BufferWriter &w, bwf::Spec const &spec, OutboundConnTrack::Group const &g) +bwformat(BufferWriter &w, bwf::Spec const &spec, ConnectionTracker::Group const &g) { switch (g._match_type) { - case OutboundConnTrack::MATCH_BOTH: + case ConnectionTracker::MATCH_BOTH: w.print("{:s} {},{}", g._match_type, g._addr, g._fqdn); break; - case OutboundConnTrack::MATCH_HOST: + case ConnectionTracker::MATCH_HOST: w.print("{:s} {}", g._match_type, g._fqdn); break; - case OutboundConnTrack::MATCH_PORT: + case ConnectionTracker::MATCH_PORT: w.print("{:s} {}", g._match_type, g._addr); break; - case OutboundConnTrack::MATCH_IP: + case ConnectionTracker::MATCH_IP: w.print("{:s} {::a}", g._match_type, g._addr); break; } diff --git a/src/iocore/net/Makefile.am b/src/iocore/net/Makefile.am index 24852ace96a..6318c46b384 100644 --- a/src/iocore/net/Makefile.am +++ b/src/iocore/net/Makefile.am @@ -150,6 +150,7 @@ libinknet_a_SOURCES = \ BoringSSLUtils.cc \ BoringSSLUtils.h \ Connection.cc \ + ConnectionTracker.cc \ EventIO.h \ EventIO.cc \ I_Net.h \ diff --git a/src/proxy/http/CMakeLists.txt b/src/proxy/http/CMakeLists.txt index e036b5fd6aa..e4a596bd9ef 100644 --- a/src/proxy/http/CMakeLists.txt +++ b/src/proxy/http/CMakeLists.txt @@ -24,7 +24,6 @@ add_library( Http1ClientTransaction.cc Http1ServerTransaction.cc HttpConfig.cc - HttpConnectionCount.cc HttpDebugNames.cc HttpPages.cc HttpProxyServerMain.cc diff --git a/src/proxy/http/HttpConfig.cc b/src/proxy/http/HttpConfig.cc index ed2f3d9948a..75ecc3092ec 100644 --- a/src/proxy/http/HttpConfig.cc +++ b/src/proxy/http/HttpConfig.cc @@ -994,7 +994,7 @@ HttpConfig::startup() HttpEstablishStaticConfigStringAlloc(c.oride.ssl_client_alpn_protocols, "proxy.config.ssl.client.alpn_protocols"); HttpEstablishStaticConfigByte(c.scheme_proto_mismatch_policy, "proxy.config.ssl.client.scheme_proto_mismatch_policy"); - OutboundConnTrack::config_init(&c.global_outbound_conntrack, &c.oride.outbound_conntrack); + ConnectionTracker::config_init(&c.global_connection_tracker_config, &c.oride.connection_tracker_config); MUTEX_TRY_LOCK(lock, http_config_cont->mutex, this_ethread()); if (!lock.is_locked()) { @@ -1037,8 +1037,8 @@ HttpConfig::reconfigure() params->server_max_connections = m_master.server_max_connections; params->max_websocket_connections = m_master.max_websocket_connections; - params->oride.outbound_conntrack = m_master.oride.outbound_conntrack; - params->global_outbound_conntrack = m_master.global_outbound_conntrack; + params->oride.connection_tracker_config = m_master.oride.connection_tracker_config; + params->global_connection_tracker_config = m_master.global_connection_tracker_config; 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; @@ -1048,10 +1048,11 @@ HttpConfig::reconfigure() 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; - if (params->oride.outbound_conntrack.max > 0 && params->oride.outbound_conntrack.max < params->oride.outbound_conntrack.min) { + if (params->oride.connection_tracker_config.server_max > 0 && + params->oride.connection_tracker_config.server_max < params->oride.connection_tracker_config.server_min) { Warning("'%s' < per_server.min_keep_alive_connections, setting min=max , please correct your %s", - OutboundConnTrack::CONFIG_VAR_MAX.data(), ts::filename::RECORDS); - params->oride.outbound_conntrack.min = params->oride.outbound_conntrack.max; + ConnectionTracker::CONFIG_SERVER_VAR_MAX.data(), ts::filename::RECORDS); + params->oride.connection_tracker_config.server_min = params->oride.connection_tracker_config.server_max; } params->oride.insert_request_via_string = m_master.oride.insert_request_via_string; diff --git a/src/proxy/http/HttpProxyServerMain.cc b/src/proxy/http/HttpProxyServerMain.cc index f097960d2a2..d823fdc5a42 100644 --- a/src/proxy/http/HttpProxyServerMain.cc +++ b/src/proxy/http/HttpProxyServerMain.cc @@ -27,6 +27,7 @@ #include "proxy/http/HttpConfig.h" #include "proxy/http/HttpSessionAccept.h" #include "proxy/ReverseProxy.h" +#include "proxy/Show.h" #include "proxy/http/HttpSessionManager.h" #include "proxy/http/remap/RemapHitCount.h" #ifdef USE_HTTP_DEBUG_LISTS @@ -35,10 +36,10 @@ #include "proxy/http/HttpPages.h" #include "proxy/http/HttpTunnel.h" #include "tscore/Tokenizer.h" +#include "iocore/net/ConnectionTracker.h" #include "../../iocore/net/P_SSLNextProtocolAccept.h" #include "proxy/ProtocolProbeSessionAccept.h" #include "proxy/http2/Http2SessionAccept.h" -#include "proxy/http/HttpConnectionCount.h" #include "proxy/http/HttpProxyServerMain.h" #if TS_USE_QUIC == 1 #include "../../iocore/net/P_QUICNetProcessor.h" @@ -66,6 +67,24 @@ std::mutex etUdpMutex; std::condition_variable etUdpCheck; bool et_udp_threads_ready = false; +struct ShowConnectionCount : public ShowCont { + ShowConnectionCount(Continuation *c, HTTPHdr *h) : ShowCont(c, h) { SET_HANDLER(&ShowConnectionCount::showHandler); } + int + showHandler(int event, Event *e) + { + CHECK_SHOW(show(ConnectionTracker::to_json_string().c_str())); + return completeJson(event, e); + } +}; + +Action * +register_ShowConnectionCount(Continuation *c, HTTPHdr *h) +{ + ShowConnectionCount *s = new ShowConnectionCount(c, h); + this_ethread()->schedule_imm(s); + return &s->action; +} + // File / process scope initializations static bool HTTP_SERVER_INITIALIZED __attribute__((unused)) = []() -> bool { swoc::bwf::Global_Names.assign("ts-thread", [](swoc::BufferWriter &w, swoc::bwf::Spec const &spec) -> swoc::BufferWriter & { diff --git a/src/proxy/http/HttpSM.cc b/src/proxy/http/HttpSM.cc index e1bdfbc53c0..24325f600a6 100644 --- a/src/proxy/http/HttpSM.cc +++ b/src/proxy/http/HttpSM.cc @@ -46,6 +46,7 @@ #include "proxy/http/remap/RemapProcessor.h" #include "proxy/Transform.h" #include "../../iocore/net/P_SSLConfig.h" +#include "iocore/net/ConnectionTracker.h" #include "iocore/net/SSLSNIConfig.h" #include "iocore/net/TLSALPNSupport.h" #include "iocore/net/TLSBasicSupport.h" @@ -1706,7 +1707,7 @@ HttpSM::create_server_session(NetVConnection &netvc, MIOBuffer *netvc_read_buffe // the max and or min number of connections per host. Transfer responsibility for this to the // session object. if (t_state.outbound_conn_track_state.is_active()) { - SMDebug("http_connect", "max number of outbound connections: %d", t_state.txn_conf->outbound_conntrack.max); + SMDebug("http_connect", "max number of outbound connections: %d", t_state.txn_conf->connection_tracker_config.server_max); retval->enable_outbound_connection_tracking(t_state.outbound_conn_track_state.drop()); } return retval; @@ -5481,28 +5482,30 @@ HttpSM::do_http_server_open(bool raw, bool only_direct) } // See if the outbound connection tracker data is needed. If so, get it here for consistency. - if (t_state.txn_conf->outbound_conntrack.max > 0 || t_state.txn_conf->outbound_conntrack.min > 0) { - t_state.outbound_conn_track_state = OutboundConnTrack::obtain( - t_state.txn_conf->outbound_conntrack, std::string_view{t_state.current.server->name}, t_state.current.server->dst_addr); + if (t_state.txn_conf->connection_tracker_config.server_max > 0 || t_state.txn_conf->connection_tracker_config.server_min > 0) { + t_state.outbound_conn_track_state = + ConnectionTracker::obtain_outbound(t_state.txn_conf->connection_tracker_config, + std::string_view{t_state.current.server->name}, t_state.current.server->dst_addr); } // Check to see if we have reached the max number of connections on this upstream host. - if (t_state.txn_conf->outbound_conntrack.max > 0) { - auto &ct_state = t_state.outbound_conn_track_state; - auto ccount = ct_state.reserve(); - if (ccount > t_state.txn_conf->outbound_conntrack.max) { + if (t_state.txn_conf->connection_tracker_config.server_max > 0) { + auto &ct_state = t_state.outbound_conn_track_state; + auto ccount = ct_state.reserve(); + int const server_max = t_state.txn_conf->connection_tracker_config.server_max; + if (ccount > server_max) { ct_state.release(); ink_assert(pending_action.empty()); // in case of reschedule must not have already pending. ct_state.blocked(); Metrics::increment(http_rsb.origin_connections_throttled); - ct_state.Warn_Blocked(&t_state.txn_conf->outbound_conntrack, sm_id, ccount - 1, &t_state.current.server->dst_addr.sa, + ct_state.Warn_Blocked(server_max, sm_id, ccount - 1, &t_state.current.server->dst_addr.sa, debug_on && is_debug_tag_set("http") ? "http" : nullptr); send_origin_throttled_response(); return; } else { - ct_state.Note_Unblocked(&t_state.txn_conf->outbound_conntrack, ccount, &t_state.current.server->dst_addr.sa); + ct_state.Note_Unblocked(&t_state.txn_conf->connection_tracker_config, ccount, &t_state.current.server->dst_addr.sa); } ct_state.update_max_count(ccount); diff --git a/src/proxy/http/Makefile.am b/src/proxy/http/Makefile.am index 716c6ba2273..57278fb7ad1 100644 --- a/src/proxy/http/Makefile.am +++ b/src/proxy/http/Makefile.am @@ -56,8 +56,6 @@ libhttp_a_SOURCES = \ Http1ServerTransaction.cc \ HttpConfig.cc \ HttpConfig.h \ - HttpConnectionCount.cc \ - HttpConnectionCount.h \ HttpDebugNames.cc \ HttpDebugNames.h \ HttpPages.cc \ diff --git a/src/shared/overridable_txn_vars.cc b/src/shared/overridable_txn_vars.cc index 5cf1ea4b0e7..da6767ca421 100644 --- a/src/shared/overridable_txn_vars.cc +++ b/src/shared/overridable_txn_vars.cc @@ -85,11 +85,11 @@ const std::unordered_map Date: Mon, 30 Oct 2023 20:36:56 +0000 Subject: [PATCH 2/3] Build updates for test_net Moving ConnectionTracker to iocore/net induced linking behavior differences that required these changes to fix test_net. --- src/api/CMakeLists.txt | 2 +- src/iocore/cache/unit_tests/main.cc | 1 + src/iocore/net/libinknet_stub.cc | 117 +--------------------------- src/tests/CMakeLists.txt | 10 ++- 4 files changed, 12 insertions(+), 118 deletions(-) diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt index eb9daae79c2..8027734fa77 100644 --- a/src/api/CMakeLists.txt +++ b/src/api/CMakeLists.txt @@ -29,7 +29,7 @@ set(TSAPI_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ts/experimental.h ) -target_link_libraries(tsapi PRIVATE ts::tscore) +target_link_libraries(tsapi PRIVATE libswoc yaml-cpp::yaml-cpp PCRE::PCRE OpenSSL::SSL) set_target_properties(tsapi PROPERTIES PUBLIC_HEADER "${TSAPI_PUBLIC_HEADERS}") add_library( diff --git a/src/iocore/cache/unit_tests/main.cc b/src/iocore/cache/unit_tests/main.cc index 6b8cf62fa1e..863f656ee2a 100644 --- a/src/iocore/cache/unit_tests/main.cc +++ b/src/iocore/cache/unit_tests/main.cc @@ -24,6 +24,7 @@ #include "tscore/ink_config.h" #include #include "proxy/HttpAPIHooks.h" +#include "proxy/StatPages.h" #include "iocore/net/SSLAPIHooks.h" #define CATCH_CONFIG_MAIN diff --git a/src/iocore/net/libinknet_stub.cc b/src/iocore/net/libinknet_stub.cc index 9eff56e3e9a..eeea04daddc 100644 --- a/src/iocore/net/libinknet_stub.cc +++ b/src/iocore/net/libinknet_stub.cc @@ -21,119 +21,6 @@ limitations under the License. */ -class EThread; -class Continuation; +#include "tscore/Version.h" -#include "P_UnixNet.h" -#include "../dns/P_DNSConnection.h" -int -DNSConnection::close() -{ - ink_assert(false); - return 0; -} - -void -DNSConnection::trigger() -{ - ink_assert(false); -} - -#include "proxy/StatPages.h" -void -StatPagesManager::register_http(char const *, Action *(*)(Continuation *, HTTPHdr *)) -{ - ink_assert(false); -} - -#include "proxy/ParentSelection.h" -void -SocksServerConfig::startup() -{ - ink_assert(false); -} - -int SocksServerConfig::m_id = 0; - -void -ParentConfigParams::findParent(HttpRequestData *, ParentResult *, unsigned int, unsigned int) -{ - ink_assert(false); -} - -void -ParentConfigParams::nextParent(HttpRequestData *, ParentResult *, unsigned int, unsigned int) -{ - ink_assert(false); -} - -#include "api/InkAPIInternal.h" -#include "proxy/ControlMatcher.h" -char * -HttpRequestData::get_string() -{ - ink_assert(false); - return nullptr; -} - -const char * -HttpRequestData::get_host() -{ - ink_assert(false); - return nullptr; -} - -sockaddr const * -HttpRequestData::get_ip() -{ - ink_assert(false); - return nullptr; -} - -sockaddr const * -HttpRequestData::get_client_ip() -{ - ink_assert(false); - return nullptr; -} - -StatPagesManager statPagesManager; - -#include "api/FetchSM.h" -ClassAllocator FetchSMAllocator("unusedFetchSMAllocator"); -void -FetchSM::ext_launch() -{ -} -void -FetchSM::ext_destroy() -{ -} -ssize_t -FetchSM::ext_read_data(char *, unsigned long) -{ - return 0; -} -void -FetchSM::ext_add_header(char const *, int, char const *, int) -{ -} -void -FetchSM::ext_write_data(void const *, unsigned long) -{ -} -void * -FetchSM::ext_get_user_data() -{ - return nullptr; -} -void -FetchSM::ext_set_user_data(void *) -{ -} -void -FetchSM::ext_init(Continuation *, char const *, char const *, char const *, sockaddr const *, int) -{ -} - -ChunkedHandler::ChunkedHandler() {} +AppVersionInfo appVersionInfo; diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 1c029502b45..792f960382b 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -67,7 +67,11 @@ macro(add_cache_test name) endmacro() macro(add_net_test name) - add_executable(${name} ${CMAKE_SOURCE_DIR}/src/iocore/net/libinknet_stub.cc ${ARGN}) + add_executable(${name} + ${CMAKE_SOURCE_DIR}/src/iocore/net/libinknet_stub.cc + ${CMAKE_SOURCE_DIR}/src/shared/overridable_txn_vars.cc + ${ARGN}) + target_link_libraries(${name} PRIVATE ts::tsapicore ts::inknet ts::configmanager ts::tsapi ts::inknet ts::configmanager) add_test(NAME test_cache_${name} COMMAND $) endmacro() @@ -121,7 +125,9 @@ add_test( ) add_net_test( - test_net "${CMAKE_SOURCE_DIR}/src/iocore/net/unit_tests/test_ProxyProtocol.cc" + test_net + "${CMAKE_SOURCE_DIR}/src/iocore/net/NetVCTest.cc" + "${CMAKE_SOURCE_DIR}/src/iocore/net/unit_tests/test_ProxyProtocol.cc" "${CMAKE_SOURCE_DIR}/src/iocore/net/unit_tests/test_SSLSNIConfig.cc" "${CMAKE_SOURCE_DIR}/src/iocore/net/unit_tests/test_YamlSNIConfig.cc" "${CMAKE_SOURCE_DIR}/src/iocore/net/unit_tests/unit_test_main.cc" From 2bb82fa42d8d37e21461faccc16967c204e9d108 Mon Sep 17 00:00:00 2001 From: Brian Neradt Date: Mon, 30 Oct 2023 20:37:53 +0000 Subject: [PATCH 3/3] Fix tls_bridge to use Regex from tscore tls_bridge had previously linked to tscore, but had copied in its own version of Regex. This removes the duplicated code and logic which, with these changes, caused duplicate definitions errors. --- .../experimental/tls_bridge/CMakeLists.txt | 2 +- plugins/experimental/tls_bridge/regex.cc | 130 ------------------ plugins/experimental/tls_bridge/regex.h | 60 -------- plugins/experimental/tls_bridge/tls_bridge.cc | 4 +- 4 files changed, 3 insertions(+), 193 deletions(-) delete mode 100644 plugins/experimental/tls_bridge/regex.cc delete mode 100644 plugins/experimental/tls_bridge/regex.h diff --git a/plugins/experimental/tls_bridge/CMakeLists.txt b/plugins/experimental/tls_bridge/CMakeLists.txt index a01a201063d..10e0c8fd0d0 100644 --- a/plugins/experimental/tls_bridge/CMakeLists.txt +++ b/plugins/experimental/tls_bridge/CMakeLists.txt @@ -15,6 +15,6 @@ # ####################### -add_atsplugin(tls_bridge regex.cc tls_bridge.cc) +add_atsplugin(tls_bridge tls_bridge.cc) target_link_libraries(tls_bridge PRIVATE libswoc ts::tscpputil) diff --git a/plugins/experimental/tls_bridge/regex.cc b/plugins/experimental/tls_bridge/regex.cc deleted file mode 100644 index 6b822d98065..00000000000 --- a/plugins/experimental/tls_bridge/regex.cc +++ /dev/null @@ -1,130 +0,0 @@ -/** @file - - PCRE support wrapper. - - @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 "regex.h" - -#ifdef PCRE_CONFIG_JIT -#include - -struct RegexThreadKey { - RegexThreadKey() { pthread_key_create(&this->key, reinterpret_cast(&pcre_jit_stack_free)); } - pthread_key_t key; -}; - -static RegexThreadKey k; - -static pcre_jit_stack * -get_jit_stack(void *) -{ - pcre_jit_stack *jit_stack; - - if ((jit_stack = static_cast(pthread_getspecific(k.key))) == nullptr) { - jit_stack = pcre_jit_stack_alloc(8192, 1024 * 1024); // 1 page min and 1MB max - pthread_setspecific(k.key, (void *)jit_stack); - } - - return jit_stack; -} -#endif - -bool -Regex::compile(const char *pattern, const unsigned flags) -{ - const char *error; - int erroffset; - int options = 0; - int study_opts = 0; - - if (regex) { - return false; - } - - if (flags & CASE_INSENSITIVE) { - options |= PCRE_CASELESS; - } - - if (flags & ANCHORED) { - options |= PCRE_ANCHORED; - } - - regex = pcre_compile(pattern, options, &error, &erroffset, nullptr); - if (error) { - regex = nullptr; - return false; - } - -#ifdef PCRE_CONFIG_JIT - study_opts |= PCRE_STUDY_JIT_COMPILE; -#endif - - regex_extra = pcre_study(regex, study_opts, &error); - -#ifdef PCRE_CONFIG_JIT - if (regex_extra) { - pcre_assign_jit_stack(regex_extra, &get_jit_stack, nullptr); - } -#endif - - return true; -} - -int -Regex::get_capture_count() -{ - int captures = -1; - if (pcre_fullinfo(regex, regex_extra, PCRE_INFO_CAPTURECOUNT, &captures) != 0) { - return -1; - } - - return captures; -} - -bool -Regex::exec(std::string_view src) const -{ - int ovector[30]; - return exec(src, ovector, 30); -} - -bool -Regex::exec(std::string_view src, int *ovector, int ovecsize) const -{ - int rv; - - rv = pcre_exec(regex, regex_extra, src.data(), src.size(), 0, 0, ovector, ovecsize); - return rv > 0 ? true : false; -} - -Regex::~Regex() -{ - if (regex_extra) { -#ifdef PCRE_CONFIG_JIT - pcre_free_study(regex_extra); -#else - pcre_free(regex_extra); -#endif - } - if (regex) { - pcre_free(regex); - } -} diff --git a/plugins/experimental/tls_bridge/regex.h b/plugins/experimental/tls_bridge/regex.h deleted file mode 100644 index 4771dff81b4..00000000000 --- a/plugins/experimental/tls_bridge/regex.h +++ /dev/null @@ -1,60 +0,0 @@ -/** @file - - Wrapper to make PCRE handling easier. - - @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 -#include -#include - -class Regex -{ - using self_type = Regex; - -public: - enum Flag { - CASE_INSENSITIVE = 0x0001, // default is case sensitive - UNANCHORED = 0x0002, // default (for DFA) is to anchor at the first matching position - ANCHORED = 0x0004, // default (for Regex) is unanchored - }; - - Regex() = default; - Regex(self_type &&that); - - bool compile(const char *pattern, const unsigned flags = 0); - // It is safe to call exec() concurrently on the same object instance - bool exec(std::string_view src) const; - bool exec(std::string_view src, int *ovector, int ovecsize) const; - int get_capture_count(); - ~Regex(); - -private: - pcre *regex = nullptr; - pcre_extra *regex_extra = nullptr; -}; - -inline Regex::Regex(self_type &&that) -{ - std::swap(regex, that.regex); - std::swap(regex_extra, that.regex_extra); -} diff --git a/plugins/experimental/tls_bridge/tls_bridge.cc b/plugins/experimental/tls_bridge/tls_bridge.cc index 7fd862918d2..2990b56fe42 100644 --- a/plugins/experimental/tls_bridge/tls_bridge.cc +++ b/plugins/experimental/tls_bridge/tls_bridge.cc @@ -21,7 +21,7 @@ #include "ts/ts.h" #include "swoc/TextView.h" -#include "regex.h" +#include "tscore/Regex.h" using swoc::TextView; @@ -116,7 +116,7 @@ BridgeConfig::load_pair(std::string_view rxp, std::string_view service, swoc::fi Regex r; // Unfortunately PCRE can only compile null terminated strings... std::string pattern{rxp}; - if (r.compile(pattern.c_str(), Regex::ANCHORED)) { + if (r.compile(pattern.c_str(), REFlags::RE_ANCHORED)) { _items.emplace_back(rxp, std::move(r), service); } else { char buff[std::numeric_limits::digits10 + 2] = "";