[exim-cvs] cvs commit: exim/exim-doc/doc-txt ChangeLog exim…

Top Page
Delete this message
Reply to this message
Author: Philip Hazel
Date:  
To: exim-cvs
Subject: [exim-cvs] cvs commit: exim/exim-doc/doc-txt ChangeLog exim/exim-src/src host.c exim/exim-test/stderr 0419 0499 1006 exim/exim-test/stdout 0430
ph10 2006/02/07 16:36:25 GMT

  Modified files:
    exim-doc/doc-txt     ChangeLog 
    exim-src/src         host.c 
    exim-test/stderr     0419 0499 1006 
    exim-test/stdout     0430 
  Log:
  Always do explicit A/AAAA lookups; no longer make use of the additional
  RR section from MX/SRV lookups.


  Revision  Changes    Path
  1.286     +10 -0     exim/exim-doc/doc-txt/ChangeLog
  1.21      +33 -179   exim/exim-src/src/host.c
  1.2       +4 -0      exim/exim-test/stderr/0419
  1.2       +5 -0      exim/exim-test/stderr/0499
  1.2       +5 -0      exim/exim-test/stderr/1006
  1.2       +2 -2      exim/exim-test/stdout/0430


  Index: ChangeLog
  ===================================================================
  RCS file: /home/cvs/exim/exim-doc/doc-txt/ChangeLog,v
  retrieving revision 1.285
  retrieving revision 1.286
  diff -u -r1.285 -r1.286
  --- ChangeLog    7 Feb 2006 14:20:58 -0000    1.285
  +++ ChangeLog    7 Feb 2006 16:36:25 -0000    1.286
  @@ -1,4 +1,4 @@
  -$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.285 2006/02/07 14:20:58 ph10 Exp $
  +$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.286 2006/02/07 16:36:25 ph10 Exp $


Change log file for Exim from version 4.21
-------------------------------------------
@@ -88,6 +88,16 @@

   PH/15 Minor change to Makefile for building test_host (undocumented testing
         feature).
  +
  +PH/16 As discussed on the list in Nov/Dec: Exim no longer looks at the
  +      additional section of a DNS packet that returns MX or SRV records.
  +      Instead, it always explicitly searches for A/AAAA records. This avoids
  +      major problems that occur when a DNS server includes only records of one
  +      type (A or AAAA) in an MX/SRV packet. A byproduct of this change has
  +      fixed another bug: if SRV records were looked up and the corresponding
  +      address records were *not* found in the additional section, the port
  +      values from the SRV records were lost.
  +



Exim version 4.60

  Index: host.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/host.c,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- host.c    7 Feb 2006 11:19:00 -0000    1.20
  +++ host.c    7 Feb 2006 16:36:25 -0000    1.21
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/host.c,v 1.20 2006/02/07 11:19:00 ph10 Exp $ */
  +/* $Cambridge: exim/exim-src/src/host.c,v 1.21 2006/02/07 16:36:25 ph10 Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -2192,10 +2192,10 @@
   *        Fill in a host address from the DNS     *
   *************************************************/


-/* Given a host item, with its name and mx fields set, and its address 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.
+/* Given a host item, with its name, port and mx fields set, and its address
+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,
  @@ -2250,7 +2250,6 @@
     #endif


     host->address = host->name;
  -  host->port = PORT_NONE;
     return HOST_FOUND;
     }


  @@ -2360,7 +2359,6 @@
             if (strcmpic(host->name, rr->name) != 0)
               host->name = string_copy_dnsdomain(rr->name);
             host->address = da->address;
  -          host->port = PORT_NONE;
             host->sort_key = host->mx * 1000 + random_number(500) + randoffset;
             host->status = hstatus_unknown;
             host->why = hwhy_unknown;
  @@ -2395,10 +2393,9 @@


             if (new_sort_key < host->sort_key)
               {
  -            *next = *host;
  +            *next = *host;                                  /* Copies port */
               host->next = next;
               host->address = da->address;
  -            host->port = PORT_NONE;
               host->sort_key = new_sort_key;
               if (thishostlast == host) thishostlast = next;  /* Local last */
               if (*lastptr == host) *lastptr = next;          /* Global last */
  @@ -2415,10 +2412,9 @@
                 if (new_sort_key < h->next->sort_key) break;
                 h = h->next;
                 }
  -            *next = *h;
  +            *next = *h;                                 /* Copies port */
               h->next = next;
               next->address = da->address;
  -            next->port = PORT_NONE;
               next->sort_key = new_sort_key;
               if (h == thishostlast) thishostlast = next; /* Local last */
               if (h == *lastptr) *lastptr = next;         /* Global last */
  @@ -2439,15 +2435,15 @@



   /*************************************************
  -*  Find IP addresses and names for host via DNS  *
  +*    Find IP addresses and host names via DNS    *
   *************************************************/


