diff -Nru squid-2.6-DEVEL-20020122/include/slist.h squid-2.6-DEVEL-20020122-fixed/include/slist.h --- squid-2.6-DEVEL-20020122/include/slist.h Thu Jan 1 10:00:00 1970 +++ squid-2.6-DEVEL-20020122-fixed/include/slist.h Wed Jan 23 15:44:13 2002 @@ -0,0 +1,70 @@ +/* + * + * AUTHOR: Jean-Francois Dive + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +/* + * slist is a basic sorted linked list, using uint32_t as a key and void* as + * data ptr. + */ + + +#ifndef SQUID_SLIST_H +#define SQUID_SLIST_H + +#include "util.h" + +/* + * This code assume : + * -> The "public interface" is limited to: + * - addNode; + * - firstNode; + * - nextNode; + * - printNode; + * - purgeNodes; + */ +struct _node +{ + uint32_t key; + void *ptr; + struct _node *next; +}; +typedef struct _node node; +typedef node *pnode; + +extern pnode sfindSortedNode(pnode root, uint32_t key); +extern pnode saddNode(pnode * pRoot, uint32_t key, void *ptr); +extern pnode snextNode(pnode root, uint32_t key); +extern void sfindNodes(pnode root, uint32_t key); +extern void sdeleteNode(pnode root, uint32_t key); +extern void spurgeNodes(pnode root); +extern void sinitNodes(pnode * pRoot); + +#endif diff -Nru squid-2.6-DEVEL-20020122/lib/Makefile.am squid-2.6-DEVEL-20020122-fixed/lib/Makefile.am --- squid-2.6-DEVEL-20020122/lib/Makefile.am Thu Nov 22 10:47:12 2001 +++ squid-2.6-DEVEL-20020122-fixed/lib/Makefile.am Wed Jan 23 15:17:34 2002 @@ -31,6 +31,7 @@ getfullhostname.c \ hash.c \ heap.c \ + slist.c \ html_quote.c \ iso3307.c \ $(MD5SOURCE) \ diff -Nru squid-2.6-DEVEL-20020122/lib/slist.c squid-2.6-DEVEL-20020122-fixed/lib/slist.c --- squid-2.6-DEVEL-20020122/lib/slist.c Thu Jan 1 10:00:00 1970 +++ squid-2.6-DEVEL-20020122-fixed/lib/slist.c Wed Jan 23 15:44:23 2002 @@ -0,0 +1,158 @@ +/* + * + * AUTHOR: Jean-Francois Dive + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is xfree software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +/* + * slist is a basic sorted linked list, using uint32_t as a key and void* as + * data ptr. + */ + + +#include "slist.h" + +/* + * Add a node to the list, sorting it's position + * return : + * NULL = mem allocation failure + * -1 = node already exist + * default = ptr to added node entry + */ +pnode +saddNode(pnode * pRoot, uint32_t key, void *ptr) +{ + pnode t = (pnode) xmalloc(sizeof(node)); + pnode root = *pRoot; + pnode i; + pnode x; + if (t == NULL) { + return t; + } + t->key = key; + t->ptr = ptr; + t->next = NULL; + if (root == NULL) { + *pRoot = t; + } else { + i = sfindSortedNode(root, key); + if ((int) i == -1) { /* key already exist */ + xfree(t); + return NULL; + } + if (i == NULL) { /* insertion before root */ + t->next = root; + *pRoot = t; + } else { + x = i->next; + i->next = t; + t->next = x; + } + } + return t; +} + +void +sinitNodes(pnode * pRoot) +{ + *pRoot = NULL; +} + +pnode +snextNode(pnode root, uint32_t key) +{ + pnode t = root; + for (t = root; t != NULL; t = t->next) { + if (key == t->key) + return t->next; + } + return NULL; +} + +void +spurgeNodes(pnode root) +{ + pnode t = root; + pnode x; + while (t != NULL) { + x = t->next; + xfree(t); + t = x; + } + root = NULL; +} + +pnode +sfindNode(pnode root, uint32_t key) +{ + pnode t = root; + for (t = root; t != NULL; t = t->next) { + if (key == t->key) + return t; + } + return NULL; +} + +void +sdeleteNode(pnode root, uint32_t key) +{ + pnode t = root; + pnode pPrev = root; + for (t = root; t != NULL; t = t->next) { + if (key == t->key) { + pPrev->next = t->next; + xfree(t); + return; + } + pPrev = t; + } +} + +/* + * Return the position to insert a new node by key + * Assume root != NULL + * return NULL is key < root->key + * return -1 if key already exist + */ +pnode +sfindSortedNode(pnode root, uint32_t key) +{ + pnode t = root; + pnode pPrev = root; + if (key < root->key) + return NULL; + for (t = root; t != NULL; t = t->next) { + if (key == t->key) + return (pnode) - 1; + if (key < t->key) + return pPrev; + pPrev = t; + } + return t; +} diff -Nru squid-2.6-DEVEL-20020122/src/client_db.c squid-2.6-DEVEL-20020122-fixed/src/client_db.c --- squid-2.6-DEVEL-20020122/src/client_db.c Sat Feb 24 07:59:50 2001 +++ squid-2.6-DEVEL-20020122-fixed/src/client_db.c Wed Jan 23 15:48:13 2002 @@ -34,11 +34,14 @@ */ #include "squid.h" +#include "slist.h" static hash_table *client_table = NULL; static ClientInfo *clientdbAdd(struct in_addr addr); static FREE clientdbFreeItem; +static pnode root = NULL; + static ClientInfo * clientdbAdd(struct in_addr addr) { @@ -48,6 +51,7 @@ c->addr = addr; hash_join(client_table, &c->hash); statCounter.client_http.clients++; + saddNode(&root,(uint32_t)addr.s_addr,(void*)c); return c; } @@ -57,6 +61,7 @@ if (client_table) return; client_table = hash_create((HASHCMP *) strcmp, 467, hash_string); + sinitNodes(&root); cachemgrRegister("client_list", "Cache Client List", clientdbDump, @@ -214,6 +219,7 @@ clientdbFreeItem(void *data) { ClientInfo *c = data; + sdeleteNode(root,(uint32_t)c->hash.key); safe_free(c->hash.key); memFree(c, MEM_CLIENT_INFO); } @@ -224,6 +230,7 @@ hashFreeItems(client_table, clientdbFreeItem); hashFreeMemory(client_table); client_table = NULL; + spurgeNodes(root); } #if SQUID_SNMP @@ -231,25 +238,19 @@ client_entry(struct in_addr *current) { ClientInfo *c = NULL; - char *key; + pnode t = NULL; if (current) { - key = inet_ntoa(*current); - hash_first(client_table); - while ((c = (ClientInfo *) hash_next(client_table))) { - if (!strcmp(key, hashKeyStr(&c->hash))) - break; - } - c = (ClientInfo *) hash_next(client_table); + t = snextNode(root,(uint32_t)current->s_addr); + if (t) + c = (ClientInfo*) t ->ptr; } else { - hash_first(client_table); - c = (ClientInfo *) hash_next(client_table); + if (root) + c = (ClientInfo*) root->ptr; } - hash_last(client_table); if (c) return (&c->addr); else return (NULL); - } variable_list *