From 51caffb4543cca80b9f04890b179db2e87dc041b Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Tue, 22 Jan 2019 15:36:58 +0000 Subject: [PATCH] - Fix for #4219: secondaries not updated after serial change, unbound falls back to AXFR after IXFR gives several timeout failures. git-svn-id: file:///svn/unbound/trunk@5052 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 2 ++ services/authzone.c | 18 ++++++++++++++++++ services/authzone.h | 2 ++ 3 files changed, 22 insertions(+) diff --git a/doc/Changelog b/doc/Changelog index 152e6011b..2b69fde83 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -3,6 +3,8 @@ - Doc for stream-wait-size and unit test. - unbound-control stats has mem.streamwait that counts TCP and TLS waiting result buffers. + - Fix for #4219: secondaries not updated after serial change, unbound + falls back to AXFR after IXFR gives several timeout failures. 21 January 2018: Wouter - Fix tcp idle timeout test, for difference in the tcp reply code. diff --git a/services/authzone.c b/services/authzone.c index ff8b23e62..8f74fe3eb 100644 --- a/services/authzone.c +++ b/services/authzone.c @@ -88,6 +88,9 @@ #define AUTH_HTTPS_PORT 443 /* max depth for nested $INCLUDEs */ #define MAX_INCLUDE_DEPTH 10 +/** number of timeouts before we fallback from IXFR to AXFR, + * because some versions of servers (eg. dnsmasq) drop IXFR packets. */ +#define NUM_TIMEOUTS_FALLBACK_IXFR 3 /** pick up nextprobe task to start waiting to perform transfer actions */ static void xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env, @@ -5636,6 +5639,20 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err, * and continue task_transfer*/ verbose(VERB_ALGO, "xfr stopped, connection lost to %s", xfr->task_transfer->master->host); + + /* see if IXFR caused the failure, if so, try AXFR */ + if(xfr->task_transfer->on_ixfr) { + xfr->task_transfer->ixfr_possible_timeout_count++; + if(xfr->task_transfer->ixfr_possible_timeout_count >= + NUM_TIMEOUTS_FALLBACK_IXFR) { + verbose(VERB_ALGO, "xfr to %s, fallback " + "from IXFR to AXFR (because of timeouts)", + xfr->task_transfer->master->host); + xfr->task_transfer->ixfr_fail = 1; + gonextonfail = 0; + } + } + failed: /* delete transferred data from list */ auth_chunks_delete(xfr->task_transfer); @@ -5645,6 +5662,7 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err, xfr_transfer_nexttarget_or_end(xfr, env); return 0; } + xfr->task_transfer->ixfr_possible_timeout_count = 0; /* handle returned packet */ /* if it fails, cleanup and end this transfer */ diff --git a/services/authzone.h b/services/authzone.h index 243f3e4a0..4706803a8 100644 --- a/services/authzone.h +++ b/services/authzone.h @@ -378,6 +378,8 @@ struct auth_transfer { * data or add of duplicate data). Flag is cleared once the retry * with axfr is done. */ int ixfr_fail; + /** we saw an ixfr-indicating timeout, count of them */ + int ixfr_possible_timeout_count; /** we are doing IXFR right now */ int on_ixfr; /** did we detect the current AXFR/IXFR serial number yet, 0 not yet, -- 2.47.3