]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/comm/ConnOpener.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / comm / ConnOpener.cc
index a253faf6a7408c1dfe922774b10ec01c41ae5b0d..a5e36609d038640a517e119f59073c0f768989d1 100644 (file)
@@ -1,39 +1,44 @@
 /*
- * DEBUG: section 05    Socket Connection Opener
+ * Copyright (C) 1996-2015 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.
  */
 
+/* DEBUG: section 05    Socket Connection Opener */
+
 #include "squid.h"
 #include "CachePeer.h"
-#include "comm/ConnOpener.h"
+#include "comm.h"
 #include "comm/Connection.h"
+#include "comm/ConnOpener.h"
 #include "comm/Loops.h"
-#include "comm.h"
 #include "fd.h"
 #include "fde.h"
 #include "globals.h"
 #include "icmp/net_db.h"
-#include "ipcache.h"
+#include "ip/QosConfig.h"
 #include "ip/tools.h"
+#include "ipcache.h"
 #include "SquidConfig.h"
 #include "SquidTime.h"
 
-#if HAVE_ERRNO_H
-#include <errno.h>
-#endif
+#include <cerrno>
 
 class CachePeer;
 
 CBDATA_NAMESPACED_CLASS_INIT(Comm, ConnOpener);
 
 Comm::ConnOpener::ConnOpener(Comm::ConnectionPointer &c, AsyncCall::Pointer &handler, time_t ctimeout) :
-        AsyncJob("Comm::ConnOpener"),
-        host_(NULL),
-        temporaryFd_(-1),
-        conn_(c),
-        callback_(handler),
-        totalTries_(0),
-        failRetries_(0),
-        deadline_(squid_curtime + static_cast<time_t>(ctimeout))
+    AsyncJob("Comm::ConnOpener"),
+    host_(NULL),
+    temporaryFd_(-1),
+    conn_(c),
+    callback_(handler),
+    totalTries_(0),
+    failRetries_(0),
+    deadline_(squid_curtime + static_cast<time_t>(ctimeout))
 {}
 
 Comm::ConnOpener::~ConnOpener()
