Subject: pkg/12488: pkg - www/www6to4 fail to use getaddrinfo righ
To: None <gnats-bugs@gnats.netbsd.org>
From: Love <lha@stacken.kth.se>
List: netbsd-bugs
Date: 03/28/2001 08:30:32
>Number:         12488
>Category:       pkg
>Synopsis:       w/www6to4 fail to use getaddrinfo righ
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Mar 27 22:31:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Love <lha@stacken.kth.se>
>Release:        NetBSD with IPv6 support
>Organization:
        Stacken computer club
>Environment:
        <machine, os, target, libraries (multiple lines)>
System: NetBSD nutcracker.dynarc.se 1.5S NetBSD 1.5S (NUTCRACKER) #2: Mon Mar 12 16:45:25 CET 2001 lha@nutcracker.dynarc.se:/usr/src/sys/arch/i386/compile/NUTCRACKER i386
Architecture: i386
Machine: i386
>Description:

        www/www6to4 only uses the first address that getaddrinfo return.

        That make me fail to talk to www.kame.net then I doesn't have ipv6
        connectivity.

        I've also sent this patch to the author (Feico Dillema).

>How-To-Repeat:

        Code inspection.

>Fix:


Add this as patch-ab.


$NetBSD$

Use all addresses returned by getaddrinfo.

--- socket.c.orig	Wed Mar 28 08:01:09 2001
+++ socket.c	Wed Mar 28 08:11:01 2001
@@ -123,7 +123,7 @@
     struct timeval  tv[1];
     int             flags;
 
-    struct addrinfo hints, r, *res;
+    struct addrinfo hints, *res, *res0;
     struct sockaddr_storage sas;
     int             s, error;
     int             reuse_addr = 1;
@@ -132,25 +132,24 @@
     hints.ai_family = AF_UNSPEC;
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_protocol = 0;
-    error = getaddrinfo (host, port, &hints, &res);
+    error = getaddrinfo (host, port, &hints, &res0);
     if (error)
 	return (-1);
 
     fprintf (logfp, "Connecting to: %s at %s.\n", host, port);
-    memcpy (&r, res, sizeof (*res));
-    memcpy (&sas, res->ai_addr, res->ai_addrlen);
-    r.ai_addr = (struct sockaddr *)&sas;
 
-    if (res)
-	freeaddrinfo (res);
+    for (res = res0; res; res = res->ai_next) {
+
+	fd = socket(res->ai_family, res->ai_socktype,
+		    res->ai_protocol);
+	if (fd < 0)
+	    continue;
 
-    if ((fd = socket (r.ai_family, r.ai_socktype, r.ai_protocol)) < 0) {
-	return (-1);
-    }
 #ifdef TCP_NODELAY
     {				/* turn off TCP coalescence */
 	int             mi = 1;
-	setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (char *) &mi, sizeof (int));
+	    setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, 
+			(char *) &mi, sizeof (int));
     }
 #endif
 
@@ -159,17 +158,28 @@
 	fcntl (fd, F_SETFL, flags);
     }
 
-    if (connect (fd, (struct sockaddr *) r.ai_addr, r.ai_addrlen) == -1) {
+	error = connect(fd, (struct sockaddr *) res->ai_addr, res->ai_addrlen);
+	if (error < 0) {
         if (errno != EINPROGRESS) {
-            (void) close (fd);
-            return (-1);
+		close (fd);
+		fd = -1;
+		continue;
 	}
     }
+	break; /* connected to a server */
+    }
+
+    if (res0)
+	freeaddrinfo (res0);
+    
+    if (fd < 0)
+	return -1;
 
     if (flags != -1) {
 	flags &= ~O_NDELAY;
 	fcntl (fd, F_SETFL, flags);
     }
+
     /* wait for connection to complete */
     FD_ZERO (&wfds);
     FD_SET (fd, &wfds);

>Release-Note:
>Audit-Trail:
>Unformatted: