diff options
author | des <des@FreeBSD.org> | 2015-04-26 11:23:26 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2015-04-26 11:23:26 +0000 |
commit | fe0c01d26579d19ddf439fb46ef0bd3cc2bc7f4c (patch) | |
tree | 01c1d94467622a175fad10cd34a2f6f05d32c1b7 /iterator | |
parent | cabe860377233bc13a6d101fdb59bb834cab980a (diff) | |
download | FreeBSD-src-fe0c01d26579d19ddf439fb46ef0bd3cc2bc7f4c.zip FreeBSD-src-fe0c01d26579d19ddf439fb46ef0bd3cc2bc7f4c.tar.gz |
import unbound 1.5.2
Diffstat (limited to 'iterator')
-rw-r--r-- | iterator/iter_scrub.c | 4 | ||||
-rw-r--r-- | iterator/iter_utils.c | 36 | ||||
-rw-r--r-- | iterator/iter_utils.h | 9 | ||||
-rw-r--r-- | iterator/iterator.c | 15 |
4 files changed, 59 insertions, 5 deletions
diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c index b2248bc..1c81975 100644 --- a/iterator/iter_scrub.c +++ b/iterator/iter_scrub.c @@ -680,7 +680,9 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg, * (we dont want its glue that was approved * during the normalize action) */ del_addi = 1; - } else if(!env->cfg->harden_glue) { + } else if(!env->cfg->harden_glue && ( + rrset->type == LDNS_RR_TYPE_A || + rrset->type == LDNS_RR_TYPE_AAAA)) { /* store in cache! Since it is relevant * (from normalize) it will be picked up * from the cache to be used later */ diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index 9d0aa69..10ae12f 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -715,6 +715,42 @@ reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region) } void +caps_strip_reply(struct reply_info* rep) +{ + size_t i; + if(!rep) return; + /* see if message is a referral, in which case the additional and + * NS record cannot be removed */ + /* referrals have the AA flag unset (strict check, not elsewhere in + * unbound, but for 0x20 this is very convenient). */ + if(!(rep->flags&BIT_AA)) + return; + /* remove the additional section from the reply */ + if(rep->ar_numrrsets != 0) { + verbose(VERB_ALGO, "caps fallback: removing additional section"); + rep->rrset_count -= rep->ar_numrrsets; + rep->ar_numrrsets = 0; + } + /* is there an NS set in the authority section to remove? */ + /* the failure case (Cisco firewalls) only has one rrset in authsec */ + for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++) { + struct ub_packed_rrset_key* s = rep->rrsets[i]; + if(ntohs(s->rk.type) == LDNS_RR_TYPE_NS) { + /* remove NS rrset and break from loop (loop limits + * have changed) */ + /* move last rrset into this position (there is no + * additional section any more) */ + verbose(VERB_ALGO, "caps fallback: removing NS rrset"); + if(i < rep->rrset_count-1) + rep->rrsets[i]=rep->rrsets[rep->rrset_count-1]; + rep->rrset_count --; + rep->ns_numrrsets --; + break; + } + } +} + +void iter_store_parentside_rrset(struct module_env* env, struct ub_packed_rrset_key* rrset) { diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h index d7c2b68..9373487 100644 --- a/iterator/iter_utils.h +++ b/iterator/iter_utils.h @@ -223,6 +223,15 @@ int iter_msg_from_zone(struct dns_msg* msg, struct delegpt* dp, int reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region); /** + * Remove unused bits from the reply if possible. + * So that caps-for-id (0x20) fallback is more likely to be successful. + * This removes like, the additional section, and NS record in the authority + * section if those records are gratuitous (not for a referral). + * @param rep: the reply to strip stuff out of. + */ +void caps_strip_reply(struct reply_info* rep); + +/** * Store parent-side rrset in seperate rrset cache entries for later * last-resort * lookups in case the child-side versions of this information * fails. diff --git a/iterator/iterator.c b/iterator/iterator.c index 6e05c99..2037cc8 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -1383,8 +1383,10 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq, return 0; if(iq->depth > 0 && iq->target_count && iq->target_count[1] > MAX_TARGET_COUNT) { - verbose(VERB_QUERY, "request has exceeded the maximum " - "number of glue fetches %d", iq->target_count[1]); + char s[LDNS_MAX_DOMAINLEN+1]; + dname_str(qstate->qinfo.qname, s); + verbose(VERB_QUERY, "request %s has exceeded the maximum " + "number of glue fetches %d", s, iq->target_count[1]); return 0; } @@ -1581,8 +1583,10 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, } if(iq->depth > 0 && iq->target_count && iq->target_count[1] > MAX_TARGET_COUNT) { - verbose(VERB_QUERY, "request has exceeded the maximum " - "number of glue fetches %d", iq->target_count[1]); + char s[LDNS_MAX_DOMAINLEN+1]; + dname_str(qstate->qinfo.qname, s); + verbose(VERB_QUERY, "request %s has exceeded the maximum " + "number of glue fetches %d", s, iq->target_count[1]); return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); } /* mark cycle targets for parent-side lookups */ @@ -2878,6 +2882,9 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq, iq->response->rep); if(event == module_event_capsfail || iq->caps_fallback) { + /* for fallback we care about main answer, not additionals */ + /* removing that makes comparison more likely to succeed */ + caps_strip_reply(iq->response->rep); if(!iq->caps_fallback) { /* start fallback */ iq->caps_fallback = 1; |