]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix for #4219: secondaries not updated after serial change, unbound
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 22 Jan 2019 15:36:58 +0000 (15:36 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 22 Jan 2019 15:36:58 +0000 (15:36 +0000)
  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
services/authzone.c
services/authzone.h

index 152e6011b29af25d57f2d359b8c90513a8ea284a..2b69fde8322fe6d121629699336818227592c2e6 100644 (file)
@@ -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.
index ff8b23e622e06c52711422e1d4a716b1c3855d6b..8f74fe3eb6531dc81837f5b558058f83b16e02b4 100644 (file)
@@ -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 */
index 243f3e4a01e8822b34762f858dd19cfa97fe722e..4706803a86b305d33b8ed094bf6c763289712c97 100644 (file)
@@ -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,