/* * Copyright (C) 1996-2021 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. */ /* DEBUG: section 05 Socket Functions */ #ifndef _SQUIDCONNECTIONDETAIL_H_ #define _SQUIDCONNECTIONDETAIL_H_ #include "comm/forward.h" #include "defines.h" #if USE_SQUID_EUI #include "eui/Eui48.h" #include "eui/Eui64.h" #endif #include "hier_code.h" #include "ip/Address.h" #include "ip/forward.h" #include "mem/forward.h" #include "SquidTime.h" #include #include class CachePeer; namespace Security { class NegotiationHistory; }; namespace Comm { /* TODO: make these a struct of boolean flags members in the connection instead of a bitmap. * we can't do that until all non-comm code uses Commm::Connection objects to create FD * currently there is code still using comm_open() and comm_openex() synchronously!! */ #define COMM_UNSET 0x00 #define COMM_NONBLOCKING 0x01 // default flag. #define COMM_NOCLOEXEC 0x02 #define COMM_REUSEADDR 0x04 // shared FD may be both accept()ing and read()ing #define COMM_DOBIND 0x08 // requires a bind() #define COMM_TRANSPARENT 0x10 // arrived via TPROXY #define COMM_INTERCEPTION 0x20 // arrived via NAT /** * Store data about the physical and logical attributes of a connection. * * Some link state can be infered from the data, however this is not an * object for state data. But a semantic equivalent for FD with easily * accessible cached properties not requiring repeated complex lookups. * * Connection properties may be changed until the connection is opened. * Properties should be considered read-only outside of the Comm layer * code once the connection is open. * * These objects should not be passed around directly, * but a Comm::ConnectionPointer should be passed instead. */ class Connection : public RefCountable { MEMPROXY_CLASS(Comm::Connection); public: Connection(); /** Clear the connection properties and close any open socket. */ ~Connection(); /** Copy an existing connections IP and properties. * This excludes the FD. The new copy will be a closed connection. */ ConnectionPointer copyDetails() const; /** Close any open socket. */ void close(); /** Synchronize with Comm: Somebody closed our connection. */ void noteClosure(); /** determine whether this object describes an active connection or not. */ bool isOpen() const { return (fd >= 0); } /** Alter the stored IP address pair. * WARNING: Does not ensure matching IPv4/IPv6 are supplied. */ void setAddrs(const Ip::Address &aLocal, const Ip::Address &aRemote) {local = aLocal; remote = aRemote;} /** retrieve the CachePeer pointer for use. * The caller is responsible for all CBDATA operations regarding the * used of the pointer returned. */ CachePeer * getPeer() const; /** alter the stored CachePeer pointer. * Perform appropriate CBDATA operations for locking the CachePeer pointer */ void setPeer(CachePeer * p); /** The time the connection started */ time_t startTime() const {return startTime_;} /** The connection lifetime */ time_t lifeTime() const {return squid_curtime - startTime_;} /** The time left for this connection*/ time_t timeLeft(const time_t idleTimeout) const; /// Connection establishment timeout for callers that have already decided /// to connect(2), either for the first time or after checking /// EnoughTimeToReForward() during any re-forwarding attempts. /// \returns the time left for this connection to become connected /// \param fwdStart The start time of the peer selection/connection process. time_t connectTimeout(const time_t fwdStart) const; void noteStart() {startTime_ = squid_curtime;} Security::NegotiationHistory *tlsNegotiations(); const Security::NegotiationHistory *hasTlsNegotiations() const {return tlsHistory;} private: /** These objects may not be exactly duplicated. Use copyDetails() instead. */ Connection(const Connection &c); /** These objects may not be exactly duplicated. Use copyDetails() instead. */ Connection & operator =(const Connection &c); public: /** Address/Port for the Squid end of a TCP link. */ Ip::Address local; /** Address for the Remote end of a TCP link. */ Ip::Address remote; /** Hierarchy code for this connection link */ hier_code peerType; /** Socket used by this connection. Negative if not open. */ int fd; /** Quality of Service TOS values currently sent on this connection */ tos_t tos; /** Netfilter MARK values currently sent on this connection */ nfmark_t nfmark; /** COMM flags set on this connection */ int flags; char rfc931[USER_IDENT_SZ]; #if USE_SQUID_EUI Eui::Eui48 remoteEui48; Eui::Eui64 remoteEui64; #endif private: /** cache_peer data object (if any) */ CachePeer *peer_; /** The time the connection object was created */ time_t startTime_; /** TLS connection details*/ Security::NegotiationHistory *tlsHistory; }; }; // namespace Comm // NP: Order and namespace here is very important. // * The second define inlines the first. // * Stream inheritance overloading is searched in the global scope first. inline std::ostream & operator << (std::ostream &os, const Comm::Connection &conn) { os << "local=" << conn.local << " remote=" << conn.remote; if (conn.fd >= 0) os << " FD " << conn.fd; if (conn.flags != COMM_UNSET) os << " flags=" << conn.flags; #if USE_IDENT if (*conn.rfc931) os << " IDENT::" << conn.rfc931; #endif return os; } inline std::ostream & operator << (std::ostream &os, const Comm::ConnectionPointer &conn) { if (conn != NULL) os << *conn; return os; } #endif