From: hno <> Date: Sun, 7 Jan 2001 21:47:17 +0000 (+0000) Subject: proxy_auth and ident ACL types converted to use splay trees X-Git-Tag: SQUID_3_0_PRE1~1678 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0009ba2f8aec87c32717adcdb583880f6561cfa1;p=thirdparty%2Fsquid.git proxy_auth and ident ACL types converted to use splay trees this should make large user lists much more efficient. by Francesco Chemolli --- diff --git a/src/acl.cc b/src/acl.cc index 2a5592decf..a3b167de18 100644 --- a/src/acl.cc +++ b/src/acl.cc @@ -1,6 +1,6 @@ /* - * $Id: acl.cc,v 1.231 2001/01/05 09:51:36 adrian Exp $ + * $Id: acl.cc,v 1.232 2001/01/07 14:47:17 hno Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -41,6 +41,7 @@ static FILE *aclFile; static hash_table *proxy_auth_cache = NULL; static void aclParseDomainList(void *curlist); +static void aclParseProxyAuthList(void **current); static void aclParseIpList(void *curlist); static void aclParseIntlist(void *curlist); static void aclParseWordList(void *curlist); @@ -57,7 +58,7 @@ static struct _acl *aclFindByName(const char *name); static int aclMatchAcl(struct _acl *, aclCheck_t *); static int aclMatchIntegerRange(intrange * data, int i); static int aclMatchTime(acl_time_data * data, time_t when); -static int aclMatchUser(wordlist * data, const char *ident); +static int aclMatchUser(void *proxyauth_acl, char *user); static int aclMatchIp(void *dataptr, struct in_addr c); static int aclMatchDomainList(void *dataptr, const char *); static int aclMatchIntegerRange(intrange * data, int i); @@ -634,6 +635,48 @@ aclParseWordList(void *curlist) wordlistAdd(curlist, t); } +static void +aclParseProxyAuthList(void **current) +{ + char *t = NULL; + acl_proxy_auth_data *data; + splayNode *Top = NULL; + + debug(28, 2) ("aclParseProxyAuthList: parsing authlist\n"); + if (*current == NULL) { + debug(28, 3) ("aclParseProxyAuthList: current is null. Creating\n"); + *current = memAllocate(MEM_ACL_PROXY_AUTH_DATA); /*we rely on mA. zeroing */ + } + data = *current; + if ((t = strtokFile())) { + debug(28, 5) ("aclParseProxyAuthList: First token is %s\n", t); + if (strcmp("-i", t) == 0) { + debug(28, 5) ("aclParseProxyAuthList: Going case-insensitive\n"); + data->flags.case_insensitive = 1; + } else if (strcmp("REQUIRED", t) == 0) { + debug(28, 5) ("aclParseProxyAuthList: REQUIRED-type enabled\n"); + data->flags.required = 1; + } else { + if (data->flags.case_insensitive) + Tolower(t); + Top = splay_insert(xstrdup(t), Top, (SPLAYCMP *) strcmp); + } + } + debug(28, 3) ("aclParseProxyAuthList: Case-insensitive-switch is %d\n", + data->flags.case_insensitive); + /* we might inherit from a previous declaration */ + + debug(28, 4) ("aclParseProxyAuthList: parsing proxy-auth list\n"); + while ((t = strtokFile())) { + debug(28, 6) ("aclParseProxyAuthList: Got token: %s\n", t); + if (data->flags.case_insensitive) + Tolower(t); + Top = splay_insert(xstrdup(t), Top, (SPLAYCMP *) strcmp); + } + data->names = Top; +} + + /**********************/ /* aclParseDomainList */ /**********************/ @@ -745,7 +788,7 @@ aclParseAclLine(acl ** head) aclParseMethodList(&A->data); break; case ACL_PROXY_AUTH: - aclParseWordList(&A->data); + aclParseProxyAuthList(&A->data); if (!proxy_auth_cache) { /* First time around, 7921 should be big enough */ proxy_auth_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string); @@ -1009,20 +1052,33 @@ aclMatchRegex(relist * data, const char *word) } static int -aclMatchUser(wordlist * data, const char *user) +aclMatchUser(void *proxyauth_acl, char *user) { + acl_proxy_auth_data *data = (acl_proxy_auth_data *) proxyauth_acl; + splayNode *Top = data->names; + + debug(28, 7) ("aclMatchUser: user is %s, case_insensitive is %d\n", + user, data->flags.case_insensitive); + debug(28, 8) ("Top is %p, Top->data is %s\n", Top, + (Top != NULL ? (Top)->data : "Unavailable")); + if (user == NULL) return 0; - debug(28, 3) ("aclMatchUser: checking '%s'\n", user); - while (data) { - debug(28, 3) ("aclMatchUser: looking for '%s'\n", data->key); - if (strcmp(data->key, "REQUIRED") == 0 && *user != '\0' && strcmp(user, "-") != 0) - return 1; - if (strcmp(data->key, user) == 0) - return 1; - data = data->next; + + if (data->flags.case_insensitive) + Tolower(user); + + if (data->flags.required) { + debug(28, 7) ("aclMatchUser: user REQUIRED and auth-info present.\n"); + return 1; } - return 0; + Top = splay_splay(user, Top, (SPLAYCMP *) strcmp); + /* Top=splay_splay(user,Top,(SPLAYCMP *)dumping_strcmp); */ + debug(28, 7) ("aclMatchUser: returning %d,Top is %p, Top->data is %s\n", + !splayLastResult, + Top, (Top ? Top->data : "Unavailable")); + data->names = Top; + return !splayLastResult; } static int @@ -1892,6 +1948,15 @@ aclFreeIpData(void *p) memFree(p, MEM_ACL_IP_DATA); } +static void +aclFreeProxyAuthData(void *data) +{ + acl_proxy_auth_data *d = data; + splay_destroy(d->names, xfree); + memFree(d, MEM_ACL_PROXY_AUTH_DATA); +} + + void aclDestroyAcls(acl ** head) { @@ -1913,12 +1978,16 @@ aclDestroyAcls(acl ** head) break; #if SQUID_SNMP case ACL_SNMP_COMMUNITY: + wordlistDestroy((wordlist **) & a->data); + break; #endif #if USE_IDENT case ACL_IDENT: + wordlistDestroy((wordlist **) & a->data); + break; #endif case ACL_PROXY_AUTH: - wordlistDestroy((wordlist **) & a->data); + aclFreeProxyAuthData(a->data); break; case ACL_TIME: aclDestroyTimeList(a->data); @@ -2094,6 +2163,27 @@ aclIpNetworkCompare(const void *a, const void *b) return rc; } +static void +aclDumpProxyAuthListWalkee(void *node_data, void *outlist) +{ + /* outlist is really a wordlist ** */ + wordlistAdd(outlist, node_data); +} + +wordlist * +aclDumpProxyAuthList(acl_proxy_auth_data * data) +{ + wordlist *wl = NULL; + if ((data->flags.case_insensitive) != 0) + wordlistAdd(&wl, "-i"); + /* damn this is VERY inefficient for long ACL lists... filling + * a wordlist this way costs Sum(1,N) iterations. For instance + * a 1000-elements list will be filled in 499500 iterations. + */ + splay_walk(data->names, aclDumpProxyAuthListWalkee, &wl); + return wl; +} + static void aclDumpIpListWalkee(void *node, void *state) { @@ -2235,6 +2325,8 @@ aclDumpGeneric(const acl * a) break; #if SQUID_SNMP case ACL_SNMP_COMMUNITY: + return wordlistDup(a->data); + break; #endif #if USE_IDENT case ACL_IDENT: @@ -2245,7 +2337,7 @@ aclDumpGeneric(const acl * a) break; #endif case ACL_PROXY_AUTH: - return wordlistDup(a->data); + return aclDumpProxyAuthList(a->data); break; case ACL_TIME: return aclDumpTimeSpecList(a->data); diff --git a/src/enums.h b/src/enums.h index e4b63f0e91..2f00c510c4 100644 --- a/src/enums.h +++ b/src/enums.h @@ -1,6 +1,6 @@ /* - * $Id: enums.h,v 1.179 2001/01/06 11:45:46 hno Exp $ + * $Id: enums.h,v 1.180 2001/01/07 14:47:17 hno Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -517,6 +517,7 @@ typedef enum { MEM_ACL_IP_DATA, MEM_ACL_LIST, MEM_ACL_NAME_LIST, + MEM_ACL_PROXY_AUTH_DATA, MEM_ACL_PROXY_AUTH_USER, MEM_ACL_TIME_DATA, MEM_CACHEMGR_PASSWD, diff --git a/src/mem.cc b/src/mem.cc index 022f00e3d9..14ee3eb9bf 100644 --- a/src/mem.cc +++ b/src/mem.cc @@ -1,6 +1,6 @@ /* - * $Id: mem.cc,v 1.49 2000/10/17 08:06:04 adrian Exp $ + * $Id: mem.cc,v 1.50 2001/01/07 14:47:17 hno Exp $ * * DEBUG: section 13 High Level Memory Pool Management * AUTHOR: Harvest Derived @@ -204,6 +204,8 @@ memInit(void) memDataInit(MEM_ACL_LIST, "acl_list", sizeof(acl_list), 0); memDataInit(MEM_ACL_NAME_LIST, "acl_name_list", sizeof(acl_name_list), 0); memDataInit(MEM_ACL_TIME_DATA, "acl_time_data", sizeof(acl_time_data), 0); + memDataInit(MEM_ACL_PROXY_AUTH_DATA, "acl_proxy_auth_data", + sizeof(acl_proxy_auth_data), 0); memDataInit(MEM_ACL_PROXY_AUTH_USER, "acl_proxy_auth_user", sizeof(acl_proxy_auth_user), 0); memDataInit(MEM_CACHEMGR_PASSWD, "cachemgr_passwd", diff --git a/src/structs.h b/src/structs.h index ed20849b14..7d30c95d07 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.372 2001/01/05 03:58:18 wessels Exp $ + * $Id: structs.h,v 1.373 2001/01/07 14:47:17 hno Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -31,6 +31,9 @@ * */ +#include "config.h" +#include "splay.h" + struct _dlink_node { void *data; dlink_node *prev; @@ -42,6 +45,15 @@ struct _dlink_list { dlink_node *tail; }; +struct _acl_proxy_auth_data { + splayNode *names; + struct { + unsigned int case_insensitive:1; + unsigned int required:1; + } flags; +}; + + struct _acl_ip_data { struct in_addr addr1; /* if addr2 non-zero then its a range */ struct in_addr addr2; diff --git a/src/typedefs.h b/src/typedefs.h index 94f6a36c05..ca4675c05c 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.113 2001/01/05 09:51:41 adrian Exp $ + * $Id: typedefs.h,v 1.114 2001/01/07 14:47:17 hno Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -62,6 +62,7 @@ typedef struct _acl_time_data acl_time_data; typedef struct _acl_name_list acl_name_list; typedef struct _acl_deny_info_list acl_deny_info_list; typedef struct _acl_proxy_auth acl_proxy_auth; +typedef struct _acl_proxy_auth_data acl_proxy_auth_data; typedef struct _acl_proxy_auth_user acl_proxy_auth_user; typedef struct _acl_arp_data acl_arp_data; typedef struct _acl acl;