Arrange to call dns_init() for host_find_byname() as well as for
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 9 Oct 2006 14:36:25 +0000 (14:36 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 9 Oct 2006 14:36:25 +0000 (14:36 +0000)
host_find_bydns().

doc/doc-txt/ChangeLog
src/src/expand.c
src/src/functions.h
src/src/host.c
src/src/route.c
src/src/routers/iplookup.c
src/src/routers/rf_lookup_hostlist.c
src/src/smtp_in.c
src/src/transports/appendfile.c
src/src/transports/smtp.c
src/src/verify.c

index e7d4a3f55ac94b7d3bad4c4f9f5331cf664b9b7d..599c7877a57a31ff1454af0e75633687e7246010 100644 (file)
@@ -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
 -------------------------------------------
 
 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.
 
       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
 -----------------
 
 Exim version 4.63
 -----------------
index fc4d63aad3bb26e9cf245f3a84d26cd6dc59b59d..23e46200d980c925be9ff8c852337542caaeda5c 100644 (file)
@@ -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    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -3748,7 +3748,8 @@ while (*s != 0)
           else
             {
             shost.name = server_name;
           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);
               {
               expand_string_message =
                 string_sprintf("no IP address found for host %s", shost.name);
index 85b48ee37d14a2434088b236e3c1eecb8c006d40..302f8b6d16f5ba38ec21f32bd99ecde702455698 100644 (file)
@@ -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    *
 
 /*************************************************
 *     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 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);
 extern int     host_find_bydns(host_item *, uschar *, int, uschar *, uschar *,
                  uschar *,uschar **, BOOL *);
 extern ip_address_item *host_find_interfaces(void);
index fdaab31e5919220aee7ed81a0978f542ddf3fc99..039f58fb219576862ae7f7602d06c8bb4bdc70c5 100644 (file)
@@ -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    *
 
 /*************************************************
 *     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;
 
   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. */
 
   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);
     {
     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
 *************************************************/
 
 /* 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
 
 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
                            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
   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
 */
 
 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;
   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;
   }
 
   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
 /* 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
 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))
         match_isinlist(host->name, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN,
           TRUE, NULL) == OK))
+  #endif
+
     { af = AF_INET; times = 1; }
   else
     { af = AF_INET; times = 1; }
   else
-  #endif  /* STAND_ALONE */
-
     { af = AF_INET6; times = 2; }
 
 /* No IPv6 support */
     { af = AF_INET6; times = 2; }
 
 /* No IPv6 support */
@@ -1939,6 +1953,10 @@ for (i = 1; i <= times;
   int error_num = 0;
   struct hostent *hostdata;
 
   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);
   #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];
 
 uschar **argv = USS cargv;
 uschar buffer[256];
 
+disable_ipv6 = FALSE;
 primary_hostname = US"";
 store_pool = POOL_MAIN;
 debug_selector = D_host_lookup|D_interface;
 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, "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;
   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?
     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);
       :
       host_find_bydns(&h, NULL, flags, US"smtp", NULL, NULL,
         &fully_qualified_name, NULL);
index cc0d63cb0281c4b10d1320401eac92e960adfd62..f80256e3e82f4128b06e973bcea1aafd3592ca1e 100644 (file)
@@ -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    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1884,7 +1884,7 @@ if (r->translate_ip_address != NULL)
     h->mx = MX_NONE;
 
     store_pool = POOL_PERM;
     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)
     store_pool = old_pool;
 
     if (rc == HOST_FIND_FAILED || rc == HOST_FIND_AGAIN)
index 9dafd6fa536979afd02a90da23ec496b02638cc6..069c0dda1a333aa873d62e2968099cadc6602514 100644 (file)
@@ -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    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -206,7 +206,7 @@ while ((hostname = string_nextinlist(&listptr, &sep, host_buffer,
     host->address = host->name;
   else
     {
     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;
     }
 
     if (rc == HOST_FIND_FAILED || rc == HOST_FIND_AGAIN) continue;
     }
 
index cea4c3d6f5929b43bac762358a47b097bca10d2f..9876225478d879217b13988c888ef68e331d1a56 100644 (file)
@@ -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    *
 
 /*************************************************
 *     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");
   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
     }
 
   /* 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");
         {
         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);
         }
       }
     }
         }
       }
     }
index 36c4c3021d921a7f8540ab3ded2f898d45d8bada..a87b65221bf1b355035a34ec4eec18624089f48e 100644 (file)
@@ -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    *
 
 /*************************************************
 *     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);
     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;
     if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL)
       {
       host_item *hh = &h;
index 76acded26db3d801f285e6efd5922d4fa4016a89..1925888c8253c3050838fa5b897cbb8239ae12c1 100644 (file)
@@ -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    *
 
 /*************************************************
 *     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
 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;
   {
   DEBUG(D_transport) debug_printf("\"localhost\" unknown\n");
   return;
index 3d7c64e40fa16c0c1944dddd3a47b4e41466f001..55f13d6a39903965f05199500e681a54852817c7 100644 (file)
@@ -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    *
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -2311,7 +2311,7 @@ for (cutoff_retry = 0; expired &&
 
     if (host->address == NULL)
       {
 
     if (host->address == NULL)
       {
-      int new_port;
+      int new_port, flags;
       host_item *hh;
       uschar *canonical_name;
 
       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. */
 
       /* 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)
       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
       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);
         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. */
 
       /* Update the host (and any additional blocks, resulting from
       multihoming) with a host-specific port, if any. */
index 4d0fe69d2f2a526bc03485ac37e663ee2ebd3f7c..4f0da9bbdf65c1792ba72ad5e829560d63e601db 100644 (file)
@@ -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    *
 
 /*************************************************
 *     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;
 while (addr_new != NULL)
   {
   int rc;
-  uschar *show_address;
   address_item *addr = addr_new;
 
   addr_new = addr->next;
   addr->next = NULL;
 
   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");
   DEBUG(D_verify)
     {
     debug_printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
@@ -1141,6 +1135,7 @@ while (addr_new != NULL)
             }
           else
             {
             }
           else
             {
+            int flags;
             uschar *canonical_name;
             host_item *host, *nexthost;
             host_build_hostlist(&host_list, s, tf.hosts_randomize);
             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. */
 
             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)
             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
               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);
                 (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;
 
       {
       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_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,
       {
       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)
       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 */
       {
          (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
         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;
 
   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;
   if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL)
     {
     host_item *hh;