From a31d45b13e2e496b2fdb6ce4715481681362472f Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards 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 --- doc/Changelog | 2 ++ services/authzone.c | 75 +++++++++++++++++++++++++++++---------------- services/authzone.h | 3 ++ 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 251e6bd53..617ccbf09 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/services/authzone.c b/services/authzone.c index a76b51f69..9de43b754 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; } - /* 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(verbosity >= VERB_ALGO) { + char buf[256]; + dname_str(xfr->name, buf); + verbose(VERB_ALGO, "auth zone %s: bad reply to soa probe", buf); + } + } + } else { + if(verbosity >= VERB_ALGO) { + char buf[256]; + dname_str(xfr->name, buf); + verbose(VERB_ALGO, "auth zone %s: soa probe failed", buf); } } - 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 69158de23..6b25452dd 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 */