From a31d45b13e2e496b2fdb6ce4715481681362472f Mon Sep 17 00:00:00 2001
From: Wouter Wijngaards <wouter@nlnetlabs.nl>
Date: Tue, 26 Jun 2018 13:48:36 +0000
Subject: [PATCH] - Fix that auth-zone master reply with current SOA serial
does not stop scan of masters for an updated zone.
git-svn-id: file:///svn/unbound/trunk@4755 be551aaa-1e26-0410-a405-d3ace91eadb9
---
services/authzone.c | 75 ++++++++++++++++++++++++++++++++++-------------------
services/authzone.h | 3 +++
2 files changed, 52 insertions(+), 26 deletions(-)
diff --git a/services/authzone.c b/services/authzone.c
index a76b51f6..9de43b75 100644
--- a/services/authzone.c
+++ b/services/authzone.c
@@ -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 */
diff --git a/services/authzone.h b/services/authzone.h
index 69158de2..6b25452d 100644
--- a/services/authzone.h
+++ b/services/authzone.h
@@ -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 */
--
2.14.4