mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-22 07:41:16 -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
|
14 August 2008: Wouter
|
||||||
- synthesize DLV messages from the rrset cache, like done for DS.
|
- synthesize DLV messages from the rrset cache, like done for DS.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -661,6 +661,7 @@
|
||||||
848,
|
848,
|
||||||
860,
|
860,
|
||||||
861,
|
861,
|
||||||
|
862,
|
||||||
873,
|
873,
|
||||||
886,
|
886,
|
||||||
887,
|
887,
|
||||||
|
|
|
||||||
|
|
@ -482,26 +482,26 @@ val_nsec_proves_no_wc(struct ub_packed_rrset_key* nsec, uint8_t* qname,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closest NONEMPTY encloser.
|
* Find shared topdomain that exists
|
||||||
* Thus, no empty nonterminals are returned.
|
|
||||||
* @param qname: query name
|
|
||||||
* @param nsec: nsec record.
|
|
||||||
* @return the name (part of qname).
|
|
||||||
*/
|
*/
|
||||||
static uint8_t*
|
static void
|
||||||
nsec_closest_nonempty(uint8_t* qname, struct ub_packed_rrset_key* nsec)
|
dlv_topdomain(struct ub_packed_rrset_key* nsec, uint8_t* qname,
|
||||||
|
uint8_t** nm, size_t* nm_len)
|
||||||
{
|
{
|
||||||
uint8_t* next;
|
/* make sure reply is part of nm */
|
||||||
size_t nlen;
|
/* take shared topdomain with left of NSEC. */
|
||||||
uint8_t* common1, *common2;
|
|
||||||
if(!nsec_get_next(nsec, &next, &nlen))
|
/* because, if empty nonterminal, then right is subdomain of qname.
|
||||||
return NULL;
|
* and any shared topdomain would be empty nonterminals.
|
||||||
/* shortest common with owner or next name */
|
*
|
||||||
common1 = dname_get_shared_topdomain(qname, nsec->rk.dname);
|
* If nxdomain, then the right is bigger, and could have an
|
||||||
common2 = dname_get_shared_topdomain(qname, next);
|
* interesting shared topdomain, but if it does have one, it is
|
||||||
if(dname_count_labels(common1) < dname_count_labels(common2))
|
* an empty nonterminal. An empty nonterminal shared with the left
|
||||||
return common1;
|
* one. */
|
||||||
return common2;
|
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,
|
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);
|
rep->rrsets[i]->rk.dname, qinfo->qname);
|
||||||
if(c == 0) {
|
if(c == 0) {
|
||||||
/* plain match */
|
/* plain match */
|
||||||
|
if(nsec_has_type(rep->rrsets[i],
|
||||||
|
LDNS_RR_TYPE_DLV))
|
||||||
|
return 0;
|
||||||
dname_remove_label(nm, nm_len);
|
dname_remove_label(nm, nm_len);
|
||||||
return 1;
|
return 1;
|
||||||
} else if(c < 0 &&
|
} else if(c < 0 &&
|
||||||
dname_strict_subdomain_c(next, qinfo->qname)) {
|
dname_strict_subdomain_c(next, qinfo->qname)) {
|
||||||
/* ENT */
|
/* ENT */
|
||||||
*nm = nsec_closest_nonempty(
|
dlv_topdomain(rep->rrsets[i], qinfo->qname,
|
||||||
*nm, rep->rrsets[i]);
|
nm, nm_len);
|
||||||
if(!*nm) return 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -546,9 +548,8 @@ int val_nsec_check_dlv(struct query_info* qinfo,
|
||||||
for(i=0; i<rep->ns_numrrsets; i++) {
|
for(i=0; i<rep->ns_numrrsets; i++) {
|
||||||
if(val_nsec_proves_name_error(rep->rrsets[i],
|
if(val_nsec_proves_name_error(rep->rrsets[i],
|
||||||
qinfo->qname)) {
|
qinfo->qname)) {
|
||||||
*nm = nsec_closest_nonempty(
|
dlv_topdomain(rep->rrsets[i], qinfo->qname,
|
||||||
*nm, rep->rrsets[i]);
|
nm, nm_len);
|
||||||
if(!*nm) return 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1129,13 +1129,6 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
vq->ds_rrset = 0;
|
vq->ds_rrset = 0;
|
||||||
vq->trust_anchor = anchors_lookup(qstate->env->anchors,
|
vq->trust_anchor = anchors_lookup(qstate->env->anchors,
|
||||||
lookup_name, lookup_len, vq->qchase.qclass);
|
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 */
|
/* Determine the signer/lookup name */
|
||||||
val_find_signer(subtype, &vq->qchase, vq->orig_msg->rep,
|
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 */
|
/* for NXDOMAIN it could be signed by a parent of the trust anchor */
|
||||||
if(subtype == VAL_CLASS_NAMEERROR && vq->signer_name &&
|
if(subtype == VAL_CLASS_NAMEERROR && vq->signer_name &&
|
||||||
|
vq->trust_anchor &&
|
||||||
dname_strict_subdomain_c(vq->trust_anchor->name, lookup_name)){
|
dname_strict_subdomain_c(vq->trust_anchor->name, lookup_name)){
|
||||||
while(vq->trust_anchor && dname_strict_subdomain_c(
|
while(vq->trust_anchor && dname_strict_subdomain_c(
|
||||||
vq->trust_anchor->name, lookup_name)) {
|
vq->trust_anchor->name, lookup_name)) {
|
||||||
|
|
@ -1182,10 +1176,18 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
|
|
||||||
vq->key_entry = key_cache_obtain(ve->kcache, lookup_name, lookup_len,
|
vq->key_entry = key_cache_obtain(ve->kcache, lookup_name, lookup_len,
|
||||||
vq->qchase.qclass, qstate->region, *qstate->env->now);
|
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.
|
/* if not key, or if keyentry is *above* the trustanchor, i.e.
|
||||||
* the keyentry is based on another (higher) trustanchor */
|
* 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)) {
|
vq->trust_anchor->name, vq->key_entry->name)) {
|
||||||
/* fire off a trust anchor priming query. */
|
/* fire off a trust anchor priming query. */
|
||||||
verbose(VERB_DETAIL, "prime trust anchor");
|
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)
|
else if(vq->dlv_status==dlv_there_is_no_dlv)
|
||||||
verbose(VERB_ALGO, "DLV woke up with 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");
|
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) {
|
if(vq->dlv_status == dlv_error) {
|
||||||
verbose(VERB_QUERY, "failed DLV lookup");
|
verbose(VERB_QUERY, "failed DLV lookup");
|
||||||
return val_error(qstate, id);
|
return val_error(qstate, id);
|
||||||
} else if(vq->dlv_status == dlv_success) {
|
} else if(vq->dlv_status == dlv_success) {
|
||||||
|
uint8_t* nm;
|
||||||
|
size_t nmlen;
|
||||||
/* chain continues with DNSKEY, continue in FINDKEY */
|
/* chain continues with DNSKEY, continue in FINDKEY */
|
||||||
vq->state = VAL_FINDKEY_STATE;
|
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,
|
if(!generate_request(qstate, id, vq->ds_rrset->rk.dname,
|
||||||
vq->ds_rrset->rk.dname_len, LDNS_RR_TYPE_DNSKEY,
|
vq->ds_rrset->rk.dname_len, LDNS_RR_TYPE_DNSKEY,
|
||||||
vq->qchase.qclass, BIT_CD)) {
|
vq->qchase.qclass, BIT_CD)) {
|
||||||
|
|
@ -1779,8 +1798,8 @@ processDLVLookup(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!generate_request(qstate, id, vq->dlv_lookup_name,
|
if(!generate_request(qstate, id, vq->dlv_lookup_name,
|
||||||
vq->dlv_lookup_name_len, LDNS_RR_TYPE_DLV,
|
vq->dlv_lookup_name_len, LDNS_RR_TYPE_DLV,
|
||||||
vq->qchase.qclass, 0)) {
|
vq->qchase.qclass, 0)) {
|
||||||
return val_error(qstate, id);
|
return val_error(qstate, id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue