From 45fc85440cc55c05940a96f6a7be82f58528ed68 Mon Sep 17 00:00:00 2001
From: "Eric S. Raymond" <esr@thyrsus.com>
Date: Mon, 20 Jul 1998 07:40:43 +0000
Subject: Eliminate some DNS round trips.

svn path=/trunk/; revision=1991
---
 NEWS         |  5 +++-
 checkalias.c |  8 +++----
 fetchmail.c  | 75 +++++++++++++++++++++++++-----------------------------------
 3 files changed, 39 insertions(+), 49 deletions(-)

diff --git a/NEWS b/NEWS
index ea00e3d2..ecdaf6f6 100644
--- a/NEWS
+++ b/NEWS
@@ -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)
-- 
cgit v1.2.3