mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
DLV negative cache works.
git-svn-id: file:///svn/unbound/trunk@1200 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
a61d10f715
commit
a39a7704af
4 changed files with 61 additions and 13 deletions
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue