From: Amos Jeffries Date: Fri, 27 Aug 2010 09:08:48 +0000 (+1200) Subject: Roll Comm::Connection into client-facing X-Git-Tag: take08~55^2~124^2~80 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5c336a3bac7636e9e3bbf4cd9257dac14acc3a86;p=thirdparty%2Fsquid.git Roll Comm::Connection into client-facing --- diff --git a/src/CacheManager.h b/src/CacheManager.h index 975c96617b..6bc205227a 100644 --- a/src/CacheManager.h +++ b/src/CacheManager.h @@ -36,6 +36,7 @@ #include "squid.h" #include "Array.h" +#include "comm/forward.h" /** \defgroup CacheManagerAPI Cache Manager API @@ -104,7 +105,7 @@ public: void registerAction(CacheManagerAction *anAction); CacheManagerAction * findAction(char const * action); - void Start(int fd, HttpRequest * request, StoreEntry * entry); + void Start(const Comm::ConnectionPointer &client, HttpRequest * request, StoreEntry * entry); static CacheManager* GetInstance(); const char *ActionProtection(const CacheManagerAction * at); diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index 8b6f8419d2..f33b0b5d6e 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -249,7 +249,8 @@ asnCacheStart(int as) if ((e = storeGetPublic(asres, METHOD_GET)) == NULL) { e = storeCreateEntry(asres, asres, request_flags(), METHOD_GET); asState->sc = storeClientListAdd(e, asState); - FwdState::fwdStart(-1, e, asState->request); + Comm::ConnectionPointer nul; + FwdState::fwdStart(nul, e, asState->request); } else { e->lock(); diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 72ec05750b..a5c81d2cd4 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -5,6 +5,8 @@ #include "auth/UserRequest.h" #include "auth/AclProxyAuth.h" #include "acl/FilledChecklist.h" +#include "comm/Connection.h" +#include "comm/forward.h" CBDATA_CLASS_INIT(ACLFilledChecklist); @@ -106,13 +108,13 @@ ACLFilledChecklist::conn(ConnStateData *aConn) int ACLFilledChecklist::fd() const { - return conn_ != NULL ? conn_->fd : fd_; + return (conn_ != NULL && conn_->clientConn != NULL) ? conn_->clientConn->fd : fd_; } void ACLFilledChecklist::fd(int aDescriptor) { - assert(!conn() || conn()->fd == aDescriptor); + assert(!conn() || conn()->clientConn == NULL || conn()->clientConn->fd == aDescriptor); fd_ = aDescriptor; } diff --git a/src/auth/UserRequest.cc b/src/auth/UserRequest.cc index 608574a015..29815f9f37 100644 --- a/src/auth/UserRequest.cc +++ b/src/auth/UserRequest.cc @@ -42,12 +42,9 @@ #include "squid.h" #include "auth/UserRequest.h" #include "auth/User.h" -/*#include "auth/Gadgets.h" -#include "acl/Acl.h" -#include "client_side.h" -*/ #include "auth/Config.h" #include "auth/Scheme.h" +#include "comm/Connection.h" #include "HttpReply.h" #include "HttpRequest.h" @@ -345,7 +342,9 @@ AuthUserRequest::authenticate(AuthUserRequest::Pointer * auth_user_request, http debugs(29, 9, HERE << "header " << (proxy_auth ? proxy_auth : "-") << "."); if (*auth_user_request == NULL) { - debugs(29, 9, HERE << "This is a new checklist test on FD:" << (conn != NULL ? conn->fd : -1) ); + if (conn != NULL) { + debugs(29, 9, HERE << "This is a new checklist test on:" << conn->clientConn); + } if (proxy_auth && request->auth_user_request == NULL && conn != NULL && conn->auth_user_request != NULL) { AuthConfig * scheme = AuthConfig::Find(proxy_auth); diff --git a/src/cache_manager.cc b/src/cache_manager.cc index 23ae897b8b..d8d03a14e5 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -32,8 +32,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */ - +#include "config.h" #include "CacheManager.h" +#include "comm/Connection.h" #include "errorpage.h" #include "HttpReply.h" #include "HttpRequest.h" @@ -259,7 +260,7 @@ CacheManager::StateFree(cachemgrStateData * mgr) * all needed internal work and renders the response. */ void -CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry) +CacheManager::Start(const Comm::ConnectionPointer &client, HttpRequest * request, StoreEntry * entry) { cachemgrStateData *mgr = NULL; ErrorState *err = NULL; @@ -279,7 +280,7 @@ CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry) entry->lock(); entry->expires = squid_curtime; - debugs(16, 5, "CacheManager: " << fd_table[fd].ipaddr << " requesting '" << mgr->action << "'"); + debugs(16, 5, "CacheManager: " << client << " requesting '" << mgr->action << "'"); /* get additional info from request headers */ ParseHeaders(mgr, request); @@ -296,13 +297,13 @@ CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry) if (mgr->passwd) debugs(16, DBG_IMPORTANT, "CacheManager: " << (mgr->user_name ? mgr->user_name : "") << "@" << - fd_table[fd].ipaddr << ": incorrect password for '" << + client << ": incorrect password for '" << mgr->action << "'" ); else debugs(16, DBG_IMPORTANT, "CacheManager: " << (mgr->user_name ? mgr->user_name : "") << "@" << - fd_table[fd].ipaddr << ": password needed for '" << - mgr->action << "'" ); + client << ": password needed for '" << + mgr->action << "'"); rep = errState->BuildHttpReply(); @@ -328,7 +329,7 @@ CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry) debugs(16, 2, "CacheManager: " << (mgr->user_name ? mgr->user_name : "") << "@" << - fd_table[fd].ipaddr << " requesting '" << + client << " requesting '" << mgr->action << "'" ); /* retrieve object requested */ a = findAction(mgr->action); diff --git a/src/client_side.cc b/src/client_side.cc index 99058b656f..22919f60f0 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -190,7 +190,7 @@ static void clientUpdateHierCounters(HierarchyLogEntry *); static bool clientPingHasFinished(ping_data const *aPing); void prepareLogWithRequestDetails(HttpRequest *, AccessLogEntry *); #ifndef PURIFY -static int connIsUsable(ConnStateData * conn); +static bool connIsUsable(ConnStateData * conn); #endif static int responseFinishedOrFailed(HttpReply * rep, StoreIOBuffer const &receivedData); static void ClientSocketContextPushDeferredIfNeeded(ClientSocketContext::Pointer deferredRequest, ConnStateData * conn); @@ -201,15 +201,17 @@ static void connNoteUseOfBuffer(ConnStateData* conn, size_t byteCount); static int connKeepReadingIncompleteRequest(ConnStateData * conn); static void connCancelIncompleteRequests(ConnStateData * conn); -static ConnStateData *connStateCreate(const Ip::Address &peer, const Ip::Address &me, int fd, http_port_list *port); +static ConnStateData *connStateCreate(const Comm::ConnectionPointer &details, http_port_list *port); +// TODO make this return the conn for use instead. int ClientSocketContext::fd() const { assert (http); assert (http->getConn() != NULL); - return http->getConn()->fd; + assert (http->getConn()->clientConn != NULL); + return http->getConn()->clientConn->fd; } clientStreamNode * @@ -237,14 +239,14 @@ ConnStateData::readSomeData() if (reading()) return; - debugs(33, 4, "clientReadSomeData: FD " << fd << ": reading request..."); + debugs(33, 4, "clientReadSomeData: FD " << clientConn->fd << ": reading request..."); makeSpaceAvailable(); typedef CommCbMemFunT Dialer; reader = asyncCall(33, 5, "ConnStateData::clientReadRequest", Dialer(this, &ConnStateData::clientReadRequest)); - comm_read(fd, in.addressToReadInto(), getAvailableBufferLength(), reader); + comm_read(clientConn->fd, in.addressToReadInto(), getAvailableBufferLength(), reader); } @@ -673,7 +675,6 @@ ConnStateData::notifyAllContexts(int xerrno) /* This is a handler normally called by comm_close() */ void ConnStateData::connStateClosed(const CommCloseCbParams &io) { - assert (fd == io.fd); deleteThis("ConnStateData::connStateClosed"); } @@ -681,8 +682,8 @@ void ConnStateData::connStateClosed(const CommCloseCbParams &io) void ConnStateData::swanSong() { - debugs(33, 2, "ConnStateData::swanSong: FD " << fd); - fd = -1; + debugs(33, 2, "ConnStateData::swanSong: FD " << (clientConn!=NULL?clientConn->fd:-1)); + clientConn = NULL; flags.readMoreRequests = false; clientdbEstablished(peer, -1); /* decrement */ assert(areAllContextsForThisConnection()); @@ -704,20 +705,20 @@ bool ConnStateData::isOpen() const { return cbdataReferenceValid(this) && // XXX: checking "this" in a method - fd >= 0 && - !fd_table[fd].closing(); + Comm::IsConnOpen(clientConn) && + !fd_table[clientConn->fd].closing(); } ConnStateData::~ConnStateData() { assert(this != NULL); - debugs(33, 3, "ConnStateData::~ConnStateData: FD " << fd); + debugs(33, 3, "ConnStateData::~ConnStateData: FD " << (clientConn!=NULL?clientConn->fd:-1) ); if (isOpen()) - debugs(33, 1, "BUG: ConnStateData did not close FD " << fd); + debugs(33, 1, "BUG: ConnStateData did not close FD " << clientConn->fd); if (!flags.swanSang) - debugs(33, 1, "BUG: ConnStateData was not destroyed properly; FD " << fd); + debugs(33, 1, "BUG: ConnStateData was not destroyed properly; FD " << (clientConn!=NULL?clientConn->fd:-1)); cbdataReferenceDone(port); @@ -794,13 +795,13 @@ clientIsRequestBodyTooLargeForPolicy(int64_t bodyLength) } #ifndef PURIFY -int +bool connIsUsable(ConnStateData * conn) { - if (conn == NULL || !cbdataReferenceValid(conn) || conn->fd == -1) - return 0; + if (conn == NULL || !cbdataReferenceValid(conn) || !Comm::IsConnOpen(conn->clientConn)) + return false; - return 1; + return true; } #endif @@ -1318,7 +1319,6 @@ static void clientSocketRecipient(clientStreamNode * node, ClientHttpRequest * http, HttpReply * rep, StoreIOBuffer receivedData) { - int fd; /* Test preconditions */ assert(node != NULL); PROF_start(clientSocketRecipient); @@ -1332,7 +1332,8 @@ clientSocketRecipient(clientStreamNode * node, ClientHttpRequest * http, ClientSocketContext::Pointer context = dynamic_cast(node->data.getRaw()); assert(context != NULL); assert(connIsUsable(http->getConn())); - fd = http->getConn()->fd; + int fd = http->getConn()->clientConn->fd; + /* TODO: check offset is what we asked for */ if (context != http->getConn()->getCurrentContext()) { @@ -1394,16 +1395,16 @@ clientWriteBodyComplete(int fd, char *buf, size_t size, comm_err_t errflag, int void ConnStateData::readNextRequest() { - debugs(33, 5, "ConnStateData::readNextRequest: FD " << fd << " reading next req"); + debugs(33, 5, "ConnStateData::readNextRequest: FD " << clientConn->fd << " reading next req"); - fd_note(fd, "Waiting for next request"); + fd_note(clientConn->fd, "Waiting for next request"); /** * Set the timeout BEFORE calling clientReadRequest(). */ typedef CommCbMemFunT TimeoutDialer; AsyncCall::Pointer timeoutCall = asyncCall(33, 5, "ConnStateData::requestTimeout", TimeoutDialer(this, &ConnStateData::requestTimeout)); - commSetTimeout(fd, Config.Timeout.persistent_request, timeoutCall); + commSetTimeout(clientConn->fd, Config.Timeout.persistent_request, timeoutCall); readSomeData(); /** Please don't do anything with the FD past here! */ @@ -1412,7 +1413,7 @@ ConnStateData::readNextRequest() static void ClientSocketContextPushDeferredIfNeeded(ClientSocketContext::Pointer deferredRequest, ConnStateData * conn) { - debugs(33, 2, "ClientSocketContextPushDeferredIfNeeded: FD " << conn->fd << " Sending next"); + debugs(33, 2, HERE << conn->clientConn << " Sending next"); /** If the client stream is waiting on a socket write to occur, then */ @@ -1437,12 +1438,12 @@ ClientSocketContext::keepaliveNextRequest() ConnStateData * conn = http->getConn(); bool do_next_read = false; - debugs(33, 3, "ClientSocketContext::keepaliveNextRequest: FD " << conn->fd); + debugs(33, 3, HERE << conn->clientConn); connIsFinished(); if (conn->pinning.pinned && conn->pinning.fd == -1) { - debugs(33, 2, "clientKeepaliveNextRequest: FD " << conn->fd << " Connection was pinned but server side gone. Terminating client connection"); - comm_close(conn->fd); + debugs(33, 2, HERE << conn->clientConn << " Connection was pinned but server side gone. Terminating client connection"); + conn->clientConn->close(); return; } @@ -1457,7 +1458,7 @@ ClientSocketContext::keepaliveNextRequest() */ if (clientParseRequest(conn, do_next_read)) { - debugs(33, 3, "clientSocketContext::keepaliveNextRequest: FD " << conn->fd << ": parsed next request from buffer"); + debugs(33, 3, HERE << conn->clientConn << ": parsed next request from buffer"); } /** \par @@ -1467,9 +1468,9 @@ ClientSocketContext::keepaliveNextRequest() * half-closed _AND_ then, sometimes, spending "Timeout" time in * the keepalive "Waiting for next request" state. */ - if (commIsHalfClosed(conn->fd) && (conn->getConcurrentRequestCount() == 0)) { + if (commIsHalfClosed(conn->clientConn->fd) && (conn->getConcurrentRequestCount() == 0)) { debugs(33, 3, "ClientSocketContext::keepaliveNextRequest: half-closed client with no pending requests, closing"); - comm_close(conn->fd); + conn->clientConn->close(); return; } @@ -1484,10 +1485,10 @@ ClientSocketContext::keepaliveNextRequest() */ if ((deferredRequest = conn->getCurrentContext()).getRaw()) { - debugs(33, 3, "ClientSocketContext:: FD " << conn->fd << ": calling PushDeferredIfNeeded"); + debugs(33, 3, HERE << conn->clientConn << ": calling PushDeferredIfNeeded"); ClientSocketContextPushDeferredIfNeeded(deferredRequest, conn); } else { - debugs(33, 3, "ClientSocketContext:: FD " << conn->fd << ": calling conn->readNextRequest()"); + debugs(33, 3, HERE << conn->clientConn << ": calling conn->readNextRequest()"); conn->readNextRequest(); } } @@ -1738,13 +1739,14 @@ ClientSocketContext::writeComplete(int aFileDescriptor, char *bufnotused, size_t ", err " << errflag << ", off " << http->out.size << ", len " << entry ? entry->objectLen() : 0); clientUpdateSocketStats(http->logType, size); - assert (this->fd() == aFileDescriptor); /* Bail out quickly on COMM_ERR_CLOSING - close handlers will tidy up */ if (errflag == COMM_ERR_CLOSING) return; + assert (Comm::IsConnOpen(http->getConn()->clientConn) && this->fd() == aFileDescriptor); + if (errflag || clientHttpRequestStatus(aFileDescriptor, http)) { initiateClose("failure or true request status"); /* Do we leak here ? */ @@ -2251,16 +2253,16 @@ int ConnStateData::connReadWasError(comm_err_t flag, int size, int xerrno) { if (flag != COMM_OK) { - debugs(33, 2, "connReadWasError: FD " << fd << ": got flag " << flag); + debugs(33, 2, "connReadWasError: FD " << (clientConn!=NULL?clientConn->fd:-1) << ": got flag " << flag); return 1; } if (size < 0) { if (!ignoreErrno(xerrno)) { - debugs(33, 2, "connReadWasError: FD " << fd << ": " << xstrerr(xerrno)); + debugs(33, 2, "connReadWasError: FD " << clientConn->fd << ": " << xstrerr(xerrno)); return 1; } else if (in.notYetUsed == 0) { - debugs(33, 2, "connReadWasError: FD " << fd << ": no data to process (" << xstrerr(xerrno) << ")"); + debugs(33, 2, "connReadWasError: FD " << clientConn->fd << ": no data to process (" << xstrerr(xerrno) << ")"); } } @@ -2273,11 +2275,11 @@ ConnStateData::connFinishedWithConn(int size) if (size == 0) { if (getConcurrentRequestCount() == 0 && in.notYetUsed == 0) { /* no current or pending requests */ - debugs(33, 4, "connFinishedWithConn: FD " << fd << " closed"); + debugs(33, 4, "connFinishedWithConn: FD " << clientConn->fd << " closed"); return 1; } else if (!Config.onoff.half_closed_clients) { /* admin doesn't want to support half-closed client sockets */ - debugs(33, 3, "connFinishedWithConn: FD " << fd << " aborted (half_closed_clients disabled)"); + debugs(33, 3, "connFinishedWithConn: FD " << clientConn->fd << " aborted (half_closed_clients disabled)"); notifyAllContexts(0); // no specific error implies abort return 1; } @@ -2353,11 +2355,11 @@ ConnStateData::clientAfterReadingRequests(int do_next_read) * yet, then close this connection. */ - if (fd_table[fd].flags.socket_eof) { + if (fd_table[clientConn->fd].flags.socket_eof) { if ((int64_t)in.notYetUsed < bodySizeLeft()) { /* Partial request received. Abort client connection! */ - debugs(33, 3, "clientAfterReadingRequests: FD " << fd << " aborted, partial request"); - comm_close(fd); + debugs(33, 3, "clientAfterReadingRequests: FD " << clientConn->fd << " aborted, partial request"); + clientConn->close(); return; } } @@ -2600,10 +2602,10 @@ finish: * be freed and the above connNoteUseOfBuffer() would hit an * assertion, not to mention that we were accessing freed memory. */ - if (http->request->flags.resetTCP() && conn->fd > -1) { - debugs(33, 3, HERE << "Sending TCP RST on FD " << conn->fd); + if (http->request->flags.resetTCP() && Comm::IsConnOpen(conn->clientConn)) { + debugs(33, 3, HERE << "Sending TCP RST on " << conn->clientConn); conn->flags.readMoreRequests = false; - comm_reset_close(conn->fd); + comm_reset_close(conn->clientConn); return; } } @@ -2623,10 +2625,8 @@ connOkToAddRequest(ConnStateData * conn) int result = conn->getConcurrentRequestCount() < (Config.onoff.pipeline_prefetch ? 2 : 1); if (!result) { - debugs(33, 3, "connOkToAddRequest: FD " << conn->fd << - " max concurrent requests reached"); - debugs(33, 5, "connOkToAddRequest: FD " << conn->fd << - " defering new request until one is done"); + debugs(33, 3, HERE << conn->clientConn << " max concurrent requests reached"); + debugs(33, 5, HERE << conn->clientConn << " defering new request until one is done"); } return result; @@ -2665,7 +2665,7 @@ clientParseRequest(ConnStateData * conn, bool &do_next_read) HttpVersion http_ver; HttpParser hp; - debugs(33, 5, "clientParseRequest: FD " << conn->fd << ": attempting to parse"); + debugs(33, 5, HERE << conn->clientConn << ": attempting to parse"); while (conn->in.notYetUsed > 0 && conn->bodySizeLeft() == 0) { connStripBufferWhitespace (conn); @@ -2706,8 +2706,8 @@ clientParseRequest(ConnStateData * conn, bool &do_next_read) /* status -1 or 1 */ if (context) { - debugs(33, 5, "clientParseRequest: FD " << conn->fd << ": parsed a request"); - commSetTimeout(conn->fd, Config.Timeout.lifetime, clientLifetimeTimeout, + debugs(33, 5, HERE << conn->clientConn << ": parsed a request"); + commSetTimeout(conn->clientConn->fd, Config.Timeout.lifetime, clientLifetimeTimeout, context->http); clientProcessRequest(conn, &hp, context, method, http_ver); @@ -2742,15 +2742,16 @@ ConnStateData::clientReadRequest(const CommIoCbParams &io) reader = NULL; bool do_next_read = 1; /* the default _is_ to read data! - adrian */ - assert (io.fd == fd); - /* Bail out quickly on COMM_ERR_CLOSING - close handlers will tidy up */ if (io.flag == COMM_ERR_CLOSING) { - debugs(33,5, HERE << " FD " << fd << " closing Bailout."); + debugs(33,5, HERE << " FD " << io.fd << " closing Bailout."); return; } + assert(Comm::IsConnOpen(clientConn)); + assert(io.fd == clientConn->fd); + /* * Don't reset the timeout value here. The timeout value will be * set to Config.Timeout.request by httpAccept() and @@ -2760,7 +2761,7 @@ ConnStateData::clientReadRequest(const CommIoCbParams &io) */ if (connReadWasError(io.flag, io.size, io.xerrno)) { notifyAllContexts(io.xerrno); - comm_close(fd); + clientConn->close(); return; } @@ -2775,21 +2776,21 @@ ConnStateData::clientReadRequest(const CommIoCbParams &io) return; } else if (io.size == 0) { - debugs(33, 5, "clientReadRequest: FD " << fd << " closed?"); + debugs(33, 5, "clientReadRequest: FD " << io.fd << " closed?"); if (connFinishedWithConn(io.size)) { - comm_close(fd); + clientConn->close(); return; } /* It might be half-closed, we can't tell */ - fd_table[fd].flags.socket_eof = 1; + fd_table[io.fd].flags.socket_eof = 1; - commMarkHalfClosed(fd); + commMarkHalfClosed(io.fd); do_next_read = 0; - fd_note(fd, "half-closed"); + fd_note(io.fd, "half-closed"); /* There is one more close check at the end, to detect aborted * (partial) requests. At this point we can't tell if the request @@ -2801,7 +2802,7 @@ ConnStateData::clientReadRequest(const CommIoCbParams &io) /* Process next request */ if (getConcurrentRequestCount() == 0) - fd_note(fd, "Reading next request"); + fd_note(io.fd, "Reading next request"); if (! clientParseRequest(this, do_next_read)) { if (!isOpen()) @@ -2814,9 +2815,9 @@ ConnStateData::clientReadRequest(const CommIoCbParams &io) * be if we have an incomplete request. * XXX: This duplicates ClientSocketContext::keepaliveNextRequest */ - if (getConcurrentRequestCount() == 0 && commIsHalfClosed(fd)) { - debugs(33, 5, "clientReadRequest: FD " << fd << ": half-closed connection, no completed request parsed, connection closing."); - comm_close(fd); + if (getConcurrentRequestCount() == 0 && commIsHalfClosed(io.fd)) { + debugs(33, 5, "clientReadRequest: FD " << io.fd << ": half-closed connection, no completed request parsed, connection closing."); + clientConn->close(); return; } } @@ -2866,7 +2867,7 @@ ConnStateData::handleRequestBodyData() // responses which we may encourage by sending chunked requests. // The error generation code probably needs more work. if (in.bodyParser) { // chunked body - debugs(33,5, HERE << "handling chunked request body for FD " << fd); + debugs(33,5, HERE << "handling chunked request body for FD " << clientConn->fd); bool malformedChunks = false; MemBuf raw; // ChunkedCodingParser only works with MemBufs @@ -2912,7 +2913,7 @@ ConnStateData::handleRequestBodyData() } else // identity encoding #endif { - debugs(33,5, HERE << "handling plain request body for FD " << fd); + debugs(33,5, HERE << "handling plain request body for FD " << clientConn->fd); putSize = bodyPipe->putMoreData(in.buf, in.notYetUsed); if (!bodyPipe->mayNeedMoreData()) { // BodyPipe will clear us automagically when we produced everything @@ -2924,7 +2925,7 @@ ConnStateData::handleRequestBodyData() connNoteUseOfBuffer(this, putSize); if (!bodyPipe) { - debugs(33,5, HERE << "produced entire request body for FD " << fd); + debugs(33,5, HERE << "produced entire request body for FD " << clientConn->fd); if (closing()) { /* we've finished reading like good clients, @@ -2936,7 +2937,7 @@ ConnStateData::handleRequestBodyData() * the case of an endless request. This if-statement does not, * because mayNeedMoreData is true if request size is not known. */ - comm_close(fd); + clientConn->close(); } } } @@ -2968,12 +2969,12 @@ ConnStateData::requestTimeout(const CommTimeoutCbParams &io) /* * Some data has been sent to the client, just close the FD */ - comm_close(io.fd); + clientConn->close(); } else if (nrequests) { /* * assume its a persistent connection; just close it */ - comm_close(io.fd); + clientConn->close(); } else { /* * Generate an error @@ -3022,7 +3023,7 @@ ConnStateData::requestTimeout(const CommTimeoutCbParams &io) */ debugs(33, 3, "requestTimeout: FD " << io.fd << ": lifetime is expired."); - comm_close(io.fd); + clientConn->close(); #endif } @@ -3038,22 +3039,22 @@ clientLifetimeTimeout(int fd, void *data) } ConnStateData * -connStateCreate(const Ip::Address &peer, const Ip::Address &me, int fd, http_port_list *port) +connStateCreate(const Comm::ConnectionPointer &conn, http_port_list *port) { ConnStateData *result = new ConnStateData; - result->peer = peer; - result->log_addr = peer; + result->peer = conn->remote; + result->log_addr = conn->remote; result->log_addr.ApplyMask(Config.Addrs.client_netmask); - result->me = me; - result->fd = fd; + result->me = conn->local; + result->clientConn = conn; result->in.buf = (char *)memAllocBuf(CLIENT_REQ_BUF_SZ, &result->in.allocatedSize); result->port = cbdataReference(port); if (port->intercepted || port->spoof_client_ip) { Ip::Address client, dst; - if (Ip::Interceptor.NatLookup(fd, me, peer, client, dst) == 0) { + if (Ip::Interceptor.NatLookup(conn->fd, conn->local, conn->remote, client, dst) == 0) { result->me = client; result->peer = dst; result->transparent(true); @@ -3064,7 +3065,7 @@ connStateCreate(const Ip::Address &peer, const Ip::Address &me, int fd, http_por (result->transparent() || port->disable_pmtu_discovery == DISABLE_PMTU_ALWAYS)) { #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) int i = IP_PMTUDISC_DONT; - setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &i, sizeof i); + setsockopt(conn->fd, SOL_IP, IP_MTU_DISCOVER, &i, sizeof i); #else @@ -3085,7 +3086,7 @@ connStateCreate(const Ip::Address &peer, const Ip::Address &me, int fd, http_por /** Handle a new connection on HTTP socket. */ void -httpAccept(int sock, int newfd, Comm::ConnectionPointer &details, +httpAccept(int sock, int unused, Comm::ConnectionPointer &details, comm_err_t flag, int xerrno, void *data) { http_port_list *s = (http_port_list *)data; @@ -3096,14 +3097,14 @@ httpAccept(int sock, int newfd, Comm::ConnectionPointer &details, return; } - debugs(33, 4, "httpAccept: FD " << newfd << ": accepted"); - fd_note(newfd, "client http connect"); - connState = connStateCreate(&details->remote, &details->local, newfd, s); + debugs(33, 4, HERE << details << ": accepted"); + fd_note(details->fd, "client http connect"); + connState = connStateCreate(details, s); typedef CommCbMemFunT Dialer; AsyncCall::Pointer call = asyncCall(33, 5, "ConnStateData::connStateClosed", Dialer(connState, &ConnStateData::connStateClosed)); - comm_add_close_handler(newfd, call); + comm_add_close_handler(details->fd, call); if (Config.onoff.log_fqdn) fqdncache_gethostbyaddr(details->remote, FQDN_LOOKUP_IF_MISS); @@ -3111,7 +3112,7 @@ httpAccept(int sock, int newfd, Comm::ConnectionPointer &details, typedef CommCbMemFunT TimeoutDialer; AsyncCall::Pointer timeoutCall = asyncCall(33, 5, "ConnStateData::requestTimeout", TimeoutDialer(connState,&ConnStateData::requestTimeout)); - commSetTimeout(newfd, Config.Timeout.read, timeoutCall); + commSetTimeout(details->fd, Config.Timeout.read, timeoutCall); #if USE_IDENT if (Ident::TheConfig.identLookup) { @@ -3134,7 +3135,7 @@ httpAccept(int sock, int newfd, Comm::ConnectionPointer &details, #endif if (s->tcp_keepalive.enabled) { - commSetTcpKeepalive(newfd, s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout); + commSetTcpKeepalive(details->fd, s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout); } connState->readSomeData(); @@ -3142,33 +3143,30 @@ httpAccept(int sock, int newfd, Comm::ConnectionPointer &details, clientdbEstablished(details->remote, 1); incoming_sockets_accepted++; - - // TODO: remove this when details conn is passed around properly. - details->fd = -1; // ConnStateData has assumed control of the FD now. } #if USE_SSL /** Create SSL connection structure and update fd_table */ static SSL * -httpsCreate(int newfd, Comm::ConnectionPointer details, SSL_CTX *sslContext) +httpsCreate(Comm::ConnectionPointer &details, SSL_CTX *sslContext) { SSL *ssl = SSL_new(sslContext); if (!ssl) { const int ssl_error = ERR_get_error(); debugs(83, 1, "httpsAccept: Error allocating handle: " << ERR_error_string(ssl_error, NULL) ); - comm_close(newfd); + details->close(); return NULL; } - SSL_set_fd(ssl, newfd); - fd_table[newfd].ssl = ssl; - fd_table[newfd].read_method = &ssl_read_method; - fd_table[newfd].write_method = &ssl_write_method; + SSL_set_fd(ssl, details->fd); + fd_table[details->fd].ssl = ssl; + fd_table[details->fd].read_method = &ssl_read_method; + fd_table[details->fd].write_method = &ssl_write_method; - debugs(33, 5, "httpsCreate: will negotate SSL on FD " << newfd); - fd_note(newfd, "client https start"); + debugs(33, 5, "httpsCreate: will negotate SSL on " << details); + fd_note(details->fd, "client https start"); return ssl; } @@ -3307,17 +3305,16 @@ httpsAccept(int sock, int newfd, Comm::ConnectionPointer& details, } SSL *ssl = NULL; - if (!(ssl = httpsCreate(newfd, details, sslContext))) + if (!(ssl = httpsCreate(details, sslContext))) return; - debugs(33, 5, "httpsAccept: FD " << newfd << " accepted, starting SSL negotiation."); - fd_note(newfd, "client https connect"); - ConnStateData *connState = connStateCreate(details->remote, details->local, - newfd, &s->http); + debugs(33, 5, HERE << details << " accepted, starting SSL negotiation."); + fd_note(details->fd, "client https connect"); + ConnStateData *connState = connStateCreate(details, &s->http); typedef CommCbMemFunT Dialer; AsyncCall::Pointer call = asyncCall(33, 5, "ConnStateData::connStateClosed", Dialer(connState, &ConnStateData::connStateClosed)); - comm_add_close_handler(newfd, call); + comm_add_close_handler(details->fd, call); if (Config.onoff.log_fqdn) fqdncache_gethostbyaddr(details->remote, FQDN_LOOKUP_IF_MISS); @@ -3325,7 +3322,7 @@ httpsAccept(int sock, int newfd, Comm::ConnectionPointer& details, typedef CommCbMemFunT TimeoutDialer; AsyncCall::Pointer timeoutCall = asyncCall(33, 5, "ConnStateData::requestTimeout", TimeoutDialer(connState,&ConnStateData::requestTimeout)); - commSetTimeout(newfd, Config.Timeout.request, timeoutCall); + commSetTimeout(details->fd, Config.Timeout.request, timeoutCall); #if USE_IDENT if (Ident::TheConfig.identLookup) { @@ -3338,17 +3335,14 @@ httpsAccept(int sock, int newfd, Comm::ConnectionPointer& details, #endif if (s->http.tcp_keepalive.enabled) { - commSetTcpKeepalive(newfd, s->http.tcp_keepalive.idle, s->http.tcp_keepalive.interval, s->http.tcp_keepalive.timeout); + commSetTcpKeepalive(details->fd, s->http.tcp_keepalive.idle, s->http.tcp_keepalive.interval, s->http.tcp_keepalive.timeout); } - commSetSelect(newfd, COMM_SELECT_READ, clientNegotiateSSL, connState, 0); + commSetSelect(details->fd, COMM_SELECT_READ, clientNegotiateSSL, connState, 0); clientdbEstablished(details->remote, 1); incoming_sockets_accepted++; - - // TODO: remove this when details conn is passed around properly. - details->fd = -1; // ConnStateData has assumed control of the FD now. } bool @@ -3361,24 +3355,26 @@ ConnStateData::switchToHttps() freeAllContexts(); //currentobject->connIsFinished(); - debugs(33, 5, HERE << "converting FD " << fd << " to SSL"); + debugs(33, 5, HERE << "converting " << clientConn << " to SSL"); +#if 0 // use the actual clientConn now that we have it. // fake a Comm::Connection object; XXX: make ConnState a Comm::Connection? Comm::Connection detail; detail.local = me; detail.remote = peer; +#endif SSL_CTX *sslContext = port->sslContext; SSL *ssl = NULL; - if (!(ssl = httpsCreate(fd, &detail, sslContext))) + if (!(ssl = httpsCreate(clientConn, sslContext))) return false; // commSetTimeout() was called for this request before we switched. // Disable the client read handler until peer selection is complete - commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0); + commSetSelect(clientConn->fd, COMM_SELECT_READ, NULL, NULL, 0); - commSetSelect(fd, COMM_SELECT_READ, clientNegotiateSSL, this, 0); + commSetSelect(clientConn->fd, COMM_SELECT_READ, clientNegotiateSSL, this, 0); switchedToHttps_ = true; return true; @@ -3666,7 +3662,10 @@ clientAclChecklistCreate(const acl_access * acl, ClientHttpRequest * http) CBDATA_CLASS_INIT(ConnStateData); -ConnStateData::ConnStateData() :AsyncJob("ConnStateData"), transparent_ (false), closing_ (false) +ConnStateData::ConnStateData() : + AsyncJob("ConnStateData"), + transparent_(false), + closing_(false) { pinning.fd = -1; pinning.pinned = false; @@ -3695,7 +3694,7 @@ void ConnStateData::stopReading() { if (reading()) { - comm_read_cancel(fd, reader); + comm_read_cancel(clientConn->fd, reader); reader = NULL; } } @@ -3878,7 +3877,6 @@ ConnStateData::clientPinnedConnectionClosed(const CommCloseCbParams &io) void ConnStateData::pinConnection(int pinning_fd, HttpRequest *request, struct peer *aPeer, bool auth) { - fde *f; char desc[FD_DESC_SZ]; if (pinning.fd == pinning_fd) @@ -3898,9 +3896,9 @@ void ConnStateData::pinConnection(int pinning_fd, HttpRequest *request, struct p if (aPeer) pinning.peer = cbdataReference(aPeer); pinning.auth = auth; - f = &fd_table[fd]; snprintf(desc, FD_DESC_SZ, "%s pinned connection for %s:%d (%d)", - (auth || !aPeer) ? request->GetHost() : aPeer->name, f->ipaddr, (int) f->remote_port, fd); + (auth || !aPeer) ? request->GetHost() : aPeer->name, fd_table[clientConn->fd].ipaddr, + clientConn->remote.GetPort(), clientConn->fd); fd_note(pinning_fd, desc); typedef CommCbMemFunT Dialer; diff --git a/src/client_side.h b/src/client_side.h index e9fd1682bd..c4c4adfe0a 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -145,7 +145,8 @@ public: int getConcurrentRequestCount() const; bool isOpen() const; - int fd; + // Client TCP connection details from comm layer. + Comm::ConnectionPointer clientConn; /// chunk buffering and parsing algorithm state typedef enum { chunkUnknown, chunkNone, chunkParsing, chunkReady, chunkError } DechunkingState; diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index a32d7e40a2..94987545dc 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -265,11 +265,10 @@ clientReplyContext::processExpired() * A refcounted pointer so that FwdState stays around as long as * this clientReplyContext does */ - FwdState::fwdStart(http->getConn() != NULL ? http->getConn()->fd : -1, - http->storeEntry(), - http->request); - /* Register with storage manager to receive updates when data comes in. */ + Comm::ConnectionPointer conn = http->getConn() != NULL ? http->getConn()->clientConn : NULL; + FwdState::fwdStart(conn, http->storeEntry(), http->request); + /* Register with storage manager to receive updates when data comes in. */ if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) debugs(88, 0, "clientReplyContext::processExpired: Found ENTRY_ABORTED object"); @@ -681,9 +680,8 @@ clientReplyContext::processMiss() r->protocol = PROTO_INTERNAL; /** Start forwarding to get the new object from network */ - FwdState::fwdStart(http->getConn() != NULL ? http->getConn()->fd : -1, - http->storeEntry(), - r); + Comm::ConnectionPointer conn = http->getConn() != NULL ? http->getConn()->clientConn : NULL; + FwdState::fwdStart(conn, http->storeEntry(), r); } } @@ -1934,10 +1932,11 @@ clientReplyContext::sendMoreData (StoreIOBuffer result) ConnStateData * conn = http->getConn(); - int fd = conn != NULL ? conn->fd : -1; - if (fd >= 0 && fd_table[fd].closing()) { // too late, our conn is closing - // TODO: should we also quit when fd is negative? - debugs(33,3, HERE << "not sending more data to a closing FD " << fd); + // AYJ: this seems a bit weird to ignore CLOSED but drop on closing. + if (conn != NULL && Comm::IsConnOpen(conn->clientConn) && fd_table[conn->clientConn->fd].closing()) { + // too late, our conn is closing + // TODO: should we also quit? + debugs(33,3, HERE << "not sending more data to a closing " << conn->clientConn); return; } @@ -1954,7 +1953,7 @@ clientReplyContext::sendMoreData (StoreIOBuffer result) #if USE_ZPH_QOS if (reqofs==0 && !logTypeIsATcpHit(http->logType)) { - assert(fd >= 0); // the beginning of this method implies fd may be -1 + assert(conn != NULL && Comm::IsConnOpen(conn->clientConn)); // the beginning of this method implies FD may be closed. int tos = 0; if (Ip::Qos::TheConfig.tos_sibling_hit && http->request->hier.code==SIBLING_HIT ) { tos = Ip::Qos::TheConfig.tos_sibling_hit; @@ -1963,10 +1962,10 @@ clientReplyContext::sendMoreData (StoreIOBuffer result) tos = Ip::Qos::TheConfig.tos_parent_hit; debugs(33, 2, "ZPH: Parent Peer hit with hier.code=" << http->request->hier.code << ", TOS=" << tos); } else if (Ip::Qos::TheConfig.preserve_miss_tos && Ip::Qos::TheConfig.preserve_miss_tos_mask) { - tos = fd_table[fd].upstreamTOS & Ip::Qos::TheConfig.preserve_miss_tos_mask; + tos = fd_table[conn->clientConn->fd].upstreamTOS & Ip::Qos::TheConfig.preserve_miss_tos_mask; debugs(33, 2, "ZPH: Preserving TOS on miss, TOS="<clientConn->fd,tos); } #endif @@ -1989,7 +1988,7 @@ clientReplyContext::sendMoreData (StoreIOBuffer result) reqofs << " bytes (" << result.length << " new bytes)"); debugs(88, 5, "clientReplyContext::sendMoreData:" - " FD " << fd << + << conn->clientConn << " '" << entry->url() << "'" << " out.offset=" << http->out.offset); @@ -2025,8 +2024,6 @@ clientReplyContext::sendMoreData (StoreIOBuffer result) return; } - - /* Using this breaks the client layering just a little! */ void diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 90aa7fcbe8..0f886035e7 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -59,6 +59,7 @@ #include "client_side_reply.h" #include "client_side_request.h" #include "ClientRequestContext.h" +#include "comm/Connection.h" #include "compat/inet_pton.h" #include "fde.h" #include "HttpReply.h" @@ -663,7 +664,8 @@ ClientRequestContext::adaptationAclCheckDone(Adaptation::ServiceGroupPointer g) if (http->getConn() != NULL) { ih->rfc931 = http->getConn()->rfc931; #if USE_SSL - ih->ssluser = sslGetUserEmail(fd_table[http->getConn()->fd].ssl); + assert(http->getConn()->clientConn != NULL); + ih->ssluser = sslGetUserEmail(fd_table[http->getConn()->clientConn->fd].ssl); #endif } ih->log_uri = http->log_uri; @@ -1059,8 +1061,8 @@ ClientRequestContext::clientRedirectDone(char *result) /* FIXME PIPELINE: This is innacurate during pipelining */ - if (http->getConn() != NULL) - fd_note(http->getConn()->fd, http->uri); + if (http->getConn() != NULL && Comm::IsConnOpen(http->getConn()->clientConn)) + fd_note(http->getConn()->clientConn->fd, http->uri); assert(http->uri); @@ -1189,16 +1191,14 @@ ClientHttpRequest::sslBumpEstablish(comm_err_t errflag) void ClientHttpRequest::sslBumpStart() { - debugs(85, 5, HERE << "ClientHttpRequest::sslBumpStart"); - + debugs(85, 5, HERE << "Confirming CONNECT tunnel on FD " << getConn()->clientConn); // send an HTTP 200 response to kick client SSL negotiation - const int fd = getConn()->fd; - debugs(33, 7, HERE << "Confirming CONNECT tunnel on FD " << fd); + debugs(33, 7, HERE << "Confirming CONNECT tunnel on FD " << getConn()->clientConn); // TODO: Unify with tunnel.cc and add a Server(?) header static const char *const conn_established = "HTTP/1.0 200 Connection established\r\n\r\n"; - comm_write(fd, conn_established, strlen(conn_established), + comm_write(getConn()->clientConn->fd, conn_established, strlen(conn_established), &SslBumpEstablish, this, NULL); } @@ -1333,13 +1333,13 @@ ClientHttpRequest::doCallouts() if (!calloutContext->clientside_tos_done) { calloutContext->clientside_tos_done = true; - if (getConn() != NULL) { + if (getConn() != NULL && Comm::IsConnOpen(getConn()->clientConn)) { ACLFilledChecklist ch(NULL, request, NULL); ch.src_addr = request->client_addr; ch.my_addr = request->my_addr; int tos = aclMapTOS(Config.accessList.clientside_tos, &ch); if (tos) - comm_set_tos(getConn()->fd, tos); + comm_set_tos(getConn()->clientConn->fd, tos); } } diff --git a/src/comm.cc b/src/comm.cc index e392dc57f0..1e2ddb4d0d 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1130,14 +1130,27 @@ comm_lingering_close(int fd) #endif -/* +/** * enable linger with time of 0 so that when the socket is * closed, TCP generates a RESET */ void -comm_reset_close(int fd) +comm_reset_close(Comm::ConnectionPointer &conn) { + struct linger L; + L.l_onoff = 1; + L.l_linger = 0; + if (setsockopt(conn->fd, SOL_SOCKET, SO_LINGER, (char *) &L, sizeof(L)) < 0) + debugs(50, DBG_CRITICAL, "ERROR: Closing FD " << conn->fd << " with TCP RST: " << xstrerror()); + + conn->close(); +} + +// Legacy close function. +void +old_comm_reset_close(int fd) +{ struct linger L; L.l_onoff = 1; L.l_linger = 0; @@ -1759,7 +1772,7 @@ commCloseAllSockets(void) ScheduleCallHere(callback); } else { debugs(5, 5, "commCloseAllSockets: FD " << fd << ": calling comm_reset_close()"); - comm_reset_close(fd); + old_comm_reset_close(fd); } } } diff --git a/src/comm.h b/src/comm.h index ffc7fd33d4..fdcd4df841 100644 --- a/src/comm.h +++ b/src/comm.h @@ -23,7 +23,8 @@ SQUIDCEXTERN void commSetCloseOnExec(int fd); SQUIDCEXTERN void commSetTcpKeepalive(int fd, int idle, int interval, int timeout); extern void _comm_close(int fd, char const *file, int line); #define comm_close(x) (_comm_close((x), __FILE__, __LINE__)) -SQUIDCEXTERN void comm_reset_close(int fd); +SQUIDCEXTERN void old_comm_reset_close(int fd); +SQUIDCEXTERN void comm_reset_close(Comm::ConnectionPointer &conn); #if LINGERING_CLOSE SQUIDCEXTERN void comm_lingering_close(int fd); #endif diff --git a/src/comm/Connection.h b/src/comm/Connection.h index da1b651cff..9838a099ab 100644 --- a/src/comm/Connection.h +++ b/src/comm/Connection.h @@ -37,11 +37,19 @@ #ifndef _SQUIDCONNECTIONDETAIL_H_ #define _SQUIDCONNECTIONDETAIL_H_ +#include "config.h" #include "comm/forward.h" #include "hier_code.h" #include "ip/Address.h" #include "RefCount.h" +#if HAVE_IOSFWD +#include +#endif +#if HAVE_OSTREAM +#include +#endif + struct peer; namespace Comm { @@ -136,4 +144,25 @@ private: }; // namespace Comm + +// NP: Order and namespace here is very important. +// * The second define inlines the first. +// * Stream inheritance overloading is searched in the global scope first. + +inline std::ostream & +operator << (std::ostream &os, const Comm::Connection &conn) +{ + os << "FD " << conn.fd << " local=" << conn.local << + " remote=" << conn.remote << " flags=" << conn.flags; + return os; +} + +inline std::ostream & +operator << (std::ostream &os, const Comm::ConnectionPointer &conn) +{ + if (conn != NULL) + os << *conn; + return os; +} + #endif diff --git a/src/external_acl.cc b/src/external_acl.cc index 5808ec5ca7..61018a0bda 100644 --- a/src/external_acl.cc +++ b/src/external_acl.cc @@ -55,6 +55,7 @@ #endif #include "ip/tools.h" #include "client_side.h" +#include "comm/Connection.h" #include "HttpRequest.h" #include "HttpReply.h" #include "auth/Acl.h" @@ -995,8 +996,8 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data) case _external_acl_format::EXT_ACL_USER_CERT_RAW: - if (ch->conn() != NULL) { - SSL *ssl = fd_table[ch->conn()->fd].ssl; + if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConn)) { + SSL *ssl = fd_table[ch->conn()->clientConn->fd].ssl; if (ssl) str = sslGetUserCertificatePEM(ssl); @@ -1006,8 +1007,8 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data) case _external_acl_format::EXT_ACL_USER_CERTCHAIN_RAW: - if (ch->conn() != NULL) { - SSL *ssl = fd_table[ch->conn()->fd].ssl; + if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConn)) { + SSL *ssl = fd_table[ch->conn()->clientConn->fd].ssl; if (ssl) str = sslGetUserCertificateChainPEM(ssl); @@ -1017,8 +1018,8 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data) case _external_acl_format::EXT_ACL_USER_CERT: - if (ch->conn() != NULL) { - SSL *ssl = fd_table[ch->conn()->fd].ssl; + if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConn)) { + SSL *ssl = fd_table[ch->conn()->clientConn->fd].ssl; if (ssl) str = sslGetUserAttribute(ssl, format->header); @@ -1028,8 +1029,8 @@ makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data) case _external_acl_format::EXT_ACL_CA_CERT: - if (ch->conn() != NULL) { - SSL *ssl = fd_table[ch->conn()->fd].ssl; + if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConn)) { + SSL *ssl = fd_table[ch->conn()->clientConn->fd].ssl; if (ssl) str = sslGetCAAttribute(ssl, format->header); diff --git a/src/forward.cc b/src/forward.cc index b04ebf6f55..e81260d4d0 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -89,10 +89,10 @@ FwdState::abort(void* d) /**** PUBLIC INTERFACE ********************************************************/ -FwdState::FwdState(int fd, StoreEntry * e, HttpRequest * r) +FwdState::FwdState(Comm::ConnectionPointer &client, StoreEntry * e, HttpRequest * r) { entry = e; - client_fd = fd; + clientConn = client; request = HTTPMSGLOCK(r); start_t = squid_curtime; serverDestinations.reserve(Config.forward_max_tries); @@ -187,7 +187,7 @@ FwdState::~FwdState() * allocate a FwdState. */ void -FwdState::fwdStart(int client_fd, StoreEntry *entry, HttpRequest *request) +FwdState::fwdStart(Comm::ConnectionPointer &clientConn, StoreEntry *entry, HttpRequest *request) { /** \note * client_addr == no_addr indicates this is an "internal" request @@ -245,7 +245,7 @@ FwdState::fwdStart(int client_fd, StoreEntry *entry, HttpRequest *request) return; case PROTO_CACHEOBJ: - CacheManager::GetInstance()->Start(client_fd, request, entry); + CacheManager::GetInstance()->Start(clientConn, request, entry); return; case PROTO_URN: @@ -253,7 +253,7 @@ FwdState::fwdStart(int client_fd, StoreEntry *entry, HttpRequest *request) return; default: - FwdState::Pointer fwd = new FwdState(client_fd, entry, request); + FwdState::Pointer fwd = new FwdState(clientConn, entry, request); fwd->start(fwd); return; } @@ -837,7 +837,7 @@ FwdState::connectStart() void FwdState::dispatch() { - debugs(17, 3, "fwdDispatch: FD " << client_fd << ": Fetching '" << RequestMethodStr(request->method) << " " << entry->url() << "'" ); + debugs(17, 3, HERE << clientConn << ": Fetching '" << RequestMethodStr(request->method) << " " << entry->url() << "'"); /* * Assert that server_fd is set. This is to guarantee that fwdState * is attached to something and will be deallocated when server_fd @@ -865,7 +865,7 @@ FwdState::dispatch() * original client request FD object. It is later used to forward * remote server's TOS in the response to the client in case of a MISS. */ - fde * clientFde = &fd_table[client_fd]; + fde * clientFde = &fd_table[clientConn->fd]; if (clientFde) { int tos = 1; int tos_len = sizeof(tos); diff --git a/src/forward.h b/src/forward.h index c310d63530..34eb3d0030 100644 --- a/src/forward.h +++ b/src/forward.h @@ -19,7 +19,7 @@ public: ~FwdState(); static void initModule(); - static void fwdStart(int fd, StoreEntry *, HttpRequest *); + static void fwdStart(Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *); void startConnectionOrFail(); void fail(ErrorState *err); void unregister(Comm::ConnectionPointer &conn); @@ -48,7 +48,7 @@ public: private: // hidden for safer management of self; use static fwdStart - FwdState(int fd, StoreEntry *, HttpRequest *); + FwdState(Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *); void start(Pointer aSelf); static void logReplyStatus(int tries, http_status status); @@ -72,7 +72,7 @@ public: private: Pointer self; ErrorState *err; - int client_fd; + Comm::ConnectionPointer clientConn; ///< a possibly open connection to the client. time_t start_t; int n_tries; int origin_tries; diff --git a/src/redirect.cc b/src/redirect.cc index 43c884a9bb..b3a5b503d0 100644 --- a/src/redirect.cc +++ b/src/redirect.cc @@ -36,6 +36,7 @@ #include "squid.h" #include "auth/UserRequest.h" #include "CacheManager.h" +#include "comm/Connection.h" #include "Store.h" #include "fde.h" #include "client_side_request.h" @@ -147,8 +148,8 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data) #if USE_SSL - if (!r->client_ident && conn != NULL) - r->client_ident = sslGetUserEmail(fd_table[conn->fd].ssl); + if (!r->client_ident && conn != NULL && Comm::IsConnOpen(conn->clientConn)) + r->client_ident = sslGetUserEmail(fd_table[conn->clientConn->fd].ssl); #endif diff --git a/src/stat.cc b/src/stat.cc index b92abc3f8a..da66b9e231 100644 --- a/src/stat.cc +++ b/src/stat.cc @@ -37,6 +37,7 @@ #include "StoreClient.h" #include "auth/UserRequest.h" #include "CacheManager.h" +#include "comm/Connection.h" #include "Store.h" #include "HttpRequest.h" #include "MemObject.h" @@ -1611,7 +1612,6 @@ statClientRequests(StoreEntry * s) dlink_node *i; ClientHttpRequest *http; StoreEntry *e; - int fd; char buf[MAX_IPSTRLEN]; for (i = ClientActiveRequests.head; i; i = i->next) { @@ -1622,7 +1622,7 @@ statClientRequests(StoreEntry * s) storeAppendPrintf(s, "Connection: %p\n", conn); if (conn != NULL) { - fd = conn->fd; + const int fd = conn->clientConn->fd; storeAppendPrintf(s, "\tFD %d, read %"PRId64", wrote %"PRId64"\n", fd, fd_table[fd].bytes_read, fd_table[fd].bytes_written); storeAppendPrintf(s, "\tFD desc: %s\n", fd_table[fd].desc); @@ -1667,8 +1667,8 @@ statClientRequests(StoreEntry * s) #if USE_SSL - if (!p && conn != NULL) - p = sslGetUserEmail(fd_table[conn->fd].ssl); + if (!p && conn != NULL && Comm::IsConnOpen(conn->clientConn)) + p = sslGetUserEmail(fd_table[conn->clientConn->fd].ssl); #endif diff --git a/src/tunnel.cc b/src/tunnel.cc index d12d9f515a..970388ced4 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -227,7 +227,7 @@ TunnelStateData::ReadServer(int fd, char *buf, size_t len, comm_err_t errcode, i TunnelStateData *tunnelState = (TunnelStateData *)data; assert (cbdataReferenceValid (tunnelState)); - assert(fd == tunnelState->server.conn->fd); + assert(errcode == COMM_ERR_CLOSING || fd == tunnelState->server.conn->fd); tunnelState->readServer(buf, len, errcode, xerrno); } @@ -579,7 +579,6 @@ tunnelStart(ClientHttpRequest * http, int64_t * size_ptr, int *status_ptr) TunnelStateData *tunnelState = NULL; ErrorState *err = NULL; int answer; - int client_fd = http->getConn()->fd; HttpRequest *request = http->request; char *url = http->uri; @@ -602,7 +601,7 @@ tunnelStart(ClientHttpRequest * http, int64_t * size_ptr, int *status_ptr) if (answer == 0) { err = errorCon(ERR_FORWARDING_DENIED, HTTP_FORBIDDEN, request); *status_ptr = HTTP_FORBIDDEN; - errorSend(client_fd, err); + errorSend(http->getConn()->clientConn->fd, err); return; } } @@ -619,13 +618,7 @@ tunnelStart(ClientHttpRequest * http, int64_t * size_ptr, int *status_ptr) tunnelState->request = HTTPMSGLOCK(request); tunnelState->server.size_ptr = size_ptr; tunnelState->status_ptr = status_ptr; - - /* TODO: when ClientHttpRequests is passing around the client Comm::Connection - * we can grab that instead of copying the FD and address details here */ - tunnelState->client.conn = new Comm::Connection; - tunnelState->client.conn->local = request->my_addr; - tunnelState->client.conn->remote = request->client_addr; - tunnelState->client.conn->fd = client_fd; + tunnelState->client.conn = http->getConn()->clientConn; comm_add_close_handler(tunnelState->client.conn->fd, tunnelClientClosed, diff --git a/src/urn.cc b/src/urn.cc index e96f2ad1df..b5a44825f0 100644 --- a/src/urn.cc +++ b/src/urn.cc @@ -256,7 +256,8 @@ UrnState::created(StoreEntry *newEntry) if (urlres_e->isNull()) { urlres_e = storeCreateEntry(urlres, urlres, request_flags(), METHOD_GET); sc = storeClientListAdd(urlres_e, this); - FwdState::fwdStart(-1, urlres_e, urlres_r); + Comm::ConnectionPointer nul; + FwdState::fwdStart(nul, urlres_e, urlres_r); } else { urlres_e->lock();