]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
DLV negative cache works.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 21 Aug 2008 10:43:45 +0000 (10:43 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 21 Aug 2008 10:43:45 +0000 (10:43 +0000)
git-svn-id: file:///svn/unbound/trunk@1200 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
validator/val_neg.c
validator/validator.c
validator/validator.h

index 63495ee94f143f88ffc5798d1a4dbbd01770761e..01808e65d34073f3238288ae7ab7a202ad30313c 100644 (file)
@@ -1,3 +1,7 @@
+21 August 2008: Wouter
+       - negative cache code linked into validator, for DLV use.
+         negative cache works for DLV.
+
 20 August 2008: Wouter
        - negative cache code, reviewed.
 
index 85152a70bd4b71ab866346482057b07188ec81a0..29fd2d0065237bb2d34826346f41565fccffa8e1 100644 (file)
@@ -464,7 +464,7 @@ static struct val_neg_zone* neg_zone_chain(
        struct val_neg_zone* parent)
 {
        int i;
-       int tolabs = parent?parent->labs:-1;
+       int tolabs = parent?parent->labs:0;
        struct val_neg_zone* zone, *prev = NULL, *first = NULL;
 
        /* create the new subtree, i is labelcount of current creation */
@@ -612,7 +612,7 @@ static struct val_neg_data* neg_data_chain(
        uint8_t* nm, size_t nm_len, int labs, struct val_neg_data* parent)
 {
        int i;
-       int tolabs = parent?parent->labs:-1;
+       int tolabs = parent?parent->labs:0;
        struct val_neg_data* el, *first = NULL, *prev = NULL;
 
        /* create the new subtree, i is labelcount of current creation */
@@ -680,11 +680,11 @@ static void wipeout(struct val_neg_cache* neg, struct val_neg_zone* zone,
        }
 
        walk = rbtree_next(&el->node);
-       while( walk ) {
+       while(walk && walk != RBTREE_NULL) {
                cur = (struct val_neg_data*)walk;
                /* sanity check: must be larger than start */
-               if(dname_canon_lab_cmp(el->name, el->labs, 
-                       cur->name, cur->labs, &m) <= 0) {
+               if(dname_canon_lab_cmp(cur->name, cur->labs, 
+                       el->name, el->labs, &m) <= 0) {
                        /* r == 0 skip original record. */
                        /* r < 0  too small! */
                        walk = rbtree_next(walk);
@@ -738,6 +738,8 @@ static void neg_insert_data(struct val_neg_cache* neg,
        d = (struct packed_rrset_data*)nsec->entry.data;
        if(d->security != sec_status_secure)
                return;
+       log_nametypeclass(VERB_ALGO, "negcache rr", 
+               nsec->rk.dname, LDNS_RR_TYPE_NSEC, ntohs(nsec->rk.rrset_class));
 
        /* find closest enclosing parent data that (still) exists */
        parent = neg_closest_data_parent(zone, nm, nm_len, labs);
@@ -766,6 +768,7 @@ static void neg_insert_data(struct val_neg_cache* neg,
                        /* mem use */
                        neg->use += sizeof(struct val_neg_data) + p->len;
                        /* insert in tree */
+                       p->zone = zone;
                        (void)rbtree_insert(&zone->tree, &p->node);
                        /* last one needs proper parent pointer */
                        if(np == NULL)
@@ -806,6 +809,9 @@ void val_neg_addreply(struct val_neg_cache* neg, struct reply_info* rep)
        if(!soa)
                return;
 
+       log_nametypeclass(VERB_ALGO, "negcache insert for zone",
+               soa->rk.dname, LDNS_RR_TYPE_SOA, ntohs(soa->rk.rrset_class));
+       
        /* ask for enough space to store all of it */
        need = calc_data_need(rep) + calc_zone_need(soa);
        lock_basic_lock(&neg->lock);
@@ -875,6 +881,9 @@ int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
        uint8_t* wc;
        struct query_info qinfo;
        if(!neg) return 0;
+
+       log_nametypeclass(VERB_ALGO, "negcache dlvlookup", qname, 
+               LDNS_RR_TYPE_DLV, qclass);
        
        labs = dname_count_labels(qname);
        lock_basic_lock(&neg->lock);
@@ -885,6 +894,8 @@ int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
                lock_basic_unlock(&neg->lock);
                return 0;
        }
+       log_nametypeclass(VERB_ALGO, "negcache zone", zone->name, 0, 
+               zone->dclass);
 
        /* lookup closest data record */
        (void)neg_closest_data(zone, qname, len, labs, &data);
@@ -894,6 +905,8 @@ int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
                lock_basic_unlock(&neg->lock);
                return 0;
        }
+       log_nametypeclass(VERB_ALGO, "negcache rr", data->name, 
+               LDNS_RR_TYPE_NSEC, zone->dclass);
 
        /* lookup rrset in rrset cache */
        flags = 0;
@@ -908,7 +921,7 @@ int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
                return 0;
        }
        d = (struct packed_rrset_data*)nsec->entry.data;
-       if(!d || d->ttl > now) {
+       if(!d || now > d->ttl) {
                lock_rw_unlock(&nsec->entry.lock);
                /* delete data record if expired */
                neg_delete_data(neg, data);
@@ -921,6 +934,7 @@ int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
                lock_basic_unlock(&neg->lock);
                return 0;
        }
+       verbose(VERB_ALGO, "negcache got secure rrset");
 
        /* check NSEC security */
        /* check if NSEC proves no DLV type exists */
@@ -933,6 +947,7 @@ int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
                /* the NSEC is not a denial for the DLV */
                lock_rw_unlock(&nsec->entry.lock);
                lock_basic_unlock(&neg->lock);
+               verbose(VERB_ALGO, "negcache not proven");
                return 0;
        }
        /* so the NSEC was a NODATA proof, or NXDOMAIN proof. */
@@ -944,5 +959,6 @@ int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
        /* if OK touch the LRU for neg_data element */
        neg_lru_touch(neg, data);
        lock_basic_unlock(&neg->lock);
-       return 0;
+       verbose(VERB_ALGO, "negcache DLV denial proven");
+       return 1;
 }
index 89547da9fce8bdd333c195abcd2a11585ae5beed..0b4e7f87830a6dc66ed803f7eb7ff764eab8cf6a 100644 (file)
@@ -47,6 +47,7 @@
 #include "validator/val_utils.h"
 #include "validator/val_nsec.h"
 #include "validator/val_nsec3.h"
+#include "validator/val_neg.h"
 #include "services/cache/dns.h"
 #include "util/data/dname.h"
 #include "util/module.h"
@@ -120,6 +121,16 @@ val_apply_cfg(struct module_env* env, struct val_env* val_env,
                log_err("validator: error in trustanchors config");
                return 0;
        }
+       if(!val_env->neg_cache)
+               val_env->neg_cache = val_neg_create();
+       if(!val_env->neg_cache) {
+               log_err("out of memory");
+               return 0;
+       }
+       if(!val_neg_apply_cfg(val_env->neg_cache, cfg)) {
+               log_err("validator: error in negative cache config");
+               return 0;
+       }
        val_env->date_override = cfg->val_date_override;
        c = cfg_count_numbers(cfg->val_nsec3_key_iterations);
        if(c < 1 || (c&1)) {
@@ -164,6 +175,7 @@ val_deinit(struct module_env* env, int id)
        anchors_delete(env->anchors);
        env->anchors = NULL;
        key_cache_delete(val_env->kcache);
+       neg_cache_delete(val_env->neg_cache);
        free(val_env->nsec3_keysize);
        free(val_env->nsec3_maxiter);
        free(val_env);
@@ -1575,12 +1587,11 @@ val_dlv_init(struct module_qstate* qstate, struct val_qstate* vq,
 
        /* If we can find the name in the aggressive negative cache,
         * give up; insecure is the answer */
-       /* lookup, several places in the tree may qualify 
-        *    between insecure_at and the lookup_name
-        * Check proof thoroughly
-        * TODO
-        * return 1;
-        */
+       if(val_neg_dlvlookup(ve->neg_cache, vq->dlv_lookup_name,
+               vq->dlv_lookup_name_len, vq->qchase.qclass,
+               qstate->env->rrset_cache, *qstate->env->now)) {
+               return 1;
+       }
 
        /* perform a lookup for the DLV; with validation */
        vq->state = VAL_DLVLOOKUP_STATE;
@@ -1798,6 +1809,16 @@ processDLVLookup(struct module_qstate* qstate, struct val_qstate* vq,
                return 1;
        }
 
+       /* check negative cache before making new request */
+       if(val_neg_dlvlookup(ve->neg_cache, vq->dlv_lookup_name,
+               vq->dlv_lookup_name_len, vq->qchase.qclass,
+               qstate->env->rrset_cache, *qstate->env->now)) {
+               vq->dlv_status = dlv_there_is_no_dlv;
+               /* continue with the insecure result we got */
+               vq->state = VAL_FINISHED_STATE;
+               return 1;
+       }
+
        if(!generate_request(qstate, id, vq->dlv_lookup_name,
                vq->dlv_lookup_name_len, LDNS_RR_TYPE_DLV, 
                vq->qchase.qclass, 0)) {
@@ -2383,6 +2404,8 @@ process_dlv_response(struct module_qstate* qstate, struct val_qstate* vq,
                vq->dlv_status = dlv_success;
                return;
        }
+       /* store NSECs into negative cache */
+       val_neg_addreply(ve->neg_cache, msg->rep);
 
        /* was the lookup a failure? 
         *   if we have to go up into the DLV for a higher DLV anchor
@@ -2460,6 +2483,7 @@ val_get_mem(struct module_env* env, int id)
        if(!ve)
                return 0;
        return sizeof(*ve) + key_cache_get_mem(ve->kcache) + 
+               val_neg_get_mem(ve->neg_cache) +
                anchors_get_mem(env->anchors) + 
                sizeof(size_t)*2*ve->nsec3_keyiter_count;
 }
index daf65c34f055636785eb8252c753706837e1ff7a..28fbbc058b35954abe8638d0e80e4bca15c7c1c2 100644 (file)
@@ -48,6 +48,7 @@
 struct val_anchors;
 struct key_cache;
 struct key_entry_key;
+struct val_neg_cache;
 
 /**
  * This is the TTL to use when a trust anchor fails to prime. A trust anchor
@@ -63,6 +64,9 @@ struct val_env {
         * end up here after being primed. */
        struct key_cache* kcache;
 
+       /** aggressive negative cache. index into NSECs in rrset cache. */
+       struct val_neg_cache* neg_cache;
+
        /** for debug testing a fixed validation date can be entered.
         * if 0, current time is used for rrsig validation */
        int32_t date_override;