From: Amos Jeffries Date: Fri, 3 Dec 2010 00:18:43 +0000 (+1300) Subject: Merge from trunk X-Git-Tag: take08~55^2~124^2~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a8b7ec30aaef57d05ac209238ab11af4bc13a54a;p=thirdparty%2Fsquid.git Merge from trunk --- a8b7ec30aaef57d05ac209238ab11af4bc13a54a diff --cc src/client_side.cc index 3fafbef0b9,58eb9e7bdd..4d78877906 --- a/src/client_side.cc +++ b/src/client_side.cc @@@ -3158,9 -3163,9 +3158,9 @@@ httpAccept(int sock, const Comm::Connec connState->readSomeData(); - clientdbEstablished(details->peer, 1); + clientdbEstablished(details->remote, 1); - #if DELAY_POOLS + #if USE_DELAY_POOLS fd_table[newfd].clientInfo = NULL; if (Config.onoff.client_db) { diff --cc src/comm.cc index 0aaab34e77,7fe3c10826..d71dc7af77 --- a/src/comm.cc +++ b/src/comm.cc @@@ -71,10 -71,10 +71,10 @@@ static void commStopHalfClosedMonitor(int fd); static IOCB commHalfClosedReader; -static void comm_init_opened(int new_socket, Ip::Address &addr, tos_t tos, nfmark_t nfmark, const char *note, struct addrinfo *AI); +static void comm_init_opened(const Comm::ConnectionPointer &conn, tos_t tos, nfmark_t nfmark, const char *note, struct addrinfo *AI); static int comm_apply_flags(int new_socket, Ip::Address &addr, int flags, struct addrinfo *AI); - #if DELAY_POOLS + #if USE_DELAY_POOLS CBDATA_CLASS_INIT(CommQuotaQueue); static void commHandleWriteHelper(void * data); diff --cc src/comm/IoCallback.cc index 7d059b1b4b,4e5b2bdf56..2e9f9c927d --- a/src/comm/IoCallback.cc +++ b/src/comm/IoCallback.cc @@@ -60,11 -54,11 +60,11 @@@ Comm::IoCallback::setCallback(Comm::ioc void Comm::IoCallback::selectOrQueueWrite() { - #if DELAY_POOLS + #if USE_DELAY_POOLS // stand in line if there is one - if (ClientInfo *clientInfo = fd_table[fd].clientInfo) { + if (ClientInfo *clientInfo = fd_table[conn->fd].clientInfo) { if (clientInfo->writeLimitingActive) { - quotaQueueReserv = clientInfo->quotaEnqueue(fd); + quotaQueueReserv = clientInfo->quotaEnqueue(conn->fd); clientInfo->kickQuotaQueue(); return; } diff --cc src/comm/IoCallback.h index 3a450687f4,9ce281a0ec..85d1b3f2ad --- a/src/comm/IoCallback.h +++ b/src/comm/IoCallback.h @@@ -4,9 -4,9 +4,10 @@@ #include "config.h" #include "base/AsyncCall.h" #include "comm_err_t.h" +#include "comm/forward.h" - namespace Comm { + namespace Comm + { /// Type of IO callbacks the Comm layer deals with. typedef enum { @@@ -16,10 -16,11 +17,11 @@@ } iocb_type; /// Details about a particular Comm IO callback event. - class IoCallback { + class IoCallback + { public: iocb_type type; - int fd; + Comm::ConnectionPointer conn; AsyncCall::Pointer callback; char *buf; FREE *freefunc; diff --cc src/comm/Write.cc index f1ed25aeed,822f503d74..4d5cf46a69 --- a/src/comm/Write.cc +++ b/src/comm/Write.cc @@@ -1,8 -1,7 +1,8 @@@ #include "config.h" - #if DELAY_POOLS + #if USE_DELAY_POOLS #include "ClientInfo.h" #endif +#include "comm/Connection.h" #include "comm/IoCallback.h" #include "comm/Write.h" #include "fde.h" diff --cc src/comm/Write.h index 8b5ecc7fc5,8300dc80ec..87aba9de23 --- a/src/comm/Write.h +++ b/src/comm/Write.h @@@ -2,9 -2,9 +2,10 @@@ #define _SQUID_COMM_IOWRITE_H #include "base/AsyncCall.h" +#include "comm/forward.h" - namespace Comm { + namespace Comm + { /** * Queue a write. callback is scheduled when the write diff --cc src/gopher.cc index 9082f5c78e,5b31f3a395..52620934c2 --- a/src/gopher.cc +++ b/src/gopher.cc @@@ -803,10 -801,8 +801,10 @@@ gopherReadReply(const Comm::ConnectionP /* leave one space for \0 in gopherToHTML */ + debugs(10, 5, HERE << conn << " read len=" << len); + if (flag == COMM_OK && len > 0) { - #if DELAY_POOLS + #if USE_DELAY_POOLS delayId.bytesIn(len); #endif diff --cc src/http.cc index d0badb1175,c162f2d878..dad0dee729 --- a/src/http.cc +++ b/src/http.cc @@@ -45,9 -45,8 +45,9 @@@ #include "base/AsyncJobCalls.h" #include "base/TextException.h" #include "base64.h" +#include "comm/Connection.h" #include "comm/Write.h" - #if DELAY_POOLS + #if USE_DELAY_POOLS #include "DelayPools.h" #endif #include "errorpage.h" diff --cc src/main.cc index 854c763365,4ac574d01a..89a206d7f9 --- a/src/main.cc +++ b/src/main.cc @@@ -47,9 -38,35 +47,36 @@@ #include "adaptation/icap/icap_log.h" #endif #include "auth/Gadgets.h" +#include "base/Subscription.h" #include "base/TextException.h" + #if USE_DELAY_POOLS + #include "ClientDelayConfig.h" + #endif + #include "ConfigParser.h" + #include "CpuAffinity.h" + #if USE_DELAY_POOLS + #include "DelayPools.h" + #endif + #include "errorpage.h" + #include "event.h" + #include "EventLoop.h" + #include "ExternalACL.h" + #include "Store.h" + #include "ICP.h" + #include "ident/Ident.h" ++#include "ip/tools.h" ++#include "ipc/Coordinator.h" ++#include "ipc/Kids.h" ++#include "ipc/Strand.h" + #include "HttpReply.h" + #include "pconn.h" + #include "Mem.h" + #include "acl/Asn.h" + #include "acl/Acl.h" + #include "htcp.h" + #include "StoreFileSystem.h" + #include "DiskIO/DiskIOModule.h" #include "comm.h" -#include "ipc/Kids.h" -#include "ipc/Coordinator.h" -#include "ipc/Strand.h" -#include "ip/tools.h" #if USE_EPOLL #include "comm_epoll.h" #endif @@@ -62,31 -79,13 +89,22 @@@ #if defined(USE_SELECT) || defined(USE_SELECT_WIN32) #include "comm_select.h" #endif -#include "SquidTime.h" -#include "SwapDir.h" +#include "ConfigParser.h" +#include "CpuAffinity.h" +#include "DiskIO/DiskIOModule.h" +#include "errorpage.h" +#if USE_SQUID_ESI +#include "esi/Module.h" +#endif +#include "event.h" +#include "EventLoop.h" +#include "ExternalACL.h" #include "forward.h" -#include "MemPool.h" +#include "fs/Module.h" +#include "htcp.h" +#include "HttpReply.h" #include "icmp/IcmpSquid.h" #include "icmp/net_db.h" - #include "ICP.h" - #include "ident/Ident.h" - #include "ip/tools.h" - #include "ipc/Coordinator.h" - #include "ipc/Kids.h" - #include "ipc/Strand.h" - #if DELAY_POOLS - #include "ClientDelayConfig.h" - #endif - #if USE_LOADABLE_MODULES #include "LoadableModules.h" #endif diff --cc src/store.cc index 894b502881,af732464eb..499efd6a60 --- a/src/store.cc +++ b/src/store.cc @@@ -34,27 -34,25 +34,27 @@@ */ #include "squid.h" +#include "CacheManager.h" +#include "comm/Connection.h" #include "event.h" - #if DELAY_POOLS ++#if USE_DELAY_POOLS +#include "DelayPools.h" +#endif #include "fde.h" -#include "Store.h" -#include "mgr/Registration.h" -#include "StoreClient.h" -#include "stmem.h" #include "HttpReply.h" #include "HttpRequest.h" -#include "MemObject.h" #include "mem_node.h" -#include "StoreMeta.h" -#include "SwapDir.h" -#if USE_DELAY_POOLS -#include "DelayPools.h" -#endif -#include "Stack.h" +#include "MemObject.h" +#include "mgr/Registration.h" #include "SquidTime.h" -#include "swap_log_op.h" +#include "Stack.h" +#include "stmem.h" +#include "Store.h" +#include "StoreClient.h" #include "mgr/StoreIoAction.h" +#include "StoreMeta.h" +#include "swap_log_op.h" +#include "SwapDir.h" static STMCB storeWriteComplete; diff --cc src/tunnel.cc index 3784a5b017,269229b5d4..6404ab87fd --- a/src/tunnel.cc +++ b/src/tunnel.cc @@@ -33,23 -34,20 +33,23 @@@ */ #include "squid.h" -#include "errorpage.h" -#include "HttpRequest.h" -#include "fde.h" +#include "acl/FilledChecklist.h" +#include "Array.h" #include "comm.h" +#include "comm/Connection.h" +#include "comm/ConnOpener.h" #include "comm/Write.h" +#include "client_side.h" #include "client_side_request.h" - #if DELAY_POOLS -#include "acl/FilledChecklist.h" + #if USE_DELAY_POOLS #include "DelayId.h" #endif -#include "client_side.h" -#include "MemBuf.h" +#include "errorpage.h" +#include "fde.h" +#include "HttpRequest.h" #include "http.h" -#include "ip/tools.h" +#include "MemBuf.h" +#include "PeerSelectState.h" class TunnelStateData { @@@ -77,13 -73,15 +77,13 @@@ public { public: - Connection() : len (0),buf ((char *)xmalloc(SQUID_TCP_SO_RCVBUF)), size_ptr(NULL), fd_(-1) {} + Connection() : len (0), buf ((char *)xmalloc(SQUID_TCP_SO_RCVBUF)), size_ptr(NULL) {} ~Connection(); - int const & fd() const { return fd_;} - void fd(int const newFD); int bytesWanted(int lower=0, int upper = INT_MAX) const; void bytesIn(int const &); - #if DELAY_POOLS + #if USE_DELAY_POOLS void setDelayId(DelayId const &); #endif @@@ -96,11 -94,10 +96,10 @@@ char *buf; int64_t *size_ptr; /* pointer to size in an ConnStateData for logging */ + Comm::ConnectionPointer conn; ///< The currently connected connection. + private: - #if DELAY_POOLS - - int fd_; + #if USE_DELAY_POOLS - DelayId delayId; #endif @@@ -319,8 -324,8 +318,8 @@@ TunnelStateData::copy(size_t len, comm_ } } else if (cbdataReferenceValid(this)) { AsyncCall::Pointer call = commCbCall(5,5, "SomeTunnelWriteHandler", - CommIoCbPtrFun(completion, this)); + CommIoCbPtrFun(completion, this)); - Comm::Write(to.fd(), from.buf, len, call, NULL); + Comm::Write(to.conn, from.buf, len, call, NULL); } cbdataInternalUnlock(this); /* ??? */ @@@ -517,65 -565,46 +516,65 @@@ tunnelConnectDone(const Comm::Connectio HttpRequest *request = tunnelState->request; ErrorState *err = NULL; - #if DELAY_POOLS - request->recordLookup(dns); ++#if USE_DELAY_POOLS + /* no point using the delayIsNoDelay stuff since tunnel is nice and simple */ + if (conn->getPeer() && conn->getPeer()->options.no_delay) + tunnelState->server.setDelayId(DelayId()); +#endif - if (tunnelState->servers->_peer) - hierarchyNote(&tunnelState->request->hier, tunnelState->servers->code, - tunnelState->servers->_peer->host); + if (conn != NULL && conn->getPeer()) + hierarchyNote(&tunnelState->request->hier, conn->peerType, conn->getPeer()->host); else if (Config.onoff.log_ip_on_direct) - hierarchyNote(&tunnelState->request->hier, tunnelState->servers->code, - fd_table[tunnelState->server.fd()].ipaddr); + hierarchyNote(&tunnelState->request->hier, conn->peerType, fd_table[conn->fd].ipaddr); else - hierarchyNote(&tunnelState->request->hier, tunnelState->servers->code, - tunnelState->host); - - if (status == COMM_ERR_DNS) { - debugs(26, 4, "tunnelConnect: Unknown host: " << tunnelState->host); - err = errorCon(ERR_DNS_FAIL, HTTP_NOT_FOUND, request); - *tunnelState->status_ptr = HTTP_NOT_FOUND; - err->dnsError = dns.error; - err->callback = tunnelErrorComplete; - err->callback_data = tunnelState; - errorSend(tunnelState->client.fd(), err); - } else if (status != COMM_OK) { - err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request); - *tunnelState->status_ptr = HTTP_SERVICE_UNAVAILABLE; - err->xerrno = xerrno; - err->port = tunnelState->port; - err->callback = tunnelErrorComplete; - err->callback_data = tunnelState; - errorSend(tunnelState->client.fd(), err); - } else { - if (tunnelState->servers->_peer) - tunnelProxyConnected(tunnelState->server.fd(), tunnelState); - else { - tunnelConnected(tunnelState->server.fd(), tunnelState); + hierarchyNote(&tunnelState->request->hier, conn->peerType, tunnelState->getHost()); + + // TODO: merge this into hierarchyNote with a conn parameter instead of peerType + request->hier.peer_local_port = conn->local.GetPort(); // for %serverDestinations.shift(); + if (status != COMM_TIMEOUT && tunnelState->serverDestinations.size() > 0) { + /* Try another IP of this destination host */ + AsyncCall::Pointer call = commCbCall(26,3, "tunnelConnectDone", CommConnectCbPtrFun(tunnelConnectDone, tunnelState)); + Comm::ConnOpener *cs = new Comm::ConnOpener(tunnelState->serverDestinations[0], call, Config.Timeout.connect); + cs->setHost(tunnelState->url); + AsyncJob::Start(cs); + } else { + err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request); + *tunnelState->status_ptr = HTTP_SERVICE_UNAVAILABLE; + err->xerrno = xerrno; + // on timeout is this still: err->xerrno = ETIMEDOUT; + err->port = conn->remote.GetPort(); + err->callback = tunnelErrorComplete; + err->callback_data = tunnelState; + errorSend(tunnelState->client.conn, err); } + return; + } + + tunnelState->server.conn = conn; + request->peer_host = conn->getPeer() ? conn->getPeer()->host : NULL; + comm_add_close_handler(conn->fd, tunnelServerClosed, tunnelState); + + if (conn->getPeer()) { + tunnelState->request->peer_login = conn->getPeer()->login; + tunnelState->request->flags.proxying = 1; + } else { + tunnelState->request->peer_login = NULL; + tunnelState->request->flags.proxying = 0; + } - commSetTimeout(tunnelState->server.fd(), - Config.Timeout.read, - tunnelTimeout, - tunnelState); + if (conn->getPeer()) + tunnelRelayConnectRequest(conn, tunnelState); + else { + tunnelConnected(conn, tunnelState); } + + commSetTimeout(conn->fd, Config.Timeout.read, tunnelTimeout, tunnelState); } extern tos_t GetTosToServer(HttpRequest * request); @@@ -618,11 -648,55 +617,11 @@@ tunnelStart(ClientHttpRequest * http, i debugs(26, 3, "tunnelStart: '" << RequestMethodStr(request->method) << " " << url << "'"); statCounter.server.all.requests++; statCounter.server.other.requests++; - /* Create socket. */ - Ip::Address temp = getOutgoingAddr(request,NULL); - - // if IPv6 is disabled try to force IPv4-only outgoing. - if (!Ip::EnableIpv6 && !temp.SetIPv4()) { - debugs(50, 4, "tunnelStart: IPv6 is Disabled. Tunnel failed from " << temp); - ErrorState *anErr = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request); - anErr->xerrno = EAFNOSUPPORT; - errorSend(fd, anErr); - return; - } - - // if IPv6 is split-stack, prefer IPv4 - if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK) { - // NP: This is not a great choice of default, - // but with the current Internet being IPv4-majority has a higher success rate. - // if setting to IPv4 fails we dont care, that just means to use IPv6 outgoing. - temp.SetIPv4(); - } - - int flags = COMM_NONBLOCKING; - if (request->flags.spoof_client_ip) { - flags |= COMM_TRANSPARENT; - } - sock = comm_openex(SOCK_STREAM, - IPPROTO_TCP, - temp, - flags, - GetTosToServer(request), - GetNfmarkToServer(request), - url); - - if (sock == COMM_ERROR) { - debugs(26, 4, "tunnelStart: Failed because we're out of sockets."); - err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR, request); - *status_ptr = HTTP_INTERNAL_SERVER_ERROR; - err->xerrno = errno; - errorSend(fd, err); - return; - } - - request->hier.peer_local_port = comm_local_port(sock); // for %server.setDelayId(DelayId::DelayClient(http)); #endif - tunnelState->url = xstrdup(url); tunnelState->request = HTTPMSGLOCK(request); tunnelState->server.size_ptr = size_ptr; @@@ -714,10 -827,16 +713,10 @@@ TunnelStateData::operator delete (void bool TunnelStateData::noConnections() const { - return fd_closed(server.fd()) && fd_closed(client.fd()); + return !Comm::IsConnOpen(server.conn) && !Comm::IsConnOpen(client.conn); } - #if DELAY_POOLS + #if USE_DELAY_POOLS void TunnelStateData::Connection::setDelayId(DelayId const &newDelay) {