From: swilton <> Date: Sat, 9 Feb 2008 10:48:05 +0000 (+0000) Subject: Author: Steven Wilton X-Git-Tag: BASIC_TPROXY4~131 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=264096e2b701430a0a517dff122bc2aaa4e6eb1a;p=thirdparty%2Fsquid.git Author: Steven Wilton Sort cache list in wccpv2 to ensure a consistent hash allocation across all serv ices Under some circumstances different caches were being allocated differnet hash assignments for different wccpv2 services. This caused problems when using TPROXY as the reply traffic was being sent to a different cache than the request causing problems in browsing web pages. This patch applied a selection sort algorithm to the cache list to ensure that as long as the same group of caches are registered for any number of wccpv2 services, they will be allocated the same hash assignments in the router. --- diff --git a/src/wccp2.cc b/src/wccp2.cc index 491ac92e53..f50b87340b 100644 --- a/src/wccp2.cc +++ b/src/wccp2.cc @@ -1,6 +1,6 @@ /* - * $Id: wccp2.cc,v 1.22 2008/02/05 22:39:42 amosjeffries Exp $ + * $Id: wccp2.cc,v 1.23 2008/02/09 03:48:05 swilton Exp $ * * DEBUG: section 80 WCCP Support * AUTHOR: Steven Wilton @@ -463,6 +463,7 @@ int empty_portlist[WCCP2_NUMPORTS] = /* END WCCP V2 */ void wccp2_add_service_list(int service, int service_id, int service_priority, int service_proto, int service_flags, int ports[], int security_type, char *password); +static void wccp2SortCacheList(struct wccp2_cache_list_t *head); /* * The functions used during startup: @@ -1495,6 +1496,8 @@ wccp2HandleUdp(int sock, void *not_used) num_caches = 1; } + wccp2SortCacheList(&router_list_ptr->cache_list_head); + router_list_ptr->num_caches = htonl(num_caches); if ((found == 1) && (service_list_ptr->lowest_ip == 1)) { @@ -2388,6 +2391,41 @@ dump_wccp2_service_info(StoreEntry * e, const char *label, void *v) } } +/* Sort the cache list by doing a "selection sort" by IP address */ +static void +wccp2SortCacheList(struct wccp2_cache_list_t *head) +{ + struct wccp2_cache_list_t tmp; + struct wccp2_cache_list_t *this_item; + struct wccp2_cache_list_t *find_item; + struct wccp2_cache_list_t *next_lowest; + + /* Go through each position in the list one at a time */ + for (this_item = head; this_item->next; this_item = this_item->next) { + /* Find the item with the lowest IP */ + next_lowest = this_item; + + for (find_item = this_item; find_item->next; find_item = find_item->next) { + if (find_item->cache_ip.s_addr < next_lowest->cache_ip.s_addr) { + next_lowest = find_item; + } + } + /* Swap if we need to */ + if (next_lowest != this_item) { + /* First make a copy of the current item */ + memcpy(&tmp, this_item, sizeof(struct wccp2_cache_list_t)); + + /* Next update the pointers to maintain the linked list */ + tmp.next = next_lowest->next; + next_lowest->next = this_item->next; + + /* Finally copy the updated items to their correct location */ + memcpy(this_item, next_lowest, sizeof(struct wccp2_cache_list_t)); + memcpy(next_lowest, &tmp, sizeof(struct wccp2_cache_list_t)); + } + } +} + void free_wccp2_service_info(void *v) {}