From: Amos Jeffries Date: Fri, 25 Feb 2011 03:38:04 +0000 (+1300) Subject: Move EUI and NAT results into Comm::Connection X-Git-Tag: take08~55^2~124^2~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=40d34a62e781cec2cb08b544c6d5f4ccaffab162;p=thirdparty%2Fsquid.git Move EUI and NAT results into Comm::Connection 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. --- diff --git a/src/CommCalls.h b/src/CommCalls.h index 26a1747373..eb2abd5e11 100644 --- a/src/CommCalls.h +++ b/src/CommCalls.h @@ -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. diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 930f3de3b2..d5bdbd3e35 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -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; diff --git a/src/HttpRequest.h b/src/HttpRequest.h index afa1226101..d2b018b932 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -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 clientConnection; + CbcPointer clientConnectionManager; int64_t getRangeOffsetLimit(); /* the result of this function gets cached in rangeOffsetLimit */ diff --git a/src/Makefile.am b/src/Makefile.am index 2379ff560f..1a5eb4993b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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) \ diff --git a/src/ProtoPort.cc b/src/ProtoPort.cc index 5ac803df6c..1153e5e2b7 100644 --- a/src/ProtoPort.cc +++ b/src/ProtoPort.cc @@ -5,9 +5,9 @@ #include #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::max()) #endif { diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 1cc4177608..e621d6a1ca 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -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) { diff --git a/src/client_side.cc b/src/client_side.cc index a984281214..e6a4118958 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -109,7 +109,6 @@ #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 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 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 diff --git a/src/client_side.h b/src/client_side.h index f02441c8db..24c1104098 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -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_; diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index 11162361b5..0f86bc22c5 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -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; diff --git a/src/comm/ConnOpener.h b/src/comm/ConnOpener.h index afb8731a92..594fe61993 100644 --- a/src/comm/ConnOpener.h +++ b/src/comm/ConnOpener.h @@ -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 { diff --git a/src/comm/Connection.h b/src/comm/Connection.h index 5b062158e9..712d691db9 100644 --- a/src/comm/Connection.h +++ b/src/comm/Connection.h @@ -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. diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index 6dd7dc68cc..221394bf20 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -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; diff --git a/src/external_acl.cc b/src/external_acl.cc index 86665cf336..d5aab6cb18 100644 --- a/src/external_acl.cc +++ b/src/external_acl.cc @@ -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 diff --git a/src/http.cc b/src/http.cc index 76eb727d0e..dd46bbb226 100644 --- a/src/http.cc +++ b/src/http.cc @@ -785,7 +785,7 @@ HttpStateData::handle1xx(HttpReply *reply) typedef NullaryMemFunT 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. diff --git a/src/ip/Intercept.cc b/src/ip/Intercept.cc index 602ce22261..d0d25fc0d7 100644 --- a/src/ip/Intercept.cc +++ b/src/ip/Intercept.cc @@ -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 diff --git a/src/ip/Intercept.h b/src/ip/Intercept.h index 0a4e3ff566..8744d83376 100644 --- a/src/ip/Intercept.h +++ b/src/ip/Intercept.h @@ -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) diff --git a/src/log/FormatSquidCustom.cc b/src/log/FormatSquidCustom.cc index f1a031ceac..5674556bf7 100644 --- a/src/log/FormatSquidCustom.cc +++ b/src/log/FormatSquidCustom.cc @@ -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; diff --git a/src/tests/stub_MemObject.cc b/src/tests/stub_MemObject.cc index 9863612fc4..c0da38891d 100644 --- a/src/tests/stub_MemObject.cc +++ b/src/tests/stub_MemObject.cc @@ -33,6 +33,7 @@ */ #include "squid.h" +#include "comm/Connection.h" #include "MemObject.h" #include "HttpReply.h" #if USE_DELAY_POOLS diff --git a/src/tests/stub_comm.cc b/src/tests/stub_comm.cc index dbdfcd6e8a..60b3ef9683 100644 --- a/src/tests/stub_comm.cc +++ b/src/tests/stub_comm.cc @@ -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"); }