From: hno <> Date: Tue, 19 Sep 2006 05:05:43 +0000 (+0000) Subject: Bug #1770: wccp2_weight directive X-Git-Tag: SQUID_3_0_PRE5~70 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f16fbc821da7fe7ea65333ff7832f18625de400b;p=thirdparty%2Fsquid.git Bug #1770: wccp2_weight directive The WCCP2 implementation was missing weighted assignment, useful when the farm is built from unequally powered servers. --- diff --git a/src/cf.data.pre b/src/cf.data.pre index 02aae2bc07..f72932a6b3 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.423 2006/09/03 18:47:18 serassio Exp $ +# $Id: cf.data.pre,v 1.424 2006/09/18 23:05:43 hno Exp $ # # # SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -4188,6 +4188,16 @@ DOC_START 'wccp2_service dynamic ' entry. DOC_END +NAME: wccp2_weight +TYPE: int +LOC: Config.Wccp2.weight +DEFAULT: 10000 +IFDEF: USE_WCCPv2 +DOC_START + Each cache server gets assigned a set of the destination + hash proportional to their weight. +DOC_END + NAME: wccp_address TYPE: address LOC: Config.Wccp.address diff --git a/src/structs.h b/src/structs.h index 62c2d4da82..15ba3ab5eb 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.548 2006/08/25 18:53:35 serassio Exp $ + * $Id: structs.h,v 1.549 2006/09/18 23:05:43 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -321,6 +321,7 @@ struct _SquidConfig struct IN_ADDR address; int forwarding_method; int return_method; + int weight; int rebuildwait; void *info; } diff --git a/src/wccp2.cc b/src/wccp2.cc index 5b9c5054eb..cfefee26ca 100644 --- a/src/wccp2.cc +++ b/src/wccp2.cc @@ -1,6 +1,6 @@ /* - * $Id: wccp2.cc,v 1.8 2006/09/15 20:49:49 serassio Exp $ + * $Id: wccp2.cc,v 1.9 2006/09/18 23:05:43 hno Exp $ * * DEBUG: section 80 WCCP Support * AUTHOR: Steven Wilton @@ -320,6 +320,8 @@ struct wccp2_cache_list_t struct IN_ADDR cache_ip; + int weight; + struct wccp2_cache_list_t *next; }; @@ -672,7 +674,7 @@ wccp2Init(void) memset(&wccp2_identity_info.cache_identity.buckets, '\0', sizeof(wccp2_identity_info.cache_identity.buckets)); - wccp2_identity_info.cache_identity.weight = htons(10000); + wccp2_identity_info.cache_identity.weight = htons(Config.Wccp2.weight); memset(&wccp2_identity_info.cache_identity.status, '\0', sizeof(wccp2_identity_info.cache_identity.status)); @@ -1281,7 +1283,7 @@ wccp2HandleUdp(int sock, void *not_used) /* Update the cache list */ cache_list_ptr->cache_ip = cache_address; - + cache_list_ptr->weight = ntohs(cache_identity->weight); cache_list_ptr->next = (wccp2_cache_list_t*) xcalloc(1, sizeof(struct wccp2_cache_list_t)); cache_list_ptr = cache_list_ptr->next; cache_list_ptr->next = NULL; @@ -1526,20 +1528,26 @@ wccp2AssignBuckets(void *voidnotused) saved_offset = offset; for (router_list_ptr = &service_list_ptr->router_list_head; router_list_ptr->next != NULL; router_list_ptr = router_list_ptr->next) { + unsigned long *weight = (unsigned long *)xcalloc(sizeof(*weight), ntohl(router_list_ptr->num_caches)); + unsigned long total_weight = 0; + int num_caches = ntohl(router_list_ptr->num_caches); + offset = saved_offset; /* Number of caches */ xmemcpy(&wccp_packet[offset], &router_list_ptr->num_caches, sizeof(router_list_ptr->num_caches)); offset += sizeof(router_list_ptr->num_caches); - if (ntohl(router_list_ptr->num_caches)) { - for (cache_list_ptr = &router_list_ptr->cache_list_head; cache_list_ptr->next; cache_list_ptr = cache_list_ptr->next) { + if (num_caches) { + int cache; + for (cache = 0, cache_list_ptr = &router_list_ptr->cache_list_head; cache_list_ptr->next; cache_list_ptr = cache_list_ptr->next, cache++) { /* add caches */ cache_address = (struct IN_ADDR *) &wccp_packet[offset]; xmemcpy(cache_address, &cache_list_ptr->cache_ip, sizeof(struct IN_ADDR)); - + total_weight += cache_list_ptr->weight << 12; + weight[cache] = cache_list_ptr->weight << 12; offset += sizeof(struct IN_ADDR); } } @@ -1549,13 +1557,40 @@ wccp2AssignBuckets(void *voidnotused) memset(buckets, '\0', WCCP_BUCKETS); - if (ntohl(router_list_ptr->num_caches) != 0) { - for (bucket_counter = 0; bucket_counter < WCCP_BUCKETS; bucket_counter++) { - buckets[bucket_counter] = (char) (bucket_counter % ntohl(router_list_ptr->num_caches)); - } - } - - offset += (WCCP_BUCKETS * sizeof(char)); + if (num_caches != 0) { + if (total_weight == 0) { + for (bucket_counter = 0; bucket_counter < WCCP_BUCKETS; bucket_counter++) { + buckets[bucket_counter] = (char) (bucket_counter % num_caches); + } + } else { + unsigned long *assigned = (unsigned long *)xcalloc(sizeof(*assigned), num_caches); + unsigned long done = 0; + int cache = -1; + unsigned long per_bucket = total_weight / WCCP_BUCKETS; + for (bucket_counter = 0; bucket_counter < WCCP_BUCKETS; bucket_counter++) { + int n; + unsigned long step; + for (n = num_caches; n; n--) { + cache++; + if (cache >= num_caches) + cache = 0; + if (!weight[cache]) { + n++; + continue; + } + if (assigned[cache] <= done) + break; + } + buckets[bucket_counter] = (char)cache; + step = per_bucket * total_weight / weight[cache]; + assigned[cache] += step; + done += per_bucket; + } + safe_free(assigned); + } + } + offset += (WCCP_BUCKETS * sizeof(char)); + safe_free(weight); /* Fill in length */