[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 b2c9c43a81ad356ec021373c12d5c764fa5b76f4..60f8e9a1d07cceafa4dcc51bb64ec5ae6b50b82e 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;