--------------------- PatchSet 11960 Date: 2008/02/23 01:46:25 Author: hno Branch: SQUID_2_6 Tag: (none) Log: 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. Members: src/wccp2.c:1.30.2.1->1.30.2.2 Index: squid/src/wccp2.c =================================================================== RCS file: /cvsroot/squid/squid/src/wccp2.c,v retrieving revision 1.30.2.1 retrieving revision 1.30.2.2 diff -u -r1.30.2.1 -r1.30.2.2 --- squid/src/wccp2.c 17 Apr 2007 09:40:59 -0000 1.30.2.1 +++ squid/src/wccp2.c 23 Feb 2008 01:46:25 -0000 1.30.2.2 @@ -1,6 +1,6 @@ /* - * $Id: wccp2.c,v 1.30.2.1 2007/04/17 09:40:59 hno Exp $ + * $Id: wccp2.c,v 1.30.2.2 2008/02/23 01:46:25 hno Exp $ * * DEBUG: section 80 WCCP Support * AUTHOR: Steven WIlton @@ -361,6 +361,7 @@ /* 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: @@ -1166,6 +1167,8 @@ found = 1; 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)) { @@ -1913,6 +1916,41 @@ } } +/* 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) {