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,
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:
"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) {
- 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.
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);
{
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;
+}
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.