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'; } |