This patch is generated from the ntlm_ip_cache branch of HEAD in squid Tue Apr 3 00:20:20 2007 GMT See http://devel.squid-cache.org/ Index: squid/src/authenticate.c diff -u squid/src/authenticate.c:1.35 squid/src/authenticate.c:1.34.8.5 --- squid/src/authenticate.c:1.35 Mon Jan 1 14:51:01 2007 +++ squid/src/authenticate.c Wed Dec 20 01:07:18 2006 @@ -44,6 +44,7 @@ static void authenticateDecodeAuth(const char *proxy_auth, auth_user_request_t * auth_user_request); static auth_acl_t authenticateAuthenticate(auth_user_request_t ** auth_user_request, http_hdr_type headertype, request_t * request, ConnStateData * conn, struct in_addr src_addr); +static void authenticateAuthUserRequestUnlinkIp(const struct in_addr ipaddr); /* * @@ -252,12 +253,100 @@ { /* remove the node */ dlinkDelete(&ipdata->node, &auth_user->ip_list); + authenticateAuthUserRequestUnlinkIp(ipdata->ipaddr); cbdataFree(ipdata); /* catch incipient underflow */ assert(auth_user->ipcount); auth_user->ipcount--; } +typedef struct { + hash_link hash; /* must be first */ + struct in_addr ipaddr; + auth_user_request_t *auth_user_request; + time_t last_seen; +} auth_user_request_ip_hash_t; +MemPool *auth_user_request_ip_pool = NULL; +hash_table *auth_user_request_ip_hash = NULL; + +static unsigned int +hash_in_addr(const void *a, unsigned int size) +{ + const struct in_addr *ipaddr = a; + const uint32_t ip = ntohl(ipaddr->s_addr); + return ip % size; +} + +static int +cmp_in_addr(const struct in_addr *a, const struct in_addr *b) +{ + const uint32_t ipa = ntohl(a->s_addr); + const uint32_t ipb = ntohl(b->s_addr); + + return memcmp(&ipa, &ipb, 4); +} + +static void +authenticateAuthUserRequestUnlinkIp(const struct in_addr ipaddr) +{ + auth_user_request_ip_hash_t *hash_entry; + + if (!auth_user_request_ip_hash) + return; + + hash_entry = hash_lookup(auth_user_request_ip_hash, &ipaddr); + if (hash_entry) { + hash_remove_link(auth_user_request_ip_hash, &hash_entry->hash); + authenticateAuthUserRequestUnlock(hash_entry->auth_user_request); + memPoolFree(auth_user_request_ip_pool, hash_entry); + } +} + +static void +authenticateAuthUserRequestLinkIp(auth_user_request_t * auth_user_request, const struct in_addr ipaddr) +{ + auth_user_request_ip_hash_t *hash_entry; + + if (!Config.authenticateIpShortcircuitTTL) + return; + + if (!auth_user_request_ip_hash) { + auth_user_request_ip_hash = hash_create((HASHCMP *) cmp_in_addr, 7921, hash_in_addr); + auth_user_request_ip_pool = memPoolCreate("auth_user_request_ip_hash_t", sizeof(auth_user_request_ip_hash_t)); + } + authenticateAuthUserRequestUnlinkIp(ipaddr); + + hash_entry = memPoolAlloc(auth_user_request_ip_pool); + hash_entry->ipaddr = ipaddr; + hash_entry->hash.key = &hash_entry->ipaddr; + hash_entry->auth_user_request = auth_user_request; + authenticateAuthUserRequestLock(hash_entry->auth_user_request); + hash_entry->last_seen = squid_curtime; + hash_join(auth_user_request_ip_hash, &hash_entry->hash); +} + +static auth_user_request_t * +authenticateAuthUserRequestFindByIp(const struct in_addr ipaddr) +{ + time_t delta = Config.authenticateIpShortcircuitTTL; + auth_user_request_ip_hash_t *hash_entry; + auth_user_request_t *auth_user_request = NULL; + + if (!auth_user_request_ip_hash) + return NULL; + + hash_entry = hash_lookup(auth_user_request_ip_hash, &ipaddr); + if (!hash_entry) + return NULL; + + auth_user_request = hash_entry->auth_user_request; + if (hash_entry->last_seen + delta < squid_curtime) { + authenticateAuthUserRequestUnlinkIp(ipaddr); + return NULL; + } + return hash_entry->auth_user_request; +} + static void authenticateAuthUserRequestSetIp(auth_user_request_t * auth_user_request, struct in_addr ipaddr) { @@ -289,6 +378,8 @@ } } + authenticateAuthUserRequestLinkIp(auth_user_request, ipaddr); + if (found) return; @@ -408,10 +499,14 @@ return *auth_user_request; else if (request && request->auth_user_request) return request->auth_user_request; - else if (conn) + else if (conn && conn->auth_user_request) return conn->auth_user_request; - else - return NULL; + else { + request->auth_user_request = authenticateAuthUserRequestFindByIp(request->client_addr); + if (request->auth_user_request) + authenticateAuthUserRequestLock(request->auth_user_request); + return request->auth_user_request; + } } /* returns one of Index: squid/src/cf.data.pre diff -u squid/src/cf.data.pre:1.169 squid/src/cf.data.pre:1.161.8.3 --- squid/src/cf.data.pre:1.169 Sun Feb 25 03:54:34 2007 +++ squid/src/cf.data.pre Sun Mar 11 15:05:47 2007 @@ -2131,6 +2131,15 @@ corporate LAN environment with relatively static address assignments. DOC_END +NAME: authenticate_ip_shortcircuit_ttl +TYPE: time_t +LOC: Config.authenticateIpShortcircuitTTL +DEFAULT: 0 seconds +DOC_START + Cache authentication credentials per client IP address for this + long. Default is 0 seconds (disabled). +DOC_END + NAME: external_acl_type TYPE: externalAclHelper LOC: Config.externalAclHelperList Index: squid/src/structs.h diff -u squid/src/structs.h:1.142 squid/src/structs.h:1.136.8.3 --- squid/src/structs.h:1.142 Sun Mar 18 18:53:56 2007 +++ squid/src/structs.h Mon Mar 26 19:59:44 2007 @@ -563,6 +563,7 @@ time_t authenticateGCInterval; time_t authenticateTTL; time_t authenticateIpTTL; + time_t authenticateIpShortcircuitTTL; char *appendDomain; int appendDomainLen; char *debugOptions;