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