]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Move EUI and NAT results into Comm::Connection
authorAmos Jeffries <squid3@treenet.co.nz>
Fri, 25 Feb 2011 03:38:04 +0000 (16:38 +1300)
committerAmos Jeffries <squid3@treenet.co.nz>
Fri, 25 Feb 2011 03:38:04 +0000 (16:38 +1300)
This makes NAT lookup utilize Comm::Connection as both data source and
storage location for results. The net output is that teh active Comm::Connection
object stores accurate data regardless of NAT.

Also moves the EUI lookup results in Comm::Connection.

Removed ConnStateData fields which are available via its Comm::Connection.
Removed HttPRequest fields which are available via its ConnStateData Comm::Connection

Also fixes several build issues unconvered during the transition.

19 files changed:
src/CommCalls.h
src/HttpRequest.cc
src/HttpRequest.h
src/Makefile.am
src/ProtoPort.cc
src/cache_cf.cc
src/client_side.cc
src/client_side.h
src/client_side_reply.cc
src/comm/ConnOpener.h
src/comm/Connection.h
src/comm/TcpAcceptor.cc
src/external_acl.cc
src/http.cc
src/ip/Intercept.cc
src/ip/Intercept.h
src/log/FormatSquidCustom.cc
src/tests/stub_MemObject.cc
src/tests/stub_comm.cc

index 26a17473736278a7f65ca0212701f2fc6683c709..eb2abd5e11df6efd0f2be028cc571e0f5fd7f8a1 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "base/AsyncCall.h"
 #include "base/AsyncJobCalls.h"
-#include "comm/comm_err_t.h"
+#include "comm_err_t.h"
 #include "comm/forward.h"
 
 /* CommCalls implement AsyncCall interface for comm_* callbacks.
index 930f3de3b2dcef810b89c3d310ea2a1efc93c9ce..d5bdbd3e359c8dc08a51a9cb2ad67ead842f51a4 100644 (file)
@@ -93,10 +93,6 @@ HttpRequest::init()
     imslen = 0;
     lastmod = -1;
     client_addr.SetEmpty();
-#if USE_SQUID_EUI
-    client_eui48.clear();
-    client_eui64.clear();
-#endif
     my_addr.SetEmpty();
     body_pipe = NULL;
     // hier
@@ -597,13 +593,12 @@ bool HttpRequest::inheritProperties(const HttpMsg *aMsg)
     if (!aReq)
         return false;
 
+    // main property is which connection the request was received on (if any)
+    clientConnectionManager = aReq->clientConnectionManager;
+
     client_addr = aReq->client_addr;
 #if FOLLOW_X_FORWARDED_FOR
     indirect_client_addr = aReq->indirect_client_addr;
-#endif
-#if USE_SQUID_EUI
-    client_eui48 = aReq->client_eui48;
-    client_eui64 = aReq->client_eui64;
 #endif
     my_addr = aReq->my_addr;
 
index afa12261014c602a0ab1c7b13e8ddfa75a40d383..d2b018b932fa079c8b0b1365d271942ff568a3a8 100644 (file)
@@ -181,13 +181,6 @@ public:
     Ip::Address indirect_client_addr;
 #endif /* FOLLOW_X_FORWARDED_FOR */
 
-#if USE_SQUID_EUI
-    /* TODO these might be merged into one field if we can reliably map the EUI-48 into EUI-64
-       there are some OS differences in the upper bytes. */
-    Eui::Eui48 client_eui48;
-    Eui::Eui64 client_eui64;
-#endif
-
     Ip::Address my_addr;
 
     HierarchyLogEntry hier;
@@ -259,7 +252,7 @@ public:
     }
 
     /// client-side conn manager, if known; used for 1xx response forwarding
-    CbcPointer<ConnStateData> clientConnection;
+    CbcPointer<ConnStateData> clientConnectionManager;
 
     int64_t getRangeOffsetLimit(); /* the result of this function gets cached in rangeOffsetLimit */
 
index 2379ff560f22625b921e3abc2c9ad5e82c130f0c..1a5eb4993be4a082a167de42e6d199c27a1ccb6d 100644 (file)
@@ -25,6 +25,7 @@ SBUF_SOURCE= \
        MemBlob.cc
 
 SNMP_ALL_SOURCE = \
+       snmp_core.h \
        snmp_core.cc \
        snmp_agent.cc
 if USE_SNMP
@@ -286,7 +287,6 @@ squid_SOURCES = \
        ConfigOption.cc \
        ConfigParser.cc \
        ConfigParser.h \
-       ConnectionDetail.h \
        CpuAffinity.cc \
        CpuAffinity.h \
        CpuAffinityMap.cc \
@@ -585,6 +585,12 @@ INCLUDES += $(KRB5INCS)
 
 
 unlinkd_SOURCES = unlinkd_daemon.cc
+unlinkd_LDADD = \
+       ipc/libipc.la \
+       ip/libip.la \
+       $(COMPAT_LIB) \
+       $(XTRA_LIBS)
+
 dnsserver_SOURCES = dnsserver.cc SquidNew.cc tests/stub_debug.cc test_tools.cc time.cc
 recv_announce_SOURCES = recv-announce.cc
 
@@ -2081,18 +2087,40 @@ tests_testString_DEPENDENCIES = \
        $(SQUID_CPPUNIT_LA)
 
 SWAP_TEST_SOURCES = \
-       tests/stub_internal.cc \
-       tests/stub_CommIO.cc \
-       tests/stub_store_rebuild.cc \
-       fd.cc \
+       CacheDigest.cc \
+       cbdata.cc \
+       ClientInfo.h \
+       ConfigOption.cc \
+       ConfigParser.cc \
        disk.cc \
+       ETag.cc \
+       EventLoop.cc \
+       fd.cc \
        filemap.cc \
        HttpBody.cc \
