1 /* 2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors 3 * 4 * Squid software is distributed under GPLv2+ license and includes 5 * contributions from numerous individuals and organizations. 6 * Please see the COPYING and CONTRIBUTORS files for details. 7 */ 8 9 /* DEBUG: section 05 Socket Functions */ 10 11 #ifndef _SQUIDCONNECTIONDETAIL_H_ 12 #define _SQUIDCONNECTIONDETAIL_H_ 13 14 #include "comm/forward.h" 15 #include "defines.h" 16 #if USE_SQUID_EUI 17 #include "eui/Eui48.h" 18 #include "eui/Eui64.h" 19 #endif 20 #include "hier_code.h" 21 #include "ip/Address.h" 22 #include "ip/forward.h" 23 #include "mem/forward.h" 24 #include "SquidTime.h" 25 26 #include <iosfwd> 27 #include <ostream> 28 29 class CachePeer; 30 31 namespace Security 32 { 33 class NegotiationHistory; 34 }; 35 36 namespace Comm 37 { 38 39 /* TODO: make these a struct of boolean flags members in the connection instead of a bitmap. 40 * we can't do that until all non-comm code uses Commm::Connection objects to create FD 41 * currently there is code still using comm_open() and comm_openex() synchronously!! 42 */ 43 #define COMM_UNSET 0x00 44 #define COMM_NONBLOCKING 0x01 // default flag. 45 #define COMM_NOCLOEXEC 0x02 46 #define COMM_REUSEADDR 0x04 // shared FD may be both accept()ing and read()ing 47 #define COMM_DOBIND 0x08 // requires a bind() 48 #define COMM_TRANSPARENT 0x10 // arrived via TPROXY 49 #define COMM_INTERCEPTION 0x20 // arrived via NAT 50 51 /** 52 * Store data about the physical and logical attributes of a connection. 53 * 54 * Some link state can be infered from the data, however this is not an 55 * object for state data. But a semantic equivalent for FD with easily 56 * accessible cached properties not requiring repeated complex lookups. 57 * 58 * Connection properties may be changed until the connection is opened. 59 * Properties should be considered read-only outside of the Comm layer 60 * code once the connection is open. 61 * 62 * These objects should not be passed around directly, 63 * but a Comm::ConnectionPointer should be passed instead. 64 */ 65 class Connection : public RefCountable 66 { 67 MEMPROXY_CLASS(Comm::Connection); 68 69 public: 70 Connection(); 71 72 /** Clear the connection properties and close any open socket. */ 73 ~Connection(); 74 75 /** Copy an existing connections IP and properties. 76 * This excludes the FD. The new copy will be a closed connection. 77 */ 78 ConnectionPointer copyDetails() const; 79 80 /** Close any open socket. */ 81 void close(); 82 83 /** Synchronize with Comm: Somebody closed our connection. */ 84 void noteClosure(); 85 86 /** determine whether this object describes an active connection or not. */ isOpen()87 bool isOpen() const { return (fd >= 0); } 88 89 /** Alter the stored IP address pair. 90 * WARNING: Does not ensure matching IPv4/IPv6 are supplied. 91 */ setAddrs(const Ip::Address & aLocal,const Ip::Address & aRemote)92 void setAddrs(const Ip::Address &aLocal, const Ip::Address &aRemote) {local = aLocal; remote = aRemote;} 93 94 /** retrieve the CachePeer pointer for use. 95 * The caller is responsible for all CBDATA operations regarding the 96 * used of the pointer returned. 97 */ 98 CachePeer * getPeer() const; 99 100 /** alter the stored CachePeer pointer. 101 * Perform appropriate CBDATA operations for locking the CachePeer pointer 102 */ 103 void setPeer(CachePeer * p); 104 105 /** The time the connection started */ startTime()106 time_t startTime() const {return startTime_;} 107 108 /** The connection lifetime */ lifeTime()109 time_t lifeTime() const {return squid_curtime - startTime_;} 110 111 /** The time left for this connection*/ 112 time_t timeLeft(const time_t idleTimeout) const; 113 114 /// Connection establishment timeout for callers that have already decided 115 /// to connect(2), either for the first time or after checking 116 /// EnoughTimeToReForward() during any re-forwarding attempts. 117 /// \returns the time left for this connection to become connected 118 /// \param fwdStart The start time of the peer selection/connection process. 119 time_t connectTimeout(const time_t fwdStart) const; 120 noteStart()121 void noteStart() {startTime_ = squid_curtime;} 122 123 Security::NegotiationHistory *tlsNegotiations(); hasTlsNegotiations()124 const Security::NegotiationHistory *hasTlsNegotiations() const {return tlsHistory;} 125 126 private: 127 /** These objects may not be exactly duplicated. Use copyDetails() instead. */ 128 Connection(const Connection &c); 129 130 /** These objects may not be exactly duplicated. Use copyDetails() instead. */ 131 Connection & operator =(const Connection &c); 132 133 public: 134 /** Address/Port for the Squid end of a TCP link. */ 135 Ip::Address local; 136 137 /** Address for the Remote end of a TCP link. */ 138 Ip::Address remote; 139 140 /** Hierarchy code for this connection link */ 141 hier_code peerType; 142 143 /** Socket used by this connection. Negative if not open. */ 144 int fd; 145 146 /** Quality of Service TOS values currently sent on this connection */ 147 tos_t tos; 148 149 /** Netfilter MARK values currently sent on this connection */ 150 nfmark_t nfmark; 151 152 /** COMM flags set on this connection */ 153 int flags; 154 155 char rfc931[USER_IDENT_SZ]; 156 157 #if USE_SQUID_EUI 158 Eui::Eui48 remoteEui48; 159 Eui::Eui64 remoteEui64; 160 #endif 161 162 private: 163 /** cache_peer data object (if any) */ 164 CachePeer *peer_; 165 166 /** The time the connection object was created */ 167 time_t startTime_; 168 169 /** TLS connection details*/ 170 Security::NegotiationHistory *tlsHistory; 171 }; 172 173 }; // namespace Comm 174 175 // NP: Order and namespace here is very important. 176 // * The second define inlines the first. 177 // * Stream inheritance overloading is searched in the global scope first. 178 179 inline std::ostream & 180 operator << (std::ostream &os, const Comm::Connection &conn) 181 { 182 os << "local=" << conn.local << " remote=" << conn.remote; 183 if (conn.fd >= 0) 184 os << " FD " << conn.fd; 185 if (conn.flags != COMM_UNSET) 186 os << " flags=" << conn.flags; 187 #if USE_IDENT 188 if (*conn.rfc931) 189 os << " IDENT::" << conn.rfc931; 190 #endif 191 return os; 192 } 193 194 inline std::ostream & 195 operator << (std::ostream &os, const Comm::ConnectionPointer &conn) 196 { 197 if (conn != NULL) 198 os << *conn; 199 return os; 200 } 201 202 #endif 203 204