[NET]: Bug-fix for getaddrinfo()
authorGerrit Renker <gerrit@erg.abdn.ac.uk>
Wed, 14 May 2008 11:16:33 +0000 (13:16 +0200)
committerAndre Noll <maan@systemlinux.org>
Wed, 14 May 2008 11:16:33 +0000 (13:16 +0200)
Something changed in the getaddrinfo() mechanism, causing AF_UNSPEC
in combination with ai_socktype=0 to return IPv4 addresses first
(instead of starting with IPv6 addresses). As a consequence, IPv6
servers are restricted to only IPv4 connections - IPv6 clients will
receive an ICMPv6 error message, which gets translated into an annoying
"protocol error" locally.

The fix is to pretend to be UDP instead of DCCP (pretending to be TCP
also works). This allows getaddrinfo to look up the address without
side effects and has been found to work.

net.c

diff --git a/net.c b/net.c
index b2c9c43..60f8e9a 100644 (file)
--- a/net.c
+++ b/net.c
@@ -157,9 +157,13 @@ int makesock(unsigned l3type, unsigned l4type, int passive,
        /* Set up address hint structure */
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = l3type;
-       /* getaddrinfo does not really work well with SOCK_DCCP */
-       if (socktype == SOCK_DGRAM || socktype == SOCK_STREAM)
-               hints.ai_socktype = socktype;
+       hints.ai_socktype = socktype;
+       /* 
+        * getaddrinfo does not support SOCK_DCCP, so for the sake of lookup
+        * (and only then) pretend to be UDP.
+        */
+       if (l4type == IPPROTO_DCCP)
+               hints.ai_socktype = SOCK_DGRAM;
 
        /* only use addresses available on the host */
        hints.ai_flags = AI_ADDRCONFIG;