mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
basic DLV works.
iana port update. git-svn-id: file:///svn/unbound/trunk@1191 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
7549bddfda
commit
8e39c9c1cb
4 changed files with 64 additions and 37 deletions
|
|
@ -1,3 +1,9 @@
|
|||
15 August 2008: Wouter
|
||||
- DLV nsec code fixed for better detection of closest existing
|
||||
enclosers from NSEC responses.
|
||||
- DLV works, straight to the dlv repository, so not for production.
|
||||
- Iana port update.
|
||||
|
||||
14 August 2008: Wouter
|
||||
- synthesize DLV messages from the rrset cache, like done for DS.
|
||||
|
||||
|
|
|
|||
|
|
@ -661,6 +661,7 @@
|
|||
848,
|
||||
860,
|
||||
861,
|
||||
862,
|
||||
873,
|
||||
886,
|
||||
887,
|
||||
|
|
|
|||
|
|
@ -482,26 +482,26 @@ val_nsec_proves_no_wc(struct ub_packed_rrset_key* nsec, uint8_t* qname,
|
|||
}
|
||||
|
||||
/**
|
||||
* Closest NONEMPTY encloser.
|
||||
* Thus, no empty nonterminals are returned.
|
||||
* @param qname: query name
|
||||
* @param nsec: nsec record.
|
||||
* @return the name (part of qname).
|
||||
* Find shared topdomain that exists
|
||||
*/
|
||||
static uint8_t*
|
||||
nsec_closest_nonempty(uint8_t* qname, struct ub_packed_rrset_key* nsec)
|
||||
static void
|
||||
dlv_topdomain(struct ub_packed_rrset_key* nsec, uint8_t* qname,
|
||||
uint8_t** nm, size_t* nm_len)
|
||||
{
|
||||
uint8_t* next;
|
||||
size_t nlen;
|
||||
uint8_t* common1, *common2;
|
||||
if(!nsec_get_next(nsec, &next, &nlen))
|
||||
return NULL;
|
||||
/* shortest common with owner or next name */
|
||||
common1 = dname_get_shared_topdomain(qname, nsec->rk.dname);
|
||||
common2 = dname_get_shared_topdomain(qname, next);
|
||||
if(dname_count_labels(common1) < dname_count_labels(common2))
|
||||
return common1;
|
||||
return common2;
|
||||
/* make sure reply is part of nm */
|
||||
/* take shared topdomain with left of NSEC. */
|
||||
|
||||
/* because, if empty nonterminal, then right is subdomain of qname.
|
||||
* and any shared topdomain would be empty nonterminals.
|
||||
*
|
||||
* If nxdomain, then the right is bigger, and could have an
|
||||
* interesting shared topdomain, but if it does have one, it is
|
||||
* an empty nonterminal. An empty nonterminal shared with the left
|
||||
* one. */
|
||||
int n;
|
||||
uint8_t* common = dname_get_shared_topdomain(qname, nsec->rk.dname);
|
||||
n = dname_count_labels(*nm) - dname_count_labels(common);
|
||||
dname_remove_labels(nm, nm_len, n);
|
||||
}
|
||||
|
||||
int val_nsec_check_dlv(struct query_info* qinfo,
|
||||
|
|
@ -525,14 +525,16 @@ int val_nsec_check_dlv(struct query_info* qinfo,
|
|||
rep->rrsets[i]->rk.dname, qinfo->qname);
|
||||
if(c == 0) {
|
||||
/* plain match */
|
||||
if(nsec_has_type(rep->rrsets[i],
|
||||
LDNS_RR_TYPE_DLV))
|
||||
return 0;
|
||||
dname_remove_label(nm, nm_len);
|
||||
return 1;
|
||||
} else if(c < 0 &&
|
||||
dname_strict_subdomain_c(next, qinfo->qname)) {
|
||||
/* ENT */
|
||||
*nm = nsec_closest_nonempty(
|
||||
*nm, rep->rrsets[i]);
|
||||
if(!*nm) return 0;
|
||||
dlv_topdomain(rep->rrsets[i], qinfo->qname,
|
||||
nm, nm_len);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -546,9 +548,8 @@ int val_nsec_check_dlv(struct query_info* qinfo,
|
|||
for(i=0; i<rep->ns_numrrsets; i++) {
|
||||
if(val_nsec_proves_name_error(rep->rrsets[i],
|
||||
qinfo->qname)) {
|
||||
*nm = nsec_closest_nonempty(
|
||||
*nm, rep->rrsets[i]);
|
||||
if(!*nm) return 0;
|
||||
dlv_topdomain(rep->rrsets[i], qinfo->qname,
|
||||
nm, nm_len);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1129,13 +1129,6 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
vq->ds_rrset = 0;
|
||||
vq->trust_anchor = anchors_lookup(qstate->env->anchors,
|
||||
lookup_name, lookup_len, vq->qchase.qclass);
|
||||
if(vq->trust_anchor == NULL) {
|
||||
/*response isn't under a trust anchor, so we cannot validate.*/
|
||||
vq->chase_reply->security = sec_status_indeterminate;
|
||||
/* go to finished state to cache this result */
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Determine the signer/lookup name */
|
||||
val_find_signer(subtype, &vq->qchase, vq->orig_msg->rep,
|
||||
|
|
@ -1153,6 +1146,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
|
||||
/* for NXDOMAIN it could be signed by a parent of the trust anchor */
|
||||
if(subtype == VAL_CLASS_NAMEERROR && vq->signer_name &&
|
||||
vq->trust_anchor &&
|
||||
dname_strict_subdomain_c(vq->trust_anchor->name, lookup_name)){
|
||||
while(vq->trust_anchor && dname_strict_subdomain_c(
|
||||
vq->trust_anchor->name, lookup_name)) {
|
||||
|
|
@ -1183,9 +1177,17 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
vq->key_entry = key_cache_obtain(ve->kcache, lookup_name, lookup_len,
|
||||
vq->qchase.qclass, qstate->region, *qstate->env->now);
|
||||
|
||||
/* there is no key(from DLV) and no trust anchor */
|
||||
if(vq->key_entry == NULL && vq->trust_anchor == NULL) {
|
||||
/*response isn't under a trust anchor, so we cannot validate.*/
|
||||
vq->chase_reply->security = sec_status_indeterminate;
|
||||
/* go to finished state to cache this result */
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
}
|
||||
/* if not key, or if keyentry is *above* the trustanchor, i.e.
|
||||
* the keyentry is based on another (higher) trustanchor */
|
||||
if(vq->key_entry == NULL || dname_strict_subdomain_c(
|
||||
else if(vq->key_entry == NULL || dname_strict_subdomain_c(
|
||||
vq->trust_anchor->name, vq->key_entry->name)) {
|
||||
/* fire off a trust anchor priming query. */
|
||||
verbose(VERB_DETAIL, "prime trust anchor");
|
||||
|
|
@ -1739,15 +1741,32 @@ processDLVLookup(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
else if(vq->dlv_status==dlv_there_is_no_dlv)
|
||||
verbose(VERB_ALGO, "DLV woke up with status dlv_there_is_no_dlv");
|
||||
else verbose(VERB_ALGO, "DLV woke up with status unknown");
|
||||
log_nametypeclass(VERB_ALGO, "next look", vq->dlv_lookup_name,
|
||||
LDNS_RR_TYPE_DLV, vq->qchase.qclass);
|
||||
|
||||
if(vq->dlv_status == dlv_error) {
|
||||
verbose(VERB_QUERY, "failed DLV lookup");
|
||||
return val_error(qstate, id);
|
||||
} else if(vq->dlv_status == dlv_success) {
|
||||
uint8_t* nm;
|
||||
size_t nmlen;
|
||||
/* chain continues with DNSKEY, continue in FINDKEY */
|
||||
vq->state = VAL_FINDKEY_STATE;
|
||||
|
||||
/* strip off the DLV suffix from the name; could result in . */
|
||||
log_assert(dname_subdomain_c(vq->ds_rrset->rk.dname,
|
||||
qstate->env->anchors->dlv_anchor->name));
|
||||
nmlen = vq->ds_rrset->rk.dname_len -
|
||||
qstate->env->anchors->dlv_anchor->namelen + 1;
|
||||
nm = regional_alloc_init(qstate->region,
|
||||
vq->ds_rrset->rk.dname, nmlen);
|
||||
if(!nm) {
|
||||
log_err("Out of memory in DLVLook");
|
||||
return val_error(qstate, id);
|
||||
}
|
||||
nm[nmlen-1] = 0;
|
||||
|
||||
vq->ds_rrset->rk.dname = nm;
|
||||
vq->ds_rrset->rk.dname_len = nmlen;
|
||||
|
||||
if(!generate_request(qstate, id, vq->ds_rrset->rk.dname,
|
||||
vq->ds_rrset->rk.dname_len, LDNS_RR_TYPE_DNSKEY,
|
||||
vq->qchase.qclass, BIT_CD)) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue