diff options
| -rw-r--r-- | Makefile.in | 4 | ||||
| -rw-r--r-- | driver.c | 70 | 
2 files changed, 49 insertions, 25 deletions
| diff --git a/Makefile.in b/Makefile.in index 1a997968..9348df72 100644 --- a/Makefile.in +++ b/Makefile.in @@ -78,7 +78,7 @@ CTAGS = ctags -tw  popobjs = socket.o getpass.o pop2.o pop3.o imap.o fetchmail.o options.o	\         rcfile_l.o rcfile_y.o daemon.o driver.o smtp.o xmalloc.o \ -       uid.o md5c.o md5ify.o +       uid.o mxget.o md5c.o md5ify.o  objs = $(popobjs) $(extras) $(EXTRAOBJ) @@ -86,7 +86,7 @@ srcs = $(srcdir)/socket.c $(srcdir)/getpass.c $(srcdir)/pop2.c 		\         $(srcdir)/pop3.c $(srcdir)/imap.c $(srcdir)/fetchmail.c		\         $(srcdir)/options.c $(srcdir)/daemon.c $(srcdir)/driver.c	\         $(srcdir)/smtp.c $(srcdir)/xmalloc.c $(srcdir)/uid.c		\ -       $(srcdir)/md5c.c $(srcdir)/md5ify.c +       $(srcdir)/mxget.c $(srcdir)/md5c.c $(srcdir)/md5ify.c  .SUFFIXES:  .SUFFIXES: .o .c .h .y .l .ps .dvi .info .texi @@ -22,6 +22,7 @@  #ifdef HAVE_GETHOSTBYNAME  #include <netdb.h> +#include "mx.h"  #endif /* HAVE_GETHOSTBYNAME */  #ifdef KERBEROS_V4 @@ -300,14 +301,17 @@ char *hdr;	/* header line to be parsed, NUL to continue in previous hdr */  }  #ifdef HAVE_GETHOSTBYNAME -static int is_host_alias(name, host, canonical) -/* determine whether name is a DNS alias of either following hostname */ -const char *name, *host, *canonical; +#define MX_RETRIES	3 + +static int is_host_alias(name, queryctl) +/* determine whether name is a DNS alias of the hostname */ +const char *name; +struct hostrec	*queryctl;  {      struct hostent	*he; +    int			i, n;      /* -       * The first two checks are optimizations that will catch a good       * many cases.  First, check against the hostname the user specified.       * Odds are good this will either be the mailserver's FQDN or a @@ -319,24 +323,46 @@ const char *name, *host, *canonical;       * name doesn't match either is it time to call the bind library.       * If this happens odds are good we're looking at an MX name.       */ -    if (strcmp(name, host) == 0) -	return(1); -    else if (strcmp(name, canonical) == 0) -	return(1); -    else if ((he = gethostbyname(name)) == (struct hostent *)NULL) +    if (strcmp(name, queryctl->servername) == 0) +	return(TRUE); +    else if (strcmp(name, queryctl->canonical_name) == 0) +	return(TRUE); + +    /* +     * We treat DNS lookup failure as a negative on the theory that +     * the mailserver's DNS server is `nearby' and should be able +     * to respond quickly and reliably.  Ergo if we get failure, +     * the name isn't a mailserver alias. +     */ +    else if ((he = gethostbyname(name)) && strcmp(queryctl->canonical_name, he->h_name) == 0) +	return(TRUE); + +    /* +     * Search for a name match on MX records pointing to the server +     * site.  These may live far away, so allow a couple of retries. +     */ +    for (i = 0; i < MX_RETRIES; i++)      { -	/* -	 * We treat lookup failure as a negative on the theory that -	 * the mailserver's DNS server is `nearby' and should be able -	 * to respond quickly and reliably.  Ergo if we get failure, -	 * the name isn't a mailserver alias. -	 */ -	if (outlevel == O_VERBOSE) -	    fprintf(stderr, "fetchmail: DNS lookup of %s failed\n", name); -	return(FALSE); +	struct mxentry mxresp[32]; +	int j; + +	n = getmxrecords(name, sizeof(mxresp)/sizeof(struct mxentry), mxresp); + +	if (n == -1) +	    if (h_errno == TRY_AGAIN) +	    { +		sleep(1); +		continue; +	    } +	    else +		break; + +	for (j = 0; j < n; j++) +	    if (strcmp(name, mxresp[i].name) == 0) +		return(TRUE);      } -    else -	return(strcmp(name, he->h_name) == 0); + +    return(FALSE);  }  void find_server_names(hdr, queryctl, xmit_names) @@ -360,9 +386,7 @@ struct idlist **xmit_names;	/* list of recipient names parsed out */  			continue;  		    else  		    { -			if (!is_host_alias(atsign+1,  -					   queryctl->servername, -					   queryctl->canonical_name)) +			if (!is_host_alias(atsign+1, queryctl))  			    continue;  			atsign[0] = '\0';  		    } | 
