diff options
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | checkalias.c | 8 | ||||
-rw-r--r-- | fetchmail.c | 75 |
3 files changed, 39 insertions, 49 deletions
@@ -2,7 +2,6 @@ * Add an "ident" per-user option for debugging that produces an "X-Fetchmail-ID" header in fetched messages for debugging. -* Can the initial gethostname() be eliminated? Release Notes: @@ -11,6 +10,10 @@ fetchmail-4.5.3 (): * Minor fixes to the GSSAPI code. Seems to work with stock UW IMAP now! * Fetchmail running as root now sends misaddressed multidrop mail to `postmaster', not root. Added `postmaster' option to allow override. +* DNS names of target servers are now canonicalized only once, at start + of run, and then only if they'll actually be needed later for multidrop + checking or ftching Kerberos tickets. This eliminates many gethostbyname + calls. There are 267 people on fetchmail-friends and 249 on fetchmail-announce. diff --git a/checkalias.c b/checkalias.c index 317cd2d1..eb045e37 100644 --- a/checkalias.c +++ b/checkalias.c @@ -121,12 +121,12 @@ int is_host_alias(const char *name, struct query *ctl) #else /* * The only code that calls the BIND library is here and in the - * start-of-query probe with gethostbyname(3). + * start-of-run probe with gethostbyname(3). * - * We know DNS service was up at the beginning of this poll cycle. + * We know DNS service was up at the beginning of the run. * If it's down, our nameserver has crashed. We don't want to try - * delivering the current message or anything else from this - * mailbox until it's back up. + * delivering the current message or anything else from the + * current server until it's back up. */ else if ((he = gethostbyname(name)) != (struct hostent *)NULL) { diff --git a/fetchmail.c b/fetchmail.c index 41a34567..63ad9999 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -478,45 +478,6 @@ int main (int argc, char **argv) continue; #endif /* defined(linux) && !INET6 */ -#ifdef HAVE_GETHOSTBYNAME - /* - * This functions partly as a probe to make sure our - * nameserver is still up. The multidrop case - * (especially) needs it. - */ - if (ctl->server.preauthenticate==A_KERBEROS_V4 || - ctl->server.preauthenticate==A_KERBEROS_V5 || - MULTIDROP(ctl)) - { - struct hostent *namerec; - - /* compute the canonical name of the host */ - errno = 0; - namerec = gethostbyname(ctl->server.queryname); - if (namerec == (struct hostent *)NULL) - { - error(0, errno, - "skipping %s poll, ", - ctl->server.pollname); - if (errno) - { - if (errno == ENETUNREACH) - break; /* go to sleep */ - } -#ifdef HAVE_HERROR /* NEXTSTEP doesn't */ - else - herror("DNS error"); -#endif /* HAVE_HERROR */ - continue; - } - else - { - free(ctl->server.truename); - ctl->server.truename=xstrdup((char *)namerec->h_name); - } - } -#endif /* HAVE_GETHOSTBYNAME */ - querystatus = query_host(ctl); if (querystatus == PS_SUCCESS) @@ -924,16 +885,42 @@ static int load_params(int argc, char **argv, int optind) * * We're going to assume the via name is true unless it's * localhost. - * - * Each poll cycle, if we've got DNS, we'll try to canonicalize - * the name. This will function as a probe to ensure the - * host's nameserver is up. */ if (ctl->server.via && strcmp(ctl->server.via, "localhost")) ctl->server.queryname = xstrdup(ctl->server.via); else ctl->server.queryname = xstrdup(ctl->server.pollname); - ctl->server.truename = xstrdup(ctl->server.queryname); + + /* + * We may have to canonicalize the server truename for later use. + * Do this just once for each lead server, if necessary, in order + * to minimize DNS round trips. + */ + if (ctl->server.lead_server) + ctl->server.truename = xstrdup(ctl->server.lead_server->truename); +#ifdef HAVE_GETHOSTBYNAME + else if (ctl->server.preauthenticate==A_KERBEROS_V4 || + ctl->server.preauthenticate==A_KERBEROS_V5 || + (ctl->server.dns && MULTIDROP(ctl))) + { + struct hostent *namerec; + + /* compute the canonical name of the host */ + errno = 0; + namerec = gethostbyname(ctl->server.queryname); + if (namerec == (struct hostent *)NULL) + { + error(0, errno, + "couldn't find canonical DNS name of %s", + ctl->server.pollname); + exit(PS_DNS); + } + else + ctl->server.truename=xstrdup((char *)namerec->h_name); + } +#endif /* HAVE_GETHOSTBYNAME */ + else + ctl->server.truename = xstrdup(ctl->server.queryname); /* if no folders were specified, set up the null one as default */ if (!ctl->mailboxes) |