summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Hazel <ph10@hermes.cam.ac.uk>2006-10-09 14:36:25 +0000
committerPhilip Hazel <ph10@hermes.cam.ac.uk>2006-10-09 14:36:25 +0000
commit322050c2d9e83d10f046da71aa2cd9cc5a355b0b (patch)
tree8b5db136d7c53054c7326605579d931605866116
parentef85a7860b2750dd180885106a765bdc1afa6e7d (diff)
Arrange to call dns_init() for host_find_byname() as well as for
host_find_bydns().
-rw-r--r--doc/doc-txt/ChangeLog16
-rw-r--r--src/src/expand.c5
-rw-r--r--src/src/functions.h4
-rw-r--r--src/src/host.c44
-rw-r--r--src/src/route.c4
-rw-r--r--src/src/routers/iplookup.c4
-rw-r--r--src/src/routers/rf_lookup_hostlist.c8
-rw-r--r--src/src/smtp_in.c4
-rw-r--r--src/src/transports/appendfile.c6
-rw-r--r--src/src/transports/smtp.c15
-rw-r--r--src/src/verify.c28
11 files changed, 84 insertions, 54 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index e7d4a3f55..599c7877a 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.403 2006/10/03 15:11:22 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.404 2006/10/09 14:36:25 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
@@ -95,6 +95,20 @@ PH/15 Applied Michael Deutschmann's patch to allow DNS black list processing to
look up a TXT record in a specific list after matching in a combined
list.
+PH/16 It seems that the options setting for the resolver (RES_DEFNAMES and
+ RES_DNSRCH) can affect the behaviour of gethostbyname() and friends when
+ they consult the DNS. I had assumed they would set it the way they
+ wanted; and indeed my experiments on Linux seem to show that in some
+ cases they do (I could influence IPv6 lookups but not IPv4 lookups).
+ To be on the safe side, however, I have now made the interface to
+ host_find_byname() similar to host_find_bydns(), with an argument
+ containing the DNS resolver options. The host_find_byname() function now
+ sets these options at its start, just as host_find_bydns() does. The smtp
+ transport options dns_qualify_single and dns_search_parents are passed to
+ host_find_byname() when gethostbyname=TRUE in this transport. Other uses
+ of host_find_byname() use the default settings of RES_DEFNAMES
+ (qualify_single) but not RES_DNSRCH (search_parents).
+
Exim version 4.63
-----------------
diff --git a/src/src/expand.c b/src/src/expand.c
index fc4d63aad..23e46200d 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/expand.c,v 1.63 2006/10/03 08:54:50 ph10 Exp $ */
+/* $Cambridge: exim/src/src/expand.c,v 1.64 2006/10/09 14:36:25 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -3748,7 +3748,8 @@ while (*s != 0)
else
{
shost.name = server_name;
- if (host_find_byname(&shost, NULL, NULL, FALSE) != HOST_FOUND)
+ if (host_find_byname(&shost, NULL, HOST_FIND_QUALIFY_SINGLE, NULL,
+ FALSE) != HOST_FOUND)
{
expand_string_message =
string_sprintf("no IP address found for host %s", shost.name);
diff --git a/src/src/functions.h b/src/src/functions.h
index 85b48ee37..302f8b6d1 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/functions.h,v 1.27 2006/09/19 11:28:45 ph10 Exp $ */
+/* $Cambridge: exim/src/src/functions.h,v 1.28 2006/10/09 14:36:25 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -116,7 +116,7 @@ extern void host_build_hostlist(host_item **, uschar *, BOOL);
extern ip_address_item *host_build_ifacelist(uschar *, uschar *);
extern void host_build_log_info(void);
extern void host_build_sender_fullhost(void);
-extern BOOL host_find_byname(host_item *, uschar *, uschar **, BOOL);
+extern BOOL host_find_byname(host_item *, uschar *, int, uschar **, BOOL);
extern int host_find_bydns(host_item *, uschar *, int, uschar *, uschar *,
uschar *,uschar **, BOOL *);
extern ip_address_item *host_find_interfaces(void);
diff --git a/src/src/host.c b/src/src/host.c
index fdaab31e5..039f58fb2 100644
--- a/src/src/host.c
+++ b/src/src/host.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/host.c,v 1.25 2006/09/05 14:05:43 ph10 Exp $ */
+/* $Cambridge: exim/src/src/host.c,v 1.26 2006/10/09 14:36:25 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -1763,11 +1763,11 @@ for (hname = sender_host_name; hname != NULL; hname = *aliases++)
h.mx = MX_NONE;
h.address = NULL;
- /* When called with the 5th argument FALSE, host_find_byname() won't return
+ /* When called with the last argument FALSE, host_find_byname() won't return
HOST_FOUND_LOCAL. If the incoming address is an IPv4 address expressed in
IPv6 format, we must compare the IPv4 part to any IPv4 addresses. */
- if ((rc = host_find_byname(&h, NULL, NULL, FALSE)) == HOST_FOUND)
+ if ((rc = host_find_byname(&h, NULL, 0, NULL, FALSE)) == HOST_FOUND)
{
host_item *hh;
HDEBUG(D_host_lookup) debug_printf("checking addresses for %s\n", hname);
@@ -1848,9 +1848,12 @@ return FAIL;
*************************************************/
/* The input is a host_item structure with the name filled in and the address
-field set to NULL. We use gethostbyname(). Of course, gethostbyname() may use
-the DNS, but it doesn't do MX processing. If more than one address is given,
-chain on additional host items, with other relevant fields copied.
+field set to NULL. We use gethostbyname() or getipnodebyname() or
+gethostbyname2(), as appropriate. Of course, these functions may use the DNS,
+but they do not do MX processing. It appears, however, that in some systems the
+current setting of resolver options is used when one of these functions calls
+the resolver. For this reason, we call dns_init() at the start, with arguments
+influenced by bits in "flags", just as we do for host_find_bydns().
The second argument provides a host list (usually an IP list) of hosts to
ignore. This makes it possible to ignore IPv6 link-local addresses or loopback
@@ -1867,6 +1870,8 @@ Arguments:
multiple IP addresses cause other host items to be
chained on.
ignore_target_hosts a list of hosts to ignore
+ flags HOST_FIND_QUALIFY_SINGLE ) passed to
+ HOST_FIND_SEARCH_PARENTS ) dns_init()
fully_qualified_name if not NULL, set to point to host name for
compatibility with host_find_bydns
local_host_check TRUE if a check for the local host is wanted
@@ -1878,7 +1883,7 @@ Returns: HOST_FIND_FAILED Failed to find the host or domain
*/
int
-host_find_byname(host_item *host, uschar *ignore_target_hosts,
+host_find_byname(host_item *host, uschar *ignore_target_hosts, int flags,
uschar **fully_qualified_name, BOOL local_host_check)
{
int i, yield, times;
@@ -1899,6 +1904,12 @@ if (running_in_test_harness)
if (Ustrcmp(endname - 14, "test.again.dns") == 0) goto RETURN_AGAIN;
}
+/* Make sure DNS options are set as required. This appears to be necessary in
+some circumstances when the get..byname() function actually calls the DNS. */
+
+dns_init((flags & HOST_FIND_QUALIFY_SINGLE) != 0,
+ (flags & HOST_FIND_SEARCH_PARENTS) != 0);
+
/* In an IPv6 world, unless IPv6 has been disabled, we need to scan for both
kinds of address, so go round the loop twice. Note that we have ensured that
AF_INET6 is defined even in an IPv4 world, which makes for slightly tidier
@@ -1906,14 +1917,17 @@ code. However, if dns_ipv4_lookup matches the domain, we also just do IPv4
lookups here (except when testing standalone). */
#if HAVE_IPV6
- #ifndef STAND_ALONE
- if (disable_ipv6 || (dns_ipv4_lookup != NULL &&
+ #ifdef STAND_ALONE
+ if (disable_ipv6)
+ #else
+ if (disable_ipv6 ||
+ (dns_ipv4_lookup != NULL &&
match_isinlist(host->name, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN,
TRUE, NULL) == OK))
+ #endif
+
{ af = AF_INET; times = 1; }
else
- #endif /* STAND_ALONE */
-
{ af = AF_INET6; times = 2; }
/* No IPv6 support */
@@ -1939,6 +1953,10 @@ for (i = 1; i <= times;
int error_num = 0;
struct hostent *hostdata;
+ #ifdef STAND_ALONE
+ printf("Looking up: %s\n", host->name);
+ #endif
+
#if HAVE_IPV6
if (running_in_test_harness)
hostdata = host_fake_gethostbyname(host->name, af, &error_num);
@@ -2976,6 +2994,7 @@ BOOL search_parents = FALSE;
uschar **argv = USS cargv;
uschar buffer[256];
+disable_ipv6 = FALSE;
primary_hostname = US"";
store_pool = POOL_MAIN;
debug_selector = D_host_lookup|D_interface;
@@ -3023,6 +3042,7 @@ while (Ufgets(buffer, 256, stdin) != NULL)
else if (Ustrcmp(buffer, "no_search_parents") == 0) search_parents = FALSE;
else if (Ustrcmp(buffer, "test_harness") == 0)
running_in_test_harness = !running_in_test_harness;
+ else if (Ustrcmp(buffer, "ipv6") == 0) disable_ipv6 = !disable_ipv6;
else if (Ustrcmp(buffer, "res_debug") == 0)
{
_res.options ^= RES_DEBUG;
@@ -3053,7 +3073,7 @@ while (Ufgets(buffer, 256, stdin) != NULL)
if (search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
rc = byname?
- host_find_byname(&h, NULL, &fully_qualified_name, TRUE)
+ host_find_byname(&h, NULL, flags, &fully_qualified_name, TRUE)
:
host_find_bydns(&h, NULL, flags, US"smtp", NULL, NULL,
&fully_qualified_name, NULL);
diff --git a/src/src/route.c b/src/src/route.c
index cc0d63cb0..f80256e3e 100644
--- a/src/src/route.c
+++ b/src/src/route.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/route.c,v 1.10 2006/07/17 09:21:00 ph10 Exp $ */
+/* $Cambridge: exim/src/src/route.c,v 1.11 2006/10/09 14:36:25 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -1884,7 +1884,7 @@ if (r->translate_ip_address != NULL)
h->mx = MX_NONE;
store_pool = POOL_PERM;
- rc = host_find_byname(h, NULL, NULL, TRUE);
+ rc = host_find_byname(h, NULL, HOST_FIND_QUALIFY_SINGLE, NULL, TRUE);
store_pool = old_pool;
if (rc == HOST_FIND_FAILED || rc == HOST_FIND_AGAIN)
diff --git a/src/src/routers/iplookup.c b/src/src/routers/iplookup.c
index 9dafd6fa5..069c0dda1 100644
--- a/src/src/routers/iplookup.c
+++ b/src/src/routers/iplookup.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/iplookup.c,v 1.7 2006/04/04 09:09:45 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/iplookup.c,v 1.8 2006/10/09 14:36:25 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -206,7 +206,7 @@ while ((hostname = string_nextinlist(&listptr, &sep, host_buffer,
host->address = host->name;
else
{
- int rc = host_find_byname(host, NULL, NULL, TRUE);
+ int rc = host_find_byname(host, NULL, HOST_FIND_QUALIFY_SINGLE, NULL, TRUE);
if (rc == HOST_FIND_FAILED || rc == HOST_FIND_AGAIN) continue;
}
diff --git a/src/src/routers/rf_lookup_hostlist.c b/src/src/routers/rf_lookup_hostlist.c
index cea4c3d6f..987622547 100644
--- a/src/src/routers/rf_lookup_hostlist.c
+++ b/src/src/routers/rf_lookup_hostlist.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/routers/rf_lookup_hostlist.c,v 1.6 2006/02/07 11:19:02 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/rf_lookup_hostlist.c,v 1.7 2006/10/09 14:36:25 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -106,7 +106,8 @@ for (h = addr->host_list; h != NULL; prev = h, h = next_h)
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, &canonical_name, TRUE);
+ rc = host_find_byname(h, ignore_target_hosts, HOST_FIND_QUALIFY_SINGLE,
+ &canonical_name, TRUE);
}
/* Otherwise, do a DNS lookup. If that yields "host not found", and the
@@ -129,7 +130,8 @@ for (h = addr->host_list; h != NULL; prev = h, h = next_h)
{
DEBUG(D_route|D_host_lookup)
debug_printf("DNS lookup failed: trying getipnodebyname\n");
- rc = host_find_byname(h, ignore_target_hosts, &canonical_name, TRUE);
+ rc = host_find_byname(h, ignore_target_hosts, HOST_FIND_QUALIFY_SINGLE,
+ &canonical_name, TRUE);
}
}
}
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 36c4c3021..a87b65221 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/smtp_in.c,v 1.44 2006/09/25 10:14:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.45 2006/10/09 14:36:25 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -2119,7 +2119,7 @@ else
h.next = NULL;
HDEBUG(D_receive) debug_printf("getting IP address for %s\n",
sender_helo_name);
- rc = host_find_byname(&h, NULL, NULL, TRUE);
+ rc = host_find_byname(&h, NULL, 0, NULL, TRUE);
if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL)
{
host_item *hh = &h;
diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c
index 76acded26..1925888c8 100644
--- a/src/src/transports/appendfile.c
+++ b/src/src/transports/appendfile.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.18 2006/04/27 08:53:24 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/appendfile.c,v 1.19 2006/10/09 14:36:25 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -599,10 +599,10 @@ host.next = NULL;
until one succeeds. However, it appears that at least on some systems, comsat
doesn't listen on the ::1 address. So for the moment, just force the address to
be 127.0.0.1. At some future stage, when IPv6 really is superseding IPv4, this
-can be changed. */
+can be changed. (But actually, comsat is probably dying out anyway.) */
/******
-if (host_find_byname(&host, NULL, NULL, FALSE) == HOST_FIND_FAILED)
+if (host_find_byname(&host, NULL, 0, NULL, FALSE) == HOST_FIND_FAILED)
{
DEBUG(D_transport) debug_printf("\"localhost\" unknown\n");
return;
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 3d7c64e40..55f13d6a3 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/transports/smtp.c,v 1.26 2006/09/25 11:25:37 ph10 Exp $ */
+/* $Cambridge: exim/src/src/transports/smtp.c,v 1.27 2006/10/09 14:36:25 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -2311,7 +2311,7 @@ for (cutoff_retry = 0; expired &&
if (host->address == NULL)
{
- int new_port;
+ int new_port, flags;
host_item *hh;
uschar *canonical_name;
@@ -2336,16 +2336,15 @@ for (cutoff_retry = 0; expired &&
/* 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;
+ if (ob->dns_qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
+ if (ob->dns_search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
+
if (ob->gethostbyname || string_is_ip_address(host->name, NULL) != 0)
- rc = host_find_byname(host, NULL, &canonical_name, TRUE);
+ rc = host_find_byname(host, NULL, flags, &canonical_name, TRUE);
else
- {
- int flags = HOST_FIND_BY_A;
- if (ob->dns_qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
- if (ob->dns_search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
rc = host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
&canonical_name, NULL);
- }
/* Update the host (and any additional blocks, resulting from
multihoming) with a host-specific port, if any. */
diff --git a/src/src/verify.c b/src/src/verify.c
index 4d0fe69d2..4f0da9bbd 100644
--- a/src/src/verify.c
+++ b/src/src/verify.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/verify.c,v 1.41 2006/10/03 15:11:22 ph10 Exp $ */
+/* $Cambridge: exim/src/src/verify.c,v 1.42 2006/10/09 14:36:25 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -1009,17 +1009,11 @@ information about the top level address, not anything that it generated. */
while (addr_new != NULL)
{
int rc;
- uschar *show_address;
address_item *addr = addr_new;
addr_new = addr->next;
addr->next = NULL;
- /* When full_info is set, child addresses are displayed in top-level
- messages. Otherwise, we show only the top level address. */
-
- show_address = full_info? addr->address : address;
-
DEBUG(D_verify)
{
debug_printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
@@ -1141,6 +1135,7 @@ while (addr_new != NULL)
}
else
{
+ int flags;
uschar *canonical_name;
host_item *host, *nexthost;
host_build_hostlist(&host_list, s, tf.hosts_randomize);
@@ -1151,20 +1146,19 @@ while (addr_new != NULL)
additional host items being inserted into the chain. Hence we must
save the next host first. */
+ flags = HOST_FIND_BY_A;
+ if (tf.qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
+ if (tf.search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
+
for (host = host_list; host != NULL; host = nexthost)
{
nexthost = host->next;
if (tf.gethostbyname ||
string_is_ip_address(host->name, NULL) != 0)
- (void)host_find_byname(host, NULL, &canonical_name, TRUE);
+ (void)host_find_byname(host, NULL, flags, &canonical_name, TRUE);
else
- {
- int flags = HOST_FIND_BY_A;
- if (tf.qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
- if (tf.search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
(void)host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
&canonical_name, NULL);
- }
}
}
}
@@ -1215,7 +1209,7 @@ while (addr_new != NULL)
{
address_item *p = addr->parent;
- fprintf(f, "%s%s %s", ko_prefix, show_address,
+ fprintf(f, "%s%s %s", ko_prefix, full_info? addr->address : address,
address_test_mode? "is undeliverable" : "failed to verify");
if (!expn && admin_user)
{
@@ -1248,7 +1242,7 @@ while (addr_new != NULL)
{
address_item *p = addr->parent;
fprintf(f, "%s%s cannot be resolved at this time", ko_prefix,
- show_address);
+ full_info? addr->address : address);
if (!expn && admin_user)
{
if (addr->basic_errno > 0)
@@ -1321,7 +1315,7 @@ while (addr_new != NULL)
(addr_new != NULL && /* At least one new address AND */
success_on_redirect))) /* success_on_redirect is set */
{
- if (f != NULL) fprintf(f, "%s %s\n", show_address,
+ if (f != NULL) fprintf(f, "%s %s\n", address,
address_test_mode? "is deliverable" : "verified");
/* If we have carried on to verify a child address, we want the value
@@ -2223,7 +2217,7 @@ if (*t == 0)
h.address = NULL;
h.mx = MX_NONE;
- rc = host_find_byname(&h, NULL, NULL, FALSE);
+ rc = host_find_byname(&h, NULL, HOST_FIND_QUALIFY_SINGLE, NULL, FALSE);
if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL)
{
host_item *hh;