Module Name:    src
Committed By:   jdc
Date:           Sun Jun  3 21:41:35 UTC 2012

Modified Files:
        src/include [netbsd-6]: netdb.h
        src/lib/libc/net [netbsd-6]: getaddrinfo.c

Log Message:
Pull up revisions:
  src/lib/libc/net/getaddrinfo.c revision 1.98 - 1.100
  src/include/netdb.h revision 1.65
(requested by khorben in ticket #278).

Add AI_ADDRCONFIG, which makes getaddrinfo() return only address with
families
that are already configured in the system.

PR 46206: fix programmed SIGSEGV
more work is needed as tests seem to indicate that name resolution now
does no seem to work (firefox reports Server not found)
thanks to Ryo ONODERA for testing.

PR pkg/46206
re-establish fqdn lookup when AI_ADDRCONFIG is used in hints
AI_ADDRCONFIG led to fqdn lookup being skipped as the systems didn't
configure any PF_UNSPEC addresses - check was too strict here.
Thnaks to Ryo ONODERA for testing.


To generate a diff of this commit:
cvs rdiff -u -r1.64 -r1.64.8.1 src/include/netdb.h
cvs rdiff -u -r1.96 -r1.96.4.1 src/lib/libc/net/getaddrinfo.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/include/netdb.h
diff -u src/include/netdb.h:1.64 src/include/netdb.h:1.64.8.1
--- src/include/netdb.h:1.64	Wed May  5 17:12:29 2010
+++ src/include/netdb.h	Sun Jun  3 21:41:34 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: netdb.h,v 1.64 2010/05/05 17:12:29 christos Exp $	*/
+/*	$NetBSD: netdb.h,v 1.64.8.1 2012/06/03 21:41:34 jdc Exp $	*/
 
 /*
  * ++Copyright++ 1980, 1983, 1988, 1993
@@ -269,7 +269,9 @@ struct addrinfo {
 #define	AI_NUMERICSERV	0x00000008 /* prevent service name resolution */
 /* valid flags for addrinfo (not a standard def, apps should not use it) */
 #define	AI_MASK	\
-    (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV)
+    (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | \
+    AI_ADDRCONFIG)
+#define	AI_ADDRCONFIG	0x00000400 /* only if any address is assigned */
 #endif
 
 #if (_POSIX_C_SOURCE - 0) >= 200112L || (_XOPEN_SOURCE - 0) >= 520 || \

Index: src/lib/libc/net/getaddrinfo.c
diff -u src/lib/libc/net/getaddrinfo.c:1.96 src/lib/libc/net/getaddrinfo.c:1.96.4.1
--- src/lib/libc/net/getaddrinfo.c:1.96	Sat Oct 15 23:00:02 2011
+++ src/lib/libc/net/getaddrinfo.c	Sun Jun  3 21:41:34 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: getaddrinfo.c,v 1.96 2011/10/15 23:00:02 christos Exp $	*/
+/*	$NetBSD: getaddrinfo.c,v 1.96.4.1 2012/06/03 21:41:34 jdc Exp $	*/
 /*	$KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $	*/
 
 /*
@@ -55,7 +55,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: getaddrinfo.c,v 1.96 2011/10/15 23:00:02 christos Exp $");
+__RCSID("$NetBSD: getaddrinfo.c,v 1.96.4.1 2012/06/03 21:41:34 jdc Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #include "namespace.h"
@@ -76,6 +76,7 @@ __RCSID("$NetBSD: getaddrinfo.c,v 1.96 2
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <ifaddrs.h>
 
 #include <syslog.h>
 #include <stdarg.h>
@@ -208,6 +209,7 @@ static int get_portmatch(const struct ad
 static int get_port(const struct addrinfo *, const char *, int,
     struct servent_data *);
 static const struct afd *find_afd(int);
+static int addrconfig(uint64_t *);
 #ifdef INET6
 static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *);
 #endif
@@ -348,6 +350,7 @@ getaddrinfo(const char *hostname, const 
 	struct addrinfo *pai;
 	const struct explore *ex;
 	struct servent_data svd;
+	uint64_t mask = (uint64_t)~0ULL;
 
 	/* hostname is allowed to be NULL */
 	/* servname is allowed to be NULL */
@@ -409,6 +412,9 @@ getaddrinfo(const char *hostname, const 
 		}
 	}
 
+	if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && addrconfig(&mask) == -1)
+		ERR(EAI_FAIL);
+
 	/*
 	 * check for special cases.  (1) numeric servname is disallowed if
 	 * socktype/protocol are left unspecified. (2) servname is disallowed
@@ -441,6 +447,10 @@ getaddrinfo(const char *hostname, const 
 	for (ex = explore; ex->e_af >= 0; ex++) {
 		*pai = ai0;
 
+		/* ADDRCONFIG check */
+		if ((((uint64_t)1 << ex->e_af) & mask) == 0)
+			continue;
+
 		/* PF_UNSPEC entries are prepared for DNS queries only */
 		if (ex->e_af == PF_UNSPEC)
 			continue;
@@ -451,7 +461,6 @@ getaddrinfo(const char *hostname, const 
 			continue;
 		if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
 			continue;
-
 		if (pai->ai_family == PF_UNSPEC)
 			pai->ai_family = ex->e_af;
 		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
@@ -494,6 +503,13 @@ getaddrinfo(const char *hostname, const 
 	for (ex = explore; ex->e_af >= 0; ex++) {
 		*pai = ai0;
 
+
+		/* ADDRCONFIG check */
+		/* PF_UNSPEC entries are prepared for DNS queries only */
+		if (ex->e_af != PF_UNSPEC &&
+		    (((uint64_t)1 << ex->e_af) & mask) == 0)
+			continue;
+
 		/* require exact match for family field */
 		if (pai->ai_family != ex->e_af)
 			continue;
@@ -1006,6 +1022,30 @@ find_afd(int af)
 	return NULL;
 }
 
+/*
+ * AI_ADDRCONFIG check: Build a mask containing a bit set for each address
+ * family configured in the system.
+ *
+ */
+static int
+addrconfig(uint64_t *mask)
+{
+	struct ifaddrs *ifaddrs, *ifa;
+
+	if (getifaddrs(&ifaddrs) == -1)
+		return -1;
+
+	*mask = 0;
+	for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next)
+		if (ifa->ifa_addr && (ifa->ifa_flags & IFF_UP)) {
+			_DIAGASSERT(ifa->ifa_addr->sa_family < 64);
+			*mask |= (uint64_t)1 << ifa->ifa_addr->sa_family;
+		}
+
+	freeifaddrs(ifaddrs);
+	return 0;
+}
+
 #ifdef INET6
 /* convert a string to a scope identifier. XXX: IPv6 specific */
 static int

Reply via email to