+       HttpHdrContRange.cc \
+       HttpHdrCc.cc \
+       HttpHdrSc.cc \
+       HttpHdrScTarget.cc \
+       HttpHdrRange.cc \
+       HttpHeaderTools.cc \
+       HttpHeader.cc \
+       HttpMsg.cc \
        HttpReply.cc \
+       HttpRequestMethod.cc \
        HttpStatusLine.cc \
        int.cc \
        list.cc \
+       MemBuf.cc \
        MemObject.cc \
+       mem_node.cc \
+       mem.cc \
+       Packer.cc \
+       Parsing.cc \
+       refresh.cc \
+       RemovalPolicy.cc \
+       StatHist.cc \
+       stmem.cc \
        StoreSwapLogData.cc \
        StoreIOState.cc \
        StoreMeta.cc \
@@ -2104,12 +2132,38 @@ SWAP_TEST_SOURCES = \
        StoreMetaVary.cc \
        StoreFileSystem.cc \
        store_io.cc \
+       store_key_md5.cc \
        store_swapout.cc \
        store_swapmeta.cc \
+       store_dir.cc \
+       store.cc \
+       String.cc \
+       SwapDir.cc \
+       tests/stub_access_log.cc \
+       tests/stub_acl.cc \
+       tests/stub_cache_cf.cc \
+       tests/stub_client_side_request.cc \
+       tests/stub_debug.cc \
+       tests/stub_errorpage.cc \
+       tests/stub_helper.cc \
+       tests/stub_http.cc \
+       tests/stub_HttpRequest.cc \
+       tests/stub_internal.cc \
+       tests/stub_mime.cc \
+       tests/stub_store_client.cc \
+       tests/stub_store_rebuild.cc \
+       tests/stub_tools.cc \
+       tests/testStoreSupport.cc \
+       tests/testStoreSupport.h \
+       time.cc \
+       url.cc \
+       URLScheme.cc \
+       wordlist.cc \
+       $(DELAY_POOL_SOURCE) \
+       $(DISKIO_SOURCE) \
+       $(TEST_CALL_SOURCES) \
        $(UNLINKDSOURCE) \
-       $(WIN32_SOURCE) \
-       $(STORE_TEST_SOURCES) \
-       $(DISKIO_SOURCE)
+       $(WIN32_SOURCE)
 
 SWAP_TEST_GEN_SOURCES = \
        $(TESTSOURCES) \
index 5ac803df6cc9d6c0312f5abc1dfcf1ac313398c0..1153e5e2b7b862e6c971b952f73a62ff8dbdf165 100644 (file)
@@ -5,9 +5,9 @@
 #include <limits>
 #endif
 
-http_port_list::http_port_list(const char *aProtocol) :
+http_port_list::http_port_list(const char *aProtocol)
 #if USE_SSL
