From: wessels <> Date: Wed, 26 Feb 1997 10:08:52 +0000 (+0000) Subject: adding X-Git-Tag: SQUID_3_0_PRE1~5069 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=062e22812e0e6cd28169be778b8a06ec7e99b1ad;p=thirdparty%2Fsquid.git adding --- diff --git a/src/peer_select.cc b/src/peer_select.cc new file mode 100644 index 0000000000..f9ebcdc089 --- /dev/null +++ b/src/peer_select.cc @@ -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; +}