host_find_bydns().
-$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
-------------------------------------------
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
-----------------
-/* $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 *
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);
-/* $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 *
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);
-/* $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 *
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);
*************************************************/
/* 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
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
*/
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;
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
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 */
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);
uschar **argv = USS cargv;
uschar buffer[256];
+disable_ipv6 = FALSE;
primary_hostname = US"";
store_pool = POOL_MAIN;
debug_selector = D_host_lookup|D_interface;
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;
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);
-/* $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 *
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)
-/* $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 *
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;
}
-/* $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 *
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
{
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);
}
}
}
-/* $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 *
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;
-/* $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 *
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;
-/* $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 *
if (host->address == NULL)
{
- int new_port;
+ int new_port, flags;
host_item *hh;
uschar *canonical_name;
/* 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. */
-/* $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 *
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");
}
else
{
+ int flags;
uschar *canonical_name;
host_item *host, *nexthost;
host_build_hostlist(&host_list, s, tf.hosts_randomize);
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);
- }
}
}
}
{
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)
{
{
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)
(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
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;