diff options
Diffstat (limited to 'iterator/iterator.c')
-rw-r--r-- | iterator/iterator.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/iterator/iterator.c b/iterator/iterator.c index 7f3c65737d595..188a623a2bc72 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -1206,7 +1206,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, iq->qchase.qname_len, iq->qchase.qtype, iq->qchase.qclass, qstate->query_flags, qstate->region, qstate->env->scratch, 0); - if(!msg && qstate->env->neg_cache) { + if(!msg && qstate->env->neg_cache && + iter_qname_indicates_dnssec(qstate->env, &iq->qchase)) { /* lookup in negative cache; may result in * NOERROR/NODATA or NXDOMAIN answers that need validation */ msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase, @@ -1298,7 +1299,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, delnamelen = iq->qchase.qname_len; } if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue || - (iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway)) { + (iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway + && can_have_last_resort(qstate->env, delname, delnamelen, iq->qchase.qclass))) { /* remove first label from delname, root goes to hints, * but only to fetch glue, not for qtype=DS. */ /* also when prefetching an NS record, fetch it again from @@ -1414,6 +1416,12 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, */ if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags, iq->dp)) { + if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass)) { + verbose(VERB_ALGO, "useless dp " + "but cannot go up, servfail"); + return error_response(qstate, id, + LDNS_RCODE_SERVFAIL); + } if(dname_is_root(iq->dp->name)) { /* use safety belt */ verbose(VERB_QUERY, "Cache has root NS but " @@ -1791,7 +1799,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, for(a = p->target_list; a; a=a->next_target) { (void)delegpt_add_addr(iq->dp, qstate->region, &a->addr, a->addrlen, a->bogus, - a->lame); + a->lame, a->tls_auth_name); } } iq->dp->has_parent_side_NS = 1; @@ -2160,11 +2168,18 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, log_dns_msg("msg from auth zone", &iq->response->qinfo, iq->response->rep); } - iq->num_current_queries++; - iq->chase_to_rd = 0; - iq->dnssec_lame_query = 0; - iq->auth_zone_response = 1; - return next_state(iq, QUERY_RESP_STATE); + if((iq->chase_flags&BIT_RD) && !(iq->response->rep->flags&BIT_AA)) { + verbose(VERB_ALGO, "forwarder, ignoring referral from auth zone"); + } else { + lock_rw_wrlock(&qstate->env->auth_zones->lock); + qstate->env->auth_zones->num_query_up++; + lock_rw_unlock(&qstate->env->auth_zones->lock); + iq->num_current_queries++; + iq->chase_to_rd = 0; + iq->dnssec_lame_query = 0; + iq->auth_zone_response = 1; + return next_state(iq, QUERY_RESP_STATE); + } } iq->auth_zone_response = 0; if(auth_fallback == 0) { @@ -2253,7 +2268,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, target = iter_server_selection(ie, qstate->env, iq->dp, iq->dp->name, iq->dp->namelen, iq->qchase.qtype, &iq->dnssec_lame_query, &iq->chase_to_rd, - iq->num_target_queries, qstate->blacklist); + iq->num_target_queries, qstate->blacklist, + qstate->prefetch_leeway); /* If no usable target was selected... */ if(!target) { @@ -2366,12 +2382,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, * (blacklist nonempty) and no trust-anchors are configured * above the qname or on the first attempt when dnssec is on */ EDNS_DO| ((iq->chase_to_rd||(iq->chase_flags&BIT_RD)!=0)&& - !qstate->blacklist&&(!iter_indicates_dnssec_fwd(qstate->env, + !qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env, &iq->qinfo_out)||target->attempts==1)?0:BIT_CD), iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted( ie, iq), &target->addr, target->addrlen, iq->dp->name, iq->dp->namelen, - (iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), qstate); + (iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), + target->tls_auth_name, qstate); if(!outq) { log_addr(VERB_DETAIL, "error sending query to auth server", &target->addr, target->addrlen); @@ -2440,9 +2457,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, } type = response_type_from_server( (int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd), - iq->response, &iq->qchase, iq->dp); + iq->response, &iq->qinfo_out, iq->dp); iq->chase_to_rd = 0; - if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD)) { + if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD) && + !iq->auth_zone_response) { /* When forwarding (RD bit is set), we handle referrals * differently. No queries should be sent elsewhere */ type = RESPONSE_TYPE_ANSWER; |