]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/comm/Connection.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / comm / Connection.cc
index 51b171126776bc59b5da03336e64224e7cd3bc82..2ada05acb9cc02795ab87583a34279f1ec9c93ff 100644 (file)
@@ -1,10 +1,27 @@
-#include "config.h"
+/*
+ * 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.
+ */
+
+#include "squid.h"
+#include "CachePeer.h"
 #include "cbdata.h"
 #include "comm.h"
 #include "comm/Connection.h"
 #include "fde.h"
+#include "FwdState.h"
+#include "neighbors.h"
+#include "security/NegotiationHistory.h"
+#include "SquidConfig.h"
 #include "SquidTime.h"
+#include <ostream>
+
+InstanceIdDefinitions(Comm::Connection, "conn", uint64_t);
 
+class CachePeer;
 bool
 Comm::IsConnOpen(const Comm::ConnectionPointer &conn)
 {
@@ -12,48 +29,56 @@ Comm::IsConnOpen(const Comm::ConnectionPointer &conn)
 }
 
 Comm::Connection::Connection() :
-        local(),
-        remote(),
-        peerType(HIER_NONE),
-        fd(-1),
-        tos(0),
-        flags(COMM_NONBLOCKING),
-        _peer(NULL)
+    peerType(HIER_NONE),
+    fd(-1),
+    tos(0),
+    nfmark(0),
+    flags(COMM_NONBLOCKING),
+    peer_(nullptr),
+    startTime_(squid_curtime),
+    tlsHistory(nullptr)
 {
     *rfc931 = 0; // quick init the head. the rest does not matter.
 }
 
-static int64_t lost_conn = 0;
 Comm::Connection::~Connection()
 {
-    assert(fd < 0); // These should never occur now.
-
     if (fd >= 0) {
-        debugs(5, 0, "NOTE: Orphan Comm::Connection: " << *this);
-        debugs(5, 0, "NOTE: Orphaned Comm::Connections: " << ++lost_conn);
+        if (flags & COMM_ORPHANED) {
+            debugs(5, 5, "closing orphan: " << *this);
+        } else {
+            static uint64_t losses = 0;
+            ++losses;
+            debugs(5, 4, "BUG #3329: Lost orphan #" << losses << ": " << *this);
+        }
         close();
     }
 
-    cbdataReferenceDone(_peer);
+    cbdataReferenceDone(peer_);
+
+    delete tlsHistory;
 }
 
 Comm::ConnectionPointer
-Comm::Connection::copyDetails() const
+Comm::Connection::cloneDestinationDetails() const
 {
-    ConnectionPointer c = new Comm::Connection;
-
-    c->local = local;
-    c->remote = remote;
+    const ConnectionPointer c = new Comm::Connection;
+    c->setAddrs(local, remote);
     c->peerType = peerType;
-    c->tos = tos;
     c->flags = flags;
+    c->peer_ = cbdataReference(getPeer());
+    assert(!c->isOpen());
+    return c;
+}
 
-    // ensure FD is not open in the new copy.
-    c->fd = -1;
-
-    // ensure we have a cbdata reference to _peer not a straight ptr copy.
-    c->_peer = cbdataReference(getPeer());
-
+Comm::ConnectionPointer
+Comm::Connection::cloneIdentDetails() const
+{
+    auto c = cloneDestinationDetails();
+    c->tos = tos;
+    c->nfmark = nfmark;
+    c->nfConnmark = nfConnmark;
+    c->startTime_ = startTime_;
     return c;
 }
 
@@ -62,30 +87,109 @@ Comm::Connection::close()
 {
     if (isOpen()) {
         comm_close(fd);
+        noteClosure();
+    }
+}
+
+void
+Comm::Connection::noteClosure()
+{
+    if (isOpen()) {
         fd = -1;
-        if (getPeer())
-            getPeer()->stats.conn_open--;
+        if (CachePeer *p=getPeer())
+            peerConnClosed(p);
     }
 }
 
-peer * const
+CachePeer *
 Comm::Connection::getPeer() const
 {
-    if (cbdataReferenceValid(_peer))
-        return _peer;
+    if (cbdataReferenceValid(peer_))
+        return peer_;
 
     return NULL;
 }
 
 void
-Comm::Connection::setPeer(peer *p)
+Comm::Connection::setPeer(CachePeer *p)
 {
     /* set to self. nothing to do. */
     if (getPeer() == p)
         return;
 
-    cbdataReferenceDone(_peer);
+    cbdataReferenceDone(peer_);
     if (p) {
-        _peer = cbdataReference(p);
+        peer_ = cbdataReference(p);
     }
 }
+
+time_t
+Comm::Connection::timeLeft(const time_t idleTimeout) const
+{
+    if (!Config.Timeout.pconnLifetime)
+        return idleTimeout;
+
+    const time_t lifeTimeLeft = lifeTime() < Config.Timeout.pconnLifetime ? Config.Timeout.pconnLifetime - lifeTime() : 1;
+    return min(lifeTimeLeft, idleTimeout);
+}
+
+Security::NegotiationHistory *
+Comm::Connection::tlsNegotiations()
+{
+    if (!tlsHistory)
+        tlsHistory = new Security::NegotiationHistory;
+    return tlsHistory;
+}
+
+time_t
+Comm::Connection::connectTimeout(const time_t fwdStart) const
+{
+    // a connection opening timeout (ignoring forwarding time limits for now)
+    const CachePeer *peer = getPeer();
+    const auto ctimeout = peer ? peer->connectTimeout() : Config.Timeout.connect;
+
+    // time we have left to finish the whole forwarding process
+    const time_t fwdTimeLeft = FwdState::ForwardTimeout(fwdStart);
+
+    // The caller decided to connect. If there is no time left, to protect
+    // connecting code from trying to establish a connection while a zero (i.e.,
+    // "immediate") timeout notification is firing, ensure a positive timeout.
+    // XXX: This hack gives some timed-out forwarding sequences more time than
+    // some sequences that have not quite reached the forwarding timeout yet!
+    const time_t ftimeout = fwdTimeLeft ? fwdTimeLeft : 5; // seconds
+
+    return min(ctimeout, ftimeout);
+}
+
+ScopedId
+Comm::Connection::codeContextGist() const {
+    return id.detach();
+}
+
+std::ostream &
+Comm::Connection::detailCodeContext(std::ostream &os) const
+{
+    return os << Debug::Extra << "connection: " << *this;
+}
+
+std::ostream &
+operator << (std::ostream &os, const Comm::Connection &conn)
+{
+    os << conn.id;
+    if (!conn.local.isNoAddr() || conn.local.port())
+        os << " local=" << conn.local;
+    if (!conn.remote.isNoAddr() || conn.remote.port())
+        os << " remote=" << conn.remote;
+    if (conn.peerType)
+        os << ' ' << hier_code_str[conn.peerType];
+    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;
+}
+