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 
23 InstanceIdDefinitions(Comm::Connection, "conn", uint64_t);
24 
25 class CachePeer;
26 bool
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 
90 void
92 {
93  if (isOpen()) {
94  comm_close(fd);
95  noteClosure();
96  }
97 }
98 
99 void
101 {
102  if (isOpen()) {
103  fd = -1;
104  if (CachePeer *p=getPeer())
105  peerConnClosed(p);
106  }
107 }
108 
109 CachePeer *
111 {
112  if (cbdataReferenceValid(peer_))
113  return peer_;
114 
115  return nullptr;
116 }
117 
118 void
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 
131 bool
133 {
134  return peer_ && !cbdataReferenceValid(peer_);
135 }
136 
137 time_t
138 Comm::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 
155 time_t
156 Comm::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 
175 ScopedId
177  return id.detach();
178 }
179 
180 std::ostream &
181 Comm::Connection::detailCodeContext(std::ostream &os) const
182 {
183  return os << Debug::Extra << "connection: " << *this;
184 }
185 
186 std::ostream &
187 Comm::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 
hier_code peerType
Definition: Connection.h:155
time_t connect
Definition: SquidConfig.h:115
struct CachePeer::@21::@27 flags
~Connection() override
Definition: Connection.cc:32
InstanceId< Connection, uint64_t > id
Definition: Connection.h:184
bool toGoneCachePeer() const
whether this is a connection to a cache_peer that was removed during reconfiguration
Definition: Connection.cc:132
#define comm_close(x)
Definition: comm.h:36
int cbdataReferenceValid(const void *p)
Definition: cbdata.cc:270
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:27
struct SquidConfig::@77 Timeout
time_t connectTimeout() const
Definition: CachePeer.cc:120
#define cbdataReference(var)
Definition: cbdata.h:348
std::ostream & operator<<(std::ostream &, const Connection &)
Definition: Connection.cc:187
time_t connectTimeout(const time_t fwdStart) const
Definition: Connection.cc:156
ConnectionPointer cloneProfile() const
Create a new closed Connection with the same configuration as this one.
Definition: Connection.cc:51
time_t timeLeft(const time_t idleTimeout) const
Definition: Connection.cc:138
void peerConnClosed(CachePeer *p)
Notifies peer of an associated connection closure.
Definition: neighbors.cc:242
unsigned short port() const
Definition: Address.cc:790
Ip::Address local
Definition: Connection.h:149
CachePeer * getPeer() const
Definition: Connection.cc:110
ScopedId codeContextGist() const override
Definition: Connection.cc:176
Ip::Address remote
Definition: Connection.h:152
#define assert(EX)
Definition: assert.h:17
SSL Connection
Definition: Session.h:49
static time_t ForwardTimeout(const time_t fwdStart)
time left to finish the whole forwarding process (which started at fwdStart)
Definition: FwdState.cc:423
#define cbdataReferenceDone(var)
Definition: cbdata.h:357
CachePeer * peer_
Definition: Connection.h:188
static std::ostream & Extra(std::ostream &)
Definition: debug.cc:1316
bool isNoAddr() const
Definition: Address.cc:304
time_t pconnLifetime
pconn_lifetime in squid.conf
Definition: SquidConfig.h:122
Security::NegotiationHistory * tlsHistory
Definition: Connection.h:194
const char * hier_code_str[]
#define COMM_UNSET
Definition: Connection.h:45
InstanceIdDefinitions(Comm::Connection, "conn", uint64_t)
std::ostream & detailCodeContext(std::ostream &os) const override
appends human-friendly context description line(s) to a cache.log record
Definition: Connection.cc:181
void setPeer(CachePeer *p)
Definition: Connection.cc:119
bool isOpen() const
Definition: Connection.h:101
bool isOpen(const int fd)
Definition: comm.cc:91
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
const A & min(A const &lhs, A const &rhs)
Security::NegotiationHistory * tlsNegotiations()
Definition: Connection.cc:148
#define COMM_ORPHANED
not registered with Comm and not owned by any connection-closing code
Definition: Connection.h:54
class SquidConfig Config
Definition: SquidConfig.cc:12

 

Introduction

Documentation

Support

Miscellaneous