mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-23 00:00:51 -05:00
check messages taken from cache, also in iterator.
git-svn-id: file:///svn/unbound/trunk@1662 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
a569062627
commit
f39e5fe3a8
5 changed files with 69 additions and 39 deletions
|
|
@ -496,43 +496,6 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** check cname chain in cache reply */
|
|
||||||
static int
|
|
||||||
check_cache_chain(struct reply_info* rep) {
|
|
||||||
/* check only answer section rrs for matching cname chain.
|
|
||||||
* the cache may return changed rdata, but owner names are untouched.*/
|
|
||||||
size_t i;
|
|
||||||
uint8_t* sname = rep->rrsets[0]->rk.dname;
|
|
||||||
size_t snamelen = rep->rrsets[0]->rk.dname_len;
|
|
||||||
for(i=0; i<rep->an_numrrsets; i++) {
|
|
||||||
uint16_t t = ntohs(rep->rrsets[i]->rk.type);
|
|
||||||
if(t == LDNS_RR_TYPE_DNAME)
|
|
||||||
continue; /* skip dnames; note TTL 0 not cached */
|
|
||||||
/* verify that owner matches current sname */
|
|
||||||
if(query_dname_compare(sname, rep->rrsets[i]->rk.dname) != 0){
|
|
||||||
/* cname chain broken */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* if this is a cname; move on */
|
|
||||||
if(t == LDNS_RR_TYPE_CNAME) {
|
|
||||||
get_cname_target(rep->rrsets[i], &sname, &snamelen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** check security status in cache reply */
|
|
||||||
static int
|
|
||||||
all_rrsets_secure(struct reply_info* rep) {
|
|
||||||
size_t i;
|
|
||||||
for(i=0; i<rep->rrset_count; i++) {
|
|
||||||
if( ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)
|
|
||||||
->security != sec_status_secure )
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** answer query from the cache */
|
/** answer query from the cache */
|
||||||
static int
|
static int
|
||||||
answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||||
|
|
@ -558,7 +521,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||||
if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
|
if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
|
||||||
htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
|
htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
|
||||||
htons(LDNS_RR_TYPE_DNAME))) {
|
htons(LDNS_RR_TYPE_DNAME))) {
|
||||||
if(!check_cache_chain(rep)) {
|
if(!reply_check_cname_chain(rep)) {
|
||||||
/* cname chain invalid, redo iterator steps */
|
/* cname chain invalid, redo iterator steps */
|
||||||
verbose(VERB_ALGO, "Cache reply: cname chain broken");
|
verbose(VERB_ALGO, "Cache reply: cname chain broken");
|
||||||
bail_out:
|
bail_out:
|
||||||
|
|
@ -590,7 +553,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||||
"validation");
|
"validation");
|
||||||
goto bail_out; /* need to validate cache entry first */
|
goto bail_out; /* need to validate cache entry first */
|
||||||
} else if(rep->security == sec_status_secure) {
|
} else if(rep->security == sec_status_secure) {
|
||||||
if(all_rrsets_secure(rep))
|
if(reply_all_rrsets_secure(rep))
|
||||||
secure = 1;
|
secure = 1;
|
||||||
else {
|
else {
|
||||||
if(must_validate) {
|
if(must_validate) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
- Fixup opportunistic target query generation to it does not
|
- Fixup opportunistic target query generation to it does not
|
||||||
generate queries that are known to fail.
|
generate queries that are known to fail.
|
||||||
- Touchup on munin total memory report.
|
- Touchup on munin total memory report.
|
||||||
|
- messages picked out of the cache by the iterator are checked
|
||||||
|
if their cname chain is still correct and if validation status
|
||||||
|
has to be reexamined.
|
||||||
|
|
||||||
15 June 2009: Wouter
|
15 June 2009: Wouter
|
||||||
- iana portlist updated.
|
- iana portlist updated.
|
||||||
|
|
|
||||||
12
services/cache/dns.c
vendored
12
services/cache/dns.c
vendored
|
|
@ -440,6 +440,18 @@ tomsg(struct module_env* env, struct msgreply_entry* e, struct reply_info* r,
|
||||||
msg->rep->authoritative = r->authoritative;
|
msg->rep->authoritative = r->authoritative;
|
||||||
if(!rrset_array_lock(r->ref, r->rrset_count, now))
|
if(!rrset_array_lock(r->ref, r->rrset_count, now))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if(r->an_numrrsets > 0 && (r->rrsets[0]->rk.type == htons(
|
||||||
|
LDNS_RR_TYPE_CNAME) || r->rrsets[0]->rk.type == htons(
|
||||||
|
LDNS_RR_TYPE_DNAME)) && !reply_check_cname_chain(r)) {
|
||||||
|
/* cname chain is now invalid, reconstruct msg */
|
||||||
|
rrset_array_unlock(r->ref, r->rrset_count);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(r->security == sec_status_secure && !reply_all_rrsets_secure(r)) {
|
||||||
|
/* message rrsets have changed status, revalidate */
|
||||||
|
rrset_array_unlock(r->ref, r->rrset_count);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||||
msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i],
|
msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i],
|
||||||
region, now);
|
region, now);
|
||||||
|
|
|
||||||
|
|
@ -790,3 +790,40 @@ log_query_info(enum verbosity_value v, const char* str,
|
||||||
{
|
{
|
||||||
log_nametypeclass(v, str, qinf->qname, qinf->qtype, qinf->qclass);
|
log_nametypeclass(v, str, qinf->qname, qinf->qtype, qinf->qclass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
reply_check_cname_chain(struct reply_info* rep)
|
||||||
|
{
|
||||||
|
/* check only answer section rrs for matching cname chain.
|
||||||
|
* the cache may return changed rdata, but owner names are untouched.*/
|
||||||
|
size_t i;
|
||||||
|
uint8_t* sname = rep->rrsets[0]->rk.dname;
|
||||||
|
size_t snamelen = rep->rrsets[0]->rk.dname_len;
|
||||||
|
for(i=0; i<rep->an_numrrsets; i++) {
|
||||||
|
uint16_t t = ntohs(rep->rrsets[i]->rk.type);
|
||||||
|
if(t == LDNS_RR_TYPE_DNAME)
|
||||||
|
continue; /* skip dnames; note TTL 0 not cached */
|
||||||
|
/* verify that owner matches current sname */
|
||||||
|
if(query_dname_compare(sname, rep->rrsets[i]->rk.dname) != 0){
|
||||||
|
/* cname chain broken */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* if this is a cname; move on */
|
||||||
|
if(t == LDNS_RR_TYPE_CNAME) {
|
||||||
|
get_cname_target(rep->rrsets[i], &sname, &snamelen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
reply_all_rrsets_secure(struct reply_info* rep)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for(i=0; i<rep->rrset_count; i++) {
|
||||||
|
if( ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)
|
||||||
|
->security != sec_status_secure )
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,21 @@ int parse_copy_decompress_rrset(ldns_buffer* pkt, struct msg_parse* msg,
|
||||||
uint8_t* reply_find_final_cname_target(struct query_info* qinfo,
|
uint8_t* reply_find_final_cname_target(struct query_info* qinfo,
|
||||||
struct reply_info* rep);
|
struct reply_info* rep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if cname chain in cached reply is still valid.
|
||||||
|
* @param rep: reply to check.
|
||||||
|
* @return: true if valid, false if invalid.
|
||||||
|
*/
|
||||||
|
int reply_check_cname_chain(struct reply_info* rep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check security status of all RRs in the message.
|
||||||
|
* @param rep: reply to check
|
||||||
|
* @return: true if all RRs are secure. False if not.
|
||||||
|
* True if there are zero RRs.
|
||||||
|
*/
|
||||||
|
int reply_all_rrsets_secure(struct reply_info* rep);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find answer rrset in reply, the one matching qinfo. Follows CNAMEs, so the
|
* Find answer rrset in reply, the one matching qinfo. Follows CNAMEs, so the
|
||||||
* result may have a different owner name.
|
* result may have a different owner name.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue