diff options
-rw-r--r-- | src/dnscache.c | 159 | ||||
-rw-r--r-- | src/dnscache.h | 19 |
2 files changed, 38 insertions, 140 deletions
diff --git a/src/dnscache.c b/src/dnscache.c index 9bc8184..7604c55 100644 --- a/src/dnscache.c +++ b/src/dnscache.c @@ -1,4 +1,4 @@ -/* $Id: dnscache.c,v 1.4 2000-04-26 16:31:29 rjkaes Exp $ +/* $Id: dnscache.c,v 1.5 2000-09-11 23:42:43 rjkaes Exp $ * * This is a caching DNS system. When a host name is needed we look it up here * and see if there is already an answer for it. The domains are placed in a @@ -21,129 +21,82 @@ */ #ifdef HAVE_CONFIG_H -#include <defines.h> +# include <config.h> #endif -#include <stdlib.h> -#include <string.h> -#include <netdb.h> -#include <time.h> #include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <assert.h> #include <ctype.h> +#include <unistd.h> -#include "utils.h" #include "dnscache.h" +#include "log.h" +#include "ternary.h" +#include "utils.h" -#define HASH_BOX 25 #define DNSEXPIRE (5 * 60) +#define DNS_GARBAGE_COL 10 struct dnscache_s { struct in_addr ipaddr; - char *domain; time_t expire; - struct dnscache_s *next; }; -struct dnscache_s *cache[HASH_BOX]; +static TERNARY dns_tree; -static unsigned int hash(unsigned char *keystr, unsigned int box) +static int dns_lookup(struct in_addr *addr, char *domain) { - unsigned long hashc = 0; - unsigned char ch; - - assert(keystr); - assert(box > 0); - - while ((ch = *keystr++)) - hashc += tolower(ch); - - return hashc % box; -} - -int lookup(struct in_addr *addr, char *domain) -{ - unsigned int box = hash(domain, HASH_BOX); - struct dnscache_s **rptr = &cache[box]; - struct dnscache_s *ptr = cache[box]; - - assert(domain); - - while (ptr && strcasecmp(ptr->domain, domain)) { - rptr = &ptr->next; - ptr = ptr->next; + struct dnscache_s *ptr; + + if (dns_tree == 0) { + if (TE_ISERROR(dns_tree = ternary_new())) + return dns_tree; } - if (ptr && !strcasecmp(ptr->domain, domain)) { - /* Woohoo... found it. Make sure it hasn't expired */ - if (difftime(time(NULL), ptr->expire) > DNSEXPIRE) { - /* Oops... expired */ - *rptr = ptr->next; - safefree(ptr->domain); - safefree(ptr); - return -1; - } - - /* chris - added this so that the routine can be used to just - * look stuff up. - */ - if (addr) - *addr = ptr->ipaddr; - return 0; + if (TE_ISERROR(ternary_search(dns_tree, domain, (void *)&ptr))) + return -1; + + if (difftime(time(NULL), ptr->expire) > DNSEXPIRE) { + return -1; } - return -1; + *addr = ptr->ipaddr; + return 0; } -int insert(struct in_addr *addr, char *domain) +static int dns_insert(struct in_addr *addr, char *domain) { - unsigned int box = hash(domain, HASH_BOX); - struct dnscache_s **rptr = &cache[box]; - struct dnscache_s *ptr = cache[box]; struct dnscache_s *newptr; - assert(addr); - assert(domain); - - while (ptr) { - rptr = &ptr->next; - ptr = ptr->next; - } - - if (!(newptr = xmalloc(sizeof(struct dnscache_s)))) { - return -1; - } - - if (!(newptr->domain = xstrdup(domain))) { - safefree(newptr); + if (!(newptr = malloc(sizeof(struct dnscache_s)))) { return -1; } newptr->ipaddr = *addr; - newptr->expire = time(NULL); - *rptr = newptr; - newptr->next = ptr; + ternary_insert(dns_tree, domain, newptr); return 0; } int dnscache(struct in_addr *addr, char *domain) { + static unsigned int dns_garbage_collect = 0; struct hostent *resolv; - - assert(addr); - assert(domain); + +#if 0 + if (++dns_garbage_collect > DNS_GARBAGE_COL) { + ternary_destroy(&dns_root, &free); + DEBUG1("Doing garbage collection."); + dns_garbage_collect = 0; + } +#endif if (inet_aton(domain, (struct in_addr *) addr) != 0) return 0; /* Well, we're not dotted-decimal so we need to look it up */ - if (lookup(addr, domain) == 0) + if (dns_lookup(addr, domain) == 0) return 0; /* Okay, so not in the list... need to actually look it up. */ @@ -151,49 +104,7 @@ int dnscache(struct in_addr *addr, char *domain) return -1; memcpy(addr, resolv->h_addr_list[0], resolv->h_length); - insert(addr, domain); + dns_insert(addr, domain); return 0; } - -static void dnsdelete(unsigned int c, struct dnscache_s *del) -{ - struct dnscache_s **rptr; - struct dnscache_s *ptr; - - assert(c > 0); - assert(del); - - rptr = &cache[c]; - ptr = cache[c]; - - while (ptr && (ptr != del)) { - rptr = &ptr->next; - ptr = ptr->next; - } - - if (ptr == del) { - *rptr = ptr->next; - safefree(ptr->domain); - safefree(ptr); - } -} - -void dnsclean(void) -{ - unsigned int c; - struct dnscache_s *ptr, *tmp; - - for (c = 0; c < HASH_BOX; c++) { - ptr = cache[c]; - - while (ptr) { - tmp = ptr->next; - - if (difftime(time(NULL), ptr->expire) > DNSEXPIRE) - dnsdelete(c, ptr); - - ptr = tmp; - } - } -} diff --git a/src/dnscache.h b/src/dnscache.h index ecb3cd6..3ff0dd8 100644 --- a/src/dnscache.h +++ b/src/dnscache.h @@ -1,4 +1,4 @@ -/* $Id: dnscache.h,v 1.1.1.1 2000-02-16 17:32:22 sdyoung Exp $ +/* $Id: dnscache.h,v 1.2 2000-09-11 23:42:43 rjkaes Exp $ * * See 'dnscache.c' for a detailed description. * @@ -15,24 +15,11 @@ * General Public License for more details. */ -#ifndef _DNSCACHE_H_ -#define _DNSCACHE_H_ 1 +#ifndef _TINYPROXY_DNSCACHE_H_ +#define _TINYPROXY_DNSCACHE_H_ -#ifdef HAVE_CONFIG_H -#include <defines.h> -#endif - -#include <sys/socket.h> -#include <netinet/in.h> #include <arpa/inet.h> -#define DNS_GARBAGE_COL 100 - extern int dnscache(struct in_addr *addr, char *domain); -extern void dnsclean(void); - -/* chris - Access these from reqs.c because of ADNS. Ugly. */ -extern int lookup(struct in_addr *addr, char *domain); -extern int insert(struct in_addr *addr, char *domain); #endif |