@@ -64,12 +69,14 @@ Comm::ConnOpener::swanSong()
 {
     if (callback_ != NULL) {
         // inform the still-waiting caller we are dying
-        sendAnswer(COMM_ERR_CONNECT, 0, "Comm::ConnOpener::swanSong");
+        sendAnswer(Comm::ERR_CONNECT, 0, "Comm::ConnOpener::swanSong");
     }
 
+    // did we abort with a temporary FD assigned?
     if (temporaryFd_ >= 0)
         closeFd();
 
+    // did we abort while waiting between retries?
     if (calls_.sleep_)
         cancelSleep();
 
@@ -99,7 +106,7 @@ Comm::ConnOpener::getHost() const
  * Pass the results back to the external handler.
  */
 void
-Comm::ConnOpener::sendAnswer(comm_err_t errFlag, int xerrno, const char *why)
+Comm::ConnOpener::sendAnswer(Comm::Flag errFlag, int xerrno, const char *why)
 {
     // only mark the address good/bad AFTER connect is finished.
     if (host_ != NULL) {
@@ -120,6 +127,7 @@ Comm::ConnOpener::sendAnswer(comm_err_t errFlag, int xerrno, const char *why)
         if (callback_->canceled()) {
             debugs(5, 4, conn_ << " not calling canceled " << *callback_ <<
                    " [" << callback_->id << ']' );
+            // TODO save the pconn to the pconnPool ?
         } else {
             typedef CommConnectCbParams Params;
             Params &params = GetCommParams<Params>(callback_);
@@ -222,12 +230,13 @@ Comm::ConnOpener::start()
     Must(conn_ != NULL);
 
     /* outbound sockets have no need to be protocol agnostic. */
-    if (!(Ip::EnableIpv6&IPV6_SPECIAL_V4MAPPING) && conn_->remote.IsIPv4()) {
-        conn_->local.SetIPv4();
+    if (!(Ip::EnableIpv6&IPV6_SPECIAL_V4MAPPING) && conn_->remote.isIPv4()) {
+        conn_->local.setIPv4();
     }
 
+    conn_->noteStart();
     if (createFd())
-        connect();
+        doConnect();
 }
 
 /// called at the end of Comm::ConnOpener::DelayedConnectRetry event
@@ -238,7 +247,7 @@ Comm::ConnOpener::restart()
     calls_.sleep_ = false;
 
     if (createFd())
-        connect();
+        doConnect();
 }
 
 /// Create a socket for the future connection or return false.
@@ -252,12 +261,25 @@ Comm::ConnOpener::createFd()
     if (callback_ == NULL || callback_->canceled())
         return false;
 
-    temporaryFd_ = comm_openex(SOCK_STREAM, IPPROTO_TCP, conn_->local, conn_->flags, conn_->tos, conn_->nfmark, host_);
+    temporaryFd_ = comm_openex(SOCK_STREAM, IPPROTO_TCP, conn_->local, conn_->flags, host_);
     if (temporaryFd_ < 0) {
-        sendAnswer(COMM_ERR_CONNECT, 0, "Comm::ConnOpener::createFd");
+        sendAnswer(Comm::ERR_CONNECT, 0, "Comm::ConnOpener::createFd");
         return false;
     }
 
+    // Set TOS if needed.
+    if (conn_->tos &&
+            Ip::Qos::setSockTos(temporaryFd_, conn_->tos, conn_->remote.isIPv4() ? AF_INET : AF_INET6) < 0)
+        conn_->tos = 0;
+#if SO_MARK
+    if (conn_->nfmark &&
+            Ip::Qos::setSockNfmark(temporaryFd_, conn_->nfmark) < 0)
+        conn_->nfmark = 0;
+#endif
+
+    fd_table[temporaryFd_].tosToServer = conn_->tos;
+    fd_table[temporaryFd_].nfmarkToServer = conn_->nfmark;
+
     typedef CommCbMemFunT<Comm::ConnOpener, CommCloseCbParams> abortDialer;
     calls_.earlyAbort_ = JobCallback(5, 4, abortDialer, this, Comm::ConnOpener::earlyAbort);
     comm_add_close_handler(temporaryFd_, calls_.earlyAbort_);
@@ -303,12 +325,12 @@ Comm::ConnOpener::connected()
     Must(fd_table[conn_->fd].flags.open);
     fd_table[conn_->fd].local_addr = conn_->local;
 
-    sendAnswer(COMM_OK, 0, "Comm::ConnOpener::connected");
+    sendAnswer(Comm::OK, 0, "Comm::ConnOpener::connected");
 }
 
 /// Make an FD connection attempt.
 void
-Comm::ConnOpener::connect()
+Comm::ConnOpener::doConnect()
 {
     Must(conn_ != NULL);
     Must(temporaryFd_ >= 0);
@@ -317,13 +339,13 @@ Comm::ConnOpener::connect()
 
     switch (comm_connect_addr(temporaryFd_, conn_->remote) ) {
 
-    case COMM_INPROGRESS:
-        debugs(5, 5, HERE << conn_ << ": COMM_INPROGRESS");
+    case Comm::INPROGRESS:
+        debugs(5, 5, HERE << conn_ << ": Comm::INPROGRESS");
         Comm::SetSelect(temporaryFd_, COMM_SELECT_WRITE, Comm::ConnOpener::InProgressConnectRetry, new Pointer(this), 0);
         break;
 
-    case COMM_OK:
-        debugs(5, 5, HERE << conn_ << ": COMM_OK - connected");
+    case Comm::OK:
+        debugs(5, 5, HERE << conn_ << ": Comm::OK - connected");
         connected();
         break;
 
@@ -336,12 +358,12 @@ Comm::ConnOpener::connect()
 
         if (failRetries_ < Config.connect_retries) {
             debugs(5, 5, HERE << conn_ << ": * - try again");
-            sleep();
+            retrySleep();
             return;
         } else {
             // send ERROR back to the upper layer.
             debugs(5, 5, HERE << conn_ << ": * - ERR tried too many times already.");
-            sendAnswer(COMM_ERR_CONNECT, xerrno, "Comm::ConnOpener::connect");
+            sendAnswer(Comm::ERR_CONNECT, xerrno, "Comm::ConnOpener::doConnect");
         }
     }
     }
@@ -349,7 +371,7 @@ Comm::ConnOpener::connect()
 
 /// Close and wait a little before trying to open and connect again.
 void
-Comm::ConnOpener::sleep()
+Comm::ConnOpener::retrySleep()
 {
     Must(!calls_.sleep_);
     closeFd();
@@ -385,16 +407,16 @@ void
 Comm::ConnOpener::lookupLocalAddress()
 {
     struct addrinfo *addr = NULL;
-    conn_->local.InitAddrInfo(addr);
+    Ip::Address::InitAddr(addr);
 
     if (getsockname(conn_->fd, addr->ai_addr, &(addr->ai_addrlen)) != 0) {
         debugs(50, DBG_IMPORTANT, "ERROR: Failed to retrieve TCP/UDP details for socket: " << conn_ << ": " << xstrerror());
-        conn_->local.FreeAddrInfo(addr);
+        Ip::Address::FreeAddr(addr);
         return;
     }
 
     conn_->local = *addr;
-    conn_->local.FreeAddrInfo(addr);
+    Ip::Address::FreeAddr(addr);
     debugs(5, 6, HERE << conn_);
 }
 
@@ -407,7 +429,7 @@ Comm::ConnOpener::earlyAbort(const CommCloseCbParams &io)
     debugs(5, 3, HERE << io.conn);
     calls_.earlyAbort_ = NULL;
     // NP: is closing or shutdown better?
-    sendAnswer(COMM_ERR_CLOSING, io.xerrno, "Comm::ConnOpener::earlyAbort");
+    sendAnswer(Comm::ERR_CLOSING, io.xerrno, "Comm::ConnOpener::earlyAbort");
 }
 
 /**
@@ -419,14 +441,14 @@ Comm::ConnOpener::timeout(const CommTimeoutCbParams &)
 {
     debugs(5, 5, HERE << conn_ << ": * - ERR took too long to receive response.");
     calls_.timeout_ = NULL;
-    sendAnswer(COMM_TIMEOUT, ETIMEDOUT, "Comm::ConnOpener::timeout");
+    sendAnswer(Comm::TIMEOUT, ETIMEDOUT, "Comm::ConnOpener::timeout");
 }
 
-/* Legacy Wrapper for the retry event after COMM_INPROGRESS
- * XXX: As soon as Comm::SetSelect() accepts Async calls we can use a ConnOpener::connect call
+/* Legacy Wrapper for the retry event after Comm::INPROGRESS
+ * XXX: As soon as Comm::SetSelect() accepts Async calls we can use a ConnOpener::doConnect call
  */
 void
-Comm::ConnOpener::InProgressConnectRetry(int fd, void *data)
+Comm::ConnOpener::InProgressConnectRetry(int, void *data)
 {
     Pointer *ptr = static_cast<Pointer*>(data);
     assert(ptr);
@@ -434,7 +456,7 @@ Comm::ConnOpener::InProgressConnectRetry(int fd, void *data)
         // Ew. we are now outside the all AsyncJob protections.
         // get back inside by scheduling another call...
         typedef NullaryMemFunT<Comm::ConnOpener> Dialer;
-        AsyncCall::Pointer call = JobCallback(5, 4, Dialer, cs, Comm::ConnOpener::connect);
+        AsyncCall::Pointer call = JobCallback(5, 4, Dialer, cs, Comm::ConnOpener::doConnect);
         ScheduleCallHere(call);
     }
     delete ptr;
@@ -457,3 +479,4 @@ Comm::ConnOpener::DelayedConnectRetry(void *data)
     }
     delete ptr;
 }
+