diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2015-02-27 18:58:59 +0000 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2015-02-27 18:58:59 +0000 |
commit | bd4ece7debfe8926fe99608da6cfe5aaac6a550b (patch) | |
tree | d49f28abf0d39963723c91d196e5165b3bd34fba /src | |
parent | b980ed83fa4ae95ee650ccf73d33dbad4c20c595 (diff) |
Add retry type "lookup". Bug 1566
Also add dnslookup router option "fail_defer_domains" to support it.
Diffstat (limited to 'src')
-rw-r--r-- | src/src/exim_dbutil.c | 13 | ||||
-rw-r--r-- | src/src/macros.h | 2 | ||||
-rw-r--r-- | src/src/readconf.c | 45 | ||||
-rw-r--r-- | src/src/routers/dnslookup.c | 48 | ||||
-rw-r--r-- | src/src/routers/dnslookup.h | 1 | ||||
-rw-r--r-- | src/src/routers/rf_lookup_hostlist.c | 1 |
6 files changed, 58 insertions, 52 deletions
diff --git a/src/src/exim_dbutil.c b/src/src/exim_dbutil.c index 48323243d..72eee42e8 100644 --- a/src/src/exim_dbutil.c +++ b/src/src/exim_dbutil.c @@ -642,19 +642,6 @@ while (key != NULL) printf("\n"); } - /* Old-style domain record, without separate timestamps. This code can - eventually be thrown away, say in 5 years' time (it's now Feb 2003). */ - - else - { - printf("%s %s callout=%s postmaster=%s random=%s\n", - print_time(((dbdata_generic *)value)->time_stamp), - keybuffer, - print_cache(callout->result), - print_cache(callout->postmaster_result), - print_cache(callout->random_result)); - } - break; case type_ratelimit: diff --git a/src/src/macros.h b/src/src/macros.h index 4db2bdab9..0f893e812 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -487,7 +487,7 @@ to conflict with system errno values. */ #define ERRNO_UIDFAIL (-29) /* Failed to get uid */ #define ERRNO_BADTRANSPORT (-30) /* Unset or non-existent transport */ #define ERRNO_MBXLENGTH (-31) /* MBX length mismatch */ -#define ERRNO_UNKNOWNHOST (-32) /* Lookup failed in smtp transport */ +#define ERRNO_UNKNOWNHOST (-32) /* Lookup failed routing or in smtp tpt */ #define ERRNO_FORMATUNKNOWN (-33) /* Can't match format in appendfile */ #define ERRNO_BADCREATE (-34) /* Creation outside home in appendfile */ #define ERRNO_LISTDEFER (-35) /* Can't check a list; lookup defer */ diff --git a/src/src/readconf.c b/src/src/readconf.c index 31e04e97e..e2d3c518f 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -3696,7 +3696,8 @@ Returns: NULL if decoded correctly; else points to error text */ uschar * -readconf_retry_error(const uschar *pp, const uschar *p, int *basic_errno, int *more_errno) +readconf_retry_error(const uschar *pp, const uschar *p, + int *basic_errno, int *more_errno) { int len; const uschar *q = pp; @@ -3736,24 +3737,19 @@ else if (len == 7 && strncmpic(pp, US"timeout", len) == 0) { 'A', 'M', RTEF_CTOUT, RTEF_CTOUT|'A', RTEF_CTOUT|'M' }; for (i = 0; i < sizeof(extras)/sizeof(uschar *); i++) - { if (strncmpic(x, extras[i], xlen) == 0) { *more_errno = values[i]; break; } - } if (i >= sizeof(extras)/sizeof(uschar *)) - { if (strncmpic(x, US"DNS", xlen) == 0) - { log_write(0, LOG_MAIN|LOG_PANIC, "\"timeout_dns\" is no longer " "available in retry rules (it has never worked) - treated as " "\"timeout\""); - } - else return US"\"A\", \"MX\", or \"connect\" expected after \"timeout\""; - } + else + return US"\"A\", \"MX\", or \"connect\" expected after \"timeout\""; } } @@ -3780,8 +3776,8 @@ else if (strncmpic(pp, US"mail_4", 6) == 0 || return string_sprintf("%.4s_4 must be followed by xx, dx, or dd, where " "x is literal and d is any digit", pp); - *basic_errno = (*pp == 'm')? ERRNO_MAIL4XX : - (*pp == 'r')? ERRNO_RCPT4XX : ERRNO_DATA4XX; + *basic_errno = *pp == 'm' ? ERRNO_MAIL4XX : + *pp == 'r' ? ERRNO_RCPT4XX : ERRNO_DATA4XX; *more_errno = x << 8; } @@ -3795,6 +3791,9 @@ else if (strncmpic(pp, US"lost_connection", p - pp) == 0) else if (strncmpic(pp, US"tls_required", p - pp) == 0) *basic_errno = ERRNO_TLSREQUIRED; +else if (strncmpic(pp, US"lookup", p - pp) == 0) + *basic_errno = ERRNO_UNKNOWNHOST; + else if (len != 1 || Ustrncmp(pp, "*", 1) != 0) return string_sprintf("unknown or malformed retry error \"%.*s\"", (int) (p-pp), pp); @@ -3849,10 +3848,8 @@ if (*p != 0 && !isspace(*p) && *p != ',' && *p != ';') *paddr = p; switch (type) { - case 0: - return readconf_readtime(pp, *p, FALSE); - case 1: - return readconf_readfixed(pp, *p); + case 0: return readconf_readtime(pp, *p, FALSE); + case 1: return readconf_readfixed(pp, *p); } return 0; /* Keep picky compilers happy */ } @@ -3866,7 +3863,7 @@ retry_config **chain = &retries; retry_config *next; const uschar *p; -while ((p = get_config_line()) != NULL) +while ((p = get_config_line())) { retry_rule **rchain; const uschar *pp; @@ -3890,8 +3887,8 @@ while ((p = get_config_line()) != NULL) /* Test error names for things we understand. */ - if ((error = readconf_retry_error(pp, p, &(next->basic_errno), - &(next->more_errno))) != NULL) + if ((error = readconf_retry_error(pp, p, &next->basic_errno, + &next->more_errno))) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%s", error); /* There may be an optional address list of senders to be used as another @@ -3928,18 +3925,18 @@ while ((p = get_config_line()) != NULL) switch (rule->rule) { case 'F': /* Fixed interval */ - rule->p1 = retry_arg(&p, 0); - break; + rule->p1 = retry_arg(&p, 0); + break; case 'G': /* Geometrically increasing intervals */ case 'H': /* Ditto, but with randomness */ - rule->p1 = retry_arg(&p, 0); - rule->p2 = retry_arg(&p, 1); - break; + rule->p1 = retry_arg(&p, 0); + rule->p2 = retry_arg(&p, 1); + break; default: - log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unknown retry rule letter"); - break; + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unknown retry rule letter"); + break; } if (rule->timeout <= 0 || rule->p1 <= 0 || diff --git a/src/src/routers/dnslookup.c b/src/src/routers/dnslookup.c index aa5b924c7..8ef4e0da9 100644 --- a/src/src/routers/dnslookup.c +++ b/src/src/routers/dnslookup.c @@ -22,6 +22,8 @@ optionlist dnslookup_router_options[] = { (void *)(offsetof(dnslookup_router_options_block, dnssec_request_domains)) }, { "dnssec_require_domains", opt_stringptr, (void *)(offsetof(dnslookup_router_options_block, dnssec_require_domains)) }, + { "fail_defer_domains", opt_stringptr, + (void *)(offsetof(dnslookup_router_options_block, fail_defer_domains)) }, { "mx_domains", opt_stringptr, (void *)(offsetof(dnslookup_router_options_block, mx_domains)) }, { "mx_fail_domains", opt_stringptr, @@ -59,7 +61,8 @@ dnslookup_router_options_block dnslookup_router_option_defaults = { NULL, /* srv_fail_domains */ NULL, /* check_srv */ NULL, /* dnssec_request_domains */ - NULL /* dnssec_require_domains */ + NULL, /* dnssec_require_domains */ + NULL /* fail_defer_domains */ }; @@ -161,10 +164,10 @@ DEBUG(D_route) /* If an SRV check is required, expand the service name */ -if (ob->check_srv != NULL) +if (ob->check_srv) { - srv_service = expand_string(ob->check_srv); - if (srv_service == NULL && !expand_string_forcedfail) + if ( !(srv_service = expand_string(ob->check_srv)) + && !expand_string_forcedfail) { addr->message = string_sprintf("%s router: failed to expand \"%s\": %s", rblock->name, ob->check_srv, expand_string_message); @@ -195,8 +198,8 @@ does not appear in the message header so it is also OK to widen. The suppression of widening for sender addresses is silent because it is the normal desirable behaviour. */ -if (ob->widen_domains != NULL && - (verify != v_sender || !ob->rewrite_headers || addr->parent != NULL)) +if ( ob->widen_domains + && (verify != v_sender || !ob->rewrite_headers || addr->parent)) { listptr = ob->widen_domains; widen = string_nextinlist(&listptr, &widen_sep, widen_buffer, @@ -220,12 +223,12 @@ for (;;) int flags = whichrrs; BOOL removed = FALSE; - if (pre_widen != NULL) + if (pre_widen) { h.name = pre_widen; pre_widen = NULL; } - else if (widen != NULL) + else if (widen) { h.name = string_sprintf("%s.%s", addr->domain, widen); widen = string_nextinlist(&listptr, &widen_sep, widen_buffer, @@ -233,7 +236,7 @@ for (;;) DEBUG(D_route) debug_printf("%s router widened %s to %s\n", rblock->name, addr->domain, h.name); } - else if (post_widen != NULL) + else if (post_widen) { h.name = post_widen; post_widen = NULL; @@ -260,7 +263,7 @@ for (;;) subsequently. We use the same logic as that for widen_domains above to avoid requesting a header rewrite that cannot work. */ - if (verify != v_sender || !ob->rewrite_headers || addr->parent != NULL) + if (verify != v_sender || !ob->rewrite_headers || addr->parent) { if (ob->qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE; if (ob->search_parents) flags |= HOST_FIND_SEARCH_PARENTS; @@ -277,10 +280,9 @@ for (;;) the option is historical. */ if ((rc == HOST_FOUND || rc == HOST_FOUND_LOCAL) && h.mx < 0 && - ob->mx_domains != NULL) - { + ob->mx_domains) switch(match_isinlist(fully_qualified_name, - (const uschar **)&(ob->mx_domains), 0, + CUSS &(ob->mx_domains), 0, &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL)) { case DEFER: @@ -292,7 +294,6 @@ for (;;) rblock->name, fully_qualified_name); continue; } - } /* Deferral returns forthwith, and anything other than failure breaks the loop. */ @@ -329,6 +330,7 @@ for (;;) addr->message = US"an MX or SRV record indicated no SMTP service"; else { + addr->basic_errno = ERRNO_UNKNOWNHOST; addr->message = US"all relevant MX records point to non-existent hosts"; if (!allow_mx_to_ip && string_is_ip_address(h.name, NULL) != 0) { @@ -340,6 +342,22 @@ for (;;) addr->message); } } + if (ob->fail_defer_domains) + { + switch(match_isinlist(fully_qualified_name, + CUSS &ob->fail_defer_domains, 0, + &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL)) + { + case DEFER: + addr->message = US"lookup defer for fail_defer_domains"; + return DEFER; + + case OK: + DEBUG(D_route) debug_printf("%s router: matched fail_defer_domains\n", + rblock->name); + return DEFER; + } + } return DECLINE; } @@ -431,3 +449,5 @@ return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)? } /* End of routers/dnslookup.c */ +/* vi: aw ai sw=2 +*/ diff --git a/src/src/routers/dnslookup.h b/src/src/routers/dnslookup.h index 518b7f478..907ff0ce3 100644 --- a/src/src/routers/dnslookup.h +++ b/src/src/routers/dnslookup.h @@ -19,6 +19,7 @@ typedef struct { uschar *check_srv; uschar *dnssec_request_domains; uschar *dnssec_require_domains; + uschar *fail_defer_domains; } dnslookup_router_options_block; /* Data for reading the private options. */ diff --git a/src/src/routers/rf_lookup_hostlist.c b/src/src/routers/rf_lookup_hostlist.c index 28d4fc4c1..ab2e4ec2c 100644 --- a/src/src/routers/rf_lookup_hostlist.c +++ b/src/src/routers/rf_lookup_hostlist.c @@ -168,6 +168,7 @@ for (h = addr->host_list; h != NULL; h = next_h) if (hff_code == hff_pass) return PASS; if (hff_code == hff_decline) return DECLINE; + addr->basic_errno = ERRNO_UNKNOWNHOST; addr->message = string_sprintf("lookup of host \"%s\" failed in %s router%s", h->name, rblock->name, |