-/* The input is a host_item structure with the name filled in and the address
-field set to NULL. This may be in a chain of other host items. The lookup may
-result in more than one IP address, in which case we must created new host
-blocks for the additional addresses, and insert them into the chain. The
-original name may not be fully qualified. Use the fully_qualified_name argument
-to return the official name, as returned by the resolver.
+/* The input is a host_item structure with the name field filled in and the
+address field set to NULL. This may be in a chain of other host items. The
+lookup may result in more than one IP address, in which case we must created
+new host blocks for the additional addresses, and insert them into the chain.
+The original name may not be fully qualified. Use the fully_qualified_name
+argument to return the official name, as returned by the resolver.

   Arguments:
     host                  point to initial host item
  @@ -2638,7 +2634,7 @@
     {
     int precedence;
     int weight = 0;        /* For SRV records */
  -  int port = PORT_NONE;  /* For SRV records */
  +  int port = PORT_NONE;
     uschar *s;             /* MUST be unsigned for GETSHORT */
     uschar data[256];


  @@ -2879,175 +2875,33 @@
       }   /* Move on to the next host */
     }


  -/* Now we have to ensure addresses exist for all the hosts. We have ensured
  -above that the names in the host items are all unique. The addresses may have
  -been returned in the additional data section of the DNS query. Because it is
  -more expensive to scan the returned DNS records (because you have to expand the
  -names) we do a single scan over them, and multiple scans of the chain of host
  -items (which is typically only 3 or 4 long anyway.) Add extra host items for
  -multi-homed hosts. */
  -
  -for (rr = dns_next_rr(&dnsa, &dnss, RESET_ADDITIONAL);
  -     rr != NULL;
  -     rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
  -  {
  -  dns_address *da;
  -  int status = hstatus_unknown;
  -  int why = hwhy_unknown;
  -  int randoffset;
  -
  -  if (rr->type != T_A
  -  #if HAVE_IPV6
  -    && ( disable_ipv6 ||
  -         (
  -         rr->type != T_AAAA
  -         #ifdef SUPPORT_A6
  -         && rr->type != T_A6
  -         #endif
  -         )
  -       )
  -  #endif
  -    ) continue;
  -
  -  /* Find the first host that matches this record's name. If there isn't
  -  one, move on to the next RR. */
  -
  -  for (h = host; h != last->next; h = h->next)
  -    { if (strcmpic(h->name, rr->name) == 0) break; }
  -  if (h == last->next) continue;
  -
  -  /* For IPv4 addresses, add 500 to the random part of the sort key, to ensure
  -  they sort after IPv6 addresses. */
  -
  -  randoffset = (rr->type == T_A)? 500 : 0;
  -
  -  /* Get the list of textual addresses for this RR. There may be more than one
  -  if it is an A6 RR. Then loop to handle multiple addresses from an A6 record.
  -  If there are none, nothing will get done - the record is ignored. */
  -
  -  for (da = dns_address_from_rr(&dnsa, rr); da != NULL; da = da->next)
  -    {
  -    /* Set status for an ignorable host. */
  -
  -    #ifndef STAND_ALONE
  -    if (ignore_target_hosts != NULL &&
  -          verify_check_this_host(&ignore_target_hosts, NULL, h->name,
  -            da->address, NULL) == OK)
  -      {
  -      DEBUG(D_host_lookup)
  -        debug_printf("ignored host %s [%s]\n", h->name, da->address);
  -      status = hstatus_unusable;
  -      why = hwhy_ignored;
  -      }
  -    #endif
  -
  -    /* If the address is already set for this host, it may be that
  -    we just have a duplicate DNS record. Alternatively, this may be
  -    a multi-homed host. Search all items with the same host name
  -    (they will all be together) and if this address is found, skip
  -    to the next RR. */
  -
  -    if (h->address != NULL)
  -      {
  -      int new_sort_key;
  -      host_item *thishostlast;
  -      host_item *hh = h;
  -
  -      do
  -        {
  -        if (hh->address != NULL && Ustrcmp(CS da->address, hh->address) == 0)
  -          goto DNS_NEXT_RR;         /* Need goto to escape from inner loop */
  -        thishostlast = hh;
  -        hh = hh->next;
  -        }
  -      while (hh != last->next && strcmpic(hh->name, rr->name) == 0);
  -
  -      /* We have a multi-homed host, since we have a new address for
  -      an existing name. Create a copy of the current item, and give it
  -      the new address. RRs can be in arbitrary order, but one is supposed
  -      to randomize the addresses of multi-homed hosts, so compute a new
  -      sorting key and do that. [Latest SMTP RFC says not to randomize multi-
  -      homed hosts, but to rely on the resolver. I'm not happy about that -
  -      caching in the resolver will not rotate as often as the name server
  -      does.] */
  -
  -      new_sort_key = h->mx * 1000 + random_number(500) + randoffset;
  -      hh = store_get(sizeof(host_item));
  -
  -      /* New address goes first: insert the new block after the first one
  -      (so as not to disturb the original pointer) but put the new address
  -      in the original block. */
  -
  -      if (new_sort_key < h->sort_key)
  -        {
  -        *hh = *h;                       /* Note: copies the port */
  -        h->next = hh;
  -        h->address = da->address;
  -        h->sort_key = new_sort_key;
  -        h->status = status;
  -        h->why = why;
  -        }
  -
  -      /* Otherwise scan down the addresses for this host to find the
  -      one to insert after. */
  -
  -      else
  -        {
  -        while (h != thishostlast)
  -          {
  -          if (new_sort_key < h->next->sort_key) break;
  -          h = h->next;
  -          }
  -        *hh = *h;                       /* Note: copies the port */
  -        h->next = hh;
  -        hh->address = da->address;
  -        hh->sort_key = new_sort_key;
  -        hh->status = status;
  -        hh->why = why;
  -        }
  -
  -      if (h == last) last = hh;         /* Inserted after last */
  -      }
  -
  -    /* The existing item doesn't have its address set yet, so just set it.
  -    Ensure that an IPv4 address gets its sort key incremented in case an IPv6
  -    address is found later. */
  -
  -    else
  -      {
  -      h->address = da->address;         /* Port should be set already */
  -      h->status = status;
  -      h->why = why;
  -      h->sort_key += randoffset;
  -      }
  -    }    /* Loop for addresses extracted from one RR */
  -
  -  /* Carry on to the next RR. It would be nice to be able to be able to stop
  -  when every host on the list has an address, but we can't be sure there won't
  -  be an additional address for a multi-homed host further down the list, so
  -  we have to continue to the end. */
  -
  -  DNS_NEXT_RR: continue;
  -  }
  -
  -/* Set the default yield to failure */
  -
  -yield = HOST_FIND_FAILED;
  -
  -/* If we haven't found all the addresses in the additional section, we
  -need to search for A or AAAA records explicitly. The names shouldn't point to
  -CNAMES, but we use the general lookup function that handles them, just
  -in case. If any lookup gives a soft error, change the default yield.
  +/* Now we have to find IP addresses for all the hosts. We have ensured above
  +that the names in all the host items are unique. Before release 4.61 we used to
  +process records from the additional section in the DNS packet that returned the
  +MX or SRV records. However, a DNS name server is free to drop any resource
  +records from the additional section. In theory, this has always been a
  +potential problem, but it is exacerbated by the advent of IPv6. If a host had
  +several IPv4 addresses and some were not in the additional section, at least
  +Exim would try the others. However, if a host had both IPv4 and IPv6 addresses
  +and all the IPv4 (say) addresses were absent, Exim would try only for a IPv6
  +connection, and never try an IPv4 address. When there was only IPv4
  +connectivity, this was a disaster that did in practice occur.
  +
  +So, from release 4.61 onwards, we always search for A and AAAA records
  +explicitly. The names shouldn't point to CNAMES, but we use the general lookup
  +function that handles them, just in case. If any lookup gives a soft error,
  +change the default yield.


For these DNS lookups, we must disable qualify_single and search_parents;
otherwise invalid host names obtained from MX or SRV records can cause trouble
if they happen to match something local. */

  -dns_init(FALSE, FALSE);
  +yield = HOST_FIND_FAILED;    /* Default yield */
  +dns_init(FALSE, FALSE);      /* Disable qualify_single and search_parents */


   for (h = host; h != last->next; h = h->next)
     {
  -  if (h->address != NULL || h->status == hstatus_unusable) continue;
  +  if (h->address != NULL) continue;  /* Inserted by a multihomed host */
     rc = set_address_from_dns(h, &last, ignore_target_hosts, allow_mx_to_ip, NULL);
     if (rc != HOST_FOUND)
       {


  Index: 0419
  ===================================================================
  RCS file: /home/cvs/exim/exim-test/stderr/0419,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- 0419    7 Feb 2006 10:47:31 -0000    1.1
  +++ 0419    7 Feb 2006 16:36:25 -0000    1.2
  @@ -24,6 +24,10 @@
     domain = mxt13.test.ex
   DNS lookup of mxt13.test.ex (MX) using fakens
   DNS lookup of mxt13.test.ex (MX) succeeded
  +DNS lookup of other1.test.ex (A) using fakens
  +DNS lookup of other1.test.ex (A) succeeded
  +DNS lookup of other2.test.ex (A) using fakens
  +DNS lookup of other2.test.ex (A) succeeded
   other1.test.ex in "!mxt13.test.ex : !other1.test.ex : *.test.ex"? no (matched "!other1.test.ex")
   other1.test.ex in hosts_treat_as_local? no (end of list)
   other2.test.ex in "!mxt13.test.ex : !other1.test.ex : *.test.ex"? yes (matched "*.test.ex")


  Index: 0499
  ===================================================================
  RCS file: /home/cvs/exim/exim-test/stderr/0499,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- 0499    7 Feb 2006 10:47:31 -0000    1.1
  +++ 0499    7 Feb 2006 16:36:25 -0000    1.2
  @@ -17,6 +17,8 @@
   checking domains
   DNS lookup of mxt1.test.ex (MX) using fakens
   DNS lookup of mxt1.test.ex (MX) succeeded
  +DNS lookup of eximtesthost.test.ex (A) using fakens
  +DNS lookup of eximtesthost.test.ex (A) succeeded
   local host has lowest MX
   host_find_bydns yield = HOST_FOUND_LOCAL (3); returned hosts:
     eximtesthost.test.ex ip4.ip4.ip4.ip4 MX=5 
  @@ -25,6 +27,9 @@
   checking "condition"
   DNS lookup of mxt1.test.ex (MX) using fakens
   DNS lookup of mxt1.test.ex (MX) succeeded
  +DNS lookup of eximtesthost.test.ex-AAAA: using cached value DNS_NODATA
  +DNS lookup of eximtesthost.test.ex (A) using fakens
  +DNS lookup of eximtesthost.test.ex (A) succeeded
   local host has lowest MX
   host_find_bydns yield = HOST_FOUND_LOCAL (3); returned hosts:
     eximtesthost.test.ex ip4.ip4.ip4.ip4 MX=5 


  Index: 1006
  ===================================================================
  RCS file: /home/cvs/exim/exim-test/stderr/1006,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- 1006    7 Feb 2006 10:47:31 -0000    1.1
  +++ 1006    7 Feb 2006 16:36:25 -0000    1.2
  @@ -6,6 +6,9 @@
   DNS lookup of 46.test.ex (AAAA) succeeded
   DNS lookup of 46.test.ex (A) using fakens
   DNS lookup of 46.test.ex (A) succeeded
  +DNS lookup of 46.test.ex (AAAA) succeeded
  +DNS lookup of 46.test.ex (A) using fakens
  +DNS lookup of 46.test.ex (A) succeeded
   DNS lookup of v6.test.ex (MX) using fakens
   DNS lookup of v6.test.ex (MX) gave NO_DATA
   returning DNS_NODATA
  @@ -19,6 +22,8 @@
   admin user
   DNS lookup of mx46.test.ex (MX) using fakens
   DNS lookup of mx46.test.ex (MX) succeeded
  +DNS lookup of 46.test.ex (A) using fakens
  +DNS lookup of 46.test.ex (A) succeeded
   DNS lookup of 46.test.ex (A) using fakens
   DNS lookup of 46.test.ex (A) succeeded
   DNS lookup of v6.test.ex (MX) using fakens


  Index: 0430
  ===================================================================
  RCS file: /home/cvs/exim/exim-test/stdout/0430,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- 0430    7 Feb 2006 10:47:37 -0000    1.1
  +++ 0430    7 Feb 2006 16:36:25 -0000    1.2
  @@ -31,10 +31,10 @@
     host ten-1.test.ex [V4NET.0.0.1] 
   y@???
     router = r2, transport = t1
  -  host ten-6.test.ex [V4NET.0.0.6] 
  -  host ten-1.test.ex [V4NET.0.0.1] 
     host ten-2.test.ex [V4NET.0.0.2] MX=5
     host ten-3.test.ex [V4NET.0.0.3] MX=6
  +  host ten-6.test.ex [V4NET.0.0.6] 
  +  host ten-1.test.ex [V4NET.0.0.1] 
   x@???
     router = r2, transport = t1
     host ten-6.test.ex [V4NET.0.0.6]