One should always read the spec!

It turns out that getaddrinfo() can already do the filtering I did
manually in my original patches. Here is a set of smarter patches that
lets getaddrinfo() filter instead.

-- 
Henning Makholm                                   "No one seems to know what
                                       distinguishes a bell from a whistle."
This patch fixes a problem with the IPv6-mode address resolution
in innfeed. The upstream code neglects to tell getaddrinfo(3) that it
wants a SOCK_STREAM; thus each address for the hostname thrice gets
reported thrice: one with each of SOCK_STREAM, SOCK_DGRAM and
SOCK_RAW. Therefore an address that is unreachable will be tried
three times before innfeed goes on to try another address.

This patch amends the getaddrinfo(3) call to request a SOCK_STREAM
address.

Created by Henning Makholm <[EMAIL PROTECTED]> on 2005-10-30 while
investigating Debian bug #336264. This patch is in the public domain.

diff -ruN inn-2.4.2.orig/innfeed/host.c inn-2.4.2/innfeed/host.c
--- inn-2.4.2.orig/innfeed/host.c       2004-12-22 05:21:19.000000000 +0100
+++ inn-2.4.2/innfeed/host.c    2005-10-30 11:20:07.903313828 +0100
@@ -1122,10 +1122,12 @@
 #ifdef HAVE_INET6
       int gai_ret;
       struct addrinfo *res, *p;
+      struct addrinfo template = {0};
+      template.ai_family = PF_UNSPEC;
+      template.ai_socktype = SOCK_STREAM;
 
