--- squid-icap-2.5-200409161544.orig/src/cache_cf.c Wed Aug 4 21:47:58 2004 +++ squid-icap-2.5-200409161544/src/cache_cf.c Tue Sep 28 15:44:03 2004 @@ -2299,13 +2299,27 @@ */ static void -icap_service_list_add(icap_service_list ** isl, icap_service * service) +icap_service_list_add(icap_service_list ** isl, char * service_name) { icap_service_list **iter; icap_service_list *new; + icap_service *gbl_service; + int i; + int max_services; new = memAllocate(MEM_ICAP_SERVICE_LIST); - new->service = service; + /* Found all services with that name, and add to the array */ + max_services = sizeof(new->services)/sizeof(icap_service *); + gbl_service = Config.icapcfg.service_head; + i=0; + while(gbl_service && i < max_services) { + if (!strcmp(service_name, gbl_service->name)) { + new->services[i++] = gbl_service; + break; + } + gbl_service = gbl_service->next; + } + new->nservices = i; if (*isl) { iter = isl; @@ -2400,7 +2414,7 @@ for (iter = c->services; iter; iter = iter->next) { service = icap_service_lookup(iter->key); if (service) { - icap_service_list_add(&isl, service); + icap_service_list_add(&isl, iter->key); } else { debug(3, 0) ("icap_class_process (line %d): skipping service %s in class %s\n", config_lineno, iter->key, c->name); } @@ -2493,7 +2507,9 @@ c->hidden = 1; wordlistAdd(&c->services, A->service_name); c->isl = memAllocate(MEM_ICAP_SERVICE_LIST); - c->isl->service = s; + /* FIXME:luc: check what access do */ + c->isl->services[0] = s; + c->isl->nservices = 1; icap_class_add(c); A->class = c; } else { @@ -2592,7 +2608,9 @@ printf(" %s: \n", c_iter->name); printf(" services = \n"); for (isl_iter = c_iter->isl; isl_iter; isl_iter = isl_iter->next) { - printf(" %s\n", isl_iter->service->name); + int i; + for (i = 0; i < isl_iter->nservices; i++) + printf(" %s\n", isl_iter->services[i]->name); } } debug(3, 0) ("IcapConfig: access =\n"); --- squid-icap-2.5-200409161544.orig/src/icap_common.c Sat Apr 3 23:12:55 2004 +++ squid-icap-2.5-200409161544/src/icap_common.c Tue Sep 28 15:36:03 2004 @@ -140,6 +140,8 @@ icapService(icap_service_t type, request_t * r) { icap_service_list *isl_iter; + int is_iter; + debug(81, 8) ("icapService: type=%s\n", icapServiceToStr(type)); if (NULL == r) { debug(81, 8) ("icapService: no request_t\n"); @@ -150,10 +152,27 @@ return NULL; } for (isl_iter = r->class->isl; isl_iter; isl_iter = isl_iter->next) { - if (type == isl_iter->service->type) { - debug(81, 8) ("icapService: found service %s\n", isl_iter->service->name); - return isl_iter->service; - } + /* TODO:luc: Do a round-robin, choose a random value ? + * For now, we use a simple round robin with checking is the + * icap server is available */ + is_iter = isl_iter->last_service_used; + do + { + is_iter = (is_iter + 1) % isl_iter->nservices; + debug(81, 9) ("icapService: checking service %s/id=%d\n",isl_iter->services[is_iter]->name,is_iter); + if (type == isl_iter->services[is_iter]->type) + { + if (!isl_iter->services[is_iter]->unreachable) + { + debug(81, 8) ("icapService: found service %s/id=%d\n", isl_iter->services[is_iter]->name,is_iter); + isl_iter->last_service_used = is_iter; + return isl_iter->services[is_iter]; + } + debug(81, 8) ("icapService: found service %s/id=%d, but it's unreachable. I don't want to use it\n", isl_iter->services[is_iter]->name,is_iter); + /* FIXME:luc: in response mod, if we return an NULL pointer, user can bypass + * the filter, is it normal ? */ + } + } while (is_iter != isl_iter->last_service_used); } debug(81, 8) ("icapService: no service found\n"); return NULL; --- squid-icap-2.5-200409161544.orig/src/structs.h Wed Aug 4 21:48:08 2004 +++ squid-icap-2.5-200409161544/src/structs.h Tue Sep 28 13:05:08 2004 @@ -1085,7 +1085,9 @@ struct _icap_service_list { icap_service_list *next; - icap_service *service; + icap_service *services[16]; + int nservices; /* Number of services already used */ + int last_service_used; /* Last services used, use to do a round robin */ }; struct _icap_class {