WCCP2 patch
We've had a couple of problems on our caches using WCCP2 + tproxy where the caches registered in a different order with the different WCCP services (traffic to the web server VS traffic from the web server). This resulted in the assignment algorithm sending traffic coming from a particular client to one cache, and the reply traffic to a different cache. My solution is to order the linked list of web caches in the WCCP2 code to ensure that each cache will be assigned the same has map regardless of when the cache registers with the router. I've attached the patch, which we're using in production. I'll commit it to head shortly unless there's any objections, and I'm not sure if it's worth applying to 2.6/2.7/3.0. Steven This message was sent using IMP, the Internet Messaging Program. Index: src/wccp2.c === RCS file: /cvsroot/squid/squid/src/wccp2.c,v retrieving revision 1.29 diff -u -u -r1.29 wccp2.c --- src/wccp2.c 26 Dec 2007 23:52:02 - 1.29 +++ src/wccp2.c 25 Jan 2008 01:10:55 - @@ -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,39 @@ } } +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) {
Re: WCCP2 patch
On Mon, 2008-01-28 at 21:00 +0900, Steven Wilton wrote: We've had a couple of problems on our caches using WCCP2 + tproxy where the caches registered in a different order with the different WCCP services (traffic to the web server VS traffic from the web server). This resulted in the assignment algorithm sending traffic coming from a particular client to one cache, and the reply traffic to a different cache. My solution is to order the linked list of web caches in the WCCP2 code to ensure that each cache will be assigned the same has map regardless of when the cache registers with the router. I've attached the patch, which we're using in production. I'll commit it to head shortly unless there's any objections, and I'm not sure if it's worth applying to 2.6/2.7/3.0. Please port and apply to Squid 3.HEAD, at least. You may want to add a comment that wccp2SortCacheList is doing bubble sort by IP address (if it is). Thanks a lot, Alex.
Re: WCCP2 patch
Hm, I think its now worth creating a Wiki article covering WCCPv2 issues and which ones have been solved. This is definitely one of those things that should be documented. Adrian On Mon, Jan 28, 2008, Steven Wilton wrote: We've had a couple of problems on our caches using WCCP2 + tproxy where the caches registered in a different order with the different WCCP services (traffic to the web server VS traffic from the web server). This resulted in the assignment algorithm sending traffic coming from a particular client to one cache, and the reply traffic to a different cache. My solution is to order the linked list of web caches in the WCCP2 code to ensure that each cache will be assigned the same has map regardless of when the cache registers with the router. I've attached the patch, which we're using in production. I'll commit it to head shortly unless there's any objections, and I'm not sure if it's worth applying to 2.6/2.7/3.0. Steven This message was sent using IMP, the Internet Messaging Program. Index: src/wccp2.c === RCS file: /cvsroot/squid/squid/src/wccp2.c,v retrieving revision 1.29 diff -u -u -r1.29 wccp2.c --- src/wccp2.c 26 Dec 2007 23:52:02 - 1.29 +++ src/wccp2.c 25 Jan 2008 01:10:55 - @@ -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,39 @@ } } +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) { -- - Xenion - http://www.xenion.com.au/ - VPS Hosting - Commercial Squid Support - - $25/pm entry-level VPSes w/ capped bandwidth charges available in WA -