]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix stub reprime when it becomes useless.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 4 Jun 2018 12:28:33 +0000 (12:28 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 4 Jun 2018 12:28:33 +0000 (12:28 +0000)
git-svn-id: file:///svn/unbound/trunk@4707 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
iterator/iterator.c

index d78810fdd868d57b6961347f3d9b2dacc487b0a2..759c1ec7faecbd01e42fc08c46cc6aa0def762ef 100644 (file)
@@ -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.
index 188a623a2bc72474bd8f50330183779520ead889..a19965b7c4ecd80f8087e6e70dfcfffb81b87225 100644 (file)
@@ -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);