Squid Web Cache master
Loading...
Searching...
No Matches
Connection.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 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#include "squid.h"
10#include "base/JobWait.h"
11#include "CachePeer.h"
12#include "cbdata.h"
13#include "comm.h"
14#include "comm/Connection.h"
15#include "fde.h"
16#include "FwdState.h"
17#include "neighbors.h"
19#include "SquidConfig.h"
20
21#include <ostream>
22
24
25class CachePeer;
26bool
28{
29 return conn != nullptr && conn->isOpen();
30}
31
33{
34 if (fd >= 0) {
35 if (flags & COMM_ORPHANED) {
36 debugs(5, 5, "closing orphan: " << *this);
37 } else {
38 static uint64_t losses = 0;
39 ++losses;
40 debugs(5, 4, "BUG #3329: Lost orphan #" << losses << ": " << *this);
41 }
42 close();
43 }
44
46
47 delete tlsHistory;
48}
49
52{
53 const ConnectionPointer clone = new Comm::Connection;
54 auto &c = *clone; // optimization
55
56 /*
57 * Copy or excuse each data member. Excused members do not belong to a
58 * Connection configuration profile because their values cannot be reused
59 * across (co-existing) Connection objects and/or are tied to their own
60 * object lifetime.
61 */
62
63 c.setAddrs(local, remote);
64 c.peerType = peerType;
65 // fd excused
66 c.tos = tos;
67 c.nfmark = nfmark;
68 c.nfConnmark = nfConnmark;
69 // COMM_ORPHANED is not a part of connection opening instructions
70 c.flags = flags & ~COMM_ORPHANED;
71
72#if USE_SQUID_EUI
73 // These are currently only set when accepting connections and never used
74 // for establishing new ones, so this copying is currently in vain, but,
75 // technically, they can be a part of connection opening instructions.
76 c.remoteEui48 = remoteEui48;
77 c.remoteEui64 = remoteEui64;
78#endif
79
80 // id excused
81 c.peer_ = cbdataReference(getPeer());
82 // startTime_ excused
83 // tlsHistory excused
84
85 debugs(5, 5, this << " made " << c);
86 assert(!c.isOpen());
87 return clone;
88}
89
90void
92{
93 if (isOpen()) {
94 comm_close(fd);
95 noteClosure();
96 }
97}
98
99void
101{
102 if (isOpen()) {
103 fd = -1;
104 if (CachePeer *p=getPeer())
106 }
107}
108
109CachePeer *
111{
112 if (cbdataReferenceValid(peer_))
113 return peer_;
114
115 return nullptr;
116}
117
118void
120{
121 /* set to self. nothing to do. */
122 if (getPeer() == p)
123 return;
124
125 cbdataReferenceDone(peer_);
126 if (p) {
127 peer_ = cbdataReference(p);
128 }
129}
130
131bool
133{
134 return peer_ && !cbdataReferenceValid(peer_);
135}
136
137time_t
138Comm::Connection::timeLeft(const time_t idleTimeout) const
139{
141 return idleTimeout;
142
143 const time_t lifeTimeLeft = lifeTime() < Config.Timeout.pconnLifetime ? Config.Timeout.pconnLifetime - lifeTime() : 1;
144 return min(lifeTimeLeft, idleTimeout);
145}
146
149{
150 if (!tlsHistory)
151 tlsHistory = new Security::NegotiationHistory;
152 return tlsHistory;
153}
154
155time_t
156Comm::Connection::connectTimeout(const time_t fwdStart) const
157{
158 // a connection opening timeout (ignoring forwarding time limits for now)
159 const CachePeer *peer = getPeer();
160 const auto ctimeout = peer ? peer->connectTimeout() : Config.Timeout.connect;
161
162 // time we have left to finish the whole forwarding process
163 const time_t fwdTimeLeft = FwdState::ForwardTimeout(fwdStart);
164
165 // The caller decided to connect. If there is no time left, to protect
166 // connecting code from trying to establish a connection while a zero (i.e.,
167 // "immediate") timeout notification is firing, ensure a positive timeout.
168 // XXX: This hack gives some timed-out forwarding sequences more time than
169 // some sequences that have not quite reached the forwarding timeout yet!
170 const time_t ftimeout = fwdTimeLeft ? fwdTimeLeft : 5; // seconds
171
172 return min(ctimeout, ftimeout);
173}
174
177 return id.detach();
178}
179
180std::ostream &
182{
183 return os << Debug::Extra << "connection: " << *this;
184}
185
186std::ostream &
187Comm::operator << (std::ostream &os, const Connection &conn)
188{
189 os << conn.id;
190 if (!conn.local.isNoAddr() || conn.local.port())
191 os << " local=" << conn.local;
192 if (!conn.remote.isNoAddr() || conn.remote.port())
193 os << " remote=" << conn.remote;
194 if (conn.peerType)
195 os << ' ' << hier_code_str[conn.peerType];
196 if (conn.fd >= 0)
197 os << " FD " << conn.fd;
198 if (conn.flags != COMM_UNSET)
199 os << " flags=" << conn.flags;
200 return os;
201}
202
#define COMM_ORPHANED
not registered with Comm and not owned by any connection-closing code
Definition Connection.h:54
#define COMM_UNSET
Definition Connection.h:45
#define InstanceIdDefinitions(...)
convenience macro to instantiate Class-specific stuff in .cc files
Definition InstanceId.h:90
class SquidConfig Config
#define assert(EX)
Definition assert.h:17
int cbdataReferenceValid(const void *p)
Definition cbdata.cc:270
#define cbdataReferenceDone(var)
Definition cbdata.h:357
#define cbdataReference(var)
Definition cbdata.h:348
time_t connectTimeout() const
Definition CachePeer.cc:120
bool isOpen() const
Definition Connection.h:101
InstanceId< Connection, uint64_t > id
Definition Connection.h:184
hier_code peerType
Definition Connection.h:155
time_t timeLeft(const time_t idleTimeout) const
CachePeer * getPeer() const
Ip::Address remote
Definition Connection.h:152
std::ostream & detailCodeContext(std::ostream &os) const override
appends human-friendly context description line(s) to a cache.log record
Security::NegotiationHistory * tlsHistory
Definition Connection.h:194
CachePeer * peer_
Definition Connection.h:188
Ip::Address local
Definition Connection.h:149
bool toGoneCachePeer() const
whether this is a connection to a cache_peer that was removed during reconfiguration
~Connection() override
Definition Connection.cc:32
time_t connectTimeout(const time_t fwdStart) const
Security::NegotiationHistory * tlsNegotiations()
ConnectionPointer cloneProfile() const
Create a new closed Connection with the same configuration as this one.
Definition Connection.cc:51
ScopedId codeContextGist() const override
void setPeer(CachePeer *p)
static std::ostream & Extra(std::ostream &)
Definition debug.cc:1316
static time_t ForwardTimeout(const time_t fwdStart)
time left to finish the whole forwarding process (which started at fwdStart)
Definition FwdState.cc:423
bool isNoAddr() const
Definition Address.cc:304
unsigned short port() const
Definition Address.cc:790
struct SquidConfig::@77 Timeout
time_t pconnLifetime
pconn_lifetime in squid.conf
time_t connect
bool isOpen(const int fd)
Definition comm.cc:91
#define comm_close(x)
Definition comm.h:36
A const & min(A const &lhs, A const &rhs)
#define debugs(SECTION, LEVEL, CONTENT)
Definition Stream.h:192
const char * hier_code_str[]
std::ostream & operator<<(std::ostream &, const Connection &)
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition Connection.cc:27
void peerConnClosed(CachePeer *p)
Notifies peer of an associated connection closure.
Definition neighbors.cc:242