mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 14:47:09 +00: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
@ -496,43 +496,6 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
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 */
|
||||
static int
|
||||
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 ==
|
||||
htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
|
||||
htons(LDNS_RR_TYPE_DNAME))) {
|
||||
if(!check_cache_chain(rep)) {
|
||||
if(!reply_check_cname_chain(rep)) {
|
||||
/* cname chain invalid, redo iterator steps */
|
||||
verbose(VERB_ALGO, "Cache reply: cname chain broken");
|
||||
bail_out:
|
||||
@ -590,7 +553,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
"validation");
|
||||
goto bail_out; /* need to validate cache entry first */
|
||||
} else if(rep->security == sec_status_secure) {
|
||||
if(all_rrsets_secure(rep))
|
||||
if(reply_all_rrsets_secure(rep))
|
||||
secure = 1;
|
||||
else {
|
||||
if(must_validate) {
|
||||
|
@ -2,6 +2,9 @@
|
||||
- Fixup opportunistic target query generation to it does not
|
||||
generate queries that are known to fail.
|
||||
- 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
|
||||
- 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;
|
||||
if(!rrset_array_lock(r->ref, r->rrset_count, now))
|
||||
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++) {
|
||||
msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i],
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
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
|
||||
* result may have a different owner name.
|
||||
|
Loading…
Reference in New Issue
Block a user