]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/peer_select.cc
Author: Henrik Nordstrom <henrik@henriknordstrom.net>
[thirdparty/squid.git] / src / peer_select.cc
index b0e5008d9e11ceb6fb349cd2314b96b8f69649f2..7caf9c5ec5801bc4911b90b9de72d9265c58aca2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: peer_select.cc,v 1.149 2008/01/20 08:54:28 amosjeffries Exp $
+ * $Id$
  *
  * DEBUG: section 44    Peer Selection Algorithm
  * AUTHOR: Duane Wessels
  *  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.
 #include "Store.h"
 #include "ICP.h"
 #include "HttpRequest.h"
-#include "ACLChecklist.h"
+#include "acl/FilledChecklist.h"
 #include "htcp.h"
 #include "forward.h"
 #include "SquidTime.h"
-
-const char *hier_strings[] =
-    {
-        "NONE",
-        "DIRECT",
-        "SIBLING_HIT",
-        "PARENT_HIT",
-        "DEFAULT_PARENT",
-        "SINGLE_PARENT",
-        "FIRST_UP_PARENT",
-        "FIRST_PARENT_MISS",
-        "CLOSEST_PARENT_MISS",
-        "CLOSEST_PARENT",
-        "CLOSEST_DIRECT",
-        "NO_DIRECT_FAIL",
-        "SOURCE_FASTEST",
-        "ROUNDROBIN_PARENT",
+#include "icmp/net_db.h"
+
+const char *hier_strings[] = {
+    "NONE",
+    "DIRECT",
+    "SIBLING_HIT",
+    "PARENT_HIT",
+    "DEFAULT_PARENT",
+    "SINGLE_PARENT",
+    "FIRST_UP_PARENT",
+    "FIRST_PARENT_MISS",
+    "CLOSEST_PARENT_MISS",
+    "CLOSEST_PARENT",
+    "CLOSEST_DIRECT",
+    "NO_DIRECT_FAIL",
+    "SOURCE_FASTEST",
+    "ROUNDROBIN_PARENT",
 #if USE_CACHE_DIGESTS
-        "CD_PARENT_HIT",
-        "CD_SIBLING_HIT",
+    "CD_PARENT_HIT",
+    "CD_SIBLING_HIT",
 #endif
-        "CARP",
-        "ANY_PARENT",
-       "USERHASH",
-       "SOURCEHASH",
-        "INVALID CODE"
-    };
-
-static struct
-{
+    "CARP",
+    "ANY_PARENT",
+    "USERHASH",
+    "SOURCEHASH",
+    "INVALID CODE"
+};
+
+static struct {
     int timeouts;
 } PeerStats;
 
-static const char *DirectStr[] =
-    {
-        "DIRECT_UNKNOWN",
-        "DIRECT_NO",
-        "DIRECT_MAYBE",
-        "DIRECT_YES"
-    };
+static const char *DirectStr[] = {
+    "DIRECT_UNKNOWN",
+    "DIRECT_NO",
+    "DIRECT_MAYBE",
+    "DIRECT_YES"
+};
 
 static void peerSelectFoo(ps_state *);
 static void peerPingTimeout(void *data);
@@ -244,6 +242,7 @@ peerSelectCallback(ps_state * psstate)
 static int
 peerCheckNetdbDirect(ps_state * psstate)
 {
+#if USE_ICMP
     peer *p;
     int myrtt;
     int myhops;
@@ -251,12 +250,13 @@ peerCheckNetdbDirect(ps_state * psstate)
     if (psstate->direct == DIRECT_NO)
         return 0;
 
+    /* base lookup on RTT and Hops if ICMP NetDB is enabled. */
+
     myrtt = netdbHostRtt(psstate->request->GetHost());
 
     debugs(44, 3, "peerCheckNetdbDirect: MY RTT = " << myrtt << " msec");
     debugs(44, 3, "peerCheckNetdbDirect: minimum_direct_rtt = " << Config.minDirectRtt << " msec");
 
-
     if (myrtt && myrtt <= Config.minDirectRtt)
         return 1;
 
@@ -265,7 +265,6 @@ peerCheckNetdbDirect(ps_state * psstate)
     debugs(44, 3, "peerCheckNetdbDirect: MY hops = " << myhops);
     debugs(44, 3, "peerCheckNetdbDirect: minimum_direct_hops = " << Config.minDirectHops);
 
-
     if (myhops && myhops <= Config.minDirectHops)
         return 1;
 
@@ -279,6 +278,8 @@ peerCheckNetdbDirect(ps_state * psstate)
     if (myrtt && myrtt <= psstate->ping.p_rtt)
         return 1;
 
+#endif /* USE_ICMP */
+
     return 0;
 }
 
@@ -289,30 +290,36 @@ peerSelectFoo(ps_state * ps)
     HttpRequest *request = ps->request;
     debugs(44, 3, "peerSelectFoo: '" << RequestMethodStr(request->method) << " " << request->GetHost() << "'");
 
+    /** If we don't known whether DIRECT is permitted ... */
     if (ps->direct == DIRECT_UNKNOWN) {
         if (ps->always_direct == 0 && Config.accessList.AlwaysDirect) {
-            ps->acl_checklist = aclChecklistCreate(
-                                    Config.accessList.AlwaysDirect,
-                                    request,
-                                    NULL);             /* ident */
-            ps->acl_checklist->nonBlockingCheck(peerCheckAlwaysDirectDone,
-                                                ps);
+            /** check always_direct; */
+            ps->acl_checklist = new ACLFilledChecklist(
+                Config.accessList.AlwaysDirect,
+                request,
+                NULL);         /* ident */
+            ps->acl_checklist->nonBlockingCheck(peerCheckAlwaysDirectDone, ps);
             return;
         } else if (ps->always_direct > 0) {
+            /** if always_direct says YES, do that. */
             ps->direct = DIRECT_YES;
         } else if (ps->never_direct == 0 && Config.accessList.NeverDirect) {
-            ps->acl_checklist = aclChecklistCreate(
-                                    Config.accessList.NeverDirect,
-                                    request,
-                                    NULL);             /* ident */
+            /** check never_direct; */
+            ps->acl_checklist = new ACLFilledChecklist(
+                Config.accessList.NeverDirect,
+                request,
+                NULL);         /* ident */
             ps->acl_checklist->nonBlockingCheck(peerCheckNeverDirectDone,
                                                 ps);
             return;
         } else if (ps->never_direct > 0) {
+            /** if always_direct says NO, do that. */
             ps->direct = DIRECT_NO;
-        } else if (request->flags.accelerated) {
+        } else if (request->flags.no_direct) {
+            /** if we are accelerating, direct is not an option. */
             ps->direct = DIRECT_NO;
         } else if (request->flags.loopdetect) {
+            /** if we are in a forwarding-loop, direct is not an option. */
             ps->direct = DIRECT_YES;
         } else if (peerCheckNetdbDirect(ps)) {
             ps->direct = DIRECT_YES;
@@ -379,7 +386,7 @@ peerSelectPinned(ps_state * ps)
     if (!request->pinnedConnection())
         return;
     if (request->pinnedConnection()->validatePinnedConnection(request) != -1) {
-       peer = request->pinnedConnection()->pinnedPeer();
+        peer = request->pinnedConnection()->pinnedPeer();
         if (peer && peerAllowedToUse(peer, request)) {
             peerAddFwdServer(&ps->servers, peer, PINNED);
             if (ps->entry)
@@ -394,12 +401,12 @@ peerSelectPinned(ps_state * ps)
 
 /*
  * peerGetSomeNeighbor
- * 
+ *
  * Selects a neighbor (parent or sibling) based on one of the
  * following methods:
  *      Cache Digests
  *      CARP
- *      Netdb RTT estimates
+ *      ICMP Netdb RTT estimates
  *      ICP/HTCP queries
  */
 static void
@@ -438,9 +445,9 @@ peerGetSomeNeighbor(ps_state * ps)
 
             if (ps->ping.n_sent == 0)
                 debugs(44, 0, "WARNING: neighborsUdpPing returned 0");
-                debugs(44, 3, "peerSelect: " << ps->ping.n_replies_expected <<
-                       " ICP replies expected, RTT " << ps->ping.timeout <<
-                       " msec");
+            debugs(44, 3, "peerSelect: " << ps->ping.n_replies_expected <<
+                   " ICP replies expected, RTT " << ps->ping.timeout <<
+                   " msec");
 
 
             if (ps->ping.n_replies_expected > 0) {
@@ -465,7 +472,7 @@ peerGetSomeNeighbor(ps_state * ps)
 
 /*
  * peerGetSomeNeighborReplies
- * 
+ *
  * Selects a neighbor (parent or sibling) based on ICP/HTCP replies.
  */
 static void
@@ -486,8 +493,7 @@ peerGetSomeNeighborReplies(ps_state * ps)
 
     if ((p = ps->hit)) {
         code = ps->hit_type == PEER_PARENT ? PARENT_HIT : SIBLING_HIT;
-    } else
-    {
+    } else {
         if (!ps->closest_parent_miss.IsAnyAddr()) {
             p = whichPeer(ps->closest_parent_miss);
             code = CLOSEST_PARENT_MISS;
@@ -505,7 +511,7 @@ peerGetSomeNeighborReplies(ps_state * ps)
 
 /*
  * peerGetSomeDirect
- * 
+ *
  * Simply adds a 'direct' entry to the FwdServers list if this
  * request can be forwarded directly to the origin server
  */
@@ -517,7 +523,7 @@ peerGetSomeDirect(ps_state * ps)
 
     /* WAIS is not implemented natively */
     if (ps->request->protocol == PROTO_WAIS)
-       return;
+        return;
 
     peerAddFwdServer(&ps->servers, NULL, HIER_DIRECT);
 }
@@ -625,12 +631,12 @@ static void
 peerIcpParentMiss(peer * p, icp_common_t * header, ps_state * ps)
 {
     int rtt;
-    int hops;
 
+#if USE_ICMP
     if (Config.onoff.query_icmp) {
         if (header->flags & ICP_FLAG_SRC_RTT) {
             rtt = header->pad & 0xFFFF;
-            hops = (header->pad >> 16) & 0xFFFF;
+            int hops = (header->pad >> 16) & 0xFFFF;
 
             if (rtt > 0 && rtt < 0xFFFF)
                 netdbUpdatePeer(ps->request, p, rtt, hops);
@@ -641,6 +647,7 @@ peerIcpParentMiss(peer * p, icp_common_t * header, ps_state * ps)
             }
         }
     }
+#endif /* USE_ICMP */
 
     /* if closest-only is set, then don't allow FIRST_PARENT_MISS */
     if (p->options.closest_only)
@@ -699,9 +706,9 @@ static void
 peerHandleHtcpReply(peer * p, peer_t type, htcpReplyData * htcp, void *data)
 {
     ps_state *psstate = (ps_state *)data;
-    debugs(44, 3, "peerHandleHtcpReply: " << 
-                  (htcp->hit ? "HIT" : "MISS") << " " << 
-                  psstate->entry->url()  );
+    debugs(44, 3, "peerHandleHtcpReply: " <<
+           (htcp->hit ? "HIT" : "MISS") << " " <<
+           psstate->entry->url()  );
     psstate->ping.n_recv++;
 
     if (htcp->hit) {
@@ -724,12 +731,12 @@ static void
 peerHtcpParentMiss(peer * p, htcpReplyData * htcp, ps_state * ps)
 {
     int rtt;
-    int hops;
 
+#if USE_ICMP
     if (Config.onoff.query_icmp) {
         if (htcp->cto.rtt > 0) {
             rtt = (int) htcp->cto.rtt * 1000;
-            hops = (int) htcp->cto.hops * 1000;
+            int hops = (int) htcp->cto.hops * 1000;
             netdbUpdatePeer(ps->request, p, rtt, hops);
 
             if (rtt && (ps->ping.p_rtt == 0 || rtt < ps->ping.p_rtt)) {
@@ -738,6 +745,7 @@ peerHtcpParentMiss(peer * p, htcpReplyData * htcp, ps_state * ps)
             }
         }
     }
+#endif /* USE_ICMP */
 
     /* if closest-only is set, then don't allow FIRST_PARENT_MISS */
     if (p->options.closest_only)
@@ -781,9 +789,9 @@ static void
 peerAddFwdServer(FwdServer ** FSVR, peer * p, hier_code code)
 {
     FwdServer *fs = (FwdServer *)memAllocate(MEM_FWD_SERVER);
-    debugs(44, 5, "peerAddFwdServer: adding " << 
-                 (p ? p->host : "DIRECT")  << " " << 
-                 hier_strings[code]  );
+    debugs(44, 5, "peerAddFwdServer: adding " <<
+           (p ? p->host : "DIRECT")  << " " <<
+           hier_strings[code]  );
     fs->_peer = cbdataReference(p);
     fs->code = code;