From 11f5e1693240f624faf409e8cd395bc3d293f663 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Wed, 26 Oct 2011 15:46:23 +0000 Subject: [PATCH] infra cache consolidated and stores per zone, IP. git-svn-id: file:///svn/unbound/trunk@2525 be551aaa-1e26-0410-a405-d3ace91eadb9 --- daemon/cachedump.c | 6 +- daemon/remote.c | 142 +++++----- daemon/worker.c | 6 +- daemon/worker.h | 4 +- doc/Changelog | 1 + iterator/iterator.c | 3 +- libunbound/libworker.c | 4 +- libunbound/libworker.h | 4 +- services/cache/infra.c | 515 ++++++++++++----------------------- services/cache/infra.h | 140 ++++------ services/outside_network.c | 45 +-- services/outside_network.h | 12 +- testcode/fake_event.c | 22 +- testcode/replay.c | 18 +- testcode/replay.h | 2 +- testcode/unitmain.c | 70 +++-- testdata/iter_lame_nosoa.rpl | 2 +- util/fptr_wlist.c | 13 +- util/fptr_wlist.h | 1 + util/module.h | 5 +- 20 files changed, 427 insertions(+), 588 deletions(-) diff --git a/daemon/cachedump.c b/daemon/cachedump.c index 242931a09..b3010a0d4 100644 --- a/daemon/cachedump.c +++ b/daemon/cachedump.c @@ -815,7 +815,8 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp) } /* lookup in infra cache */ entry_ttl = infra_get_host_rto(worker->env.infra_cache, - &a->addr, a->addrlen, &ri, &delay, *worker->env.now); + &a->addr, a->addrlen, dp->name, dp->namelen, + &ri, &delay, *worker->env.now); if(entry_ttl == -2 && ri.rto >= USEFUL_SERVER_TOP_TIMEOUT) { if(!ssl_printf(ssl, "expired, rto %d msec.\n", ri.rto)) return; @@ -848,7 +849,8 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp) if(!ssl_printf(ssl, ", probedelay %d", delay)) return; if(infra_host(worker->env.infra_cache, &a->addr, a->addrlen, - *worker->env.now, &edns_vs, &edns_lame_known, &to)) { + dp->name, dp->namelen, *worker->env.now, &edns_vs, + &edns_lame_known, &to)) { if(edns_vs == -1) { if(!ssl_printf(ssl, ", noEDNS%s.", edns_lame_known?" probed":" assumed")) diff --git a/daemon/remote.c b/daemon/remote.c index 67d50517a..ba54d78b3 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1103,12 +1103,57 @@ do_flush_stats(SSL* ssl, struct worker* worker) send_ok(ssl); } +/** + * Local info for deletion functions + */ +struct del_info { + /** worker */ + struct worker* worker; + /** name to delete */ + uint8_t* name; + /** length */ + size_t len; + /** labels */ + int labs; + /** now */ + uint32_t now; + /** time to invalidate to */ + uint32_t expired; + /** number of rrsets removed */ + size_t num_rrsets; + /** number of msgs removed */ + size_t num_msgs; + /** number of key entries removed */ + size_t num_keys; + /** length of addr */ + socklen_t addrlen; + /** socket address for host deletion */ + struct sockaddr_storage addr; +}; + +/** callback to delete hosts in infra cache */ +static void +infra_del_host(struct lruhash_entry* e, void* arg) +{ + /* entry is locked */ + struct del_info* inf = (struct del_info*)arg; + struct infra_key* k = (struct infra_key*)e->key; + if(sockaddr_cmp(&inf->addr, inf->addrlen, &k->addr, k->addrlen) == 0) { + struct infra_data* d = (struct infra_data*)e->data; + if(d->ttl >= inf->now) { + d->ttl = inf->expired; + inf->num_keys++; + } + } +} + /** flush infra cache */ static void do_flush_infra(SSL* ssl, struct worker* worker, char* arg) { struct sockaddr_storage addr; socklen_t len; + struct del_info inf; if(strcmp(arg, "all") == 0) { slabhash_clear(worker->env.infra_cache->hosts); send_ok(ssl); @@ -1118,7 +1163,22 @@ do_flush_infra(SSL* ssl, struct worker* worker, char* arg) (void)ssl_printf(ssl, "error parsing ip addr: '%s'\n", arg); return; } - infra_remove_host(worker->env.infra_cache, &addr, len); + /* delete all entries from cache */ + /* what we do is to set them all expired */ + inf.worker = worker; + inf.name = 0; + inf.len = 0; + inf.labs = 0; + inf.now = *worker->env.now; + inf.expired = *worker->env.now; + inf.expired -= 3; /* handle 3 seconds skew between threads */ + inf.num_rrsets = 0; + inf.num_msgs = 0; + inf.num_keys = 0; + inf.addrlen = len; + memmove(&inf.addr, &addr, len); + slabhash_traverse(worker->env.infra_cache->hosts, 1, &infra_del_host, + &inf); send_ok(ssl); } @@ -1130,30 +1190,6 @@ do_flush_requestlist(SSL* ssl, struct worker* worker) send_ok(ssl); } -/** - * Local info for deletion functions - */ -struct del_info { - /** worker */ - struct worker* worker; - /** name to delete */ - uint8_t* name; - /** length */ - size_t len; - /** labels */ - int labs; - /** now */ - uint32_t now; - /** time to invalidate to */ - uint32_t expired; - /** number of rrsets removed */ - size_t num_rrsets; - /** number of msgs removed */ - size_t num_msgs; - /** number of key entries removed */ - size_t num_keys; -}; - /** callback to delete rrsets in a zone */ static void zone_del_rrset(struct lruhash_entry* e, void* arg) @@ -1527,68 +1563,36 @@ struct infra_arg { SSL* ssl; /** the time now */ uint32_t now; - /** ipstr */ - char* ipstr; }; -/** callback for every lame element in the infra cache */ -static void -dump_infra_lame(struct lruhash_entry* e, void* arg) -{ - struct infra_arg* a = (struct infra_arg*)arg; - struct infra_lame_key* k = (struct infra_lame_key*)e->key; - struct infra_lame_data* d = (struct infra_lame_data*)e->data; - ldns_rdf* rdf; - size_t pos = 0; - char* nm; - /* skip expired */ - if(d->ttl < a->now) { - return; - } - /* use ldns print for domain name */ - if(ldns_wire2dname(&rdf, k->zonename, k->namelen, &pos) - != LDNS_STATUS_OK) - return; - nm = ldns_rdf2str(rdf); - ldns_rdf_deep_free(rdf); - if(!ssl_printf(a->ssl, "%s lame %s ttl %d dnssec %d rec %d " - "A %d other %d\n", a->ipstr, nm, (int)(d->ttl - a->now), - d->isdnsseclame, d->rec_lame, d->lame_type_A, d->lame_other)) { - free(nm); - return; - } - free(nm); -} - /** callback for every host element in the infra cache */ static void dump_infra_host(struct lruhash_entry* e, void* arg) { struct infra_arg* a = (struct infra_arg*)arg; - struct infra_host_key* k = (struct infra_host_key*)e->key; - struct infra_host_data* d = (struct infra_host_data*)e->data; + struct infra_key* k = (struct infra_key*)e->key; + struct infra_data* d = (struct infra_data*)e->data; char ip_str[1024]; + char name[257]; addr_to_str(&k->addr, k->addrlen, ip_str, sizeof(ip_str)); - a->ipstr = ip_str; + dname_str(k->zonename, name); /* skip expired stuff (only backed off) */ if(d->ttl < a->now) { if(d->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) { - if(!ssl_printf(a->ssl, "%s expired rto %d\n", ip_str, - d->rtt.rto)) return; + if(!ssl_printf(a->ssl, "%s %s expired rto %d\n", ip_str, + name, d->rtt.rto)) return; } - if(d->lameness) - lruhash_traverse(d->lameness, 0, &dump_infra_lame, arg); return; } - if(!ssl_printf(a->ssl, "%s ttl %d ping %d var %d rtt %d rto %d " - "ednsknown %d edns %d delay %d\n", - ip_str, (int)(d->ttl - a->now), + if(!ssl_printf(a->ssl, "%s %s ttl %d ping %d var %d rtt %d rto %d " + "ednsknown %d edns %d delay %d lame dnssec %d rec %d A %d " + "other %d\n", ip_str, name, (int)(d->ttl - a->now), d->rtt.srtt, d->rtt.rttvar, rtt_notimeout(&d->rtt), d->rtt.rto, (int)d->edns_lame_known, (int)d->edns_version, - (int)(a->nowprobedelay?d->probedelay-a->now:0))) + (int)(a->nowprobedelay?d->probedelay-a->now:0), + (int)d->isdnsseclame, (int)d->rec_lame, (int)d->lame_type_A, + (int)d->lame_other)) return; - if(d->lameness) - lruhash_traverse(d->lameness, 0, &dump_infra_lame, arg); } /** do the dump_infra command */ diff --git a/daemon/worker.c b/daemon/worker.c index 538d01a11..e16afe5b7 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1244,8 +1244,8 @@ outbound_entry_compare(void* a, void* b) struct outbound_entry* worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec, - struct sockaddr_storage* addr, socklen_t addrlen, - struct module_qstate* q) + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, + size_t zonelen, struct module_qstate* q) { struct worker* worker = q->env->worker; struct outbound_entry* e = (struct outbound_entry*)regional_alloc( @@ -1255,7 +1255,7 @@ worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype, e->qstate = q; e->qsent = outnet_serviced_query(worker->back, qname, qnamelen, qtype, qclass, flags, dnssec, want_dnssec, - q->env->cfg->tcp_upstream, addr, addrlen, + q->env->cfg->tcp_upstream, addr, addrlen, zone, zonelen, worker_handle_service_reply, e, worker->back->udp_buff, &outbound_entry_compare); if(!e->qsent) { diff --git a/daemon/worker.h b/daemon/worker.h index 8f7066a7c..96c04676a 100644 --- a/daemon/worker.h +++ b/daemon/worker.h @@ -175,6 +175,8 @@ void worker_sighandler(int sig, void* arg); * @param want_dnssec: signatures needed. * @param addr: where to. * @param addrlen: length of addr. + * @param zone: wireformat dname of the zone. + * @param zonelen: length of zone name. * @param q: wich query state to reactivate upon return. * @return: false on failure (memory or socket related). no query was * sent. @@ -182,7 +184,7 @@ void worker_sighandler(int sig, void* arg); struct outbound_entry* worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen, - struct module_qstate* q); + uint8_t* zone, size_t zonelen, struct module_qstate* q); /** * process control messages from the main thread. Frees the control diff --git a/doc/Changelog b/doc/Changelog index c7f9dcb1b..e0bc1142d 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,5 +1,6 @@ 26 October 2011: Wouter - iana portlist updated. + - Infra cache stores information about ping and lameness per IP, zone. 24 October 2011: Wouter - Fix resolve of partners.extranet.microsoft.com with a fix for the diff --git a/iterator/iterator.c b/iterator/iterator.c index a310877de..468d3d178 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -1723,7 +1723,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, iq->qchase.qname, iq->qchase.qname_len, iq->qchase.qtype, iq->qchase.qclass, iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), EDNS_DO|BIT_CD, - iq->dnssec_expected, &target->addr, target->addrlen, qstate); + iq->dnssec_expected, &target->addr, target->addrlen, + iq->dp->name, iq->dp->namelen, qstate); if(!outq) { log_addr(VERB_DETAIL, "error sending query to auth server", &target->addr, target->addrlen); diff --git a/libunbound/libworker.c b/libunbound/libworker.c index 6aa19e203..1c56f7ed6 100644 --- a/libunbound/libworker.c +++ b/libunbound/libworker.c @@ -685,7 +685,7 @@ outbound_entry_compare(void* a, void* b) struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen, - struct module_qstate* q) + uint8_t* zone, size_t zonelen, struct module_qstate* q) { struct libworker* w = (struct libworker*)q->env->worker; struct outbound_entry* e = (struct outbound_entry*)regional_alloc( @@ -695,7 +695,7 @@ struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen, e->qstate = q; e->qsent = outnet_serviced_query(w->back, qname, qnamelen, qtype, qclass, flags, dnssec, want_dnssec, - q->env->cfg->tcp_upstream, addr, addrlen, + q->env->cfg->tcp_upstream, addr, addrlen, zone, zonelen, libworker_handle_service_reply, e, w->back->udp_buff, &outbound_entry_compare); if(!e->qsent) { diff --git a/libunbound/libworker.h b/libunbound/libworker.h index 7aa35126a..fea480c0c 100644 --- a/libunbound/libworker.h +++ b/libunbound/libworker.h @@ -118,6 +118,8 @@ void libworker_alloc_cleanup(void* arg); * @param want_dnssec: signatures needed. * @param addr: where to. * @param addrlen: length of addr. + * @param zone: delegation point name. + * @param zonelen: length of zone name wireformat dname. * @param q: wich query state to reactivate upon return. * @return: false on failure (memory or socket related). no query was * sent. @@ -125,7 +127,7 @@ void libworker_alloc_cleanup(void* arg); struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen, - struct module_qstate* q); + uint8_t* zone, size_t zonelen, struct module_qstate* q); /** process incoming replies from the network */ int libworker_handle_reply(struct comm_point* c, void* arg, int error, diff --git a/services/cache/infra.c b/services/cache/infra.c index cbc603ebf..cd53ef858 100644 --- a/services/cache/infra.c +++ b/services/cache/infra.c @@ -53,36 +53,44 @@ #define PROBE_MAXRTO 12000 /* in msec */ size_t -infra_host_sizefunc(void* k, void* ATTR_UNUSED(d)) +infra_sizefunc(void* k, void* ATTR_UNUSED(d)) { - struct infra_host_key* key = (struct infra_host_key*)k; - return sizeof(*key) + sizeof(struct infra_host_data) + struct infra_key* key = (struct infra_key*)k; + return sizeof(*key) + sizeof(struct infra_data) + key->namelen + lock_get_mem(&key->entry.lock); } int -infra_host_compfunc(void* key1, void* key2) +infra_compfunc(void* key1, void* key2) { - struct infra_host_key* k1 = (struct infra_host_key*)key1; - struct infra_host_key* k2 = (struct infra_host_key*)key2; - return sockaddr_cmp(&k1->addr, k1->addrlen, &k2->addr, k2->addrlen); + struct infra_key* k1 = (struct infra_key*)key1; + struct infra_key* k2 = (struct infra_key*)key2; + int r = sockaddr_cmp(&k1->addr, k1->addrlen, &k2->addr, k2->addrlen); + if(r != 0) + return 0; + if(k1->namelen != k2->namelen) { + if(k1->namelen < k2->namelen) + return -1; + return 1; + } + return query_dname_compare(k1->zonename, k2->zonename); } void -infra_host_delkeyfunc(void* k, void* ATTR_UNUSED(arg)) +infra_delkeyfunc(void* k, void* ATTR_UNUSED(arg)) { - struct infra_host_key* key = (struct infra_host_key*)k; + struct infra_key* key = (struct infra_key*)k; if(!key) return; lock_rw_destroy(&key->entry.lock); + free(key->zonename); free(key); } void -infra_host_deldatafunc(void* d, void* ATTR_UNUSED(arg)) +infra_deldatafunc(void* d, void* ATTR_UNUSED(arg)) { - struct infra_host_data* data = (struct infra_host_data*)d; - lruhash_delete(data->lameness); + struct infra_data* data = (struct infra_data*)d; free(data); } @@ -91,21 +99,16 @@ infra_create(struct config_file* cfg) { struct infra_cache* infra = (struct infra_cache*)calloc(1, sizeof(struct infra_cache)); - /* the size of the lameness tables are not counted */ - size_t maxmem = cfg->infra_cache_numhosts * - (sizeof(struct infra_host_key)+sizeof(struct infra_host_data)); + size_t maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+ + sizeof(struct infra_data)+INFRA_BYTES_NAME); 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); + INFRA_HOST_STARTSIZE, maxmem, &infra_sizefunc, &infra_compfunc, + &infra_delkeyfunc, &infra_deldatafunc, NULL); if(!infra->hosts) { free(infra); return NULL; } infra->host_ttl = cfg->host_ttl; - infra->lame_ttl = cfg->lame_ttl; - infra->max_lame_size = cfg->infra_cache_lame_size; - infra->jostle = cfg->jostle_time; return infra; } @@ -125,11 +128,8 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg) if(!infra) return infra_create(cfg); infra->host_ttl = cfg->host_ttl; - infra->lame_ttl = cfg->lame_ttl; - infra->max_lame_size = cfg->infra_cache_lame_size; - infra->jostle = cfg->jostle_time; - maxmem = cfg->infra_cache_numhosts * - (sizeof(struct infra_host_key)+sizeof(struct infra_host_data)); + maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+ + sizeof(struct infra_data)+INFRA_BYTES_NAME); if(maxmem != slabhash_get_size(infra->hosts) || cfg->infra_cache_slabs != infra->hosts->size) { infra_delete(infra); @@ -158,65 +158,44 @@ hash_addr(struct sockaddr_storage* addr, socklen_t addrlen) return h; } -void -infra_remove_host(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen) +/** calculate infra hash for a key */ +static hashvalue_t +hash_infra(struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name) { - struct infra_host_key k; - k.addrlen = addrlen; - memcpy(&k.addr, addr, addrlen); - k.entry.hash = hash_addr(addr, addrlen); - k.entry.key = (void*)&k; - k.entry.data = NULL; - slabhash_remove(infra->hosts, k.entry.hash, &k); + return dname_query_hash(name, hash_addr(addr, addrlen)); } /** lookup version that does not check host ttl (you check it) */ -static struct lruhash_entry* -infra_lookup_host_nottl(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, int wr) +struct lruhash_entry* +infra_lookup_nottl(struct infra_cache* infra, struct sockaddr_storage* addr, + socklen_t addrlen, uint8_t* name, size_t namelen, int wr) { - struct infra_host_key k; + struct infra_key k; k.addrlen = addrlen; memcpy(&k.addr, addr, addrlen); - k.entry.hash = hash_addr(addr, addrlen); + k.namelen = namelen; + k.zonename = name; + k.entry.hash = hash_infra(addr, addrlen, name); k.entry.key = (void*)&k; k.entry.data = NULL; return slabhash_lookup(infra->hosts, k.entry.hash, &k, wr); } -struct infra_host_data* -infra_lookup_host(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, int wr, - uint32_t timenow, struct infra_host_key** key) -{ - struct infra_host_data* data; - struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr, - addrlen, wr); - *key = NULL; - if(!e) - return NULL; - /* check TTL */ - data = (struct infra_host_data*)e->data; - if(data->ttl < timenow) { - lock_rw_unlock(&e->lock); - return NULL; - } - *key = (struct infra_host_key*)e->key; - return data; -} - -/** init the host elements (not lame elems) */ +/** init the data elements */ static void -host_entry_init(struct infra_cache* infra, struct lruhash_entry* e, +data_entry_init(struct infra_cache* infra, struct lruhash_entry* e, uint32_t timenow) { - struct infra_host_data* data = (struct infra_host_data*)e->data; + struct infra_data* data = (struct infra_data*)e->data; data->ttl = timenow + infra->host_ttl; rtt_init(&data->rtt); data->edns_version = 0; data->edns_lame_known = 0; data->probedelay = 0; + data->isdnsseclame = 0; + data->rec_lame = 0; + data->lame_type_A = 0; + data->lame_other = 0; } /** @@ -224,87 +203,93 @@ host_entry_init(struct infra_cache* infra, struct lruhash_entry* e, * @param infra: infra structure with config parameters. * @param addr: host address. * @param addrlen: length of addr. + * @param name: name of zone + * @param namelen: length of name. * @param tm: time now. * @return: the new entry or NULL on malloc failure. */ static struct lruhash_entry* -new_host_entry(struct infra_cache* infra, struct sockaddr_storage* addr, - socklen_t addrlen, uint32_t tm) +new_entry(struct infra_cache* infra, struct sockaddr_storage* addr, + socklen_t addrlen, uint8_t* name, size_t namelen, uint32_t tm) { - struct infra_host_data* data; - struct infra_host_key* key = (struct infra_host_key*)malloc( - sizeof(struct infra_host_key)); + struct infra_data* data; + struct infra_key* key = (struct infra_key*)malloc(sizeof(*key)); if(!key) return NULL; - data = (struct infra_host_data*)malloc( - sizeof(struct infra_host_data)); + data = (struct infra_data*)malloc(sizeof(struct infra_data)); if(!data) { free(key); return NULL; } + key->zonename = memdup(name, namelen); + if(!key->zonename) { + free(key); + free(data); + return NULL; + } + key->namelen = namelen; lock_rw_init(&key->entry.lock); - key->entry.hash = hash_addr(addr, addrlen); + key->entry.hash = hash_infra(addr, addrlen, name); key->entry.key = (void*)key; key->entry.data = (void*)data; key->addrlen = addrlen; memcpy(&key->addr, addr, addrlen); - data->lameness = NULL; - host_entry_init(infra, &key->entry, tm); + data_entry_init(infra, &key->entry, tm); return &key->entry; } int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr, - socklen_t addrlen, uint32_t timenow, int* edns_vs, - uint8_t* edns_lame_known, int* to) + socklen_t addrlen, uint8_t* nm, size_t nmlen, uint32_t timenow, + int* edns_vs, uint8_t* edns_lame_known, int* to) { - struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr, - addrlen, 0); - struct infra_host_data* data; + struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, + nm, nmlen, 0); + struct infra_data* data; int wr = 0; - if(e && ((struct infra_host_data*)e->data)->ttl < timenow) { + if(e && ((struct infra_data*)e->data)->ttl < timenow) { /* it expired, try to reuse existing entry */ - int old = ((struct infra_host_data*)e->data)->rtt.rto; + int old = ((struct infra_data*)e->data)->rtt.rto; lock_rw_unlock(&e->lock); - e = infra_lookup_host_nottl(infra, addr, addrlen, 1); + e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1); if(e) { /* if its still there we have a writelock, init */ /* re-initialise */ /* do not touch lameness, it may be valid still */ - host_entry_init(infra, e, timenow); + data_entry_init(infra, e, timenow); wr = 1; /* TOP_TIMEOUT remains on reuse */ if(old >= USEFUL_SERVER_TOP_TIMEOUT) - ((struct infra_host_data*)e->data)->rtt.rto + ((struct infra_data*)e->data)->rtt.rto = USEFUL_SERVER_TOP_TIMEOUT; } } if(!e) { /* insert new entry */ - if(!(e = new_host_entry(infra, addr, addrlen, timenow))) + if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) return 0; - data = (struct infra_host_data*)e->data; - *to = rtt_timeout(&data->rtt); + data = (struct infra_data*)e->data; *edns_vs = data->edns_version; *edns_lame_known = data->edns_lame_known; + *to = rtt_timeout(&data->rtt); slabhash_insert(infra->hosts, e->hash, e, data, NULL); return 1; } /* use existing entry */ - data = (struct infra_host_data*)e->data; - *to = rtt_timeout(&data->rtt); + data = (struct infra_data*)e->data; *edns_vs = data->edns_version; *edns_lame_known = data->edns_lame_known; + *to = rtt_timeout(&data->rtt); if(*to >= PROBE_MAXRTO && rtt_notimeout(&data->rtt)*4 <= *to) { /* delay other queries, this is the probe query */ if(!wr) { lock_rw_unlock(&e->lock); - e = infra_lookup_host_nottl(infra, addr, addrlen, 1); + e = infra_lookup_nottl(infra, addr,addrlen,nm,nmlen, 1); if(!e) { /* flushed from cache real fast, no use to allocate just for the probedelay */ return 1; } - data = (struct infra_host_data*)e->data; + data = (struct infra_data*)e->data; } /* add 999 to round up the timeout value from msec to sec, * then add a whole second so it is certain that this probe @@ -315,170 +300,38 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr, return 1; } -/** hash lameness key */ -static hashvalue_t -hash_lameness(uint8_t* name) -{ - return dname_query_hash(name, 0xab); -} - -int -infra_lookup_lame(struct infra_host_data* host, - uint8_t* name, size_t namelen, uint32_t timenow, - int* dlame, int* rlame, int* alame, int* olame) -{ - struct lruhash_entry* e; - struct infra_lame_key k; - struct infra_lame_data *d; - if(!host->lameness) - return 0; - k.entry.hash = hash_lameness(name); - k.zonename = name; - k.namelen = namelen; - k.entry.key = (void*)&k; - k.entry.data = NULL; - e = lruhash_lookup(host->lameness, k.entry.hash, &k, 0); - if(!e) - return 0; - d = (struct infra_lame_data*)e->data; - if(d->ttl < timenow) { - lock_rw_unlock(&e->lock); - return 0; - } - *dlame = d->isdnsseclame; - *rlame = d->rec_lame; - *alame = d->lame_type_A; - *olame = d->lame_other; - lock_rw_unlock(&e->lock); - return *dlame || *rlame || *alame || *olame; -} - -size_t -infra_lame_sizefunc(void* k, void* ATTR_UNUSED(d)) -{ - struct infra_lame_key* key = (struct infra_lame_key*)k; - return sizeof(*key) + sizeof(struct infra_lame_data) - + key->namelen + lock_get_mem(&key->entry.lock); -} - -int -infra_lame_compfunc(void* key1, void* key2) -{ - struct infra_lame_key* k1 = (struct infra_lame_key*)key1; - struct infra_lame_key* k2 = (struct infra_lame_key*)key2; - if(k1->namelen != k2->namelen) { - if(k1->namelen < k2->namelen) - return -1; - return 1; - } - return query_dname_compare(k1->zonename, k2->zonename); -} - -void -infra_lame_delkeyfunc(void* k, void* ATTR_UNUSED(arg)) -{ - struct infra_lame_key* key = (struct infra_lame_key*)k; - if(!key) - return; - lock_rw_destroy(&key->entry.lock); - free(key->zonename); - free(key); -} - -void -infra_lame_deldatafunc(void* d, void* ATTR_UNUSED(arg)) -{ - if(!d) - return; - free(d); -} - int -infra_set_lame(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, - uint8_t* name, size_t namelen, uint32_t timenow, int dnsseclame, - int reclame, uint16_t qtype) +infra_set_lame(struct infra_cache* infra, struct sockaddr_storage* addr, + socklen_t addrlen, uint8_t* nm, size_t nmlen, uint32_t timenow, + int dnsseclame, int reclame, uint16_t qtype) { - struct infra_host_data* data; + struct infra_data* data; struct lruhash_entry* e; int needtoinsert = 0; - struct infra_lame_key* k; - struct infra_lame_data* d; - /* allocate at start, easier cleanup (no locks held) */ - k = (struct infra_lame_key*)malloc(sizeof(*k)); - if(!k) { - log_err("set_lame: malloc failure"); - return 0; - } - d = (struct infra_lame_data*)malloc(sizeof(*d)); - if(!d) { - free(k); - log_err("set_lame: malloc failure"); - return 0; - } - k->zonename = memdup(name, namelen); - if(!k->zonename) { - free(d); - free(k); - log_err("set_lame: malloc failure"); - return 0; - } - lock_rw_init(&k->entry.lock); - k->entry.hash = hash_lameness(name); - k->entry.key = (void*)k; - k->entry.data = (void*)d; - d->ttl = timenow + infra->lame_ttl; - d->isdnsseclame = dnsseclame; - d->rec_lame = reclame; - d->lame_type_A = (!dnsseclame && !reclame && qtype == LDNS_RR_TYPE_A); - d->lame_other = (!dnsseclame && !reclame && qtype != LDNS_RR_TYPE_A); - k->namelen = namelen; - e = infra_lookup_host_nottl(infra, addr, addrlen, 1); + e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1); if(!e) { /* insert it */ - if(!(e = new_host_entry(infra, addr, addrlen, timenow))) { - free(k->zonename); - free(k); - free(d); + if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) { log_err("set_lame: malloc failure"); return 0; } needtoinsert = 1; + } else if( ((struct infra_data*)e->data)->ttl < timenow) { + /* expired, reuse existing entry */ + data_entry_init(infra, e, timenow); } /* got an entry, now set the zone lame */ - data = (struct infra_host_data*)e->data; - if(!data->lameness) { - /* create hash table if not there already */ - data->lameness = lruhash_create(INFRA_LAME_STARTSIZE, - infra->max_lame_size, 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->hosts, - e->hash, e, e->data, NULL); - else { lock_rw_unlock(&e->lock); } - free(k->zonename); - free(k); - free(d); - return 0; - } - } else { - /* lookup existing lameness entry (if any) and merge data */ - int dlame, rlame, alame, olame; - if(infra_lookup_lame(data, name, namelen, timenow, - &dlame, &rlame, &alame, &olame)) { - /* merge data into new structure */ - if(dlame) d->isdnsseclame = 1; - if(rlame) d->rec_lame = 1; - if(alame) d->lame_type_A = 1; - if(olame) d->lame_other = 1; - } - } - - /* inserts new entry, or updates TTL of older entry */ - lruhash_insert(data->lameness, k->entry.hash, &k->entry, d, NULL); - + data = (struct infra_data*)e->data; + /* merge data (if any) */ + if(dnsseclame) + data->isdnsseclame = 1; + if(reclame) + data->rec_lame = 1; + if(!dnsseclame && !reclame && qtype == LDNS_RR_TYPE_A) + data->lame_type_A = 1; + if(!dnsseclame && !reclame && qtype != LDNS_RR_TYPE_A) + data->lame_other = 1; + /* done */ if(needtoinsert) slabhash_insert(infra->hosts, e->hash, e, e->data, NULL); else { lock_rw_unlock(&e->lock); } @@ -487,14 +340,15 @@ infra_set_lame(struct infra_cache* infra, void infra_update_tcp_works(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen) + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm, + size_t nmlen) { - struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr, - addrlen, 1); - struct infra_host_data* data; + struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, + nm, nmlen, 1); + struct infra_data* data; if(!e) return; /* doesn't exist */ - data = (struct infra_host_data*)e->data; + data = (struct infra_data*)e->data; if(data->rtt.rto >= RTT_MAX_TIMEOUT) /* do not disqualify this server altogether, it is better * than nothing */ @@ -503,24 +357,24 @@ infra_update_tcp_works(struct infra_cache* infra, } int -infra_rtt_update(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, - int roundtrip, int orig_rtt, uint32_t timenow) +infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr, + socklen_t addrlen, uint8_t* nm, size_t nmlen, int roundtrip, + int orig_rtt, uint32_t timenow) { - struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr, - addrlen, 1); - struct infra_host_data* data; + struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, + nm, nmlen, 1); + struct infra_data* data; int needtoinsert = 0; int rto = 1; if(!e) { - if(!(e = new_host_entry(infra, addr, addrlen, timenow))) + if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) return 0; needtoinsert = 1; - } else if(((struct infra_host_data*)e->data)->ttl < timenow) { - host_entry_init(infra, e, timenow); - } + } else if(((struct infra_data*)e->data)->ttl < timenow) { + data_entry_init(infra, e, timenow); + } /* have an entry, update the rtt */ - data = (struct infra_host_data*)e->data; + data = (struct infra_data*)e->data; if(roundtrip == -1) { rtt_lost(&data->rtt, orig_rtt); } else { @@ -537,15 +391,15 @@ infra_rtt_update(struct infra_cache* infra, } int infra_get_host_rto(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, - struct rtt_info* rtt, int* delay, uint32_t timenow) + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm, + size_t nmlen, struct rtt_info* rtt, int* delay, uint32_t timenow) { - struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr, - addrlen, 0); - struct infra_host_data* data; + struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, + nm, nmlen, 0); + struct infra_data* data; int ttl = -2; if(!e) return -1; - data = (struct infra_host_data*)e->data; + data = (struct infra_data*)e->data; if(data->ttl >= timenow) { ttl = (int)(data->ttl - timenow); memmove(rtt, &data->rtt, sizeof(*rtt)); @@ -558,23 +412,23 @@ int infra_get_host_rto(struct infra_cache* infra, } int -infra_edns_update(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, - int edns_version, uint32_t timenow) +infra_edns_update(struct infra_cache* infra, struct sockaddr_storage* addr, + socklen_t addrlen, uint8_t* nm, size_t nmlen, int edns_version, + uint32_t timenow) { - struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr, - addrlen, 1); - struct infra_host_data* data; + struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, + nm, nmlen, 1); + struct infra_data* data; int needtoinsert = 0; if(!e) { - if(!(e = new_host_entry(infra, addr, addrlen, timenow))) + if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) return 0; needtoinsert = 1; - } else if(((struct infra_host_data*)e->data)->ttl < timenow) { - host_entry_init(infra, e, timenow); - } + } else if(((struct infra_data*)e->data)->ttl < timenow) { + data_entry_init(infra, e, timenow); + } /* have an entry, update the rtt, and the ttl */ - data = (struct infra_host_data*)e->data; + data = (struct infra_data*)e->data; /* do not update if noEDNS and stored is yesEDNS */ if(!(edns_version == -1 && (data->edns_version != -1 && data->edns_lame_known))) { @@ -588,57 +442,23 @@ infra_edns_update(struct infra_cache* infra, return 1; } -int +int infra_get_lame_rtt(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, size_t namelen, uint16_t qtype, int* lame, int* dnsseclame, int* reclame, int* rtt, uint32_t timenow) { - struct infra_host_data* host; - struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr, - addrlen, 0); - int dlm, rlm, alm, olm; + struct infra_data* host; + struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, + name, namelen, 0); if(!e) return 0; - host = (struct infra_host_data*)e->data; + host = (struct infra_data*)e->data; *rtt = rtt_unclamped(&host->rtt); if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay && rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) /* single probe for this domain, and we are not probing */ *rtt = USEFUL_SERVER_TOP_TIMEOUT; - /* check lameness first, if so, ttl on host does not matter anymore */ - if(infra_lookup_lame(host, name, namelen, timenow, - &dlm, &rlm, &alm, &olm)) { - if(alm && qtype == LDNS_RR_TYPE_A) { - lock_rw_unlock(&e->lock); - *lame = 1; - *dnsseclame = 0; - *reclame = 0; - return 1; - } else if(olm && qtype != LDNS_RR_TYPE_A) { - lock_rw_unlock(&e->lock); - *lame = 1; - *dnsseclame = 0; - *reclame = 0; - return 1; - } else if(dlm) { - lock_rw_unlock(&e->lock); - *lame = 0; - *dnsseclame = 1; - *reclame = 0; - return 1; - } else if(rlm) { - lock_rw_unlock(&e->lock); - *lame = 0; - *dnsseclame = 0; - *reclame = 1; - return 1; - } - /* no lameness for this type of query */ - } - *lame = 0; - *dnsseclame = 0; - *reclame = 0; if(timenow > host->ttl) { /* expired entry */ /* see if this can be a re-probe of an unresponsive server */ @@ -652,43 +472,42 @@ infra_get_lame_rtt(struct infra_cache* infra, lock_rw_unlock(&e->lock); return 0; } + /* check lameness first */ + if(host->lame_type_A && qtype == LDNS_RR_TYPE_A) { + lock_rw_unlock(&e->lock); + *lame = 1; + *dnsseclame = 0; + *reclame = 0; + return 1; + } else if(host->lame_other && qtype != LDNS_RR_TYPE_A) { + lock_rw_unlock(&e->lock); + *lame = 1; + *dnsseclame = 0; + *reclame = 0; + return 1; + } else if(host->isdnsseclame) { + lock_rw_unlock(&e->lock); + *lame = 0; + *dnsseclame = 1; + *reclame = 0; + return 1; + } else if(host->rec_lame) { + lock_rw_unlock(&e->lock); + *lame = 0; + *dnsseclame = 0; + *reclame = 1; + return 1; + } + /* no lameness for this type of query */ lock_rw_unlock(&e->lock); + *lame = 0; + *dnsseclame = 0; + *reclame = 0; return 1; } -/** helper memory count for a host lame cache */ -static size_t -count_host_lame(struct lruhash_entry* e) -{ - struct infra_host_data* host_data = (struct infra_host_data*)e->data; - if(!host_data->lameness) - return 0; - return lruhash_get_mem(host_data->lameness); -} - size_t infra_get_mem(struct infra_cache* infra) { - size_t i, bin; - size_t s = sizeof(*infra) + - slabhash_get_mem(infra->hosts); - struct lruhash_entry* e; - for(i=0; ihosts->size; i++) { - lock_quick_lock(&infra->hosts->array[i]->lock); - for(bin=0; binhosts->array[i]->size; bin++) { - lock_quick_lock(&infra->hosts->array[i]-> - array[bin].lock); - /* count data size in bin items. */ - for(e = infra->hosts->array[i]->array[bin]. - overflow_list; e; e = e->overflow_next) { - lock_rw_rdlock(&e->lock); - s += count_host_lame(e); - lock_rw_unlock(&e->lock); - } - lock_quick_unlock(&infra->hosts->array[i]-> - array[bin].lock); - } - lock_quick_unlock(&infra->hosts->array[i]->lock); - } - return s; + return sizeof(*infra) + slabhash_get_mem(infra->hosts); } diff --git a/services/cache/infra.h b/services/cache/infra.h index 3d7f986f2..3a3508eac 100644 --- a/services/cache/infra.h +++ b/services/cache/infra.h @@ -47,65 +47,50 @@ struct slabhash; struct config_file; /** - * Host information kept for every server. + * Host information kept for every server, per zone. */ -struct infra_host_key { +struct infra_key { /** the host address. */ struct sockaddr_storage addr; /** length of addr. */ socklen_t addrlen; - /** hash table entry, data of type infra_host_data. */ + /** zone name in wireformat */ + uint8_t* zonename; + /** length of zonename */ + size_t namelen; + /** hash table entry, data of type infra_data. */ struct lruhash_entry entry; }; /** * Host information encompasses host capabilities and retransmission timeouts. + * And lameness information (notAuthoritative, noEDNS, Recursive) */ -struct infra_host_data { +struct infra_data { /** TTL value for this entry. absolute time. */ uint32_t ttl; + /** time in seconds (absolute) when probing re-commences, 0 disabled */ uint32_t probedelay; /** round trip times for timeout calculation */ struct rtt_info rtt; - /** Names of the zones that are lame. NULL=no lame zones. */ - struct lruhash* lameness; + /** edns version that the host supports, -1 means no EDNS */ int edns_version; /** if the EDNS lameness is already known or not. * EDNS lame is when EDNS queries or replies are dropped, * and cause a timeout */ uint8_t edns_lame_known; -}; -/** - * Lameness information, per host, per zone. - */ -struct infra_lame_key { - /** key is zone name in wireformat */ - uint8_t* zonename; - /** length of zonename */ - size_t namelen; - /** lruhash entry */ - struct lruhash_entry entry; -}; - -/** - * Lameness information. Expires. - * This host is lame because it is in the cache. - */ -struct infra_lame_data { - /** TTL of this entry. absolute time. */ - uint32_t ttl; /** is the host lame (does not serve the zone authoritatively), * or is the host dnssec lame (does not serve DNSSEC data) */ - int isdnsseclame; + uint8_t isdnsseclame; /** is the host recursion lame (not AA, but RA) */ - int rec_lame; + uint8_t rec_lame; /** the host is lame (not authoritative) for A records */ - int lame_type_A; + uint8_t lame_type_A; /** the host is lame (not authoritative) for other query types */ - int lame_other; + uint8_t lame_other; }; /** @@ -116,18 +101,12 @@ struct infra_cache { 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, in bytes */ - size_t max_lame_size; - /** jostle timeout in msec */ - size_t jostle; }; /** infra host cache default hash lookup size */ #define INFRA_HOST_STARTSIZE 32 -/** infra lame cache default hash lookup size */ -#define INFRA_LAME_STARTSIZE 2 +/** bytes per zonename reserved in the hostcache, dnamelen(zonename.com.) */ +#define INFRA_BYTES_NAME 14 /** * Create infra cache. @@ -142,10 +121,6 @@ struct infra_cache* infra_create(struct config_file* cfg); */ void infra_delete(struct infra_cache* infra); -/** explicitly delete an infra host element */ -void infra_remove_host(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen); - /** * Adjust infra cache to use updated configuration settings. * This may clean the cache. Operates a bit like realloc. @@ -158,18 +133,18 @@ struct infra_cache* infra_adjust(struct infra_cache* infra, struct config_file* cfg); /** - * Lookup host data + * Plain find infra data function (used by the the other functions) * @param infra: infrastructure cache. * @param addr: host address. * @param addrlen: length of addr. - * @param wr: set to true to get a writelock on the entry. - * @param timenow: what time it is now. - * @param key: the key for the host, returned so caller can unlock when done. - * @return: host data or NULL if not found or expired. + * @param name: domain name of zone. + * @param namelen: length of domain name. + * @param wr: if true, writelock, else readlock. + * @return the entry, could be expired (this is not checked) or NULL. */ -struct infra_host_data* infra_lookup_host(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, int wr, - uint32_t timenow, struct infra_host_key** key); +struct lruhash_entry* infra_lookup_nottl(struct infra_cache* infra, + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, + size_t namelen, int wr); /** * Find host information to send a packet. Creates new entry if not found. @@ -180,6 +155,8 @@ struct infra_host_data* infra_lookup_host(struct infra_cache* infra, * @param infra: infrastructure cache. * @param addr: host address. * @param addrlen: length of addr. + * @param name: domain name of zone. + * @param namelen: length of domain name. * @param timenow: what time it is now. * @param edns_vs: edns version it supports, is returned. * @param edns_lame_known: if EDNS lame (EDNS is dropped in transit) has @@ -188,25 +165,8 @@ struct infra_host_data* infra_lookup_host(struct infra_cache* infra, * @return: 0 on error. */ int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr, - socklen_t addrlen, uint32_t timenow, int* edns_vs, - uint8_t* edns_lame_known, int* to); - -/** - * Check for lameness of this server for a particular zone. - * You must have a lock on the host structure. - * @param host: infrastructure cache data for the host. Caller holds lock. - * @param name: domain name of zone apex. - * @param namelen: length of domain name. - * @param timenow: what time it is now. - * @param dlame: if the function returns true, is set true if dnssec lame. - * @param rlame: if the function returns true, is set true if recursion lame. - * @param alame: if the function returns true, is set true if qtype A lame. - * @param olame: if the function returns true, is set true if qtype other lame. - * @return: 0 if not lame or unknown or timed out, 1 if lame - */ -int infra_lookup_lame(struct infra_host_data* host, - uint8_t* name, size_t namelen, uint32_t timenow, - int* dlame, int* rlame, int* alame, int* olame); + socklen_t addrlen, uint8_t* name, size_t namelen, + uint32_t timenow, int* edns_vs, uint8_t* edns_lame_known, int* to); /** * Set a host to be lame for the given zone. @@ -233,6 +193,8 @@ int infra_set_lame(struct infra_cache* infra, * @param infra: infrastructure cache. * @param addr: host address. * @param addrlen: length of addr. + * @param name: zone name + * @param namelen: zone name length * @param roundtrip: estimate of roundtrip time in milliseconds or -1 for * timeout. * @param orig_rtt: original rtt for the query that timed out (roundtrip==-1). @@ -240,8 +202,8 @@ int infra_set_lame(struct infra_cache* infra, * @param timenow: what time it is now. * @return: 0 on error. new rto otherwise. */ -int infra_rtt_update(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, +int infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr, + socklen_t addrlen, uint8_t* name, size_t namelen, int roundtrip, int orig_rtt, uint32_t timenow); /** @@ -249,15 +211,20 @@ int infra_rtt_update(struct infra_cache* infra, * @param infra: infrastructure cache. * @param addr: host address. * @param addrlen: length of addr. + * @param name: name of zone + * @param namelen: length of name */ void infra_update_tcp_works(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen); + struct sockaddr_storage* addr, socklen_t addrlen, + uint8_t* name, size_t namelen); /** * Update edns information for the host. * @param infra: infrastructure cache. * @param addr: host address. * @param addrlen: length of addr. + * @param name: name of zone + * @param namelen: length of name * @param edns_version: the version that it publishes. * If it is known to support EDNS then no-EDNS is not stored over it. * @param timenow: what time it is now. @@ -265,7 +232,7 @@ void infra_update_tcp_works(struct infra_cache* infra, */ int infra_edns_update(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, - int edns_version, uint32_t timenow); + uint8_t* name, size_t namelen, int edns_version, uint32_t timenow); /** * Get Lameness information and average RTT if host is in the cache. @@ -295,6 +262,8 @@ int infra_get_lame_rtt(struct infra_cache* infra, * @param infra: infra cache. * @param addr: host address. * @param addrlen: length of addr. + * @param name: zone name + * @param namelen: zone name length * @param rtt: the rtt_info is copied into here (caller alloced return struct). * @param delay: probe delay (if any). * @param timenow: what time it is now. @@ -302,8 +271,8 @@ int infra_get_lame_rtt(struct infra_cache* infra, * TTL -2: found but expired. */ int infra_get_host_rto(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, - struct rtt_info* rtt, int* delay, uint32_t timenow); + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, + size_t namelen, struct rtt_info* rtt, int* delay, uint32_t timenow); /** * Get memory used by the infra cache. @@ -314,28 +283,15 @@ size_t infra_get_mem(struct infra_cache* infra); /** calculate size for the hashtable, does not count size of lameness, * so the hashtable is a fixed number of items */ -size_t infra_host_sizefunc(void* k, void* d); +size_t infra_sizefunc(void* k, void* d); /** compare two addresses, returns -1, 0, or +1 */ -int infra_host_compfunc(void* key1, void* key2); +int infra_compfunc(void* key1, void* key2); /** delete key, and destroy the lock */ -void infra_host_delkeyfunc(void* k, void* arg); +void infra_delkeyfunc(void* k, void* arg); /** delete data and destroy the lameness hashtable */ -void infra_host_deldatafunc(void* d, void* arg); - -/** calculate size, which is fixed, zonename does not count so that - * a fixed number of items is stored */ -size_t infra_lame_sizefunc(void* k, void* d); - -/** compare zone names, returns -1, 0, +1 */ -int infra_lame_compfunc(void* key1, void* key2); - -/** free key, lock and zonename */ -void infra_lame_delkeyfunc(void* k, void* arg); - -/** free the lameness data */ -void infra_lame_deldatafunc(void* d, void* arg); +void infra_deldatafunc(void* d, void* arg); #endif /* SERVICES_CACHE_INFRA_H */ diff --git a/services/outside_network.c b/services/outside_network.c index b3c1220ba..8d93d1892 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -669,6 +669,7 @@ serviced_node_del(rbnode_t* node, void* ATTR_UNUSED(arg)) struct serviced_query* sq = (struct serviced_query*)node; struct service_callback* p = sq->cblist, *np; free(sq->qbuf); + free(sq->zone); while(p) { np = p->next; free(p); @@ -1143,7 +1144,7 @@ lookup_serviced(struct outside_network* outnet, ldns_buffer* buff, int dnssec, static struct serviced_query* serviced_create(struct outside_network* outnet, ldns_buffer* buff, int dnssec, int want_dnssec, int tcp_upstream, struct sockaddr_storage* addr, - socklen_t addrlen) + socklen_t addrlen, uint8_t* zone, size_t zonelen) { struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq)); #ifdef UNBOUND_DEBUG @@ -1158,6 +1159,13 @@ serviced_create(struct outside_network* outnet, ldns_buffer* buff, int dnssec, return NULL; } sq->qbuflen = ldns_buffer_limit(buff); + sq->zone = memdup(zone, zonelen); + if(!sq->zone) { + free(sq->qbuf); + free(sq); + return NULL; + } + sq->zonelen = zonelen; sq->dnssec = dnssec; sq->want_dnssec = want_dnssec; sq->tcp_upstream = tcp_upstream; @@ -1324,8 +1332,8 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff) uint8_t edns_lame_known; uint32_t now = *sq->outnet->now_secs; - if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, now, &vs, - &edns_lame_known, &rtt)) + if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, sq->zone, + sq->zonelen, now, &vs, &edns_lame_known, &rtt)) return 0; sq->last_rtt = rtt; verbose(VERB_ALGO, "EDNS lookup known=%d vs=%d", edns_lame_known, vs); @@ -1495,7 +1503,7 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error, &sq->addr, sq->addrlen); if(error==NETEVENT_NOERROR) infra_update_tcp_works(sq->outnet->infra, &sq->addr, - sq->addrlen); + sq->addrlen, sq->zone, sq->zonelen); if(error==NETEVENT_NOERROR && sq->status == serviced_query_TCP_EDNS && (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) == LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(ldns_buffer_begin( @@ -1516,7 +1524,8 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error, /* only store noEDNS in cache if domain is noDNSSEC */ if(!sq->want_dnssec) if(!infra_edns_update(sq->outnet->infra, &sq->addr, - sq->addrlen, -1, *sq->outnet->now_secs)) + sq->addrlen, sq->zone, sq->zonelen, -1, + *sq->outnet->now_secs)) log_err("Out of memory caching no edns for host"); sq->status = serviced_query_TCP; } @@ -1531,7 +1540,8 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error, verbose(VERB_ALGO, "measured TCP-time at %d msec", roundtime); log_assert(roundtime >= 0); if(!infra_rtt_update(sq->outnet->infra, &sq->addr, sq->addrlen, - roundtime, sq->last_rtt, (uint32_t)now.tv_sec)) + sq->zone, sq->zonelen, roundtime, sq->last_rtt, + (uint32_t)now.tv_sec)) log_err("out of memory noting rtt."); } } @@ -1572,8 +1582,9 @@ serviced_tcp_send(struct serviced_query* sq, ldns_buffer* buff) { int vs, rtt; uint8_t edns_lame_known; - if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, - *sq->outnet->now_secs, &vs, &edns_lame_known, &rtt)) + if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, sq->zone, + sq->zonelen, *sq->outnet->now_secs, &vs, &edns_lame_known, + &rtt)) return 0; if(vs != -1) sq->status = serviced_query_TCP_EDNS; @@ -1620,7 +1631,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, } sq->retry++; if(!(rto=infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen, - -1, sq->last_rtt, (uint32_t)now.tv_sec))) + sq->zone, sq->zonelen, -1, sq->last_rtt, + (uint32_t)now.tv_sec))) log_err("out of memory in UDP exponential backoff"); if(sq->retry < OUTBOUND_UDP_RETRY) { log_name_addr(VERB_ALGO, "retry query", sq->qbuf+10, @@ -1664,7 +1676,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, /* only store noEDNS in cache if domain is noDNSSEC */ if(!sq->want_dnssec) if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen, - -1, (uint32_t)now.tv_sec)) { + sq->zone, sq->zonelen, -1, (uint32_t)now.tv_sec)) { log_err("Out of memory caching no edns for host"); } sq->status = serviced_query_UDP; @@ -1674,7 +1686,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, log_addr(VERB_ALGO, "serviced query: EDNS works for", &sq->addr, sq->addrlen); if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen, - 0, (uint32_t)now.tv_sec)) { + sq->zone, sq->zonelen, 0, (uint32_t)now.tv_sec)) { log_err("Out of memory caching edns works"); } sq->edns_lame_known = 1; @@ -1691,7 +1703,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, log_addr(VERB_ALGO, "serviced query: EDNS fails for", &sq->addr, sq->addrlen); if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen, - -1, (uint32_t)now.tv_sec)) { + sq->zone, sq->zonelen, -1, (uint32_t)now.tv_sec)) { log_err("Out of memory caching no edns for host"); } } else { @@ -1710,7 +1722,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, verbose(VERB_ALGO, "measured roundtrip at %d msec", roundtime); log_assert(roundtime >= 0); if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen, - roundtime, sq->last_rtt, (uint32_t)now.tv_sec)) + sq->zone, sq->zonelen, roundtime, sq->last_rtt, + (uint32_t)now.tv_sec)) log_err("out of memory noting rtt."); } } /* end of if_!fallback_tcp */ @@ -1750,8 +1763,8 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream, - struct sockaddr_storage* addr, socklen_t addrlen, - comm_point_callback_t* callback, void* callback_arg, + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, + size_t zonelen, comm_point_callback_t* callback, void* callback_arg, ldns_buffer* buff, int (*arg_compare)(void*,void*)) { struct serviced_query* sq; @@ -1769,7 +1782,7 @@ outnet_serviced_query(struct outside_network* outnet, if(!sq) { /* make new serviced query entry */ sq = serviced_create(outnet, buff, dnssec, want_dnssec, - tcp_upstream, addr, addrlen); + tcp_upstream, addr, addrlen, zone, zonelen); if(!sq) { free(cb); return NULL; diff --git a/services/outside_network.h b/services/outside_network.h index accf84818..798b0d453 100644 --- a/services/outside_network.h +++ b/services/outside_network.h @@ -304,6 +304,10 @@ struct serviced_query { struct sockaddr_storage addr; /** length of addr field in use. */ socklen_t addrlen; + /** zone name, uncompressed domain name in wireformat */ + uint8_t* zone; + /** length of zone name */ + size_t zonelen; /** current status */ enum serviced_query_status { /** initial status */ @@ -449,6 +453,10 @@ void pending_delete(struct outside_network* outnet, struct pending* p); * @param callback_arg: user argument to callback function. * @param addr: to which server to send the query. * @param addrlen: length of addr. + * @param zone: name of the zone of the delegation point. wireformat dname. + This is the delegation point name for which the server is deemed + authoritative. + * @param zonelen: length of zone. * @param buff: scratch buffer to create query contents in. Empty on exit. * @param arg_compare: function to compare callback args, return true if * identical. It is given the callback_arg and args that are listed. @@ -458,8 +466,8 @@ void pending_delete(struct outside_network* outnet, struct pending* p); struct serviced_query* outnet_serviced_query(struct outside_network* outnet, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream, - struct sockaddr_storage* addr, socklen_t addrlen, - comm_point_callback_t* callback, void* callback_arg, + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, + size_t zonelen, comm_point_callback_t* callback, void* callback_arg, ldns_buffer* buff, int (*arg_compare)(void*,void*)); /** diff --git a/testcode/fake_event.c b/testcode/fake_event.c index e7d1b6b5a..dc62496a7 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -51,6 +51,7 @@ #include "util/data/msgparse.h" #include "util/data/msgreply.h" #include "util/data/msgencode.h" +#include "util/data/dname.h" #include "util/config_file.h" #include "services/listen_dnsport.h" #include "services/outside_network.h" @@ -548,11 +549,17 @@ static void do_infra_rtt(struct replay_runtime* runtime) { struct replay_moment* now = runtime->now; - int rto = infra_rtt_update(runtime->infra, &now->addr, - now->addrlen, atoi(now->string), -1, runtime->now_secs); + int rto; + ldns_rdf* dp = ldns_dname_new_frm_str(now->variable); + if(!dp) fatal_exit("cannot parse %s", now->variable); + rto = infra_rtt_update(runtime->infra, &now->addr, + now->addrlen, ldns_rdf_data(dp), ldns_rdf_size(dp), + atoi(now->string), -1, runtime->now_secs); log_addr(0, "INFRA_RTT for", &now->addr, now->addrlen); - log_info("INFRA_RTT(roundtrip %d): rto of %d", atoi(now->string), rto); + log_info("INFRA_RTT(%s roundtrip %d): rto of %d", now->variable, + atoi(now->string), rto); if(rto == 0) fatal_exit("infra_rtt_update failed"); + ldns_rdf_deep_free(dp); } /** @@ -1008,19 +1015,22 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(tcp_upstream), struct sockaddr_storage* addr, - socklen_t addrlen, comm_point_callback_t* callback, void* callback_arg, + socklen_t addrlen, uint8_t* zone, size_t ATTR_UNUSED(zonelen), + comm_point_callback_t* callback, void* callback_arg, ldns_buffer* ATTR_UNUSED(buff), int (*arg_compare)(void*,void*)) { struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; struct fake_pending* pend = (struct fake_pending*)calloc(1, sizeof(struct fake_pending)); + char z[256]; ldns_status status; (void)arg_compare; log_assert(pend); log_nametypeclass(VERB_OPS, "pending serviced query", qname, qtype, qclass); - verbose(VERB_OPS, "pending serviced query flags%s%s%s%s", - (flags&BIT_RD)?" RD":"", (flags&BIT_CD)?" CD":"", + dname_str(zone, z); + verbose(VERB_OPS, "pending serviced query zone %s flags%s%s%s%s", + z, (flags&BIT_RD)?" RD":"", (flags&BIT_CD)?" CD":"", (flags&~(BIT_RD|BIT_CD))?" MORE":"", (dnssec)?" DO":""); /* create packet with EDNS */ diff --git a/testcode/replay.c b/testcode/replay.c index c8b23fee1..3d3aa01a0 100644 --- a/testcode/replay.c +++ b/testcode/replay.c @@ -331,23 +331,31 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno, mom->evt_type = repevt_assign; read_assign_step(remain, mom); } else if(parse_keyword(&remain, "INFRA_RTT")) { - char *s; + char *s, *m; mom->evt_type = repevt_infra_rtt; while(isspace((int)*remain)) remain++; s = remain; remain = strchr(s, ' '); - if(!remain) fatal_exit("expected two args for INFRA_RTT"); + if(!remain) fatal_exit("expected three args for INFRA_RTT"); remain[0] = 0; remain++; while(isspace((int)*remain)) remain++; + m = strchr(remain, ' '); + if(!m) fatal_exit("expected three args for INFRA_RTT"); + m[0] = 0; + m++; + while(isspace((int)*m)) + m++; if(!extstrtoaddr(s, &mom->addr, &mom->addrlen)) fatal_exit("bad infra_rtt address %s", s); - if(strlen(remain)>0 && remain[strlen(remain)-1]=='\n') - remain[strlen(remain)-1] = 0; - mom->string = strdup(remain); + if(strlen(m)>0 && m[strlen(m)-1]=='\n') + m[strlen(m)-1] = 0; + mom->variable = strdup(remain); + mom->string = strdup(m); if(!mom->string) fatal_exit("out of memory"); + if(!mom->variable) fatal_exit("out of memory"); } else { log_err("%d: unknown event type %s", *lineno, remain); free(mom); diff --git a/testcode/replay.h b/testcode/replay.h index 07f602e04..96814ed2d 100644 --- a/testcode/replay.h +++ b/testcode/replay.h @@ -75,7 +75,7 @@ * the step waits for traffic to stop. * o CHECK_AUTOTRUST [id] - followed by FILE_BEGIN [to match] FILE_END. * The file contents is macro expanded before match. - * o INFRA_RTT [ip] [rtt] - update infra cache entry with rtt. + * o INFRA_RTT [ip] [dp] [rtt] - update infra cache entry with rtt. * o ERROR * ; following entry starts on the next line, ENTRY_BEGIN. * ; more STEP items diff --git a/testcode/unitmain.c b/testcode/unitmain.c index aac49586f..fc69878cd 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -401,6 +401,25 @@ rtt_test(void) #include "services/cache/infra.h" #include "util/config_file.h" + +/* lookup and get key and data structs easily */ +static struct infra_data* infra_lookup_host(struct infra_cache* infra, + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, + size_t zonelen, int wr, uint32_t now, struct infra_key** k) +{ + struct infra_data* d; + struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, + zone, zonelen, wr); + if(!e) return NULL; + d = (struct infra_data*)e->data; + if(d->ttl < now) { + lock_rw_unlock(&e->lock); + return NULL; + } + *k = (struct infra_key*)e->key; + return d; +} + /** test host cache */ static void infra_test(void) @@ -414,70 +433,63 @@ infra_test(void) uint32_t now = 0; uint8_t edns_lame; int vs, to; - struct infra_host_key* k; - struct infra_host_data* d; + struct infra_key* k; + struct infra_data* d; int init = 376; - int dlame, rlame, alame, olame; unit_show_feature("infra cache"); unit_assert(ipstrtoaddr("127.0.0.1", 53, &one, &onelen)); slab = infra_create(cfg); - unit_assert( infra_host(slab, (struct sockaddr_storage*)&one, - (socklen_t)sizeof(int), now, &vs, &edns_lame, &to) ); + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now, + &vs, &edns_lame, &to) ); unit_assert( vs == 0 && to == init && edns_lame == 0 ); - unit_assert( infra_rtt_update(slab, &one, onelen, -1, init, now) ); - unit_assert( infra_host(slab, &one, onelen, + unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen, -1, init, now) ); + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now, &vs, &edns_lame, &to) ); unit_assert( vs == 0 && to == init*2 && edns_lame == 0 ); - unit_assert( infra_edns_update(slab, &one, onelen, -1, now) ); - unit_assert( infra_host(slab, &one, onelen, + unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) ); + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now, &vs, &edns_lame, &to) ); unit_assert( vs == -1 && to == init*2 && edns_lame == 1); now += cfg->host_ttl + 10; - unit_assert( infra_host(slab, &one, onelen, + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now, &vs, &edns_lame, &to) ); unit_assert( vs == 0 && to == init && edns_lame == 0 ); - unit_assert( infra_set_lame(slab, &one, onelen, + unit_assert( infra_set_lame(slab, &one, onelen, zone, zonelen, now, 0, 0, LDNS_RR_TYPE_A) ); - unit_assert( (d=infra_lookup_host(slab, &one, onelen, 0, now, &k)) ); + unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 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, - &dlame, &rlame, &alame, &olame) ); - unit_assert(!dlame && !rlame && alame && !olame); - unit_assert( !infra_lookup_lame(d, zone, zonelen, - now+cfg->lame_ttl+10, &dlame, &rlame, &alame, &olame) ); - unit_assert( !infra_lookup_lame(d, (uint8_t*)"\000", 1, now, - &dlame, &rlame, &alame, &olame) ); + unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A && + !d->lame_other); lock_rw_unlock(&k->entry.lock); /* test merge of data */ - unit_assert( infra_set_lame(slab, &one, onelen, + unit_assert( infra_set_lame(slab, &one, onelen, zone, zonelen, now, 0, 0, LDNS_RR_TYPE_AAAA) ); - unit_assert( (d=infra_lookup_host(slab, &one, onelen, 0, now, &k)) ); - unit_assert( infra_lookup_lame(d, zone, zonelen, now, - &dlame, &rlame, &alame, &olame) ); - unit_assert(!dlame && !rlame && alame && olame); + unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) ); + unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A && + d->lame_other); lock_rw_unlock(&k->entry.lock); /* test that noEDNS cannot overwrite known-yesEDNS */ now += cfg->host_ttl + 10; - unit_assert( infra_host(slab, &one, onelen, + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now, &vs, &edns_lame, &to) ); unit_assert( vs == 0 && to == init && edns_lame == 0 ); - unit_assert( infra_edns_update(slab, &one, onelen, 0, now) ); - unit_assert( infra_host(slab, &one, onelen, + unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, 0, now) ); + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now, &vs, &edns_lame, &to) ); unit_assert( vs == 0 && to == init && edns_lame == 1 ); - unit_assert( infra_edns_update(slab, &one, onelen, -1, now) ); - unit_assert( infra_host(slab, &one, onelen, + unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) ); + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now, &vs, &edns_lame, &to) ); unit_assert( vs == 0 && to == init && edns_lame == 1 ); diff --git a/testdata/iter_lame_nosoa.rpl b/testdata/iter_lame_nosoa.rpl index fac181388..903bb29bc 100644 --- a/testdata/iter_lame_nosoa.rpl +++ b/testdata/iter_lame_nosoa.rpl @@ -238,7 +238,7 @@ RANGE_END ; store bad timing for one server to influence server selection ; 1.2.3.44 (ns.example.net) gets 900 msec. ; so the 376 ns.example.com is preferred. -STEP 1 INFRA_RTT 1.2.3.44 900 +STEP 1 INFRA_RTT 1.2.3.44 example.net. 900 STEP 10 QUERY ENTRY_BEGIN diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c index dd54b3145..cf3ebf6fc 100644 --- a/util/fptr_wlist.c +++ b/util/fptr_wlist.c @@ -194,9 +194,8 @@ fptr_whitelist_hash_sizefunc(lruhash_sizefunc_t fptr) { if(fptr == &msgreply_sizefunc) return 1; else if(fptr == &ub_rrset_sizefunc) return 1; - else if(fptr == &infra_host_sizefunc) return 1; + else if(fptr == &infra_sizefunc) return 1; else if(fptr == &key_entry_sizefunc) return 1; - else if(fptr == &infra_lame_sizefunc) return 1; else if(fptr == &test_slabhash_sizefunc) return 1; return 0; } @@ -206,9 +205,8 @@ fptr_whitelist_hash_compfunc(lruhash_compfunc_t fptr) { if(fptr == &query_info_compare) return 1; else if(fptr == &ub_rrset_compare) return 1; - else if(fptr == &infra_host_compfunc) return 1; + else if(fptr == &infra_compfunc) return 1; else if(fptr == &key_entry_compfunc) return 1; - else if(fptr == &infra_lame_compfunc) return 1; else if(fptr == &test_slabhash_compfunc) return 1; return 0; } @@ -218,9 +216,8 @@ fptr_whitelist_hash_delkeyfunc(lruhash_delkeyfunc_t fptr) { if(fptr == &query_entry_delete) return 1; else if(fptr == &ub_rrset_key_delete) return 1; - else if(fptr == &infra_host_delkeyfunc) return 1; + else if(fptr == &infra_delkeyfunc) return 1; else if(fptr == &key_entry_delkeyfunc) return 1; - else if(fptr == &infra_lame_delkeyfunc) return 1; else if(fptr == &test_slabhash_delkey) return 1; return 0; } @@ -230,9 +227,8 @@ fptr_whitelist_hash_deldatafunc(lruhash_deldatafunc_t fptr) { if(fptr == &reply_info_delete) return 1; else if(fptr == &rrset_data_delete) return 1; - else if(fptr == &infra_host_deldatafunc) return 1; + else if(fptr == &infra_deldatafunc) return 1; else if(fptr == &key_entry_deldatafunc) return 1; - else if(fptr == &infra_lame_deldatafunc) return 1; else if(fptr == &test_slabhash_deldata) return 1; return 0; } @@ -251,6 +247,7 @@ fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)( uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen, + uint8_t* zone, size_t zonelen, struct module_qstate* q)) { if(fptr == &worker_send_query) return 1; diff --git a/util/fptr_wlist.h b/util/fptr_wlist.h index 25963320b..fc4a31638 100644 --- a/util/fptr_wlist.h +++ b/util/fptr_wlist.h @@ -197,6 +197,7 @@ int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)( uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen, + uint8_t* zone, size_t zonelen, struct module_qstate* q)); /** diff --git a/util/module.h b/util/module.h index 076f7c26b..41caab437 100644 --- a/util/module.h +++ b/util/module.h @@ -100,6 +100,8 @@ struct module_env { * EDNS, the answer is likely to be useless for this domain. * @param addr: where to. * @param addrlen: length of addr. + * @param zone: delegation point name. + * @param zonelen: length of zone name. * @param q: wich query state to reactivate upon return. * @return: false on failure (memory or socket related). no query was * sent. Or returns an outbound entry with qsent and qstate set. @@ -109,7 +111,8 @@ struct module_env { struct outbound_entry* (*send_query)(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec, struct sockaddr_storage* addr, - socklen_t addrlen, struct module_qstate* q); + socklen_t addrlen, uint8_t* zone, size_t zonelen, + struct module_qstate* q); /** * Detach-subqueries. -- 2.47.2