[comp.mail.sendmail] Bug in MX handling in deliver.c

paul@uxc.cso.uiuc.edu (10/23/89)

Consider the case of mail sent to user@sds.sdsc.edu .  sds.sdsc.edu has
the following MX records:

Non-authoritative answer:
sds.sdsc.edu	preference = 0, mail exchanger = SDS.SDSC.EDU
sds.sdsc.edu	preference = 10, mail exchanger = PAGES.SDSC.EDU
sds.sdsc.edu	preference = 20, mail exchanger = LUAC.SDSC.EDU
sds.sdsc.edu	preference = 30, mail exchanger = M5.SDSC.EDU
sds.sdsc.edu	preference = 40, mail exchanger = TOPGUN.SDSC.EDU
sds.sdsc.edu	preference = 50, mail exchanger = SDCTSS.SDSC.EDU


All is well and good except that sdctss.sdsc.edu no longer exists.  If none
of the sdsc.edu hosts are reachable, mail sent to user@sds.sdsc.edu address
will bounce with a non-existent host message.  This can be very surprising
since this is an address that worked for the user yesterday.

The fix is to special case the last MX contact attempt in deliver.c.  Line
numbers refer to the V5.61 sendmail + IDA 1.2.8 changes.

         Paul Pomes

UUCP:     {att,iuvax,uunet}!uiucuxc!paul     ICBM: 40 06 47 N / 88 13 35 W
Internet, BITNET: paul@uxc.cso.uiuc.edu      Phone: 217 333 6262
US Mail:  UofIllinois, CSO, 1304 W Springfield Ave, Urbana, IL  61801-2987

*** /tmp/,RCSt1008597	Mon Oct 23 10:47:30 1989
--- /tmp/,RCSt2008597	Mon Oct 23 10:47:34 1989
***************
*** 821,840 ****
--- 821,856 ----
  			else
  			{
  				i = st->s_host.ho_exitstat;
  				errno = st->s_host.ho_errno;
  			}
  #else HOSTINFO
  			i = makeconnection(MxHosts[j], port, pmfile, prfile);
  #endif HOSTINFO
  			if (i != EX_OK)
  			{
+ 				/*
+ 				 * Consider the case of multiple MX entries
+ 				 * for a given host where the last entry refers
+ 				 * to non-existent host.  On occasions when
+ 				 * none of the hosts are reachable, the mail
+ 				 * will bounce if the last ExitStat is
+ 				 * EX_NOHOST.  Handle this by resetting i to
+ 				 * EX_TEMPFAIL if it's not the primary MX entry
+ 				 * and it's the last MX entry.  -pbp
+ 				 */
+ #ifdef LOG
+ 				if (i == EX_NOHOST)
+ 					syslog(LOG_WARNING, "Found non-existent host %s in MX records for %s", CurHostName, pvp[1]);
+ #endif LOG
+ 				if (j != 0 && j == (Nmx - 1))
+ 					i = EX_TEMPFAIL;
  #ifdef HOSTINFO
  				/* enter status of this host */
  				if (st == NULL)
  					st = stab(MxHosts[j], ST_HOST, ST_ENTER);
  				st->s_host.ho_exitstat = i;
  				st->s_host.ho_errno = errno;
  #endif HOSTINFO
  				ExitStat = i;
  				continue;
  			}