Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-6]: src Pull up revisions:



details:   https://anonhg.NetBSD.org/src/rev/f928dc21b235
branches:  netbsd-6
changeset: 774151:f928dc21b235
user:      jdc <jdc%NetBSD.org@localhost>
date:      Sun Jun 03 21:41:34 2012 +0000

description:
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.

diffstat:

 include/netdb.h            |   6 ++++--
 lib/libc/net/getaddrinfo.c |  46 +++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 47 insertions(+), 5 deletions(-)

diffs (136 lines):

diff -r ca83f47a2f3b -r f928dc21b235 include/netdb.h
--- a/include/netdb.h   Wed May 30 08:06:48 2012 +0000
+++ b/include/netdb.h   Sun Jun 03 21:41:34 2012 +0000
@@ -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 @@
 #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 || \
diff -r ca83f47a2f3b -r f928dc21b235 lib/libc/net/getaddrinfo.c
--- a/lib/libc/net/getaddrinfo.c        Wed May 30 08:06:48 2012 +0000
+++ b/lib/libc/net/getaddrinfo.c        Sun Jun 03 21:41:34 2012 +0000
@@ -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 @@
 #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_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 @@
        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 @@
                }
        }
 
+       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 @@
        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 @@
                        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 @@
        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 @@
        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



Home | Main Index | Thread Index | Old Index