[fetchmail]IPv6 DNS Problems

Sebastian Wiesinger fetchmail@tracker.fire-world.de
Mon, 28 Mar 2005 01:25:35 +0200


--a8Wt8u1KmwUX3Y2C
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello,

I tried to use fetchmail with my IPv6 server and was unable to get a
connection. All I got was:

fetchmail[28460]: couldn't find canonical DNS name of alita.v6.karotte.org (alita.v6.karotte.org)
fetchmail[28460]: Query status=11 (DNS)

I use fetchmail with Linux 2.4.x, glibc 2.3.2.

I tried to find the reason for this (because I have AAAA records for
this address), and found out that driver.c doesn't resolve IPv6 hosts.
gethostbyname doesn't resolve AAAA records unless told so with a
resolver option. (Which is defined in resolv.h as RES_USE_INET6)

I attached my hotfix for this (which is poorly written, but works for
me) to this mail.

Regards,

Sebastian

-- 
GPG Key-ID: 0x76B79F20 (0x1B6034F476B79F20)
Wehret den Anfaengen: http://odem.org/informationsfreiheit/
'Are you Death?' ... IT'S THE SCYTHE, ISN'T IT? PEOPLE ALWAYS NOTICE THE SCYTHE.
            -- Terry Pratchett, The Fifth Elephant

--a8Wt8u1KmwUX3Y2C
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ipv6-dns.diff"

--- ./fetchmail-6.2.5/driver.c	Mon Mar 28 01:12:21 2005
+++ ./fetchmail-6.2.5-patched/driver.c	Mon Mar 28 01:01:46 2005
@@ -34,6 +34,7 @@
 #endif
 
 #if defined(HAVE_RES_SEARCH) || defined(HAVE_GETHOSTBYNAME)
+#include <resolv.h>
 #include <netdb.h>
 #include "mx.h"
 #endif /* defined(HAVE_RES_SEARCH) || defined(HAVE_GETHOSTBYNAME) */
@@ -826,6 +827,9 @@
     int err, mailserver_socket = -1;
 #endif /* HAVE_VOLATILE */
     const char *msg;
+#if INET6_ENABLE
+    u_long  resolver_options;
+#endif
     SIGHANDLERTYPE pipesave;
     SIGHANDLERTYPE alrmsave;
 
@@ -1007,9 +1011,28 @@
 		 * Received: from hostname [10.0.0.1]
 		 */
 		errno = 0;
+#if INET6_ENABLE
+		res_init();
+#endif /* INET6_ENABLE */
 		namerec = gethostbyname(ctl->server.queryname);
 		if (namerec == (struct hostent *)NULL)
 		{
+#if INET6_ENABLE
+			resolver_options = _res.options;
+			_res.options |= RES_USE_INET6;
+			namerec = gethostbyname(ctl->server.queryname);
+			_res.options = resolver_options;
+			if (namerec == (struct hostent *)NULL)
+			{
+			    report(stderr,
+				   GT_("couldn't find canonical DNS name of %s (%s)\n"),
+				   ctl->server.pollname, ctl->server.queryname);
+			    err = PS_DNS;
+			    set_timeout(0);
+			    phase = oldphase;
+			    goto closeUp;
+			}
+#else /* !INET6_ENABLE */
 		    report(stderr,
 			   GT_("couldn't find canonical DNS name of %s (%s)\n"),
 			   ctl->server.pollname, ctl->server.queryname);
@@ -1017,6 +1040,7 @@
 		    set_timeout(0);
 		    phase = oldphase;
 		    goto closeUp;
+#endif /* INET6_ENABLE */
 		}
 		else 
 		{

--a8Wt8u1KmwUX3Y2C--