From 0fa6818d48426d24269b506dfc846f1c08171227 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Tue, 15 May 2007 15:11:12 +0000 Subject: [PATCH] infra cache config. git-svn-id: file:///svn/unbound/trunk@322 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/example.conf | 18 +++++++++++ doc/unbound.conf.5 | 12 +++++++ services/cache/infra.c | 72 ++++++++++++++++++++++++------------------ services/cache/infra.h | 36 ++++++++++++--------- testcode/unitmain.c | 24 +++++++------- util/config_file.c | 5 +++ util/config_file.h | 10 ++++++ 7 files changed, 120 insertions(+), 57 deletions(-) diff --git a/doc/example.conf b/doc/example.conf index 8d0094eae..3bb7612eb 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -63,6 +63,24 @@ server: # more slabs reduce lock contention, but fragment memory usage. # rrset-cache-slabs: 4 + # the time to live (TTL) value for cached roundtrip times and + # EDNS version information for hosts. In seconds. + # infra-host-ttl: 900 + + # the time to live (TTL) value for cached lame delegations. In sec. + # infra-lame-ttl: 900 + + # the number of slabs to use for the Infrastructure cache. + # the number of slabs must be a power of 2. + # more slabs reduce lock contention, but fragment memory usage. + # infra-cache-slabs: 4 + + # the maximum number of hosts that are cached (roundtrip times, EDNS). + # infra-cache-numhosts: 1000 + + # the maximum number of lame zones per host that are cached. + # infra-cache-numlame: 1000 + # Enable IPv4, "yes" or "no". # do-ip4: yes diff --git a/doc/unbound.conf.5 b/doc/unbound.conf.5 index c4a4b2ce0..309554b5a 100644 --- a/doc/unbound.conf.5 +++ b/doc/unbound.conf.5 @@ -79,6 +79,18 @@ Number of bytes size of the RRset cache. Default is 4 megabytes. .It \fBrrset-cache-slabs:\fR Number of slabs in the RRset cache. Slabs reduce lock contention by threads. Must be set to a power of 2. +.It \fBinfra-host-ttl:\fR +Time to live for entries in the host cache. The host cache contains +roundtrip timing and EDNS support information. Default is 900. +.It \fBinfra-lame-ttl:\fR +The time to live when a delegation is discovered to be lame. Default is 900. +.It \fBinfra-cache-slabs:\fR +Number of slabs in the infrastructure cache. Slabs reduce lock contention +by threads. Must be set to a power of 2. +.It \fBinfra-cache-numhosts:\fR +Number of hosts for which information is cached. Default is 1000. +.It \fBinfra-cache-numlame:\fR +Number of zones per host for which lameness is cached. Default is 1000. .It \fBdo-ip4:\fR Enable or disable whether ip4 queries are answered. Default is yes. .It \fBdo-ip6:\fR diff --git a/services/cache/infra.c b/services/cache/infra.c index da33421b2..d11e59c9a 100644 --- a/services/cache/infra.c +++ b/services/cache/infra.c @@ -44,6 +44,7 @@ #include "util/storage/lookup3.h" #include "util/log.h" #include "util/net_help.h" +#include "util/config_file.h" /** calculate size for the hashtable, does not count size of lameness, * so the hashtable is a fixed number of items */ @@ -87,26 +88,36 @@ infra_host_deldatafunc(void* d, void* ATTR_UNUSED(arg)) free(data); } -struct slabhash* +struct infra_cache* infra_create(struct config_file* cfg) { + struct infra_cache* infra = (struct infra_cache*)calloc(1, + sizeof(struct infra_cache)); /* TODO: use config settings */ /* the size of the lameness tables are not counted */ - size_t maxmem = HOST_DEFAULT_SIZE * (sizeof(struct infra_host_key) + - sizeof(struct infra_host_data)); - struct slabhash* infra = slabhash_create(HASH_DEFAULT_SLABS, + size_t maxmem = cfg->infra_cache_numhosts * + (sizeof(struct infra_host_key)+sizeof(struct infra_host_data)); + infra->hosts = slabhash_create(cfg->infra_cache_slabs, INFRA_HOST_STARTSIZE, maxmem, &infra_host_sizefunc, &infra_host_compfunc, &infra_host_delkeyfunc, &infra_host_deldatafunc, NULL); + if(!infra->hosts) { + free(infra); + return NULL; + } + infra->host_ttl = cfg->host_ttl; + infra->lame_ttl = cfg->lame_ttl; + infra->max_lame = cfg->infra_cache_numlame; return infra; } void -infra_delete(struct slabhash* infra) +infra_delete(struct infra_cache* infra) { if(!infra) return; - slabhash_delete(infra); + slabhash_delete(infra->hosts); + free(infra); } /** calculate the hash value for a host key */ @@ -121,7 +132,7 @@ hash_addr(struct sockaddr_storage* addr, socklen_t addrlen) /** lookup version that does not check host ttl (you check it) */ static struct lruhash_entry* -infra_lookup_host_nottl(struct slabhash* infra, +infra_lookup_host_nottl(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, int wr) { struct infra_host_key k; @@ -130,11 +141,11 @@ infra_lookup_host_nottl(struct slabhash* infra, k.entry.hash = hash_addr(addr, addrlen); k.entry.key = (void*)&k; k.entry.data = NULL; - return slabhash_lookup(infra, k.entry.hash, &k, wr); + return slabhash_lookup(infra->hosts, k.entry.hash, &k, wr); } struct infra_host_data* -infra_lookup_host(struct slabhash* infra, +infra_lookup_host(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, int wr, time_t timenow, struct infra_host_key** key) { @@ -162,7 +173,8 @@ infra_lookup_host(struct slabhash* infra, * @return: the new entry or NULL on malloc failure. */ static struct lruhash_entry* -new_host_entry(struct sockaddr_storage* addr, socklen_t addrlen, time_t tm) +new_host_entry(struct infra_cache* infra, struct sockaddr_storage* addr, + socklen_t addrlen, time_t tm) { struct infra_host_data* data; struct infra_host_key* key = (struct infra_host_key*)malloc( @@ -181,7 +193,7 @@ new_host_entry(struct sockaddr_storage* addr, socklen_t addrlen, time_t tm) key->entry.data = (void*)data; key->addrlen = addrlen; memcpy(&key->addr, addr, addrlen); - data->ttl = tm + HOST_TTL; + data->ttl = tm + infra->host_ttl; data->lameness = NULL; data->edns_version = 0; rtt_init(&data->rtt); @@ -189,7 +201,7 @@ new_host_entry(struct sockaddr_storage* addr, socklen_t addrlen, time_t tm) } int -infra_host(struct slabhash* infra, struct sockaddr_storage* addr, +infra_host(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow, int* edns_vs, int* to) { struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr, @@ -203,7 +215,7 @@ infra_host(struct slabhash* infra, struct sockaddr_storage* addr, /* if its still there we have a writelock, init */ /* re-initialise */ data = (struct infra_host_data*)e->data; - data->ttl = timenow + HOST_TTL; + data->ttl = timenow + infra->host_ttl; rtt_init(&data->rtt); /* do not touch lameness, it may be valid still */ data->edns_version = 0; @@ -211,12 +223,12 @@ infra_host(struct slabhash* infra, struct sockaddr_storage* addr, } if(!e) { /* insert new entry */ - if(!(e = new_host_entry(addr, addrlen, timenow))) + if(!(e = new_host_entry(infra, addr, addrlen, timenow))) return 0; data = (struct infra_host_data*)e->data; *to = rtt_timeout(&data->rtt); *edns_vs = data->edns_version; - slabhash_insert(infra, e->hash, e, data, NULL); + slabhash_insert(infra->hosts, e->hash, e, data, NULL); return 1; } /* use existing entry */ @@ -304,7 +316,7 @@ infra_lame_deldatafunc(void* d, void* ATTR_UNUSED(arg)) } int -infra_set_lame(struct slabhash* infra, +infra_set_lame(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, size_t namelen, time_t timenow) { @@ -336,12 +348,12 @@ infra_set_lame(struct slabhash* infra, k->entry.hash = hash_lameness(name, namelen); k->entry.key = (void*)k; k->entry.data = (void*)d; - d->ttl = timenow + HOST_LAME_TTL; + d->ttl = timenow + infra->lame_ttl; k->namelen = namelen; e = infra_lookup_host_nottl(infra, addr, addrlen, 1); if(!e) { /* insert it */ - if(!(e = new_host_entry(addr, addrlen, timenow))) { + if(!(e = new_host_entry(infra, addr, addrlen, timenow))) { free(k->zonename); free(k); free(d); @@ -355,14 +367,14 @@ infra_set_lame(struct slabhash* infra, if(!data->lameness) { /* create hash table if not there already */ data->lameness = lruhash_create(INFRA_LAME_STARTSIZE, - INFRA_LAME_MAXMEM*(sizeof(struct infra_lame_key)+ + infra->max_lame*(sizeof(struct infra_lame_key)+ sizeof(struct infra_lame_data)), infra_lame_sizefunc, infra_lame_compfunc, infra_lame_delkeyfunc, infra_lame_deldatafunc, NULL); if(!data->lameness) { log_err("set_lame: malloc failure"); - if(needtoinsert) slabhash_insert(infra, e->hash, e, - e->data, NULL); + if(needtoinsert) slabhash_insert(infra->hosts, + e->hash, e, e->data, NULL); else lock_rw_unlock(&e->lock); free(k->zonename); free(k); @@ -374,13 +386,13 @@ infra_set_lame(struct slabhash* infra, lruhash_insert(data->lameness, k->entry.hash, &k->entry, d, NULL); if(needtoinsert) - slabhash_insert(infra, e->hash, e, e->data, NULL); + slabhash_insert(infra->hosts, e->hash, e, e->data, NULL); else lock_rw_unlock(&e->lock); return 1; } int -infra_rtt_update(struct slabhash* infra, +infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, int roundtrip, time_t timenow) { @@ -389,25 +401,25 @@ infra_rtt_update(struct slabhash* infra, struct infra_host_data* data; int needtoinsert = 0; if(!e) { - if(!(e = new_host_entry(addr, addrlen, timenow))) + if(!(e = new_host_entry(infra, addr, addrlen, timenow))) return 0; needtoinsert = 1; } /* have an entry, update the rtt, and the ttl */ data = (struct infra_host_data*)e->data; - data->ttl = timenow + HOST_TTL; + data->ttl = timenow + infra->host_ttl; if(roundtrip == -1) rtt_lost(&data->rtt); else rtt_update(&data->rtt, roundtrip); if(needtoinsert) - slabhash_insert(infra, e->hash, e, e->data, NULL); + slabhash_insert(infra->hosts, e->hash, e, e->data, NULL); else lock_rw_unlock(&e->lock); return 1; } int -infra_edns_update(struct slabhash* infra, +infra_edns_update(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, int edns_version, time_t timenow) { @@ -416,17 +428,17 @@ infra_edns_update(struct slabhash* infra, struct infra_host_data* data; int needtoinsert = 0; if(!e) { - if(!(e = new_host_entry(addr, addrlen, timenow))) + if(!(e = new_host_entry(infra, addr, addrlen, timenow))) return 0; needtoinsert = 1; } /* have an entry, update the rtt, and the ttl */ data = (struct infra_host_data*)e->data; - data->ttl = timenow + HOST_TTL; + data->ttl = timenow + infra->host_ttl; data->edns_version = edns_version; if(needtoinsert) - slabhash_insert(infra, e->hash, e, e->data, NULL); + slabhash_insert(infra->hosts, e->hash, e, e->data, NULL); else lock_rw_unlock(&e->lock); return 1; } diff --git a/services/cache/infra.h b/services/cache/infra.h index 027187034..c30687f28 100644 --- a/services/cache/infra.h +++ b/services/cache/infra.h @@ -93,31 +93,37 @@ struct infra_lame_data { time_t ttl; }; -/** default TTL value for host information, in seconds */ -#define HOST_TTL 900 -/** default TTL for Lameness information, in seconds */ -#define HOST_LAME_TTL 900 -/** default size of the host cache, number of entries */ -#define HOST_DEFAULT_SIZE 1000 +/** + * Infra cache + */ +struct infra_cache { + /** The hash table with hosts */ + struct slabhash* hosts; + /** TTL value for host information, in seconds */ + int host_ttl; + /** TTL for Lameness information, in seconds */ + int lame_ttl; + /** infra lame cache max memory per host, for this many entries */ + size_t max_lame; +}; + /** infra host cache default hash lookup size */ #define INFRA_HOST_STARTSIZE 32 /** infra lame cache default hash lookup size */ #define INFRA_LAME_STARTSIZE 2 -/** infra lame cache max memory per host, for this many entries */ -#define INFRA_LAME_MAXMEM 1000 /** * Create infra cache. * @param cfg: config parameters. * @return: new infra cache, or NULL. */ -struct slabhash* infra_create(struct config_file* cfg); +struct infra_cache* infra_create(struct config_file* cfg); /** * Delete infra cache. * @param infra: infrastructure cache to delete. */ -void infra_delete(struct slabhash* infra); +void infra_delete(struct infra_cache* infra); /** * Lookup host data @@ -129,7 +135,7 @@ void infra_delete(struct slabhash* infra); * @param key: the key for the host, returned so caller can unlock when done. * @return: host data or NULL if not found or expired. */ -struct infra_host_data* infra_lookup_host(struct slabhash* infra, +struct infra_host_data* infra_lookup_host(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, int wr, time_t timenow, struct infra_host_key** key); @@ -145,7 +151,7 @@ struct infra_host_data* infra_lookup_host(struct slabhash* infra, * @param to: timeout to use, is returned. * @return: 0 on error. */ -int infra_host(struct slabhash* infra, struct sockaddr_storage* addr, +int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow, int* edns_vs, int* to); /** @@ -170,7 +176,7 @@ int infra_lookup_lame(struct infra_host_data* host, * @param timenow: what time it is now. * @return: 0 on error. */ -int infra_set_lame(struct slabhash* infra, +int infra_set_lame(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, size_t namelen, time_t timenow); @@ -184,7 +190,7 @@ int infra_set_lame(struct slabhash* infra, * @param timenow: what time it is now. * @return: 0 on error. */ -int infra_rtt_update(struct slabhash* infra, +int infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, int roundtrip, time_t timenow); @@ -197,7 +203,7 @@ int infra_rtt_update(struct slabhash* infra, * @param timenow: what time it is now. * @return: 0 on error. */ -int infra_edns_update(struct slabhash* infra, +int infra_edns_update(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, int edns_version, time_t timenow); diff --git a/testcode/unitmain.c b/testcode/unitmain.c index 5c107557d..927a7f32f 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -152,7 +152,7 @@ infra_test() int one = 1; uint8_t* zone = (uint8_t*)"\007example\003com\000"; size_t zonelen = 13; - struct slabhash* slab; + struct infra_cache* slab; struct config_file* cfg = config_create(); time_t now = 0; int vs, to; @@ -161,35 +161,35 @@ infra_test() slab = infra_create(cfg); unit_assert( infra_host(slab, (struct sockaddr_storage*)&one, - sizeof(int), now, &vs, &to) ); + (socklen_t)sizeof(int), now, &vs, &to) ); unit_assert( vs == 0 && to == 3000 ); unit_assert( infra_rtt_update(slab, (struct sockaddr_storage*)&one, - sizeof(int), -1, now) ); + (socklen_t)sizeof(int), -1, now) ); unit_assert( infra_host(slab, (struct sockaddr_storage*)&one, - sizeof(int), now, &vs, &to) ); + (socklen_t)sizeof(int), now, &vs, &to) ); unit_assert( vs == 0 && to == 6000 ); unit_assert( infra_edns_update(slab, (struct sockaddr_storage*)&one, - sizeof(int), -1, now) ); + (socklen_t)sizeof(int), -1, now) ); unit_assert( infra_host(slab, (struct sockaddr_storage*)&one, - sizeof(int), now, &vs, &to) ); + (socklen_t)sizeof(int), now, &vs, &to) ); unit_assert( vs == -1 && to == 6000 ); - now += HOST_TTL + 10; + now += cfg->host_ttl + 10; unit_assert( infra_host(slab, (struct sockaddr_storage*)&one, - sizeof(int), now, &vs, &to) ); + (socklen_t)sizeof(int), now, &vs, &to) ); unit_assert( vs == 0 && to == 3000 ); unit_assert( infra_set_lame(slab, (struct sockaddr_storage*)&one, - sizeof(int), zone, zonelen, now) ); + (socklen_t)sizeof(int), zone, zonelen, now) ); unit_assert( (d=infra_lookup_host(slab, (struct sockaddr_storage*)&one, - sizeof(int), 0, now, &k)) ); - unit_assert( d->ttl == now+HOST_TTL ); + (socklen_t)sizeof(int), 0, now, &k)) ); + unit_assert( d->ttl == now+cfg->host_ttl ); unit_assert( d->edns_version == 0 ); unit_assert( infra_lookup_lame(d, zone, zonelen, now) ); unit_assert( !infra_lookup_lame(d, zone, zonelen, - now+HOST_LAME_TTL+10) ); + now+cfg->lame_ttl+10) ); unit_assert( !infra_lookup_lame(d, (uint8_t*)"\000", 1, now) ); lock_rw_unlock(&k->entry.lock); diff --git a/util/config_file.c b/util/config_file.c index 0128afb98..23b1fcd4c 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -83,6 +83,11 @@ config_create() cfg->num_queries_per_thread = 1024; cfg->rrset_cache_size = 4 * 1024 * 1024; cfg->rrset_cache_slabs = 4; + cfg->host_ttl = 900; + cfg->lame_ttl = 900; + cfg->infra_cache_slabs = 4; + cfg->infra_cache_numhosts = 1000; + cfg->infra_cache_numlame = 1000; if(!(cfg->fwd_address = strdup(""))) goto error_exit; if(!(cfg->username = strdup(""))) goto error_exit; if(!(cfg->chrootdir = strdup(""))) goto error_exit; diff --git a/util/config_file.h b/util/config_file.h index 47ed20a83..8444a594d 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -81,6 +81,16 @@ struct config_file { size_t rrset_cache_size; /** slabs in the rrset cache */ size_t rrset_cache_slabs; + /** host cache ttl in seconds */ + int host_ttl; + /** host is lame for a zone ttl, in seconds */ + int lame_ttl; + /** number of slabs in the infra host cache */ + size_t infra_cache_slabs; + /** max number of hosts in the infra cache */ + size_t infra_cache_numhosts; + /** max number of lame zones per host in the infra cache */ + size_t infra_cache_numlame; /** forwarder address. string. If not NULL fwder mode is enabled. */ char* fwd_address; -- 2.47.2