]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/FwdState.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / FwdState.cc
index 935837da22e32a83ad51f4804126ab65adf83eed..8397fe443575eb5ecbebdc1be83cb4a714e3a846 100644 (file)
@@ -1,35 +1,13 @@
 /*
- * DEBUG: section 17    Request Forwarding
- * AUTHOR: Duane Wessels
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; see the CREDITS file for full details.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
  *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
+/* DEBUG: section 17    Request Forwarding */
+
 #include "squid.h"
 #include "AccessLogEntry.h"
 #include "acl/AclAddress.h"
@@ -39,6 +17,7 @@
 #include "CacheManager.h"
 #include "CachePeer.h"
 #include "client_side.h"
+#include "clients/forward.h"
 #include "comm/Connection.h"
 #include "comm/ConnOpener.h"
 #include "comm/Loops.h"
@@ -47,8 +26,6 @@
 #include "event.h"
 #include "fd.h"
 #include "fde.h"
-#include "ftp.h"
-#include "FtpGatewayServer.h"
 #include "FwdState.h"
 #include "globals.h"
 #include "gopher.h"
@@ -94,7 +71,7 @@ static OBJH fwdStats;
 #define MAX_FWD_STATS_IDX 9
 static int FwdReplyCodes[MAX_FWD_STATS_IDX + 1][Http::scInvalidHeader + 1];
 
-static PconnPool *fwdPconnPool = new PconnPool("server-side", NULL);
+static PconnPool *fwdPconnPool = new PconnPool("server-peers", NULL);
 CBDATA_CLASS_INIT(FwdState);
 
 #if USE_OPENSSL
@@ -104,7 +81,7 @@ public:
     typedef void (FwdState::*Method)(Ssl::PeerConnectorAnswer &);
 
     FwdStatePeerAnswerDialer(Method method, FwdState *fwd):
-            method_(method), fwd_(fwd), answer_() {}
+        method_(method), fwd_(fwd), answer_() {}
 
     /* CallDialer API */
     virtual bool canDial(AsyncCall &call) { return fwd_.valid(); }
@@ -150,7 +127,7 @@ FwdState::closeServerConnection(const char *reason)
 /**** PUBLIC INTERFACE ********************************************************/
 
 FwdState::FwdState(const Comm::ConnectionPointer &client, StoreEntry * e, HttpRequest * r, const AccessLogEntryPointer &alp):
-        al(alp)
+    al(alp)
 {
     debugs(17, 2, HERE << "Forwarding client request " << client << ", url=" << e->url() );
     entry = e;
@@ -243,6 +220,8 @@ FwdState::completed()
 
     flags.forward_completed = true;
 
+    request->hier.stopPeerClock(false);
+
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
         debugs(17, 3, HERE << "entry aborted");
         return ;
@@ -341,7 +320,7 @@ FwdState::Start(const Comm::ConnectionPointer &clientConn, StoreEntry *entry, Ht
                 page_id = ERR_FORWARDING_DENIED;
 
             ErrorState *anErr = new ErrorState(page_id, Http::scForbidden, request);
-            errorAppendEntry(entry, anErr);    // frees anErr
+            errorAppendEntry(entry, anErr); // frees anErr
             return;
         }
     }
@@ -361,7 +340,7 @@ FwdState::Start(const Comm::ConnectionPointer &clientConn, StoreEntry *entry, Ht
     if (shutting_down) {
         /* more yuck */
         ErrorState *anErr = new ErrorState(ERR_SHUTTING_DOWN, Http::scServiceUnavailable, request);
-        errorAppendEntry(entry, anErr);        // frees anErr
+        errorAppendEntry(entry, anErr); // frees anErr
         return;
     }
 
@@ -468,7 +447,7 @@ FwdState::unregister(Comm::ConnectionPointer &conn)
     serverConn = NULL;
 }
 
-// Legacy method to be removed in favor of the above as soon as possible
+// \deprecated use unregister(Comm::ConnectionPointer &conn) instead
 void
 FwdState::unregister(int fd)
 {
@@ -478,7 +457,7 @@ FwdState::unregister(int fd)
 }
 
 /**
- * server-side modules call fwdComplete() when they are done
+ * FooClient modules call fwdComplete() when they are done
  * downloading an object.  Then, we either 1) re-forward the
  * request somewhere else if needed, or 2) call storeComplete()
  * to finish it off
@@ -524,7 +503,7 @@ FwdState::complete()
 /**** CALLBACK WRAPPERS ************************************************************/
 
 static void
