Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/net Add AI_ADDRCONFIG, which makes getaddrinfo() re...
details: https://anonhg.NetBSD.org/src/rev/6b86de6736e8
branches: trunk
changeset: 778151:6b86de6736e8
user: christos <christos%NetBSD.org@localhost>
date: Sat Mar 17 21:56:40 2012 +0000
description:
Add AI_ADDRCONFIG, which makes getaddrinfo() return only address with families
that are already configured in the system.
diffstat:
lib/libc/net/getaddrinfo.c | 43 ++++++++++++++++++++++++++++++++++++++++---
1 files changed, 40 insertions(+), 3 deletions(-)
diffs (113 lines):
diff -r 876818a4e772 -r 6b86de6736e8 lib/libc/net/getaddrinfo.c
--- a/lib/libc/net/getaddrinfo.c Sat Mar 17 21:54:12 2012 +0000
+++ b/lib/libc/net/getaddrinfo.c Sat Mar 17 21:56:40 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: getaddrinfo.c,v 1.97 2012/03/13 21:13:40 christos Exp $ */
+/* $NetBSD: getaddrinfo.c,v 1.98 2012/03/17 21:56:40 christos 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.97 2012/03/13 21:13:40 christos Exp $");
+__RCSID("$NetBSD: getaddrinfo.c,v 1.98 2012/03/17 21:56:40 christos 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,10 @@
for (ex = explore; ex->e_af >= 0; ex++) {
*pai = ai0;
+ /* ADDRCONFIG check */
+ if ((((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 +1019,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