commit d3866418208f9a16c7bab09b424dbd90a973df0c Author: Wouter Wijngaards Date: Mon Jun 4 12:28:33 2018 +0000 - Fix stub reprime when it becomes useless. git-svn-id: file:///svn/unbound/trunk@4707 be551aaa-1e26-0410-a405-d3ace91eadb9 diff --git a/doc/Changelog b/doc/Changelog index d78810fd..759c1ec7 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,7 @@ 4 June 2018: Wouter - Fix deadlock caused by incoming notify for auth-zone. - tag for 1.7.2rc1 + - Fix stub reprime when it becomes useless. 1 June 2018: Wouter - Rename additional-tls-port to tls-additional-ports. diff --git a/iterator/iterator.c b/iterator/iterator.c index 188a623a..a19965b7 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -536,7 +536,7 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq, /** see if last resort is possible - does config allow queries to parent */ static int can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen, - uint16_t qclass) + uint16_t qclass, struct iter_hints_stub** retstub) { struct delegpt* fwddp; struct iter_hints_stub* stub; @@ -549,6 +549,7 @@ can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen, /* has_parent side is turned off for stub_first, where we * are allowed to go to the parent */ stub->dp->has_parent_side_NS) { + if(retstub) *retstub = stub; return 0; } if((fwddp = forwards_find(env->fwds, nm, qclass)) && @@ -1000,7 +1001,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id) if(iq->depth == ie->max_dependency_depth) return; if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, - iq->qchase.qclass)) + iq->qchase.qclass, NULL)) return; /* is this query the same as the nscheck? */ if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS && @@ -1184,10 +1185,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, */ if (iq->refetch_glue && iq->dp && - !can_have_last_resort(qstate->env, - iq->dp->name, - iq->dp->namelen, - iq->qchase.qclass)) { + !can_have_last_resort(qstate->env, iq->dp->name, + iq->dp->namelen, iq->qchase.qclass, NULL)) { iq->refetch_glue = 0; } @@ -1300,7 +1299,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, } if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue || (iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway - && can_have_last_resort(qstate->env, delname, delnamelen, iq->qchase.qclass))) { + && can_have_last_resort(qstate->env, delname, delnamelen, iq->qchase.qclass, NULL))) { /* 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 @@ -1416,7 +1415,22 @@ 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)) { + struct iter_hints_stub* stub = NULL; + if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &stub)) { + if(stub && !stub->noprime) { + verbose(VERB_QUERY, "cache has stub " + "but no addresses, fallback " + "to stub prime addresses"); + iq->dp = delegpt_copy(stub->dp, + qstate->region); + if(!iq->dp) { + log_err("out of memory in " + "stub fallback"); + return error_response(qstate, + id, LDNS_RCODE_SERVFAIL); + } + break; + } verbose(VERB_ALGO, "useless dp " "but cannot go up, servfail"); return error_response(qstate, id, @@ -1779,7 +1793,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, log_assert(iq->dp); if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, - iq->qchase.qclass)) { + iq->qchase.qclass, NULL)) { /* fail -- no more targets, no more hope of targets, no hope * of a response. */ verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL"); @@ -1872,7 +1886,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, if( ((ie->supports_ipv6 && !ns->done_pside6) || (ie->supports_ipv4 && !ns->done_pside4)) && !can_have_last_resort(qstate->env, ns->name, ns->namelen, - iq->qchase.qclass)) { + iq->qchase.qclass, NULL)) { log_nametypeclass(VERB_ALGO, "cannot pside lookup ns " "because it is also a stub/forward,", ns->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);