/* * Copyright (C) 1996-2023 The Squid Software Foundation and contributors * * Squid software is distributed under GPLv2+ license and includes * contributions from numerous individuals and organizations. * Please see the COPYING and CONTRIBUTORS files for details. */ #ifndef SQUID_SRC_CACHEPEER_H #define SQUID_SRC_CACHEPEER_H #include "acl/forward.h" #include "base/CbcPointer.h" #include "enums.h" #include "http/StatusCode.h" #include "icp_opcode.h" #include "ip/Address.h" #include "security/PeerOptions.h" #include //TODO: remove, it is unconditionally defined and always used. #define PEER_MULTICAST_SIBLINGS 1 class NeighborTypeDomainList; class PconnPool; class PeerDigest; class PeerPoolMgr; class CachePeer { CBDATA_CLASS(CachePeer); public: explicit CachePeer(const char *hostname); ~CachePeer(); /// reacts to a successful establishment of a connection to this cache_peer void noteSuccess(); /// reacts to a failure on a connection to this cache_peer /// \param code a received response status code, if any void noteFailure(Http::StatusCode code); /// (re)configure cache_peer name=value void rename(const char *); /// \returns the effective connect timeout for the given peer time_t connectTimeout() const; u_int index = 0; /// cache_peer name (if explicitly configured) or hostname (otherwise). /// Unique across already configured cache_peers in the current configuration. /// Not necessarily unique across discovered non-peers (see mgr:non_peers). /// The value may change during CachePeer configuration. /// The value affects various peer selection hashes (e.g., carp.hash). /// Preserves configured spelling (i.e. does not lower letters case). /// Never nil. char *name = nullptr; /// The lowercase version of the configured cache_peer hostname or /// the IP address of a non-peer (see mgr:non_peers). /// May not be unique among cache_peers and non-peers. /// Never nil. char *host = nullptr; peer_t type = PEER_NONE; Ip::Address in_addr; struct { int pings_sent = 0; int pings_acked = 0; int fetches = 0; int rtt = 0; int ignored_replies = 0; int n_keepalives_sent = 0; int n_keepalives_recv = 0; time_t probe_start = 0; time_t last_query = 0; time_t last_reply = 0; time_t last_connect_failure = 0; time_t last_connect_probe = 0; int logged_state = PEER_ALIVE; ///< so we can print dead/revived msgs int conn_open = 0; ///< current opened connections } stats; struct icp_ { icp_() { memset(&counts, 0, sizeof(counts)); } int version = ICP_VERSION_CURRENT; int counts[ICP_END+1]; unsigned short port = CACHE_ICP_PORT; } icp; #if USE_HTCP struct { double version = 0.0; int counts[2] = {0, 0}; unsigned short port = 0; } htcp; #endif unsigned short http_port = CACHE_HTTP_PORT; NeighborTypeDomainList *typelist = nullptr; acl_access *access = nullptr; struct { bool proxy_only = false; bool no_query = false; bool background_ping = false; bool no_digest = false; bool default_parent = false; bool roundrobin = false; bool weighted_roundrobin = false; bool mcast_responder = false; bool closest_only = false; #if USE_HTCP bool htcp = false; bool htcp_oldsquid = false; bool htcp_no_clr = false; bool htcp_no_purge_clr = false; bool htcp_only_clr = false; bool htcp_forward_clr = false; #endif bool no_netdb_exchange = false; #if USE_DELAY_POOLS bool no_delay = false; #endif bool allow_miss = false; bool carp = false; struct { bool set = false; //If false, whole url is to be used. Overrides others bool scheme = false; bool host = false; bool port = false; bool path = false; bool params = false; } carp_key; #if USE_AUTH bool userhash = false; #endif bool sourcehash = false; bool originserver = false; bool no_tproxy = false; #if PEER_MULTICAST_SIBLINGS bool mcast_siblings = false; #endif bool auth_no_keytab = false; } options; int weight = 1; int basetime = 0; struct { double avg_n_members = 0.0; int n_times_counted = 0; int n_replies_expected = 0; int ttl = 0; int id = 0; struct { bool count_event_pending = false; bool counting = false; } flags; } mcast; #if USE_CACHE_DIGESTS PeerDigest *digest = nullptr; char *digest_url = nullptr; #endif /// The number of failures sufficient to stop selecting this cache_peer. All /// cache_peer selection algorithms skip cache_peers with 0 tcp_up values. /// The initial 0 value prevents unprobed cache_peers from being selected. int tcp_up = 0; /// whether to do another TCP probe after current TCP probes bool reprobe = false; Ip::Address addresses[10]; int n_addresses = 0; int rr_count = 0; CachePeer *next = nullptr; int testing_now = 0; struct { unsigned int hash = 0; double load_multiplier = 0.0; double load_factor = 0.0; ///< normalized weight value } carp; #if USE_AUTH struct { unsigned int hash = 0; double load_multiplier = 0.0; double load_factor = 0.0; ///< normalized weight value } userhash; #endif struct { unsigned int hash = 0; double load_multiplier = 0.0; double load_factor = 0.0; ///< normalized weight value } sourcehash; char *login = nullptr; /* Proxy authorization */ time_t connect_timeout_raw = 0; ///< connect_timeout; use connectTimeout() instead! int connect_fail_limit = 0; int max_conn = 0; /// optional "cache_peer standby=limit" feature struct { PconnPool *pool = nullptr; ///< idle connection pool for this peer CbcPointer mgr; ///< pool manager int limit = 0; ///< the limit itself bool waitingForClose = false; ///< a conn must close before we open a standby conn } standby; char *domain = nullptr; ///< Forced domain /// security settings for peer connection Security::PeerOptions secure; Security::ContextPointer sslContext; Security::SessionStatePointer sslSession; int front_end_https = 0; ///< 0 - off, 1 - on, 2 - auto int connection_auth = 2; ///< 0 - off, 1 - on, 2 - auto private: void countFailure(); }; /// reacts to a successful establishment of a connection to an origin server or cache_peer /// \param peer nil if Squid established a connection to an origin server inline void NoteOutgoingConnectionSuccess(CachePeer * const peer) { if (peer) peer->noteSuccess(); } /// reacts to a failure on a connection to an origin server or cache_peer /// \param peer nil if the connection is to an origin server /// \param code a received response status code, if any inline void NoteOutgoingConnectionFailure(CachePeer * const peer, const Http::StatusCode code) { if (peer) peer->noteFailure(code); } /// identify the given cache peer in cache.log messages and such std::ostream &operator <<(std::ostream &, const CachePeer &); #endif /* SQUID_SRC_CACHEPEER_H */