-      if(( gai_ret = getaddrinfo(host->params->ipName, NULL, NULL, &res)) != 0
-                     || res == NULL )
-
+      gai_ret = getaddrinfo(host->params->ipName, NULL, &template, &res);
+      if( gai_ret != 0 || res == NULL )
        {
           warn ("%s can't resolve hostname %s: %s", host->params->peerName,
                host->params->ipName, gai_ret == 0 ? "no addresses returned"
This patch must be applied after 'antiudp.patch'.
It fixes Debian bug #336264, by adding an innfeed configuration option
'avoid-ipv6' that suppresses IPv6 connections unless IPV6 addresses is
all we have.

In the interest of being non-intrusive the option is off by default,
but it should be mostly harmless to have it on for all feeds (such
that user configuration would in most cases be necessary for using
IPv6 transport); after all there are no documented guarantees about
the order in which which getaddrinfo(3) returns alternative addresses.

Created by Henning Makholm <[EMAIL PROTECTED]> on 2005-10-30.
This patch is in the public domain.

diff -ruN inn-2.4.2.orig/doc/man/innfeed.conf.5 inn-2.4.2/doc/man/innfeed.conf.5
--- inn-2.4.2.orig/doc/man/innfeed.conf.5       2004-12-22 05:21:19.000000000 
+0100
+++ inn-2.4.2/doc/man/innfeed.conf.5    2005-10-30 11:31:16.741264716 +0100
@@ -459,6 +459,11 @@
 This key requires a positive integer value. It defines the tcp/ip port
 number to use when connecting to the remote.
 .TP
+.B avoid-ipv6
+This key requires a boolean value. By default it is set to false.
+If it is set to true, and the \fBip-name\fP has any IPv4 addresses,
+innfeed will not try to use IPv6 communication with that peer.
+.TP
 .B drop-deferred
 This key requires a boolean value. By default it is set to false. When
 set to true, and a peer replies with code 431 or 436 (try again later) just
diff -ruN inn-2.4.2.orig/innfeed/host.c inn-2.4.2/innfeed/host.c
--- inn-2.4.2.orig/innfeed/host.c       2005-10-30 11:44:36.148433795 +0100
+++ inn-2.4.2/innfeed/host.c    2005-10-30 11:43:31.612219409 +0100
@@ -87,6 +87,9 @@
   unsigned int absMaxConnections;
   unsigned int maxChecks;
   unsigned short portNum;
+#ifdef HAVE_INET6
+  bool avoidInet6;
+#endif
   unsigned int closePeriod;
   unsigned int dynamicMethod;
   bool wantStreaming;
@@ -498,6 +501,9 @@
       params->absMaxConnections=MAX_CXNS;
       params->maxChecks=MAX_Q_SIZE;
       params->portNum=PORTNUM;
+#ifdef HAVE_INET6
+      params->avoidInet6=AVOID_INET6;
+#endif
       params->closePeriod=CLOSE_PERIOD;
       params->dynamicMethod=METHOD_STATIC;
       params->wantStreaming=STREAM;
@@ -1123,10 +1129,26 @@
       int gai_ret;
       struct addrinfo *res, *p;
       struct addrinfo template = {0};
-      template.ai_family = PF_UNSPEC;
       template.ai_socktype = SOCK_STREAM;
 
-      gai_ret = getaddrinfo(host->params->ipName, NULL, &template, &res);
+      if (host->params->avoidInet6)
+        {
+          template.ai_family = PF_INET;
+          gai_ret = getaddrinfo(host->params->ipName, NULL, &template, &res);
+          if (gai_ret == EAI_ADDRFAMILY || gai_ret == EAI_NODATA)
+            {
+              warn ("%s hostname %s has no IPv4 addresses\n",
+                    host->params->peerName,host->params->ipName);
+              template.ai_family = PF_UNSPEC;
+              gai_ret = getaddrinfo(host->params->ipName,NULL,&template, &res);
+            }
+        }
+      else
+        {
+          template.ai_family = PF_UNSPEC;
+          gai_ret = getaddrinfo(host->params->ipName, NULL, &template, &res);
+        }
+
       if( gai_ret != 0 || res == NULL )
        {
           warn ("%s can't resolve hostname %s: %s", host->params->peerName,
@@ -2676,6 +2698,9 @@
   GETREAL(s,fp,"no-check-low",0.0,100.0,REQ,p->lowPassLow, inherit);
   GETREAL(s,fp,"no-check-filter",0.1,DBL_MAX,REQ,p->lowPassFilter, inherit);
   GETINT(s,fp,"port-number",0,LONG_MAX,REQ,p->portNum, inherit);
+#ifdef HAVE_INET6
+  GETBOOL(s,fp,"avoid-ipv6",NOTREQ,p->avoidInet6,inherit);
+#endif
   GETINT(s,fp,"backlog-limit",0,LONG_MAX,REQ,p->backlogLimit, inherit);
 
   if (findValue (s,"backlog-factor",inherit) == NULL &&
diff -ruN inn-2.4.2.orig/innfeed/innfeed.h inn-2.4.2/innfeed/innfeed.h
--- inn-2.4.2.orig/innfeed/innfeed.h    2004-12-22 05:21:19.000000000 +0100
+++ inn-2.4.2/innfeed/innfeed.h 2005-10-30 11:31:16.742264580 +0100
@@ -62,6 +62,7 @@
 #define NOCHECKHIGH            95.0            /* no-check-high */
 #define NOCHECKLOW             90.0            /* no-check-low */
 #define PORTNUM                119             /* port-number */
+#define AVOID_INET6            false           /* suppress IPv6 use */
 #define BLOGLIMIT              0               /* backlog-limit */
 #define LIMIT_FUDGE            1.10            /* backlog-factor */
 #define BLOGLIMIT_HIGH         0               /* backlog-limit-high */
diff -ruN inn-2.4.2.orig/samples/innfeed.conf inn-2.4.2/samples/innfeed.conf
--- inn-2.4.2.orig/samples/innfeed.conf 2004-12-22 05:21:19.000000000 +0100
+++ inn-2.4.2/samples/innfeed.conf      2005-10-30 11:31:16.743264444 +0100
@@ -56,6 +56,7 @@
 no-check-low:                  90.0
 no-check-filter:               50.0
 port-number:                   119
+avoid-ipv6:                    false
 drop-deferred:                 false
 min-queue-connection:          false
 backlog-limit:                 0

Reply via email to