-fwdPeerSelectionCompleteWrapper(Comm::ConnectionList * unused, ErrorState *err, void *data)
+fwdPeerSelectionCompleteWrapper(Comm::ConnectionList *, ErrorState *err, void *data)
 {
     FwdState *fwd = (FwdState *) data;
     if (err)
@@ -553,7 +532,7 @@ fwdConnectDoneWrapper(const Comm::ConnectionPointer &conn, Comm::Flag status, in
  *
  * Return TRUE if the request SHOULD be retried.  This method is
  * called when the HTTP connection fails, or when the connection
- * is closed before server-side read the end of HTTP headers.
+ * is closed before reading the end of HTTP headers from the server.
  */
 bool
 FwdState::checkRetry()
@@ -644,12 +623,14 @@ FwdState::retryOrBail()
     // TODO: should we call completed() here and move doneWithRetries there?
     doneWithRetries();
 
+    request->hier.stopPeerClock(false);
+
     if (self != NULL && !err && shutting_down) {
         ErrorState *anErr = new ErrorState(ERR_SHUTTING_DOWN, Http::scServiceUnavailable, request);
         errorAppendEntry(entry, anErr);
     }
 
-    self = NULL;       // refcounted
+    self = NULL;    // refcounted
 }
 
 // If the Server quits before nibbling at the request body, the body sender
@@ -713,22 +694,16 @@ FwdState::connectDone(const Comm::ConnectionPointer &conn, Comm::Flag status, in
             // Use positive timeout when less than one second is left.
             const time_t sslNegotiationTimeout = max(static_cast<time_t>(1), timeLeft());
             Ssl::PeerConnector *connector =
-                new Ssl::PeerConnector(requestPointer, serverConnection(), callback, sslNegotiationTimeout);
+                new Ssl::PeerConnector(requestPointer, serverConnection(), clientConn, callback, sslNegotiationTimeout);
             AsyncJob::Start(connector); // will call our callback
             return;
         }
     }
 #endif
 
-    const CbcPointer<ConnStateData> &clientConnState =
-        request->clientConnectionManager;
-    if (clientConnState.valid() && clientConnState->isFtp) {
-        // this is not an idle connection, so we do not want I/O monitoring
-        const bool monitor = false;
-        clientConnState->pinConnection(serverConnection(), request,
-                                       serverConnection()->getPeer(), false,
-                                       monitor);
-    }
+    // should reach ConnStateData before the dispatched Client job starts
+    CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData,
+                 ConnStateData::notePeerConnection, serverConnection());
 
     dispatch();
 }
@@ -805,8 +780,7 @@ FwdState::connectStart()
 
     debugs(17, 3, "fwdConnectStart: " << entry->url());
 
-    if (!request->hier.first_conn_start.tv_sec) // first attempt
-        request->hier.first_conn_start = current_time;
+    request->hier.startPeerClock();
 
     if (serverDestinations[0]->getPeer() && request->flags.sslBumped) {
         debugs(50, 4, "fwdConnectStart: Ssl bumped connections through parent proxy are not allowed");
@@ -831,7 +805,6 @@ FwdState::connectStart()
             pinned_connection->stopPinnedConnectionMonitoring();
             flags.connected_okay = true;
             ++n_tries;
-            request->hier.note(serverConn, request->GetHost());
             request->flags.pinned = true;
             request->hier.note(serverConn, pinned_connection->pinning.host);
             if (pinned_connection->pinnedAuth())
@@ -1007,10 +980,10 @@ FwdState::dispatch()
             break;
 
         case AnyP::PROTO_FTP:
-            if (request->clientConnectionManager->isFtp)
-                ftpGatewayServerStart(this);
+            if (request->flags.ftpNative)
+                Ftp::StartRelay(this);
             else
-                ftpStart(this);
+                Ftp::StartGateway(this);
             break;
 
         case AnyP::PROTO_CACHE_OBJECT:
@@ -1023,7 +996,7 @@ FwdState::dispatch()
             whoisStart(this);
             break;
 
-        case AnyP::PROTO_WAIS: /* Not implemented */
+        case AnyP::PROTO_WAIS:  /* Not implemented */
 
         default:
             debugs(17, DBG_IMPORTANT, "WARNING: Cannot retrieve '" << entry->url() << "'.");
@@ -1044,7 +1017,7 @@ FwdState::dispatch()
  *
  * returns TRUE if the transaction SHOULD be re-forwarded to the
  * next choice in the serverDestinations list.  This method is called when
- * server-side communication completes normally, or experiences
+ * peer communication completes normally, or experiences
  * some error after receiving the end of HTTP headers.
  */
 int
@@ -1330,3 +1303,4 @@ GetMarkingsToServer(HttpRequest * request, Comm::Connection &conn)
     conn.nfmark = 0;
 #endif
 }
+