diff options
author | Simon Kelley <simon@thekelleys.org.uk> | 2022-09-14 16:16:08 +0100 |
---|---|---|
committer | Simon Kelley <simon@thekelleys.org.uk> | 2022-09-15 19:29:49 +0100 |
commit | 9a9f6e147cb5489faeb3ea220ab08cf81be7b72c (patch) | |
tree | ba01d98053fa719e98a8213d1197ca8b69e06f49 | |
parent | 8f2d432799280bd895a29159c38150a5c0f1ed3a (diff) | |
download | dnsmasq-9a9f6e147cb5489faeb3ea220ab08cf81be7b72c.tar.gz |
Make fast-retry more configurable and do exponential backoff.
-rw-r--r-- | man/dnsmasq.8 | 9 | ||||
-rw-r--r-- | src/config.h | 1 | ||||
-rw-r--r-- | src/dnsmasq.h | 3 | ||||
-rw-r--r-- | src/forward.c | 15 | ||||
-rw-r--r-- | src/option.c | 30 |
5 files changed, 40 insertions, 18 deletions
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 index 11640a7..3ae3000 100644 --- a/man/dnsmasq.8 +++ b/man/dnsmasq.8 @@ -105,11 +105,14 @@ Dnsmasq limits the value of this option to one hour, unless recompiled. .B --auth-ttl=<time> Set the TTL value returned in answers from the authoritative server. .TP -.B --fast-dns-retry=<time in ms> +.B --fast-dns-retry=[<initial retry delay in ms>[,<time to continue retries in ms>]] Under normal circumstances, dnsmasq relies on DNS clients to do retries; it does not generate timeouts itself. Setting this option -instructs dnsmasq to generate its own retries after the specified time, which -must be greater than 500ms. Using this option increases memory usage and +instructs dnsmasq to generate its own retries starting after a delay +which defaults to 1000ms. If the second parameter is given this controls +how long the retries will continue for +otherwise this defaults to 10000ms. Retries are repeated with exponential +backoff. Using this option increases memory usage and network bandwidth. .TP .B \-k, --keep-in-foreground diff --git a/src/config.h b/src/config.h index 5746c0b..df1d985 100644 --- a/src/config.h +++ b/src/config.h @@ -59,6 +59,7 @@ #define SOA_EXPIRY 1209600 /* SOA expiry default */ #define LOOP_TEST_DOMAIN "test" /* domain for loop testing, "test" is reserved by RFC 2606 and won't therefore clash */ #define LOOP_TEST_TYPE T_TXT +#define DEFAULT_FAST_RETRY 1000 /* ms, default delay before fast retry */ /* compile-time options: uncomment below to enable or do eg. make COPTS=-DHAVE_BROKEN_RTC diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 6f02368..d86df10 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -758,6 +758,7 @@ struct frec { int forwardall, flags; time_t time; u32 forward_timestamp; + int forward_delay; unsigned char *hash[HASH_SIZE]; struct blockdata *stash; /* Saved reply, whilst we validate */ size_t stash_len; @@ -1187,7 +1188,7 @@ extern struct daemon { int dump_mask; unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry; u32 metrics[__METRIC_MAX]; - int fast_retry_time; + int fast_retry_time, fast_retry_timeout; #ifdef HAVE_DNSSEC struct ds_config *ds; char *timestamp_file; diff --git a/src/forward.c b/src/forward.c index 7d85cf7..4e127ba 100644 --- a/src/forward.c +++ b/src/forward.c @@ -608,7 +608,7 @@ int fast_retry(time_t now) u32 millis = dnsmasq_milliseconds(); for (f = daemon->frec_list; f; f = f->next) - if (f->sentto && f->stash && difftime(now, f->time) < TIMEOUT) + if (f->sentto && f->stash && difftime(now, f->time) < daemon->fast_retry_timeout) { #ifdef HAVE_DNSSEC if (f->blocking_query) @@ -617,8 +617,8 @@ int fast_retry(time_t now) /* t is milliseconds since last query sent. */ int to_run, t = (int)(millis - f->forward_timestamp); - if (t < daemon->fast_retry_time) - to_run = daemon->fast_retry_time - t; + if (t < f->forward_delay) + to_run = f->forward_delay - t; else { unsigned char *udpsz; @@ -639,7 +639,7 @@ int fast_retry(time_t now) forward_query(-1, NULL, NULL, 0, header, f->stash_len, ((char *) header) + udp_size, now, f, f->flags & FREC_AD_QUESTION, f->flags & FREC_DO_QUESTION); - to_run = daemon->fast_retry_time; + to_run = f->forward_delay = 2 * f->forward_delay; } if (ret == -1 || ret > to_run) @@ -2822,8 +2822,11 @@ static struct frec *get_new_frec(time_t now, struct server *master, int force) } if (target) - target->time = now; - + { + target->time = now; + target->forward_delay = daemon->fast_retry_time; + } + return target; } diff --git a/src/option.c b/src/option.c index aaecebe..f2110cf 100644 --- a/src/option.c +++ b/src/option.c @@ -370,7 +370,7 @@ static const struct myoption opts[] = { "umbrella", 2, 0, LOPT_UMBRELLA }, { "quiet-tftp", 0, 0, LOPT_QUIET_TFTP }, { "port-limit", 1, 0, LOPT_RANDPORT_LIM }, - { "fast-dns-retry", 1, 0, LOPT_FAST_RETRY }, + { "fast-dns-retry", 2, 0, LOPT_FAST_RETRY }, { "use-stale-cache", 0, 0 , LOPT_STALE_CACHE }, { NULL, 0, 0, 0 } }; @@ -3230,14 +3230,28 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma } case LOPT_FAST_RETRY: - { - int retry; - if (!atoi_check(arg, &retry) || retry < 500) - ret_err(gen_err); - daemon->fast_retry_time = retry; - break; - } + daemon->fast_retry_timeout = TIMEOUT; + if (!arg) + daemon->fast_retry_time = DEFAULT_FAST_RETRY; + else + { + int retry; + + comma = split(arg); + if (!atoi_check(arg, &retry) || retry < 50) + ret_err(gen_err); + daemon->fast_retry_time = retry; + + if (comma) + { + if (!atoi_check(comma, &retry)) + ret_err(gen_err); + daemon->fast_retry_timeout = retry/1000; + } + } + break; + #ifdef HAVE_DHCP case 'X': /* --dhcp-lease-max */ if (!atoi_check(arg, &daemon->dhcp_max)) |