]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix that auth-zone master reply with current SOA serial does not
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 26 Jun 2018 13:48:36 +0000 (13:48 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 26 Jun 2018 13:48:36 +0000 (13:48 +0000)
  stop scan of masters for an updated zone.

git-svn-id: file:///svn/unbound/trunk@4755 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
services/authzone.c
services/authzone.h

index 251e6bd5321bf471b4da82304add7b7e5ee32a30..617ccbf0995a055cf9f5031b73417e32d6472638 100644 (file)
@@ -1,5 +1,7 @@
 26 June 2018: Wouter
        - Tentative fix for permission denied on IPv6 address on FreeBSD.
+       - Fix that auth-zone master reply with current SOA serial does not
+         stop scan of masters for an updated zone.
 
 21 June 2018: Wouter
        - #4108: systemd reload hang fix.
index a76b51f698be88ba47278c349f81ccb86afd1365..9de43b75439ea6989a21e19dfcacea99c6ddccbc 100644 (file)
@@ -5090,7 +5090,8 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env)
        xfr_transfer_disown(xfr);
 
        /* pick up the nextprobe task and wait */
-       xfr_set_timeout(xfr, env, 1, 0);
+       if(xfr->task_nextprobe->worker == NULL)
+               xfr_set_timeout(xfr, env, 1, 0);
        lock_basic_unlock(&xfr->lock);
 }
 
@@ -5547,7 +5548,8 @@ process_list_end_transfer(struct auth_xfer* xfr, struct module_env* env)
                        return;
                } else {
                        /* pick up the nextprobe task and wait (normail wait time) */
-                       xfr_set_timeout(xfr, env, 0, 0);
+                       if(xfr->task_nextprobe->worker == NULL)
+                               xfr_set_timeout(xfr, env, 0, 0);
                }
                lock_basic_unlock(&xfr->lock);
                return;
@@ -5888,29 +5890,35 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
                                        return 0;
 
                                }
+                               /* other tasks are running, we don't do this anymore */
+                               xfr_probe_disown(xfr);
+                               lock_basic_unlock(&xfr->lock);
+                               /* return, we don't sent a reply to this udp packet,
+                                * and we setup the tasks to do next */
+                               return 0;
                        } else {
-                               /* if zone not updated, start the wait timer again */
-                               verbose(VERB_ALGO, "auth_zone unchanged, new lease, wait");
-                               if(xfr->have_zone)
-                                       xfr->lease_time = *env->now;
-                               if(xfr->task_nextprobe->worker == NULL)
-                                       xfr_set_timeout(xfr, env, 0, 0);
+                               verbose(VERB_ALGO, "auth_zone master reports unchanged soa serial");
+                               /* we if cannot find updates amongst the
+                                * masters, this means we then have a new lease
+                                * on the zone */
+                               xfr->task_probe->have_new_lease = 1;
+                       }
+               } else {
+                       if(verbosity >= VERB_ALGO) {
+                               char buf[256];
+                               dname_str(xfr->name, buf);
+                               verbose(VERB_ALGO, "auth zone %s: bad reply to soa probe", buf);
                        }
-                       /* other tasks are running, we don't do this anymore */
-                       xfr_probe_disown(xfr);
-                       lock_basic_unlock(&xfr->lock);
-                       /* return, we don't sent a reply to this udp packet,
-                        * and we setup the tasks to do next */
-                       return 0;
                }
-       }
-       if(verbosity >= VERB_ALGO) {
-               char buf[256];
-               dname_str(xfr->name, buf);
-               verbose(VERB_ALGO, "auth zone %s: soa probe failed", buf);
+       } else {
+               if(verbosity >= VERB_ALGO) {
+                       char buf[256];
+                       dname_str(xfr->name, buf);
+                       verbose(VERB_ALGO, "auth zone %s: soa probe failed", buf);
+               }
        }
        
-       /* failed lookup */
+       /* failed lookup or not an update */
        /* delete commpoint so a new one is created, with a fresh port nr */
        comm_point_delete(xfr->task_probe->cp);
        xfr->task_probe->cp = NULL;
@@ -6013,7 +6021,8 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
                /* only wanted lookups for copy, stop probe and start wait */
                xfr->task_probe->only_lookup = 0;
                xfr_probe_disown(xfr);
-               xfr_set_timeout(xfr, env, 0, 0);
+               if(xfr->task_nextprobe->worker == NULL)
+                       xfr_set_timeout(xfr, env, 0, 0);
                lock_basic_unlock(&xfr->lock);
                return;
        }
@@ -6029,12 +6038,24 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
                xfr_probe_nextmaster(xfr);
        }
 
-       /* we failed to send this as well, move to the wait task,
-        * use the shorter retry timeout */
-       xfr_probe_disown(xfr);
+       /* done with probe sequence, wait */
+       if(xfr->task_probe->have_new_lease) {
+               /* if zone not updated, start the wait timer again */
+               verbose(VERB_ALGO, "auth_zone unchanged, new lease, wait");
+               xfr_probe_disown(xfr);
+               if(xfr->have_zone)
+                       xfr->lease_time = *env->now;
+               if(xfr->task_nextprobe->worker == NULL)
+                       xfr_set_timeout(xfr, env, 0, 0);
+       } else {
+               /* we failed to send this as well, move to the wait task,
+                * use the shorter retry timeout */
+               xfr_probe_disown(xfr);
+               /* pick up the nextprobe task and wait */
+               if(xfr->task_nextprobe->worker == NULL)
+                       xfr_set_timeout(xfr, env, 1, 0);
+       }
 
-       /* pick up the nextprobe task and wait */
-       xfr_set_timeout(xfr, env, 1, 0);
        lock_basic_unlock(&xfr->lock);
 }
 
@@ -6168,6 +6189,8 @@ xfr_start_probe(struct auth_xfer* xfr, struct module_env* env,
                xfr->task_probe->cp = NULL;
 
                /* start the task */
+               /* have not seen a new lease yet, this scan */
+               xfr->task_probe->have_new_lease = 0;
                /* if this was a timeout, no specific first master to scan */
                /* otherwise, spec is nonNULL the notified master, scan
                 * first and also transfer first from it */
index 69158de239b797e892714a08937d688952b61c48..6b25452dd503cc8dd289d883c5e40fecd184424b 100644 (file)
@@ -309,6 +309,9 @@ struct auth_probe {
        /** we only want to do lookups for making config work (for notify),
         * don't proceed with UDP SOA probe queries */
        int only_lookup;
+       /** we have seen a new lease this scan, because one of the masters
+        * replied with the current SOA serial version */
+       int have_new_lease;
 
        /** once notified, or the timeout has been reached. a scan starts. */
        /** the scan specific target (notify source), or NULL if none */