]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
adding
authorwessels <>
Wed, 26 Feb 1997 10:08:52 +0000 (10:08 +0000)
committerwessels <>
Wed, 26 Feb 1997 10:08:52 +0000 (10:08 +0000)
src/peer_select.cc [new file with mode: 0644]

diff --git a/src/peer_select.cc b/src/peer_select.cc
new file mode 100644 (file)
index 0000000..f9ebcdc
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * $Id: peer_select.cc,v 1.1 1997/02/26 03:08:52 wessels Exp $
+ *
+ * DEBUG: section 44    Peer Selection Algorithm
+ * AUTHOR: Duane Wessels
+ *
+ * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
+ * --------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from the
+ *  Internet community.  Development is led by Duane Wessels of the
+ *  National Laboratory for Applied Network Research and funded by
+ *  the National Science Foundation.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  
+ */
+
+#include "squid.h"
+
+#define OUTSIDE_FIREWALL 0
+#define INSIDE_FIREWALL  1
+#define NO_FIREWALL      2
+
+/* for debugging */
+static char *firewall_desc_str[] =
+{
+    "OUTSIDE_FIREWALL",
+    "INSIDE_FIREWALL",
+    "NO_FIREWALL"
+};
+
+int
+matchIpList(const ipcache_addrs * ia, ip_acl * ip_list)
+{
+    int i;
+    if (ip_list == NULL)
+       return 0;
+    for (i = 0; i < ia->count; i++) {
+       if (ip_access_check(ia->in_addrs[i], ip_list) == IP_DENY)
+           return 1;
+    }
+    return 0;
+}
+
+static int
+matchLocalDomain(const char *host)
+{
+    const wordlist *s = NULL;
+    for (s = Config.local_domain_list; s; s = s->next) {
+       if (matchDomainName(s->key, host))
+           return 1;
+    }
+    return 0;
+}
+
+int
+peerSelectDirect(request_t * request)
+{
+    const ipcache_addrs *ia = ipcache_gethostbyname(request->host, 0);
+    if (ia && matchIpList(ia, Config.firewall_ip_list))
+       return DIRECT_MAYBE;    /* or DIRECT_YES */
+    if (!matchInsideFirewall(request->host))
+       return DIRECT_NO;
+    if (ia && matchIpList(ia, Config.local_ip_list))
+       return DIRECT_YES;
+    if (matchLocalDomain(request->host))
+       return DIRECT_YES;
+    if (ia == NULL)
+       return DIRECT_NO;
+    return DIRECT_MAYBE;
+}
+
+int
+peerSelectIcpPing(request_t * request, int direct, StoreEntry * entry)
+{
+    if (entry->ping_status != PING_NONE)
+       return 0;
+    if (direct == DIRECT_YES)
+       fatal_dump("direct == DIRECT_YES");
+    if (!BIT_TEST(entry->flag, HIERARCHICAL) && direct != DIRECT_NO)
+       return 0;
+    if (Config.singleParentBypass && !Config.sourcePing)
+       if (getSingleParent(request))
+           return 0;
+    if (BIT_TEST(entry->flag, KEY_PRIVATE) && !neighbors_do_private_keys)
+       if (direct != DIRECT_NO)
+           return 0;
+    return neighborsCount(request);
+}
+
+
+peer *
+peerGetSomeParent(request_t * request, hier_code * code)
+{
+    peer *p;
+    if (request->method == METHOD_CONNECT)
+       if ((p = Config.sslProxy)) {
+           *code = HIER_SSL_PARENT;
+           return p;
+       }
+    if (request->method != METHOD_GET)
+       if ((p = Config.passProxy)) {
+           *code = HIER_PASS_PARENT;
+           return p;
+       }
+    if ((p = getDefaultParent(request))) {
+       *code = HIER_DEFAULT_PARENT;
+       return p;
+    }
+    if ((p = getSingleParent(request))) {
+       *code = HIER_SINGLE_PARENT;
+       return p;
+    }
+    if ((p = getRoundRobinParent(request))) {
+       *code = HIER_ROUNDROBIN_PARENT;
+       return p;
+    }
+    if ((p = getFirstUpParent(request))) {
+       *code = HIER_FIRSTUP_PARENT;
+       return p;
+    }
+    return NULL;
+}
+
+void
+peerSelect(int fd, request_t * request, StoreEntry * entry)
+{
+    peer *p;
+    hier_code code;
+    int direct = peerSelectDirect(request);
+    debug(44,3,"peerSelect: '%s'\n", entry->url);
+    if (direct == DIRECT_YES) {
+        debug(44,3,"peerSelect: direct == DIRECT_YES --> HIER_DIRECT\n");
+       hierarchyNote(request, HIER_DIRECT, 0, request->host);
+       protoStart(fd, entry, NULL, request);
+       return;
+    }
+    if (peerSelectIcpPing(request, direct, entry)) {
+        debug(44,3,"peerSelect: Doing ICP pings\n");
+       /* call neighborUdpPing and start timeout routine */
+       if (neighborsUdpPing(request, entry)) {
+           entry->ping_status = PING_WAITING;
+           commSetSelect(fd,
+               COMM_SELECT_TIMEOUT,
+               (PF) getFromDefaultSource,
+               (void *) entry,
+               Config.neighborTimeout);
+           return;
+       }
+       debug_trap("peerSelect: neighborsUdpPing returned 0");
+    }
+    if ((p = peerGetSomeParent(request, &code))) {
+        debug(44,3,"peerSelect: Got some parent %s/%s\n",
+               hier_strings[code], p->host);
+       hierarchyNote(request, code, 0, p->host);
+       protoStart(fd, entry, p, request);
+    }
+}
+
+/*
+ * return 0 if the host is outside the firewall (no domains matched), and
+ * return 1 if the host is inside the firewall or no domains at all.
+ */
+int
+matchInsideFirewall(const char *host)
+{
+    const wordlist *s = Config.inside_firewall_list;
+    const char *key = NULL;
+    int result = NO_FIREWALL;
+    struct in_addr addr;
+    if (!s && !Config.firewall_ip_list)
+       /* no firewall goop, all hosts are "inside" the firewall */
+       return NO_FIREWALL;
+    for (; s; s = s->next) {
+       key = s->key;
+       if (!strcasecmp(key, "none"))
+           /* no domains are inside the firewall, all domains are outside */
+           return OUTSIDE_FIREWALL;
+       if (*key == '!') {
+           key++;
+           result = OUTSIDE_FIREWALL;
+       } else {
+           result = INSIDE_FIREWALL;
+       }
+       if (matchDomainName(key, host))
+           return result;
+    }
+    /* Check for dotted-quads */
+    if (Config.firewall_ip_list) {
+       if ((addr.s_addr = inet_addr(host)) != inaddr_none) {
+           if (ip_access_check(addr, Config.firewall_ip_list) == IP_DENY)
+               return INSIDE_FIREWALL;
+       }
+    }
+    /* all through the list and no domains matched, this host must
+     * not be inside the firewall, it must be outside */
+    return OUTSIDE_FIREWALL;
+}