]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Roll Comm::Connection into client-facing
authorAmos Jeffries <squid3@treenet.co.nz>
Fri, 27 Aug 2010 09:08:48 +0000 (21:08 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Fri, 27 Aug 2010 09:08:48 +0000 (21:08 +1200)
19 files changed:
src/CacheManager.h
src/acl/Asn.cc
src/acl/FilledChecklist.cc
src/auth/UserRequest.cc
src/cache_manager.cc
src/client_side.cc
src/client_side.h
src/client_side_reply.cc
src/client_side_request.cc
src/comm.cc
src/comm.h
src/comm/Connection.h
src/external_acl.cc
src/forward.cc
src/forward.h
src/redirect.cc
src/stat.cc
src/tunnel.cc
src/urn.cc

index 975c96617b6155955ee7e55b51c580a894c6380c..6bc205227a7c38a1f2c209ba221b6bffa7afc083 100644 (file)
@@ -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);
index 8b6f8419d259869f71ac6d920d46556b20cbf4e3..f33b0b5d6e6fccff41a448c94c6878d1528d3269 100644 (file)
@@ -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();
index 72ec05750b18d4e4b4087e509d09915bae44d598..a5c81d2cd4fb3dbb2a5c452cc76d1965e450123c 100644 (file)
@@ -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;
 }
 
index 608574a015bcdd0573a1aadf359a8695de32ab61..29815f9f377fd8895475acb53bc33dce3c2c4f2f 100644 (file)
 #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);
index 23ae897b8bcbb6f9307401b249d1a24ff2c9bc28..d8d03a14e567fdb6edcd0a87e2fa67d2ba366e3a 100644 (file)
@@ -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 : "<unknown>") << "@" <<
-                   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 : "<unknown>") << "@" <<
-                   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 : "<unknown>") << "@" <<
-           fd_table[fd].ipaddr << " requesting '" <<
+           client << " requesting '" <<
            mgr->action << "'" );
     /* retrieve object requested */
     a = findAction(mgr->action);
index 99058b656fb5d8b83ecf6cfb579d0a860ba3bfdd..22919f60f04978167ec8ad280f20fee230846d07 100644 (file)
@@ -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<ConnStateData, CommIoCbParams> 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<ClientSocketContext *>(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<ConnStateData, CommTimeoutCbParams> 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<ConnStateData, CommCloseCbParams> 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<ConnStateData, CommTimeoutCbParams> 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<ConnStateData, CommCloseCbParams> 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<ConnStateData, CommTimeoutCbParams> 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<ConnStateData, CommCloseCbParams> Dialer;
index e9fd1682bd625a0d03a896cda8da32951249995f..c4c4adfe0a65d0b95e45c46288ec616f5702e987 100644 (file)
@@ -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;
index a32d7e40a235e3ef0f8a63be6798e15065d05c90..94987545dc1180fc2aebb08cc6ee3926b7713265 100644 (file)
@@ -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="<<tos);
         }
-        comm_set_tos(fd,tos);
+        comm_set_tos(conn->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
index 90aa7fcbe81bea3ce5b634e1ca9a13a339f5fd88..0f886035e7249f15b069096d0ad8f9f0bd47af2e 100644 (file)
@@ -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);
         }
     }
 
index e392dc57f0cffb7202efef5b70e5191a6ba58761..1e2ddb4d0d2f5b235a57718f56fdefb0be4ab675 100644 (file)
@@ -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);
         }
     }
 }
index ffc7fd33d4749d48ae58bd737173e5c9868ee0e5..fdcd4df84133f39988592475f055703638d53061 100644 (file)
@@ -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
index da1b651cff0f4064226bc874afbb307078126cc6..9838a099ab4c2bee792c189da62de6b9665e950d 100644 (file)
 #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 <iosfwd>
+#endif
+#if HAVE_OSTREAM
+#include <ostream>
+#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
index 5808ec5ca757f5f480cd5558ec7b7747873a915b..61018a0bda1397d7c88401eef6a4b3b1e0d83587 100644 (file)
@@ -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);
index b04ebf6f558d96e85fc167d0c77bcb7541b5b1bf..e81260d4d0778e13be420ee2e92aaacab8bae44b 100644 (file)
@@ -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);
index c310d6353047d5c6f4ec8325d3bcc48764080e79..34eb3d0030440f19e899b5b384eb9201a97cb6f0 100644 (file)
@@ -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;
index 43c884a9bb5637d86114429cac39332de87b5e95..b3a5b503d09c55080e661146b30073838ea8bca0 100644 (file)
@@ -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
 
index b92abc3f8ab49191566b63292fb29435f97aaa3e..da66b9e23103765a520705acc5d4261c66ec1e56 100644 (file)
@@ -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
 
index d12d9f515a021e409e0bbe0404cf459fd304684e..970388ced4932d4407670903459b62aaf3722f24 100644 (file)
@@ -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,
index e96f2ad1df998e37d5375463833f9c4300f5ed79..b5a44825f02d8ce3670dc3254c262f411914b301 100644 (file)
@@ -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();