From: wessels <> Date: Fri, 17 Jul 1998 07:02:22 +0000 (+0000) Subject: added initial CARP code X-Git-Tag: SQUID_3_0_PRE1~3058 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=afd88fbedace1d0b77b33ecb03c8243f4bc1df0e;p=thirdparty%2Fsquid.git added initial CARP code --- diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 47ee8a45fb..215f303b40 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -1,6 +1,6 @@ /* - * $Id: cache_cf.cc,v 1.287 1998/07/16 02:39:59 wessels Exp $ + * $Id: cache_cf.cc,v 1.288 1998/07/17 01:02:22 wessels Exp $ * * DEBUG: section 3 Configuration File Parsing * AUTHOR: Harvest Derived @@ -783,6 +783,13 @@ parse_peer(peer ** head) #endif } else if (!strncasecmp(token, "no-netdb-exchange", 17)) { EBIT_SET(p->options, NEIGHBOR_NO_NETDB_EXCHANGE); +#if USE_CARP + } else if (!strncasecmp(token, "carp-load-factor=", 17)) { + if (p->type != PEER_PARENT) + debug(3,0)("parse_peer: Ignoring carp-load-factor for non-parent %s/%d\n", p->host, p->http_port); + else + p->carp.load_factor = atof(token + 17); +#endif } else { debug(3, 0) ("parse_peer: token='%s'\n", token); self_destruct(); @@ -792,6 +799,16 @@ parse_peer(peer ** head) p->weight = 1; p->icp_version = ICP_VERSION_CURRENT; p->tcp_up = PEER_TCP_MAGIC_COUNT; +#if USE_CARP + if (p->carp.load_factor) { + /* + * calculate this peers hash for use in CARP + */ + p->carp.hash = 0; + for (token = p->host; *token != 0;token++) + p->carp.hash += (p->carp.hash << 19) + *token; + } +#endif cbdataAdd(p, MEM_NONE); while (*head != NULL) head = &(*head)->next; diff --git a/src/carp.cc b/src/carp.cc new file mode 100644 index 0000000000..3b101652a0 --- /dev/null +++ b/src/carp.cc @@ -0,0 +1,108 @@ +/* + * $Id: carp.cc,v 1.1 1998/07/17 01:02:24 wessels Exp $ + * + * DEBUG: section 44 Cache Array Routing Protocol + * AUTHOR: Eric Stern + * + * 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" + +#if USE_CARP + +void +carpInit(void) +{ + /* calculate load factors */ + int K = 0; + float a = 0.0; + float X; + float Xn; + float n; + int k; + peer *p; + for (p = Config.peers; p; p = p->next) { + a += p->carp.load_factor; + K++; + } + if (a == 0.0) + /* CARP load factors not configured */ + return; + /* + * sum of carp-load-factor's for all cache_peer's in squid.conf + * must equal 1.0 + */ + assert(a == 1.0); + k = 1; + n = 0; + Xn = 0; + for (p = Config.peers; p; p = p->next) { + X = pow(K * p->carp.load_factor, 1 / K); + if (Xn == 0) + Xn = X; + else + Xn *= X; + p->carp.load_multiplier = ((K - k + 1) * (p->carp.load_factor - n)) / Xn + ; + k++; + n = p->carp.load_factor; + } +} + +peer * +carpSelectParent(request_t * request) +{ + const char *c; + peer *p = NULL; + peer *tp; + unsigned long url_hash = 0; + unsigned long combined_hash; + unsigned long high_score = 0; + const char *url = urlCanonical(request); + /* calculate url hash */ + debug(44, 2) ("carpSelectParent: CARP Calculating hash for %s\n", url); + for (c = url; *c != 0; c++) + url_hash += (url_hash << 19) + *c; + /* select peer */ + for (tp = Config.peers; tp; tp = tp->next) { + if (p->carp.load_factor == 0.0) + continue; + assert(p->type == PEER_PARENT); + combined_hash = (url_hash ^ tp->carp.hash); + combined_hash += combined_hash * 0x62531965; + combined_hash = combined_hash << 21; + combined_hash = combined_hash * tp->carp.load_multiplier; + debug(44, 3) ("carpSelectParent: %s combined_hash %d\n", + tp->host, combined_hash); + if ((combined_hash > high_score) && neighborUp(tp)) { + p = tp; + high_score = combined_hash; + } + } + if (p) + debug(44, 3) ("carpSelectParent: selected CARP %s\n", p->host); + return p; +} +#endif diff --git a/src/enums.h b/src/enums.h index f73ca0c109..4c20a44652 100644 --- a/src/enums.h +++ b/src/enums.h @@ -291,6 +291,9 @@ typedef enum { #if USE_CACHE_DIGESTS CACHE_DIGEST_HIT, NO_CACHE_DIGEST_DIRECT, +#endif +#if USE_CARP + CARP, #endif HIER_MAX } hier_code; diff --git a/src/main.cc b/src/main.cc index d97b2fdc7a..d624dbb958 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,6 @@ /* - * $Id: main.cc,v 1.253 1998/07/06 19:18:30 wessels Exp $ + * $Id: main.cc,v 1.254 1998/07/17 01:02:25 wessels Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -342,6 +342,9 @@ serverConnectionsOpen(void) netdbInit(); asnInit(); peerSelectInit(); +#if USE_CARP + carpInit(); +#endif } void diff --git a/src/peer_select.cc b/src/peer_select.cc index 5ac5752e20..d503ccf863 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -1,6 +1,6 @@ /* - * $Id: peer_select.cc,v 1.69 1998/07/16 22:22:50 wessels Exp $ + * $Id: peer_select.cc,v 1.70 1998/07/17 01:02:26 wessels Exp $ * * DEBUG: section 44 Peer Selection Algorithm * AUTHOR: Duane Wessels @@ -51,6 +51,9 @@ const char *hier_strings[] = #if USE_CACHE_DIGESTS "CACHE_DIGEST_HIT", "NO_CACHE_DIGEST_DIRECT", +#endif +#if USE_CARP + "CARP", #endif "INVALID CODE" }; @@ -299,6 +302,12 @@ peerSelectFoo(ps_state * psstate) hierarchyNote(&request->hier, code, &psstate->icp, p->host); peerSelectCallback(psstate, p); return; +#endif +#if USE_CARP + } else if ((p = carpSelectParent(request))) { + hierarchyNote(&request->hier, CARP, &psstate->icp, p->host); + peerSelectCallback(psstate, p); + return; #endif } else if ((p = netdbClosestParent(request))) { request->hier.alg = PEER_SA_NETDB; diff --git a/src/protos.h b/src/protos.h index 1039884dc9..4a61c503ab 100644 --- a/src/protos.h +++ b/src/protos.h @@ -1010,6 +1010,12 @@ extern int internalStaticCheck(const char *urlpath); extern char *internalLocalUri(const char *dir, const char *name); extern char *internalRemoteUri(const char *, u_short, const char *, const char *); +#if USE_CARP +extern void carpInit(void); +extern peer * carpSelectParent(request_t *); +#endif + + /* * prototypes for system functions missing from system includes */ diff --git a/src/structs.h b/src/structs.h index f9e98b05f4..a3b4eb966c 100644 --- a/src/structs.h +++ b/src/structs.h @@ -935,6 +935,13 @@ struct _peer { int rr_count; peer *next; int test_fd; +#if USE_CARP + struct { + unsigned long hash; + unsigned long load_multiplier; + float load_factor; + } carp; +#endif }; struct _net_db_name {