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: