summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-docbook/spec.xfpt13
-rw-r--r--doc/doc-txt/ChangeLog2
-rw-r--r--src/src/lookups/dnsdb.c95
-rw-r--r--test/scripts/2200-dnsdb/22005
-rw-r--r--test/stdout/22005
5 files changed, 80 insertions, 40 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 9baaad233..535e81ee6 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -6962,6 +6962,17 @@ The default is &"never"&.
See also the &$lookup_dnssec_authenticated$& variable.
+.cindex timeout "dns lookup"
+.cindex "DNS" timeout
+Timeout for the dnsdb lookup can be controlled by a retrans modifier.
+The form is &"retrans_VAL"& where VAL is an Exim time specification
+(eg &"5s"&).
+The default value is set by the main configuration option &%dns_retrans%&.
+
+Retries for the dnsdb lookup can be controlled by a retry modifier.
+The form if &"retry_VAL"& where VAL is an integer.
+The default count is set by the main configuration option &%dns_retry%&.
+
.section "Pseudo dnsdb record types" "SECID66"
.cindex "MX record" "in &(dnsdb)& lookup"
@@ -14155,6 +14166,8 @@ servers have all been upgraded, there should be no need for this option.
.option dns_retrans main time 0s
.cindex "DNS" "resolver options"
+.cindex timeout "dns lookup"
+.cindex "DNS" timeout
The options &%dns_retrans%& and &%dns_retry%& can be used to set the
retransmission and retry parameters for DNS lookups. Values of zero (the
defaults) leave the system default settings unchanged. The first value is the
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index a75c10657..89e0ecf50 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -92,6 +92,8 @@ JH/25 Bug 466: Add RFC2322 support for MIME attachment filenames.
HS/02 Bug 1575: exigrep falls back to autodetection of compressed
files if ZCAT_COMMAND is not executable.
+JH/26 Bug 1539: Add timout/retry options on dnsdb lookups.
+
Exim version 4.85
-----------------
diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c
index 1e8df3b16..a0a457ab2 100644
--- a/src/src/lookups/dnsdb.c
+++ b/src/src/lookups/dnsdb.c
@@ -102,21 +102,28 @@ no separator. With neither of these options specified, only the first item
is output. Similarly for "SPF" records, but the default for joining multiple
items in one SPF record is the empty string, for direct concatenation.
-(c) If the next sequence of characters is 'defer_FOO' followed by a comma,
-the defer behaviour is set to FOO. The possible behaviours are: 'strict', where
-any defer causes the whole lookup to defer; 'lax', where a defer causes the
-whole lookup to defer only if none of the DNS queries succeeds; and 'never',
-where all defers are as if the lookup failed. The default is 'lax'.
-
-(d) Another optional comma-sep field: 'dnssec_FOO', with 'strict', 'lax'
-and 'never' (default); can appear before or after (c). The meanings are
+(c) Options, all comma-terminated, in any order. Any unrecognised option
+terminates option processing. Recognised options are:
+
+- 'defer_FOO': set the defer behaviour to FOO. The possible behaviours are:
+'strict', where any defer causes the whole lookup to defer; 'lax', where a defer
+causes the whole lookup to defer only if none of the DNS queries succeeds; and
+'never', where all defers are as if the lookup failed. The default is 'lax'.
+
+- 'dnssec_FOO', with 'strict', 'lax' and 'never' (default). The meanings are
require, try and don't-try dnssec respectively.
-(e) If the next sequence of characters is a sequence of letters and digits
+- 'retrans_VAL', set the timeout value. VAL is an Exim time specification
+(eg "5s"). The default is set by the main configuration option 'dns_retrans'.
+
+- 'retry_VAL', set the retry count on timeouts. VAL is an integer. The
+default is set by the main configuration option "dns_retry".
+
+(d) If the next sequence of characters is a sequence of letters and digits
followed by '=', it is interpreted as the name of the DNS record type. The
default is "TXT".
-(f) Then there follows list of domain names. This is a generalized Exim list,
+(e) Then there follows list of domain names. This is a generalized Exim list,
which may start with '<' in order to set a specific separator. The default
separator, as always, is colon. */
@@ -130,12 +137,13 @@ int ptr = 0;
int sep = 0;
int defer_mode = PASS;
int dnssec_mode = OK;
+int save_retrans = dns_retrans;
+int save_retry = dns_retry;
int type;
int failrc = FAIL;
const uschar *outsep = CUS"\n";
const uschar *outsep2 = NULL;
uschar *equals, *domain, *found;
-uschar buffer[256];
/* Because we're the working in the search pool, we try to reclaim as much
store as possible later, so we preallocate the result here */
@@ -174,58 +182,62 @@ if (*keystring == '>')
/* Check for a modifier keyword. */
-while ( strncmpic(keystring, US"defer_", 6) == 0
- || strncmpic(keystring, US"dnssec_", 7) == 0
- )
+for (;;)
{
if (strncmpic(keystring, US"defer_", 6) == 0)
{
keystring += 6;
if (strncmpic(keystring, US"strict", 6) == 0)
- {
- defer_mode = DEFER;
- keystring += 6;
- }
+ { defer_mode = DEFER; keystring += 6; }
else if (strncmpic(keystring, US"lax", 3) == 0)
- {
- defer_mode = PASS;
- keystring += 3;
- }
+ { defer_mode = PASS; keystring += 3; }
else if (strncmpic(keystring, US"never", 5) == 0)
- {
- defer_mode = OK;
- keystring += 5;
- }
+ { defer_mode = OK; keystring += 5; }
else
{
*errmsg = US"unsupported dnsdb defer behaviour";
return DEFER;
}
}
- else
+ else if (strncmpic(keystring, US"dnssec_", 7) == 0)
{
keystring += 7;
if (strncmpic(keystring, US"strict", 6) == 0)
- {
- dnssec_mode = DEFER;
- keystring += 6;
- }
+ { dnssec_mode = DEFER; keystring += 6; }
else if (strncmpic(keystring, US"lax", 3) == 0)
+ { dnssec_mode = PASS; keystring += 3; }
+ else if (strncmpic(keystring, US"never", 5) == 0)
+ { dnssec_mode = OK; keystring += 5; }
+ else
{
- dnssec_mode = PASS;
- keystring += 3;
+ *errmsg = US"unsupported dnsdb dnssec behaviour";
+ return DEFER;
}
- else if (strncmpic(keystring, US"never", 5) == 0)
+ }
+ else if (strncmpic(keystring, US"retrans_", 8) == 0)
+ {
+ int timeout_sec;
+ if ((timeout_sec = readconf_readtime(keystring += 8, ',', FALSE)) <= 0)
{
- dnssec_mode = OK;
- keystring += 5;
+ *errmsg = US"unsupported dnsdb timeout value";
+ return DEFER;
}
- else
+ dns_retrans = timeout_sec;
+ while (*keystring != ',') keystring++;
+ }
+ else if (strncmpic(keystring, US"retry_", 6) == 0)
+ {
+ int retries;
+ if ((retries = (int)strtol(keystring + 6, CSS &keystring, 0)) < 0)
{
- *errmsg = US"unsupported dnsdb dnssec behaviour";
+ *errmsg = US"unsupported dnsdb retry count";
return DEFER;
}
+ dns_retry = retries;
}
+ else
+ break;
+
while (isspace(*keystring)) keystring++;
if (*keystring++ != ',')
{
@@ -301,8 +313,7 @@ if (!outsep2) switch(type)
/* Now scan the list and do a lookup for each item */
-while ((domain = string_nextinlist(&keystring, &sep, buffer, sizeof(buffer)))
- != NULL)
+while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
{
uschar rbuffer[256];
int searchtype = (type == T_CSA)? T_SRV : /* record type we want */
@@ -357,6 +368,8 @@ while ((domain = string_nextinlist(&keystring, &sep, buffer, sizeof(buffer)))
{
if (defer_mode == DEFER)
{
+ dns_retrans = save_retrans;
+ dns_retry = save_retry;
dns_init(FALSE, FALSE, FALSE); /* clr dnssec bit */
return DEFER; /* always defer */
}
@@ -528,6 +541,8 @@ store_reset(yield + ptr + 1);
/* If ptr == 0 we have not found anything. Otherwise, insert the terminating
zero and return the result. */
+dns_retrans = save_retrans;
+dns_retry = save_retry;
dns_init(FALSE, FALSE, FALSE); /* clear the dnssec bit for getaddrbyname */
if (ptr == 0) return failrc;
diff --git a/test/scripts/2200-dnsdb/2200 b/test/scripts/2200-dnsdb/2200
index d1770c84f..837c85a1c 100644
--- a/test/scripts/2200-dnsdb/2200
+++ b/test/scripts/2200-dnsdb/2200
@@ -40,4 +40,9 @@ defer_lax:ten-1 ${lookup dnsdb{defer_lax,a=test.again.dns:ten-1.test.
defer_never:ten-1 ${lookup dnsdb{defer_never,a=test.again.dns:ten-1.test.ex}}
defer_never:defer ${lookup dnsdb{defer_never,a=test.again.dns:test.again.dns}}
defer_strict:ten-1 ${lookup dnsdb{defer_strict,a=test.again.dns:ten-1.test.ex}}
+
+# Retry timeout and count. This only tests the syntax; we do not
+# have any good way of testing the function.
+
+delay1500 ${lookup dnsdb{retrans_1s,retry_2,a=delay1500.test.ex}}
****
diff --git a/test/stdout/2200 b/test/stdout/2200
index 90504c6da..3d7d0db88 100644
--- a/test/stdout/2200
+++ b/test/stdout/2200
@@ -43,3 +43,8 @@ ten-2.test.ex
> defer_never:defer
> Failed: lookup of "defer_strict,a=test.again.dns:ten-1.test.ex" gave DEFER:
>
+> # Retry timeout and count. This only tests the syntax; we do not
+> # have any good way of testing the function.
+>
+> delay1500 ip4.ip4.ip4.ip4
+>