-        http(*this),
+        http(*this),
         dynamicCertMemCacheSize(std::numeric_limits<size_t>::max())
 #endif
 {
index 1cc4177608a8234ac48d1aae0ccbcfa53c982b82..e621d6a1ca1531457f2c35209d18510cabf62f25 100644 (file)
@@ -3491,7 +3491,7 @@ parse_http_port_option(http_port_list * s, char *token)
         if (Ip::EnableIpv6)
             debugs(3, DBG_IMPORTANT, "Disabling IPv6 on port " << s->s << " (interception enabled)");
         if ( !s->s.SetIPv4() ) {
-            debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: IPv6 addresses cannot be transparent (protocol does not provide NAT)" << s->s );
+            debugs(3, DBG_CRITICAL, "FATAL: http(s)_port: IPv6 addresses cannot NAT intercept (protocol does not provide NAT)" << s->s );
             self_destruct();
         }
     } else if (strcmp(token, "tproxy") == 0) {
index a98428121460c8eef669cb1de3339451e21b0624..e6a4118958b2a97abfd44ca903600cac8a98c517 100644 (file)
 #include "HttpRequest.h"
 #include "ident/Config.h"
 #include "ident/Ident.h"
-#include "ip/Intercept.h"
 #include "ipc/FdNotes.h"
 #include "ipc/StartListening.h"
 #include "MemBuf.h"
@@ -191,7 +190,9 @@ static ClientSocketContext *ClientSocketContextNew(const Comm::ConnectionPointer
 static IOCB clientWriteComplete;
 static IOCB clientWriteBodyComplete;
 static IOACB httpAccept;
+#if USE_SSL
 static IOACB httpsAccept;
+#endif
 static bool clientParseRequest(ConnStateData * conn, bool &do_next_read);
 static CTCB clientLifetimeTimeout;
 static ClientSocketContext *parseHttpRequestAbort(ConnStateData * conn, const char *uri);
@@ -2193,12 +2194,6 @@ parseHttpRequest(ConnStateData *csd, HttpParser *hp, HttpRequestMethod * method_
      */
     if (csd->transparent()) {
         /* intercept or transparent mode, properly working with no failures */
-        http->flags.intercepted = csd->port->intercepted;
-        http->flags.spoof_client_ip = csd->port->spoof_client_ip;
-        prepareTransparentURL(csd, http, url, req_hdr);
-
-    } else if (csd->port->intercepted || csd->port->spoof_client_ip) {
-        /* transparent or intercept mode with failures */
         prepareTransparentURL(csd, http, url, req_hdr);
 
     } else if (csd->port->accel || csd->switchedToHttps()) {
@@ -2456,6 +2451,8 @@ clientProcessRequest(ConnStateData *conn, HttpParser *hp, ClientSocketContext *c
         goto finish;
     }
 
+    request->clientConnectionManager = conn;
+
     request->flags.accelerated = http->flags.accel;
     request->flags.ignore_cc = conn->port->ignore_cc;
     request->flags.no_direct = request->flags.accelerated ? !conn->port->allow_direct : 0;
@@ -2464,11 +2461,9 @@ clientProcessRequest(ConnStateData *conn, HttpParser *hp, ClientSocketContext *c
      * If transparent or interception mode is working clone the transparent and interception flags
      * from the port settings to the request.
      */
-    if (Ip::Interceptor.InterceptActive()) {
-        request->flags.intercepted = http->flags.intercepted;
-    }
-    if (Ip::Interceptor.TransparentActive()) {
-        request->flags.spoof_client_ip = conn->port->spoof_client_ip;
+    if (http->clientConnection != NULL) {
+        request->flags.intercepted = (http->clientConnection->flags & COMM_INTERCEPTION);
+        request->flags.spoof_client_ip = (http->clientConnection->flags & COMM_TRANSPARENT);
     }
 
     if (internalCheck(request->urlpath.termedBuf())) {
@@ -2490,11 +2485,9 @@ clientProcessRequest(ConnStateData *conn, HttpParser *hp, ClientSocketContext *c
     request->flags.internal = http->flags.internal;
     setLogUri (http, urlCanonicalClean(request));
     request->client_addr = conn->clientConnection->remote; // XXX: remove reuest->client_addr member.
-#if USE_SQUID_EUI
-    request->client_eui48 = conn->clientConnection->remoteEui48;
-    request->client_eui64 = conn->clientConnection->remoteEui64;
-#endif
 #if FOLLOW_X_FORWARDED_FOR
+    // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:)
+    // not a details about teh TCP connection itself
     request->indirect_client_addr = conn->clientConnection->remote;
 #endif /* FOLLOW_X_FORWARDED_FOR */
     request->my_addr = conn->clientConnection->local;
@@ -3072,17 +3065,6 @@ connStateCreate(const Comm::ConnectionPointer &client, http_port_list *port)
     result->in.buf = (char *)memAllocBuf(CLIENT_REQ_BUF_SZ, &result->in.allocatedSize);
     result->port = cbdataReference(port);
 
-    // XXX: move the NAT and TPROXY stuff into ConnAcceptor
-    if (port->intercepted || port->spoof_client_ip) {
-        Ip::Address cl, dst;
-
-        if (Ip::Interceptor.NatLookup(client->fd, client->local, client->remote, cl, dst) == 0) {
-            result->clientConnection->local = cl;
-            result->clientConnection->remote = dst;
-            result->transparent(true);
-        }
-    }
-
     if (port->disable_pmtu_discovery != DISABLE_PMTU_OFF &&
             (result->transparent() || port->disable_pmtu_discovery == DISABLE_PMTU_ALWAYS)) {
 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
@@ -3581,7 +3563,7 @@ clientHttpConnectionsOpen(void)
         //  then pass back when active so we can start a TcpAcceptor subscription.
         s->listenConn = new Comm::Connection;
         s->listenConn->local = s->s;
-        s->listenConn->flags = COMM_NONBLOCKING | (s->spoof_client_ip ? COMM_TRANSPARENT : 0);
+        s->listenConn->flags = COMM_NONBLOCKING | (s->spoof_client_ip ? COMM_TRANSPARENT : 0) | (s->intercepted ? COMM_INTERCEPTION : 0);
 
         // setup the subscriptions such that new connections accepted by listenConn are handled by HTTP
         typedef CommCbFunPtrCallT<CommAcceptCbPtrFun> AcceptCall;
@@ -3627,7 +3609,8 @@ clientHttpsConnectionsOpen(void)
         // Fill out a Comm::Connection which IPC will open as a listener for us
         s->http.listenConn = new Comm::Connection;
         s->http.listenConn->local = s->http.s;
-        s->http.listenConn->flags = COMM_NONBLOCKING | (s->http.spoof_client_ip ? COMM_TRANSPARENT : 0);
+        s->http.listenConn->flags = COMM_NONBLOCKING | (s->http.spoof_client_ip ? COMM_TRANSPARENT : 0) |
+                                    (s->http.intercepted ? COMM_INTERCEPTION : 0);
 
         // setup the subscriptions such that new connections accepted by listenConn are handled by HTTPS
         typedef CommCbFunPtrCallT<CommAcceptCbPtrFun> AcceptCall;
@@ -3800,7 +3783,6 @@ CBDATA_CLASS_INIT(ConnStateData);
 
 ConnStateData::ConnStateData() :
         AsyncJob("ConnStateData"),
-        transparent_(false),
         closing_(false),
         switchedToHttps_(false)
 {
@@ -3811,13 +3793,7 @@ ConnStateData::ConnStateData() :
 bool
 ConnStateData::transparent() const
 {
-    return transparent_;
-}
-
-void
-ConnStateData::transparent(bool const anInt)
-{
-    transparent_ = anInt;
+    return clientConnection != NULL && (clientConnection->flags & (COMM_TRANSPARENT|COMM_INTERCEPTION));
 }
 
 bool
index f02441c8db0e4b9c367fca2f8d7eec22331d8cef..24c11040983d90705d869813eed422037c93a194 100644 (file)
@@ -233,6 +233,8 @@ public:
     ClientSocketContext::Pointer currentobject;
 
     Ip::Address log_addr;
+
+    /// count of requests made so far on this connection
     int nrequests;
 
     struct {
@@ -252,7 +254,6 @@ public:
     http_port_list *port;
 
     bool transparent() const;
-    void transparent(bool const);
     bool reading() const;
     void stopReading(); ///< cancels comm_read if it is scheduled
 
@@ -336,7 +337,6 @@ private:
     CBDATA_CLASS2(ConnStateData);
     // XXX: CBDATA macro plays with public/private exposing all of the supposedly below private fields...
 
-    bool transparent_; // AYJ: is this a duplicate of the transparent/intercept flags?
     bool closing_;
 
     bool switchedToHttps_;
index 11162361b567a0453733380ad884f5b42da3e70d..0f86bc22c59c5a2fb8b0477f81d95ef1181404b9 100644 (file)
@@ -262,7 +262,7 @@ clientReplyContext::processExpired()
     http->storeEntry(entry);
     assert(http->out.offset == 0);
 
-    http->request->clientConnection = http->getConn(); // AYJ: irrelevant?
+    http->request->clientConnectionManager = http->getConn(); // AYJ: irrelevant?
 
     /*
      * A refcounted pointer so that FwdState stays around as long as
@@ -652,7 +652,7 @@ clientReplyContext::processMiss()
         if (http->flags.internal)
             r->protocol = PROTO_INTERNAL;
 
-        r->clientConnection = http->getConn();
+        r->clientConnectionManager = http->getConn();
 
         /** Start forwarding to get the new object from network */
         Comm::ConnectionPointer conn = http->getConn() != NULL ? http->getConn()->clientConnection : NULL;
index afb8731a92b2f1fc53926967526a1fbdc034bf0a..594fe61993fd2e1a4e95667b482ed9ed03488895 100644 (file)
@@ -5,7 +5,7 @@
 #include "base/AsyncJob.h"
 #include "cbdata.h"
 #include "CommCalls.h"
-#include "comm/comm_err_t.h"
+#include "comm_err_t.h"
 #include "comm/forward.h"
 
 namespace Comm {
index 5b062158e9ab75374193f103fbbacbd31b528e2e..712d691db9415a5b50c9d2dff973fe435c4ef50b 100644 (file)
@@ -64,11 +64,12 @@ namespace Comm {
  * currently there is code still using comm_open() and comm_openex() synchronously!!
  */
 #define COMM_UNSET              0x00
-#define COMM_NONBLOCKING        0x01
+#define COMM_NONBLOCKING        0x01  // default flag.
 #define COMM_NOCLOEXEC          0x02
-#define COMM_REUSEADDR          0x04
-#define COMM_TRANSPARENT        0x08
-#define COMM_DOBIND             0x10
+#define COMM_REUSEADDR          0x04  // shared FD may be both accept()ing and read()ing
+#define COMM_DOBIND             0x08  // requires a bind()
+#define COMM_TRANSPARENT        0x10  // arrived via TPROXY
+#define COMM_INTERCEPTION       0x20  // arrived via NAT
 
 /**
  * Store data about the physical and logical attributes of a connection.
index 6dd7dc68cce045e5976bc0ac8a12503204760579..221394bf20eded834b31d133a86b4a5de91fd4f3 100644 (file)
@@ -41,6 +41,7 @@
 #include "comm/Loops.h"
 #include "comm/TcpAcceptor.h"
 #include "fde.h"
+#include "ip/Intercept.h"
 #include "protos.h"
 #include "SquidTime.h"
 
@@ -358,7 +359,13 @@ Comm::TcpAcceptor::oldAccept(Comm::ConnectionPointer &details)
     commSetNonBlocking(sock);
 
     /* IFF the socket is (tproxy) transparent, pass the flag down to allow spoofing */
-    F->flags.transparent = fd_table[conn->fd].flags.transparent;
+    F->flags.transparent = fd_table[conn->fd].flags.transparent; // XXX: can we remove this line yet?
+
+    // Perform NAT or TPROXY operations to retrieve the real client/dest IP addresses
+    if (conn->flags&(COMM_TRANSPARENT|COMM_INTERCEPTION) && !Ip::Interceptor.Lookup(details, conn)) {
+        // Failed.
+        return COMM_ERROR;
+    }
 
     PROF_stop(comm_accept);
     return COMM_OK;
index 86665cf3360dc0f857539c06da6c17a5ac735e51..d5aab6cb18c8297ee627ceb1e23723bfee96783e 100644 (file)
@@ -901,12 +901,14 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data)
 
 #if USE_SQUID_EUI
         case _external_acl_format::EXT_ACL_SRCEUI48:
-            if (request->client_eui48.encode(buf, sizeof(buf)))
+            if (request->clientConnectionManager.valid() && request->clientConnectionManager->clientConnection != NULL &&
+                    request->clientConnectionManager->clientConnection->remoteEui48.encode(buf, sizeof(buf)))
                 str = buf;
             break;
 
         case _external_acl_format::EXT_ACL_SRCEUI64:
-            if (request->client_eui64.encode(buf, sizeof(buf)))
+            if (request->clientConnectionManager.valid() && request->clientConnectionManager->clientConnection != NULL &&
+                    request->clientConnectionManager->clientConnection->remoteEui64.encode(buf, sizeof(buf)))
                 str = buf;
             break;
 #endif
index 76eb727d0e9e23463e6946f225fdf128db5db5d3..dd46bbb22658a007ff74fb24f60d8aea268bcae0 100644 (file)
@@ -785,7 +785,7 @@ HttpStateData::handle1xx(HttpReply *reply)
     typedef NullaryMemFunT<HttpStateData> CbDialer;
     const AsyncCall::Pointer cb = JobCallback(11, 3, CbDialer, this,
                                   HttpStateData::proceedAfter1xx);
-    CallJobHere1(11, 4, orig_request->clientConnection, ConnStateData,
+    CallJobHere1(11, 4, orig_request->clientConnectionManager, ConnStateData,
                  ConnStateData::sendControlMsg, HttpControlMsg(msg, cb));
     // If the call is not fired, then the Sink is gone, and HttpStateData
     // will terminate due to an aborted store entry or another similar error.
index 602ce2226186d73b0005e0193a7b9d286836d72b..d0d25fc0d7adc77cce96d635a2e7444841b73181 100644 (file)
@@ -31,6 +31,7 @@
  *
  */
 #include "config.h"
+#include "comm/Connection.h"
 #include "ip/Intercept.h"
 #include "fde.h"
 
@@ -96,104 +97,90 @@ Ip::Intercept Ip::Interceptor;
 void
 Ip::Intercept::StopTransparency(const char *str)
 {
-    if (transparent_active) {
+    if (transparentActive_) {
         debugs(89, DBG_IMPORTANT, "Stopping full transparency: " << str);
-        transparent_active = 0;
+        transparentActive_ = 0;
     }
 }
 
 void
 Ip::Intercept::StopInterception(const char *str)
 {
-    if (intercept_active) {
+    if (interceptActive_) {
         debugs(89, DBG_IMPORTANT, "Stopping IP interception: " << str);
-        intercept_active = 0;
+        interceptActive_ = 0;
     }
 }
 
-int
-Ip::Intercept::NetfilterInterception(int fd, const Ip::Address &me, Ip::Address &dst, int silent)
+bool
+Ip::Intercept::NetfilterInterception(const Comm::ConnectionPointer &newConn, int silent)
 {
 #if LINUX_NETFILTER
-    struct addrinfo *lookup = NULL;
-
-    dst.GetAddrInfo(lookup,AF_INET);
+    struct sockaddr_in lookup;
+    socklen_t len = sizeof(struct sockaddr_in);
+    newConn->local.GetSockAddr(lookup);
 
     /** \par
      * Try NAT lookup for REDIRECT or DNAT targets. */
-    if ( getsockopt(fd, IPPROTO_IP, SO_ORIGINAL_DST, lookup->ai_addr, &lookup->ai_addrlen) != 0) {
+    if ( getsockopt(newConn->fd, IPPROTO_IP, SO_ORIGINAL_DST, &lookup, &len) != 0) {
         if (!silent) {
-            debugs(89, DBG_IMPORTANT, HERE << " NF getsockopt(SO_ORIGINAL_DST) failed on FD " << fd << ": " << xstrerror());
-            last_reported = squid_curtime;
+            debugs(89, DBG_IMPORTANT, HERE << " NF getsockopt(SO_ORIGINAL_DST) failed on " << newConn << ": " << xstrerror());
+            lastReported_ = squid_curtime;
         }
+        debugs(89, 9, HERE << "address: " << newConn);
+        return false;
     } else {
-        dst = *lookup;
-    }
-
-    Address::FreeAddrInfo(lookup);
-
-    if (me != dst) {
-        debugs(89, 5, HERE << "address NAT: me= " << me << ", dst= " << dst);
-        return 0;
+        newConn->local = lookup;
+        debugs(89, 5, HERE << "address NAT: " << newConn);
+        return true;
     }
-
-    debugs(89, 9, HERE << "address: me= " << me << ", dst= " << dst);
 #endif
-    return -1;
+    return false;
 }
 
-int
-Ip::Intercept::NetfilterTransparent(int fd, const Ip::Address &me, Ip::Address &client, int silent)
+bool
+Ip::Intercept::NetfilterTransparent(const Comm::ConnectionPointer &newConn, int silent)
 {
 #if LINUX_NETFILTER
-
     /* Trust the user configured properly. If not no harm done.
      * We will simply attempt a bind outgoing on our own IP.
      */
-    if (fd_table[fd].flags.transparent) {
-        client.SetPort(0); // allow random outgoing port to prevent address clashes
-        debugs(89, 5, HERE << "address TPROXY: me= " << me << ", client= " << client);
-        return 0;
-    }
-
-    debugs(89, 9, HERE << "address: me= " << me << ", client= " << client);
+    newConn->remote.SetPort(0); // allow random outgoing port to prevent address clashes
+    debugs(89, 5, HERE << "address TPROXY: " << newConn);
+    return true;
+#else
+    return false;
 #endif
-    return -1;
 }
 
-int
-Ip::Intercept::IpfwInterception(int fd, const Ip::Address &me, Ip::Address &dst, int silent)
+bool
+Ip::Intercept::IpfwInterception(const Comm::ConnectionPointer &newConn, int silent)
 {
 #if IPFW_TRANSPARENT
-    struct addrinfo *lookup = NULL;
-
-    dst.GetAddrInfo(lookup,AF_INET);
+    struct sockaddr_in lookup;
+    socklen_t len = sizeof(struct sockaddr_in);
+    newConn->local.GetSockAddr(lookup);
 
     /** \par
      * Try lookup for IPFW interception. */
-    if ( getsockname(fd, lookup->ai_addr, &lookup->ai_addrlen) != 0 ) {
+    if ( getsockname(newConn->fd, &lookup, &len) != 0 ) {
         if ( !silent ) {
             debugs(89, DBG_IMPORTANT, HERE << " IPFW getsockname(...) failed: " << xstrerror());
-            last_reported = squid_curtime;
+            lastReported_ = squid_curtime;
         }
+        debugs(89, 9, HERE << "address: " << newConn);
+        return false;
     } else {
-        dst = *lookup;
-    }
-
-    Address::FreeAddrInfo(lookup);
-
-    if (me != dst) {
-        debugs(89, 5, HERE << "address NAT: me= " << me << ", dst= " << dst);
-        return 0;
+        newConn->local = lookup;
+        debugs(89, 5, HERE << "address NAT: " << newConn);
+        return true;
     }
-
-    debugs(89, 9, HERE << "address: me= " << me << ", dst= " << dst);
 #endif
-    return -1;
+    return false;
 }
 
-int
-Ip::Intercept::IpfInterception(int fd, const Ip::Address &me, Ip::Address &client, Ip::Address &dst, int silent)
+bool
+Ip::Intercept::IpfInterception(const Comm::ConnectionPointer &newConn, int silent)
 {
 #if IPF_TRANSPARENT  /* --enable-ipf-transparent */
 
@@ -215,10 +202,10 @@ Ip::Intercept::IpfInterception(int fd, const Ip::Address &me, Ip::Address &clien
     obj.ipfo_offset = 0;
 #endif
 
-    natLookup.nl_inport = htons(me.GetPort());
-    natLookup.nl_outport = htons(dst.GetPort());
-    me.GetInAddr(natLookup.nl_inip);
-    dst.GetInAddr(natLookup.nl_outip);
+    natLookup.nl_inport = htons(newConn->local.GetPort());
+    newConn->local.GetInAddr(natLookup.nl_inip);
+    natLookup.nl_outport = htons(neConn->remote.GetPort());
+    newConn->remote.GetInAddr(natLookup.nl_outip);
     natLookup.nl_flags = IPN_TCP;
 
     if (natfd < 0) {
@@ -237,8 +224,8 @@ Ip::Intercept::IpfInterception(int fd, const Ip::Address &me, Ip::Address &clien
     if (natfd < 0) {
         if (!silent) {
             debugs(89, DBG_IMPORTANT, HERE << "NAT open failed: " << xstrerror());
-            last_reported = squid_curtime;
-            return -1;
+            lastReported_ = squid_curtime;
+            return false;
         }
     }
 
@@ -264,33 +251,28 @@ Ip::Intercept::IpfInterception(int fd, const Ip::Address &me, Ip::Address &clien
         if (errno != ESRCH) {
             if (!silent) {
                 debugs(89, DBG_IMPORTANT, HERE << "NAT lookup failed: ioctl(SIOCGNATL)");
-                last_reported = squid_curtime;
+                lastReported_ = squid_curtime;
             }
 
             close(natfd);
             natfd = -1;
         }
 
-        return -1;
+        debugs(89, 9, HERE << "address: " << newConn);
+        return false;
     } else {
-        if (client != natLookup.nl_realip) {
-            client = natLookup.nl_realip;
-            client.SetPort(ntohs(natLookup.nl_realport));
-        }
-        // else. we already copied it.
-
-        debugs(89, 5, HERE << "address NAT: me= " << me << ", client= " << client << ", dst= " << dst);
-        return 0;
+        newConn->local = natLookup.nl_realip;
+        newConn->local.SetPort(ntohs(natLookup.nl_realport));
+        debugs(89, 5, HERE << "address NAT: " << newConn);
+        return true;
     }
 
-    debugs(89, 9, HERE << "address: me= " << me << ", client= " << client << ", dst= " << dst);
-
 #endif /* --enable-ipf-transparent */
-    return -1;
+    return false;
 }
 
-int
-Ip::Intercept::PfInterception(int fd, const Ip::Address &me, Ip::Address &client, Ip::Address &dst, int silent)
+bool
+Ip::Intercept::PfInterception(const Comm::ConnectionPointer &newConn, int silent)
 {
 #if PF_TRANSPARENT  /* --enable-pf-transparent */
 
@@ -303,17 +285,17 @@ Ip::Intercept::PfInterception(int fd, const Ip::Address &me, Ip::Address &client
     if (pffd < 0) {
         if (!silent) {
             debugs(89, DBG_IMPORTANT, HERE << "PF open failed: " << xstrerror());
-            last_reported = squid_curtime;
+            lastReported_ = squid_curtime;
         }
-        return -1;
+        return false;
     }
 
     memset(&nl, 0, sizeof(struct pfioc_natlook));
-    dst.GetInAddr(nl.saddr.v4);
-    nl.sport = htons(dst.GetPort());
+    newConn->remote.GetInAddr(nl.saddr.v4);
+    nl.sport = htons(newConn->remote.GetPort());
 
-    me.GetInAddr(nl.daddr.v4);
-    nl.dport = htons(me.GetPort());
+    newConn->local.GetInAddr(nl.daddr.v4);
+    nl.dport = htons(newConn->local.GetPort());
 
     nl.af = AF_INET;
     nl.proto = IPPROTO_TCP;
@@ -323,31 +305,26 @@ Ip::Intercept::PfInterception(int fd, const Ip::Address &me, Ip::Address &client
         if (errno != ENOENT) {
             if (!silent) {
                 debugs(89, DBG_IMPORTANT, HERE << "PF lookup failed: ioctl(DIOCNATLOOK)");
-                last_reported = squid_curtime;
+                lastReported_ = squid_curtime;
             }
             close(pffd);
             pffd = -1;
         }
+        debugs(89, 9, HERE << "address: " << newConn);
+        return false;
     } else {
-        int natted = (client != nl.rdaddr.v4);
-        client = nl.rdaddr.v4;
-        client.SetPort(ntohs(nl.rdport));
-
-        if (natted) {
-            debugs(89, 5, HERE << "address NAT: me= " << me << ", client= " << client << ", dst= " << dst);
-            return 0;
-        }
+        newConn->local = nl.rdaddr.v4;
+        newConn->local.SetPort(ntohs(nl.rdport));
+        debugs(89, 5, HERE << "address NAT: " << newConn);
+        return true;
     }
 
-    debugs(89, 9, HERE << "address: me= " << me << ", client= " << client << ", dst= " << dst);
-
 #endif /* --enable-pf-transparent */
-    return -1;
+    return false;
 }
 
-
-int
-Ip::Intercept::NatLookup(int fd, const Ip::Address &me, const Ip::Address &peer, Ip::Address &client, Ip::Address &dst)
+bool
+Ip::Intercept::Lookup(const Comm::ConnectionPointer &newConn, const Comm::ConnectionPointer &listenConn)
 {
     /* --enable-linux-netfilter    */
     /* --enable-ipfw-transparent   */
@@ -355,44 +332,42 @@ Ip::Intercept::NatLookup(int fd, const Ip::Address &me, const Ip::Address &peer,
     /* --enable-pf-transparent     */
 #if IPF_TRANSPARENT || LINUX_NETFILTER || IPFW_TRANSPARENT || PF_TRANSPARENT
 
-    client = me;
-    dst = peer;
-
 #if 0
     // Crop interception errors down to one per minute.
-    int silent = (squid_curtime - last_reported > 60 ? 0 : 1);
+    int silent = (squid_curtime - lastReported_ > 60 ? 0 : 1);
 #else
     // Show all interception errors.
     int silent = 0;
 #endif
 
-    debugs(89, 5, HERE << "address BEGIN: me= " << me << ", client= " << client <<
-           ", dst= " << dst << ", peer= " << peer);
+    debugs(89, 5, HERE << "address BEGIN: me/client= " << newConn->local << ", destination/me= " << newConn->remote);
+
+    newConn->flags |= (listenConn->flags & (COMM_TRANSPARENT|COMM_INTERCEPTION));
 
     /* NP: try TPROXY first, its much quieter than NAT when non-matching */
-    if (transparent_active) {
-        if ( NetfilterTransparent(fd, me, dst, silent) == 0) return 0;
+    if (transparentActive_ && listenConn->flags&COMM_TRANSPARENT) {
+        if (NetfilterTransparent(newConn, silent)) return true;
     }
 
     /* NAT is only available in IPv4 */
-    if ( !me.IsIPv4()   ) return -1;
-    if ( !peer.IsIPv4() ) return -1;
+    if ( !newConn->local.IsIPv4()  ) return false;
+    if ( !newConn->remote.IsIPv4() ) return false;
 
-    if (intercept_active) {
+    if (interceptActive_ && listenConn->flags&COMM_INTERCEPTION) {
         /* NAT methods that use sock-opts to return client address */
-        if ( NetfilterInterception(fd, me, client, silent) == 0) return 0;
-        if ( IpfwInterception(fd, me, client, silent) == 0) return 0;
+        if (NetfilterInterception(newConn, silent)) return true;
+        if (IpfwInterception(newConn, silent)) return true;
 
         /* NAT methods that use ioctl to return client address AND destination address */
-        if ( PfInterception(fd, me, client, dst, silent) == 0) return 0;
-        if ( IpfInterception(fd, me, client, dst, silent) == 0) return 0;
+        if (PfInterception(newConn, silent)) return true;
+        if (IpfInterception(newConn, silent)) return true;
     }
 
 #else /* none of the transparent options configured */
     debugs(89, DBG_IMPORTANT, "WARNING: transparent proxying not supported");
 #endif
 
-    return -1;
+    return false;
 }
 
 bool
index 0a4e3ff56680bb508fa80386103f2e041f490796..8744d8337641319042b381eb38ce733bb774e4b6 100644 (file)
@@ -26,11 +26,11 @@ class Address;
 class Intercept
 {
 public:
-    Intercept() : transparent_active(0), intercept_active(0), last_reported(0) {};
+    Intercept() : transparentActive_(0), interceptActive_(0), lastReported_(0) {};
     ~Intercept() {};
 
     /** Perform NAT lookups */
-    int NatLookup(int fd, const Address &me, const Address &peer, Address &client, Address &dst);
+    bool Lookup(const Comm::ConnectionPointer &newConn, const Comm::ConnectionPointer &listenConn);
 
     /**
      * Test system networking calls for TPROXY support.
@@ -47,14 +47,14 @@ public:
      \retval 0 Full transparency is disabled.
      \retval 1  Full transparency is enabled and active.
      */
-    inline int TransparentActive() { return transparent_active; };
+    inline int TransparentActive() { return transparentActive_; };
 
     /** \par
      * Turn on fully Transparent-Proxy activities.
      * This function should be called during parsing of the squid.conf
      * When any option requiring full-transparency is encountered.
      */
-    inline void StartTransparency() { transparent_active=1; };
+    inline void StartTransparency() { transparentActive_=1; };
 
     /** \par
      * Turn off fully Transparent-Proxy activities on all new connections.
@@ -68,14 +68,14 @@ public:
      \retval 0 IP Interception is disabled.
      \retval 1  IP Interception is enabled and active.
      */
-    inline int InterceptActive() { return intercept_active; };
+    inline int InterceptActive() { return interceptActive_; };
 
     /** \par
      * Turn on IP-Interception-Proxy activities.
      * This function should be called during parsing of the squid.conf
      * When any option requiring interception / NAT handling is encountered.
      */
-    inline void StartInterception() { intercept_active=1; };
+    inline void StartInterception() { interceptActive_=1; };
 
     /** \par
      * Turn off IP-Interception-Proxy activities on all new connections.
@@ -91,83 +91,52 @@ private:
     /**
      * perform Lookups on Netfilter interception targets (REDIRECT, DNAT).
      *
-     \param silent   0 if errors are to be displayed. 1 if errors are to be hidden.
-     \param fd       FD for the current TCP connection being tested.
-     \param me       IP address Squid received the connection on
-     \param client   IP address from which Squid received the connection.
-     *               May be updated by the NAT table information.
-     *               Default is the same value as the me IP address.
-     \retval 0     Successfuly located the new address.
-     \retval -1    An error occured during NAT lookups.
+     * \param silent   0 if errors are to be displayed. 1 if errors are to be hidden.
+     * \param newConn  Details known, to be updated where relevant.
+     * \return         Whether successfuly located the new address.
      */
-    int NetfilterInterception(int fd, const Address &me, Address &client, int silent);
+    bool NetfilterInterception(const Comm::ConnectionPointer &newConn, int silent);
 
     /**
      * perform Lookups on Netfilter fully-transparent interception targets (TPROXY).
      *
-     \param silent   0 if errors are to be displayed. 1 if errors are to be hidden.
-     \param fd       FD for the current TCP connection being tested.
-     \param me       IP address Squid received the connection on
-     \param dst      IP address to which the request was made.
-     *               expected to be updated from the NAT table information.
-     *               Default is the same value as the peer IP address sent to NatLookup().
-     \retval 0     Successfuly located the new address.
-     \retval -1    An error occured during NAT lookups.
+     * \param silent   0 if errors are to be displayed. 1 if errors are to be hidden.
+     * \param newConn  Details known, to be updated where relevant.
+     * \return         Whether successfuly located the new address.
      */
-    int NetfilterTransparent(int fd, const Address &me, Address &dst, int silent);
+    bool NetfilterTransparent(const Comm::ConnectionPointer &newConn, int silent);
 
     /**
      * perform Lookups on IPFW interception.
      *
-     \param silent   0 if errors are to be displayed. 1 if errors are to be hidden.
-     \param fd       FD for the current TCP connection being tested.
-     \param me       IP address Squid received the connection on
-     \param client   IP address from which Squid received the connection.
-     *               May be updated by the NAT table information.
-     *               Default is the same value as the me IP address.
-     \retval 0     Successfuly located the new address.
-     \retval -1    An error occured during NAT lookups.
+     * \param silent   0 if errors are to be displayed. 1 if errors are to be hidden.
+     * \param newConn  Details known, to be updated where relevant.
+     * \return         Whether successfuly located the new address.
      */
-    int IpfwInterception(int fd, const Address &me, Address &client, int silent);
+    bool IpfwInterception(const Comm::ConnectionPointer &newConn, int silent);
 
     /**
      * perform Lookups on IPF interception.
      *
-     \param silent   0 if errors are to be displayed. 1 if errors are to be hidden.
-     \param fd       FD for the current TCP connection being tested.
-     \param me       IP address Squid received the connection on
-     \param client   IP address from which Squid received the connection.
-     *               May be updated by the NAT table information.
-     *               Default is the same value as the me IP address.
-     \param dst      IP address to which the request was made.
-     *               expected to be updated from the NAT table information.
-     *               Default is the same value as the peer IP address sent to NatLookup().
-     \retval 0     Successfuly located the new address.
-     \retval -1    An error occured during NAT lookups.
+     * \param silent   0 if errors are to be displayed. 1 if errors are to be hidden.
+     * \param newConn  Details known, to be updated where relevant.
+     * \return         Whether successfuly located the new address.
      */
-    int IpfInterception(int fd, const Address &me, Address &client, Address &dst, int silent);
+    bool IpfInterception(const Comm::ConnectionPointer &newConn, int silent);
 
     /**
      * perform Lookups on PF interception.
      *
-     \param silent   0 if errors are to be displayed. 1 if errors are to be hidden.
-     \param fd       FD for the current TCP connection being tested.
-     \param me       IP address Squid received the connection on
-     \param client   IP address from which Squid received the connection.
-     *               May be updated by the NAT table information.
-     *               Default is the same value as the me IP address.
-     \param dst      IP address to which the request was made.
-     *               expected to be updated from the NAT table information.
-     *               Default is the same value as the peer IP address sent to NatLookup().
-     \retval 0     Successfuly located the new address.
-     \retval -1    An error occured during NAT lookups.
+     * \param silent   0 if errors are to be displayed. 1 if errors are to be hidden.
+     * \param newConn  Details known, to be updated where relevant.
+     * \return         Whether successfuly located the new address.
      */
-    int PfInterception(int fd, const Address &me, Address &client, Address &dst, int silent);
+    bool PfInterception(const Comm::ConnectionPointer &newConn, int silent);
 
 
-    int transparent_active;
-    int intercept_active;
-    time_t last_reported; /**< Time of last error report. Throttles NAT error display to 1 per minute */
+    int transparentActive_;
+    int interceptActive_;
+    time_t lastReported_; /**< Time of last error report. Throttles NAT error display to 1 per minute */
 };
 
 #if LINUX_NETFILTER && !defined(IP_TRANSPARENT)
index f1a031ceac584717455d0fd0af231791c28e1130..5674556bf7ba82be61269803e1ac6e9f1a4ce1f2 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "config.h"
 #include "AccessLogEntry.h"
+#include "comm/Connection.h"
 #include "log/File.h"
 #include "log/Formats.h"
 #include "log/Gadgets.h"
@@ -152,11 +153,12 @@ Log::Format::SquidCustom(AccessLogEntry * al, customlog * log)
 
 #if USE_SQUID_EUI
         case LFT_CLIENT_EUI:
-            if (al->request) {
-                if (al->cache.caddr.IsIPv4())
-                    al->request->client_eui48.encode(tmp, 1024);
+            // TODO make the ACL checklist have a direct link to any TCP details.
+            if (al->request && al->request->clientConnectionManager.valid() && al->request->clientConnectionManager->clientConnection != NULL) {
+                if (al->request->clientConnectionManager->clientConnection->remote.IsIPv4())
+                    al->request->clientConnectionManager->clientConnection->remoteEui48.encode(tmp, 1024);
                 else
-                    al->request->client_eui64.encode(tmp, 1024);
+                    al->request->clientConnectionManager->clientConnection->remoteEui64.encode(tmp, 1024);
                 out = tmp;
             }
             break;
index 9863612fc4112693c3cd284e8f3ed62c72b37610..c0da38891d453d07b3ed9c6425a52a80e47f19ff 100644 (file)
@@ -33,6 +33,7 @@
  */
 
 #include "squid.h"
+#include "comm/Connection.h"
 #include "MemObject.h"
 #include "HttpReply.h"
 #if USE_DELAY_POOLS
index dbdfcd6e8a50cf58d92c8317683ee72c00271610..60b3ef96834de856cf1f6f414cea3b23345e1004 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "squid.h"
 #include "comm.h"
+#include "comm/Connection.h"
 #include "comm/Loops.h"
 #include "CommRead.h"
 #include "fde.h"
@@ -74,7 +75,7 @@ comm_read(const Comm::ConnectionPointer &conn, char*, int, AsyncCall::Pointer &c
 
 /* should be in stub_CommRead */
 #include "CommRead.h"
-CommRead::CommRead (int fd, char *buf, int len, AsyncCall::Pointer &callback)
+CommRead::CommRead(const Comm::ConnectionPointer &, char *buf, int len, AsyncCall::Pointer &callback)
 {
     fatal ("Not implemented");
 }