]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
infra cache consolidated and stores per zone, IP.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 26 Oct 2011 15:46:23 +0000 (15:46 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 26 Oct 2011 15:46:23 +0000 (15:46 +0000)
git-svn-id: file:///svn/unbound/trunk@2525 be551aaa-1e26-0410-a405-d3ace91eadb9

20 files changed:
daemon/cachedump.c
daemon/remote.c
daemon/worker.c
daemon/worker.h
doc/Changelog
iterator/iterator.c
libunbound/libworker.c
libunbound/libworker.h
services/cache/infra.c
services/cache/infra.h
services/outside_network.c
services/outside_network.h
testcode/fake_event.c
testcode/replay.c
testcode/replay.h
testcode/unitmain.c
testdata/iter_lame_nosoa.rpl
util/fptr_wlist.c
util/fptr_wlist.h
util/module.h

index 242931a0950b21c4da83f706bb414771b6a7d540..b3010a0d4f8e06428aeaa7dc225320289e58aaad 100644 (file)
@@ -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"))
index 67d50517a4cee05be164b29ea604031de471addb..ba54d78b3fe1a0830b5691476c8984179558ae16 100644 (file)
@@ -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->now<d->probedelay?d->probedelay-a->now:0)))
+               (int)(a->now<d->probedelay?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 */
index 538d01a113b95435cb582877859c26930ab1c63b..e16afe5b7e027fcfd1f1fdea31775c173e097226 100644 (file)
@@ -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) {
index 8f7066a7c29ddfc76e7673e098ae0d90a1ac08d6..96c04676a11bce660891819ce1b1da9a75312fe2 100644 (file)
@@ -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 
index c7f9dcb1ba3716b83ce744b45b65c2f6653c1b09..e0bc1142d248b65bd18bf8b40c8a14879bbd2deb 100644 (file)
@@ -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
index a310877de77e81a1353803559994b88e297e44d6..468d3d178e6cbdb4da22c669a51a0483e1808b9f 100644 (file)
@@ -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);
index 6aa19e203311557a852a561cbd7757329570eb9d..1c56f7ed68774554921b279d06ff227afa2a9ec7 100644 (file)
@@ -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) {
index 7aa35126ab489deb7bf5b2520cc93401d1db7f9c..fea480c0c665c99014d7a14a4ded67585c82f5ef 100644 (file)
@@ -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,
index cbc603ebfbdcceabfcbe177e72d455cb94adefd9..cd53ef858e4dbcf41102b6a60894e23a939684b2 100644 (file)
 #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; i<infra->hosts->size; i++) {
-               lock_quick_lock(&infra->hosts->array[i]->lock);
-               for(bin=0; bin<infra->hosts->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);
 }
index 3d7f986f2cd36638da642e4027f31f7d69880ecc..3a3508eac4029124fb76e08b41b4629997dc8341 100644 (file)
@@ -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 */
index b3c1220baac49874349091fb5224dafe2f918bc0..8d93d18924c20e52e56a21dbf78335287c7ec735 100644 (file)
@@ -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;
index accf848189d5f403576928e3a56c0a9252b96761..798b0d453a8d40c2ae59089d1ab363cdb1749493 100644 (file)
@@ -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*));
 
 /**
index e7d1b6b5a7aa7cd6268ddabcb1d31e621b68c469..dc62496a72412c5b8d9bde8068e980a1a9ab52bb 100644 (file)
@@ -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 */
index c8b23fee196b00fa9fd400f9b3ed38e35446522d..3d3aa01a08d1014d97cf1cbf3b0b24c8703abc54 100644 (file)
@@ -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);
index 07f602e04232e57c8c73431d4cdfeefb44e19a42..96814ed2dd06bf8da4aa1ea09ae135e339ac45b1 100644 (file)
@@ -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
index aac49586f9e560b6285957d597e9e5404783041c..fc69878cd8084a0909cb6088ed84f193e2d382b8 100644 (file)
@@ -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 );
 
index fac18138845c42564d15eafaf28f406011187390..903bb29bc99ff7fa5d84f1ce955e59f3ec324791 100644 (file)
@@ -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
index dd54b3145b905a182d550135e1a403a8ecc3d56c..cf3ebf6fcf9b9995bfcfdc4f37c10e937764522f 100644 (file)
@@ -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;
index 25963320b3041826c9510ebeea13fa7e970c5c7e..fc4a316389514664c4b82b63b0a400429f757e24 100644 (file)
@@ -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));
 
 /**
index 076f7c26be1862a34159b40dd608ff3a98b08f5c..41caab4376769f5d484b859f5624a4d029648ab1 100644 (file)
@@ -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.