summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Kelley <simon@thekelleys.org.uk>2022-09-14 16:16:08 +0100
committerSimon Kelley <simon@thekelleys.org.uk>2022-09-15 19:29:49 +0100
commit9a9f6e147cb5489faeb3ea220ab08cf81be7b72c (patch)
treeba01d98053fa719e98a8213d1197ca8b69e06f49
parent8f2d432799280bd895a29159c38150a5c0f1ed3a (diff)
downloaddnsmasq-9a9f6e147cb5489faeb3ea220ab08cf81be7b72c.tar.gz
Make fast-retry more configurable and do exponential backoff.
-rw-r--r--man/dnsmasq.89
-rw-r--r--src/config.h1
-rw-r--r--src/dnsmasq.h3
-rw-r--r--src/forward.c15
-rw-r--r--src/option.c30
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))