diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2018-01-28 12:42:01 +0000 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2018-01-28 19:44:57 +0000 |
commit | 66387a737208e277990b0cbfe58db3db419f34b2 (patch) | |
tree | 80fb5d051e5dbbebf056d5eb4887fe2d5f6d7c71 /src | |
parent | d011368ae0e05db3dd79c111020686f3a1364ab0 (diff) |
Routing: dnslookup and manualroute routers: ipv4_only, ipv4_prefer options. Bug 2149
Diffstat (limited to 'src')
-rw-r--r-- | src/src/host.c | 85 | ||||
-rw-r--r-- | src/src/macros.h | 20 | ||||
-rw-r--r-- | src/src/routers/dnslookup.c | 49 | ||||
-rw-r--r-- | src/src/routers/dnslookup.h | 4 | ||||
-rw-r--r-- | src/src/routers/manualroute.c | 18 | ||||
-rw-r--r-- | src/src/routers/queryprogram.c | 6 | ||||
-rw-r--r-- | src/src/routers/rf_lookup_hostlist.c | 33 | ||||
-rw-r--r-- | src/src/smtp_in.c | 2 | ||||
-rw-r--r-- | src/src/transports/smtp.c | 2 | ||||
-rw-r--r-- | src/src/verify.c | 2 |
10 files changed, 140 insertions, 81 deletions
diff --git a/src/src/host.c b/src/src/host.c index 1f0d91959..72130f55a 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -1841,7 +1841,7 @@ for (hname = sender_host_name; hname; hname = *aliases++) d.request = sender_host_dnssec ? US"*" : NULL;; d.require = NULL; - if ( (rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A, + if ( (rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A | HOST_FIND_BY_AAAA, NULL, NULL, NULL, &d, NULL, NULL)) == HOST_FOUND || rc == HOST_FOUND_LOCAL ) @@ -2241,9 +2241,7 @@ field set to NULL, fill in its IP address from the DNS. If it is multi-homed, create additional host items for the additional addresses, copying all the other fields, and randomizing the order. -On IPv6 systems, A6 records are sought first (but only if support for A6 is -configured - they may never become mainstream), then AAAA records are sought, -and finally A records are sought as well. +On IPv6 systems, AAAA records are sought first, then A records. The host name may be changed if the DNS returns a different name - e.g. fully qualified or changed via CNAME. If fully_qualified_name is not NULL, dns_lookup @@ -2266,6 +2264,7 @@ Arguments: to something) dnssec_request if TRUE request the AD bit dnssec_require if TRUE require the AD bit + whichrrs select ipv4, ipv6 results Returns: HOST_FIND_FAILED couldn't find A record HOST_FIND_AGAIN try again later @@ -2278,7 +2277,7 @@ static int set_address_from_dns(host_item *host, host_item **lastptr, const uschar *ignore_target_hosts, BOOL allow_ip, const uschar **fully_qualified_name, - BOOL dnssec_request, BOOL dnssec_require) + BOOL dnssec_request, BOOL dnssec_require, int whichrrs) { dns_record *rr; host_item *thishostlast = NULL; /* Indicates not yet filled in anything */ @@ -2293,8 +2292,8 @@ those sites that feel they have to flaunt the RFC rules. */ if (allow_ip && string_is_ip_address(host->name, NULL) != 0) { #ifndef STAND_ALONE - if (ignore_target_hosts != NULL && - verify_check_this_host(&ignore_target_hosts, NULL, host->name, + if ( ignore_target_hosts + && verify_check_this_host(&ignore_target_hosts, NULL, host->name, host->name, NULL) == OK) return HOST_IGNORED; #endif @@ -2304,16 +2303,18 @@ if (allow_ip && string_is_ip_address(host->name, NULL) != 0) } /* On an IPv6 system, unless IPv6 is disabled, go round the loop up to twice, -looking for AAAA records the first time. However, unless -doing standalone testing, we force an IPv4 lookup if the domain matches -dns_ipv4_lookup is set. On an IPv4 system, go round the -loop once only, looking only for A records. */ +looking for AAAA records the first time. However, unless doing standalone +testing, we force an IPv4 lookup if the domain matches dns_ipv4_lookup global. +On an IPv4 system, go round the loop once only, looking only for A records. */ #if HAVE_IPV6 #ifndef STAND_ALONE - if (disable_ipv6 || (dns_ipv4_lookup != NULL && - match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL, - MCL_DOMAIN, TRUE, NULL) == OK)) + if ( disable_ipv6 + || !(whichrrs & HOST_FIND_BY_AAAA) + || (dns_ipv4_lookup + && match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL, + MCL_DOMAIN, TRUE, NULL) == OK) + ) i = 0; /* look up A records only */ else #endif /* STAND_ALONE */ @@ -2330,7 +2331,8 @@ for (; i >= 0; i--) { static int types[] = { T_A, T_AAAA }; int type = types[i]; - int randoffset = (i == 0)? 500 : 0; /* Ensures v6 sorts before v4 */ + int randoffset = i == (whichrrs & HOST_FIND_IPV4_FIRST ? 1 : 0) + ? 500 : 0; /* Ensures v6/4 sort order */ dns_answer dnsa; dns_scan dnss; @@ -2532,10 +2534,13 @@ Arguments: whichrrs flags indicating which RRs to look for: HOST_FIND_BY_SRV => look for SRV HOST_FIND_BY_MX => look for MX - HOST_FIND_BY_A => look for A or AAAA + HOST_FIND_BY_A => look for A + HOST_FIND_BY_AAAA => look for AAAA also flags indicating how the lookup is done HOST_FIND_QUALIFY_SINGLE ) passed to the HOST_FIND_SEARCH_PARENTS ) resolver + HOST_FIND_IPV4_FIRST => reverse usual result ordering + HOST_FIND_IPV4_ONLY => MX results elide ipv6 srv_service when SRV used, the service name srv_fail_domains DNS errors for these domains => assume nonexist mx_fail_domains DNS errors for these domains => assume nonexist @@ -2716,7 +2721,7 @@ host. */ if (rc != DNS_SUCCEED) { - if ((whichrrs & HOST_FIND_BY_A) == 0) + if (!(whichrrs & (HOST_FIND_BY_A | HOST_FIND_BY_AAAA))) { DEBUG(D_host_lookup) debug_printf("Address records are not being sought\n"); yield = HOST_FIND_FAILED; @@ -2729,7 +2734,7 @@ if (rc != DNS_SUCCEED) host->dnssec = DS_UNK; lookup_dnssec_authenticated = NULL; rc = set_address_from_dns(host, &last, ignore_target_hosts, FALSE, - fully_qualified_name, dnssec_request, dnssec_require); + fully_qualified_name, dnssec_request, dnssec_require, whichrrs); /* If one or more address records have been found, check that none of them are local. Since we know the host items all have their IP addresses @@ -3064,20 +3069,18 @@ for (h = host; h != last->next; h = h->next) if (h->address) continue; /* Inserted by a multihomed host */ rc = set_address_from_dns(h, &last, ignore_target_hosts, allow_mx_to_ip, - NULL, dnssec_request, dnssec_require); + NULL, dnssec_request, dnssec_require, + whichrrs & HOST_FIND_IPV4_ONLY + ? HOST_FIND_BY_A : HOST_FIND_BY_A | HOST_FIND_BY_AAAA); if (rc != HOST_FOUND) { h->status = hstatus_unusable; switch (rc) { - case HOST_FIND_AGAIN: - yield = rc; h->why = hwhy_deferred; break; - case HOST_FIND_SECURITY: - yield = rc; h->why = hwhy_insecure; break; - case HOST_IGNORED: - h->why = hwhy_ignored; break; - default: - h->why = hwhy_failed; break; + case HOST_FIND_AGAIN: yield = rc; h->why = hwhy_deferred; break; + case HOST_FIND_SECURITY: yield = rc; h->why = hwhy_insecure; break; + case HOST_IGNORED: h->why = hwhy_ignored; break; + default: h->why = hwhy_failed; break; } } } @@ -3128,12 +3131,22 @@ if (h != last && !disable_ipv6) for (h = host; h != last; h = h->next) host_item temp; host_item *next = h->next; - if (h->mx != next->mx || /* If next is different MX */ - h->address == NULL || /* OR this one is unset */ - Ustrchr(h->address, ':') != NULL || /* OR this one is IPv6 */ - (next->address != NULL && - Ustrchr(next->address, ':') == NULL)) /* OR next is IPv4 */ + if ( h->mx != next->mx /* If next is different MX */ + || !h->address /* OR this one is unset */ + ) + continue; /* move on to next */ + + if ( whichrrs & HOST_FIND_IPV4_FIRST + ? !Ustrchr(h->address, ':') /* OR this one is IPv4 */ + || next->address + && Ustrchr(next->address, ':') /* OR next is IPv6 */ + + : Ustrchr(h->address, ':') /* OR this one is IPv6 */ + || next->address + && !Ustrchr(next->address, ':') /* OR next is IPv4 */ + ) continue; /* move on to next */ + temp = *h; /* otherwise, swap */ temp.next = next->next; *h = *next; @@ -3194,7 +3207,7 @@ return yield; int main(int argc, char **cargv) { host_item h; -int whichrrs = HOST_FIND_BY_MX | HOST_FIND_BY_A; +int whichrrs = HOST_FIND_BY_MX | HOST_FIND_BY_A | HOST_FIND_BY_AAAA; BOOL byname = FALSE; BOOL qualify_single = TRUE; BOOL search_parents = FALSE; @@ -3236,15 +3249,15 @@ while (Ufgets(buffer, 256, stdin) != NULL) if (Ustrcmp(buffer, "byname") == 0) byname = TRUE; else if (Ustrcmp(buffer, "no_byname") == 0) byname = FALSE; - else if (Ustrcmp(buffer, "a_only") == 0) whichrrs = HOST_FIND_BY_A; + else if (Ustrcmp(buffer, "a_only") == 0) whichrrs = HOST_FIND_BY_A | HOST_FIND_BY_AAAA; else if (Ustrcmp(buffer, "mx_only") == 0) whichrrs = HOST_FIND_BY_MX; else if (Ustrcmp(buffer, "srv_only") == 0) whichrrs = HOST_FIND_BY_SRV; else if (Ustrcmp(buffer, "srv+a") == 0) - whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_A; + whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_A | HOST_FIND_BY_AAAA; else if (Ustrcmp(buffer, "srv+mx") == 0) whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_MX; else if (Ustrcmp(buffer, "srv+mx+a") == 0) - whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_MX | HOST_FIND_BY_A; + whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_MX | HOST_FIND_BY_A | HOST_FIND_BY_AAAA; else if (Ustrcmp(buffer, "qualify_single") == 0) qualify_single = TRUE; else if (Ustrcmp(buffer, "no_qualify_single") == 0) qualify_single = FALSE; else if (Ustrcmp(buffer, "search_parents") == 0) search_parents = TRUE; diff --git a/src/src/macros.h b/src/src/macros.h index b97e99315..6658fa70b 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -750,7 +750,12 @@ enum { hwhy_unknown, hwhy_retry, hwhy_insecure, hwhy_failed, hwhy_deferred, /* Domain lookup types for routers */ -enum { lk_default, lk_byname, lk_bydns }; +#define LK_DEFAULT BIT(0) +#define LK_BYNAME BIT(1) +#define LK_BYDNS BIT(2) /* those 3 should be mutually exclusive */ + +#define LK_IPV4_ONLY BIT(3) +#define LK_IPV4_PREFER BIT(4) /* Values for the self_code fields */ @@ -819,11 +824,14 @@ enum { /* Flags for host_find_bydns() */ -#define HOST_FIND_BY_SRV 0x0001 -#define HOST_FIND_BY_MX 0x0002 -#define HOST_FIND_BY_A 0x0004 -#define HOST_FIND_QUALIFY_SINGLE 0x0008 -#define HOST_FIND_SEARCH_PARENTS 0x0010 +#define HOST_FIND_BY_SRV BIT(0) +#define HOST_FIND_BY_MX BIT(1) +#define HOST_FIND_BY_A BIT(2) +#define HOST_FIND_BY_AAAA BIT(3) +#define HOST_FIND_QUALIFY_SINGLE BIT(4) +#define HOST_FIND_SEARCH_PARENTS BIT(5) +#define HOST_FIND_IPV4_FIRST BIT(6) +#define HOST_FIND_IPV4_ONLY BIT(7) /* Actions applied to specific messages. */ diff --git a/src/src/routers/dnslookup.c b/src/src/routers/dnslookup.c index 5017efbee..6ab08d7ba 100644 --- a/src/src/routers/dnslookup.c +++ b/src/src/routers/dnslookup.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2017 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ #include "../exim.h" @@ -20,6 +20,10 @@ optionlist dnslookup_router_options[] = { (void *)(offsetof(dnslookup_router_options_block, check_srv)) }, { "fail_defer_domains", opt_stringptr, (void *)(offsetof(dnslookup_router_options_block, fail_defer_domains)) }, + { "ipv4_only", opt_stringptr, + (void *)(offsetof(dnslookup_router_options_block, ipv4_only)) }, + { "ipv4_prefer", opt_stringptr, + (void *)(offsetof(dnslookup_router_options_block, ipv4_prefer)) }, { "mx_domains", opt_stringptr, (void *)(offsetof(dnslookup_router_options_block, mx_domains)) }, { "mx_fail_domains", opt_stringptr, @@ -63,16 +67,18 @@ int dnslookup_router_entry(router_instance *rblock, address_item *addr, /* Default private options block for the dnslookup router. */ dnslookup_router_options_block dnslookup_router_option_defaults = { - FALSE, /* check_secondary_mx */ - TRUE, /* qualify_single */ - FALSE, /* search_parents */ - TRUE, /* rewrite_headers */ - NULL, /* widen_domains */ - NULL, /* mx_domains */ - NULL, /* mx_fail_domains */ - NULL, /* srv_fail_domains */ - NULL, /* check_srv */ - NULL /* fail_defer_domains */ + .check_secondary_mx = FALSE, + .qualify_single = TRUE, + .search_parents = FALSE, + .rewrite_headers = TRUE, + .widen_domains = NULL, + .mx_domains = NULL, + .mx_fail_domains = NULL, + .srv_fail_domains = NULL, + .check_srv = NULL, + .fail_defer_domains = NULL, + .ipv4_only = NULL, + .ipv4_prefer = NULL, }; @@ -154,7 +160,7 @@ dnslookup_router_entry( host_item h; int rc; int widen_sep = 0; -int whichrrs = HOST_FIND_BY_MX | HOST_FIND_BY_A; +int whichrrs = HOST_FIND_BY_MX | HOST_FIND_BY_A | HOST_FIND_BY_AAAA; dnslookup_router_options_block *ob = (dnslookup_router_options_block *)(rblock->options_block); uschar *srv_service = NULL; @@ -255,6 +261,19 @@ for (;;) } else return DECLINE; + /* Check if we must request only. or prefer, ipv4 */ + + if ( ob->ipv4_only + && expand_check_condition(ob->ipv4_only, rblock->name, US"router")) + flags = flags & ~HOST_FIND_BY_AAAA | HOST_FIND_IPV4_ONLY; + else if (search_find_defer) + return DEFER; + if ( ob->ipv4_prefer + && expand_check_condition(ob->ipv4_prefer, rblock->name, US"router")) + flags |= HOST_FIND_IPV4_FIRST; + else if (search_find_defer) + return DEFER; + /* Set up the rest of the initial host item. Others may get chained on if there is more than one IP address. We set it up here instead of outside the loop so as to re-initialize if a previous try succeeded but was rejected @@ -270,7 +289,7 @@ for (;;) /* Unfortunately, we cannot set the mx_only option in advance, because the DNS lookup may extend an unqualified name. Therefore, we must do the test - subsequently. We use the same logic as that for widen_domains above to avoid + stoubsequently. 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) @@ -279,8 +298,8 @@ for (;;) if (ob->search_parents) flags |= HOST_FIND_SEARCH_PARENTS; } - rc = host_find_bydns(&h, CUS rblock->ignore_target_hosts, flags, srv_service, - ob->srv_fail_domains, ob->mx_fail_domains, + rc = host_find_bydns(&h, CUS rblock->ignore_target_hosts, flags, + srv_service, ob->srv_fail_domains, ob->mx_fail_domains, &rblock->dnssec, &fully_qualified_name, &removed); if (removed) setflag(addr, af_local_host_removed); diff --git a/src/src/routers/dnslookup.h b/src/src/routers/dnslookup.h index 3979ef231..b7e091587 100644 --- a/src/src/routers/dnslookup.h +++ b/src/src/routers/dnslookup.h @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* Private structure for the private options. */ @@ -18,6 +18,8 @@ typedef struct { uschar *srv_fail_domains; uschar *check_srv; uschar *fail_defer_domains; + uschar *ipv4_only; + uschar *ipv4_prefer; } dnslookup_router_options_block; /* Data for reading the private options. */ diff --git a/src/src/routers/manualroute.c b/src/src/routers/manualroute.c index 105fec0fe..9aa2490ec 100644 --- a/src/src/routers/manualroute.c +++ b/src/src/routers/manualroute.c @@ -331,7 +331,7 @@ DEBUG(D_route) debug_printf("expanded list of hosts = \"%s\" options = %s\n", /* Set default lookup type and scan the options */ -lookup_type = lk_default; +lookup_type = LK_DEFAULT; while (*options != 0) { @@ -342,12 +342,16 @@ while (*options != 0) if (Ustrncmp(s, "randomize", n) == 0) randomize = TRUE; else if (Ustrncmp(s, "no_randomize", n) == 0) randomize = FALSE; - else if (Ustrncmp(s, "byname", n) == 0) lookup_type = lk_byname; - else if (Ustrncmp(s, "bydns", n) == 0) lookup_type = lk_bydns; + else if (Ustrncmp(s, "byname", n) == 0) + lookup_type = lookup_type & ~(LK_DEFAULT | LK_BYDNS) | LK_BYNAME; + else if (Ustrncmp(s, "bydns", n) == 0) + lookup_type = lookup_type & ~(LK_DEFAULT | LK_BYNAME) & LK_BYDNS; + else if (Ustrncmp(s, "ipv4_prefer", n) == 0) lookup_type |= LK_IPV4_PREFER; + else if (Ustrncmp(s, "ipv4_only", n) == 0) lookup_type |= LK_IPV4_ONLY; else { transport_instance *t; - for (t = transports; t != NULL; t = t->next) + for (t = transports; t; t = t->next) if (Ustrncmp(t->name, s, n) == 0) { transport = t; @@ -355,7 +359,7 @@ while (*options != 0) break; } - if (t == NULL) + if (!t) { s = string_sprintf("unknown routing option or transport name \"%s\"", s); log_write(0, LOG_MAIN, "Error in %s router: %s", rblock->name, s); @@ -397,7 +401,7 @@ if (!individual_transport_set) /* Deal with the case of a local transport. The host list is passed over as a single text string that ends up in $host. */ -if (transport != NULL && transport->info->local) +if (transport && transport->info->local) { if (hostlist[0] != 0) { @@ -447,7 +451,7 @@ if (rc != OK) return rc; be ignored, in which case we will end up with an empty host list. What happens is controlled by host_all_ignored. */ -if (addr->host_list == NULL) +if (!addr->host_list) { int i; DEBUG(D_route) debug_printf("host_find_failed ignored every host\n"); diff --git a/src/src/routers/queryprogram.c b/src/src/routers/queryprogram.c index c7886923c..251b0b89f 100644 --- a/src/src/routers/queryprogram.c +++ b/src/src/routers/queryprogram.c @@ -520,14 +520,14 @@ s = expand_string(US"${extract{hosts}{$value}}"); if (*s != 0) { - int lookup_type = lk_default; + int lookup_type = LK_DEFAULT; uschar *ss = expand_string(US"${extract{lookup}{$value}}"); lookup_value = NULL; if (*ss != 0) { - if (Ustrcmp(ss, "byname") == 0) lookup_type = lk_byname; - else if (Ustrcmp(ss, "bydns") == 0) lookup_type = lk_bydns; + if (Ustrcmp(ss, "byname") == 0) lookup_type = LK_BYNAME; + else if (Ustrcmp(ss, "bydns") == 0) lookup_type = LK_BYDNS; else { addr->message = string_sprintf("bad lookup type \"%s\" yielded by " diff --git a/src/src/routers/rf_lookup_hostlist.c b/src/src/routers/rf_lookup_hostlist.c index c826857a7..acf976f67 100644 --- a/src/src/routers/rf_lookup_hostlist.c +++ b/src/src/routers/rf_lookup_hostlist.c @@ -35,7 +35,8 @@ Arguments: rblock the router block addr the address being routed ignore_target_hosts list of hosts to ignore - lookup_type lk_default or lk_byname or lk_bydns + lookup_type LK_DEFAULT or LK_BYNAME or LK_BYDNS, + plus LK_IPV4_{ONLY,PREFER} hff_code what to do for host find failed addr_new passed to rf_self_action for self=reroute @@ -90,6 +91,12 @@ for (prev = NULL, h = addr->host_list; h; h = next_h) len = Ustrlen(h->name); if (len > 3 && strcmpic(h->name + len - 3, US"/mx") == 0) { + int whichrrs = lookup_type & LK_IPV4_ONLY + ? HOST_FIND_BY_MX | HOST_FIND_IPV4_ONLY + : lookup_type & LK_IPV4_PREFER + ? HOST_FIND_BY_MX | HOST_FIND_IPV4_FIRST + : HOST_FIND_BY_MX; + DEBUG(D_route|D_host_lookup) debug_printf("doing DNS MX lookup for %s\n", h->name); @@ -97,19 +104,19 @@ for (prev = NULL, h = addr->host_list; h; h = next_h) h->name = string_copyn(h->name, len - 3); rc = host_find_bydns(h, ignore_target_hosts, - HOST_FIND_BY_MX, /* look only for MX records */ - NULL, /* SRV service not relevant */ - NULL, /* failing srv domains not relevant */ - NULL, /* no special mx failing domains */ + whichrrs, /* look only for MX records */ + NULL, /* SRV service not relevant */ + NULL, /* failing srv domains not relevant */ + NULL, /* no special mx failing domains */ &rblock->dnssec, /* dnssec request/require */ - NULL, /* fully_qualified_name */ - NULL); /* indicate local host removed */ + NULL, /* fully_qualified_name */ + NULL); /* indicate local host removed */ } /* If explicitly configured to look up by name, or if the "host name" is actually an IP address, do a byname lookup. */ - else if (lookup_type == lk_byname || string_is_ip_address(h->name, NULL) != 0) + else if (lookup_type & LK_BYNAME || string_is_ip_address(h->name, NULL) != 0) { DEBUG(D_route|D_host_lookup) debug_printf("calling host_find_byname\n"); rc = host_find_byname(h, ignore_target_hosts, HOST_FIND_QUALIFY_SINGLE, @@ -123,8 +130,14 @@ for (prev = NULL, h = addr->host_list; h; h = next_h) else { BOOL removed; + int whichrrs = lookup_type & LK_IPV4_ONLY + ? HOST_FIND_BY_A + : lookup_type & LK_IPV4_PREFER + ? HOST_FIND_BY_A | HOST_FIND_BY_AAAA | HOST_FIND_IPV4_FIRST + : HOST_FIND_BY_A | HOST_FIND_BY_AAAA; + DEBUG(D_route|D_host_lookup) debug_printf("doing DNS lookup\n"); - switch (rc = host_find_bydns(h, ignore_target_hosts, HOST_FIND_BY_A, NULL, + switch (rc = host_find_bydns(h, ignore_target_hosts, whichrrs, NULL, NULL, NULL, &rblock->dnssec, /* domains for request/require */ &canonical_name, &removed)) @@ -133,7 +146,7 @@ for (prev = NULL, h = addr->host_list; h; h = next_h) if (removed) setflag(addr, af_local_host_removed); break; case HOST_FIND_FAILED: - if (lookup_type == lk_default) + if (lookup_type & LK_DEFAULT) { DEBUG(D_route|D_host_lookup) debug_printf("DNS lookup failed: trying getipnodebyname\n"); diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 498cfab5e..424295dd5 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -3522,7 +3522,7 @@ else HDEBUG(D_receive) debug_printf("getting IP address for %s\n", sender_helo_name); - rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A, + rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A | HOST_FIND_BY_AAAA, NULL, NULL, NULL, &d, NULL, NULL); if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL) for (hh = &h; hh; hh = hh->next) diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 77b3eb818..ac61a405b 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -3992,7 +3992,7 @@ retry_non_continued: /* Find by name if so configured, or if it's an IP address. We don't just copy the IP address, because we need the test-for-local to happen. */ - flags = HOST_FIND_BY_A; + flags = HOST_FIND_BY_A | HOST_FIND_BY_AAAA; if (ob->dns_qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE; if (ob->dns_search_parents) flags |= HOST_FIND_SEARCH_PARENTS; diff --git a/src/src/verify.c b/src/src/verify.c index eb479d440..a4a4c4943 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -1849,7 +1849,7 @@ while (addr_new) additional host items being inserted into the chain. Hence we must save the next host first. */ - flags = HOST_FIND_BY_A; + flags = HOST_FIND_BY_A | HOST_FIND_BY_AAAA; if (tf.qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE; if (tf.search_parents) flags |= HOST_FIND_SEARCH_PARENTS; |