summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/asr/getaddrinfo_async.c41
-rw-r--r--lib/libc/net/getaddrinfo.317
2 files changed, 53 insertions, 5 deletions
diff --git a/lib/libc/asr/getaddrinfo_async.c b/lib/libc/asr/getaddrinfo_async.c
index 1f1d19c74df..00ed6a1dffc 100644
--- a/lib/libc/asr/getaddrinfo_async.c
+++ b/lib/libc/asr/getaddrinfo_async.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getaddrinfo_async.c,v 1.26 2014/03/26 18:13:15 eric Exp $ */
+/* $OpenBSD: getaddrinfo_async.c,v 1.27 2014/04/28 21:38:59 sperreault Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -21,6 +21,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
+#include <net/if.h>
#ifdef YP
#include <rpc/rpc.h>
#include <rpcsvc/yp.h>
@@ -32,6 +33,7 @@
#include <asr.h>
#include <err.h>
#include <errno.h>
+#include <ifaddrs.h>
#include <resolv.h> /* for res_hnok */
#include <stdlib.h>
#include <string.h>
@@ -104,6 +106,7 @@ getaddrinfo_async(const char *hostname, const char *servname,
else {
memset(&as->as.ai.hints, 0, sizeof as->as.ai.hints);
as->as.ai.hints.ai_family = PF_UNSPEC;
+ as->as.ai.hints.ai_flags = AI_ADDRCONFIG;
}
asr_ctx_unref(ac);
@@ -127,8 +130,9 @@ getaddrinfo_async_run(struct asr_query *as, struct asr_result *ar)
char fqdn[MAXDNAME];
const char *str;
struct addrinfo *ai;
- int i, family, r;
+ int i, family, r, v4, v6;
FILE *f;
+ struct ifaddrs *ifa, *ifa0;
union {
struct sockaddr sa;
struct sockaddr_in sain;
@@ -195,6 +199,39 @@ getaddrinfo_async_run(struct asr_query *as, struct asr_result *ar)
break;
}
+ /* Restrict result set to configured address families */
+ if (ai->ai_flags & AI_ADDRCONFIG) {
+ if (getifaddrs(&ifa0) != 0) {
+ ar->ar_gai_errno = EAI_FAIL;
+ async_set_state(as, ASR_STATE_HALT);
+ break;
+ }
+ v4 = 0;
+ v6 = 0;
+ for (ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next) {
+ if (ifa->ifa_flags & IFF_LOOPBACK)
+ continue;
+ if (ifa->ifa_addr->sa_family == PF_INET)
+ v4 = 1;
+ else if (ifa->ifa_addr->sa_family == PF_INET6 &&
+ !IN6_IS_ADDR_LINKLOCAL(&((struct
+ sockaddr_in6 *)ifa->ifa_addr)->sin6_addr))
+ v6 = 1;
+ }
+ freeifaddrs(ifa0);
+ if (ai->ai_family == PF_UNSPEC && !v4 && !v6 ||
+ ai->ai_family == PF_INET && !v4 ||
+ ai->ai_family == PF_INET6 && !v6) {
+ ar->ar_gai_errno = EAI_NONAME;
+ async_set_state(as, ASR_STATE_HALT);
+ break;
+ }
+ if (ai->ai_family == PF_UNSPEC && v4 && !v6)
+ ai->ai_family = PF_INET;
+ if (ai->ai_family == PF_UNSPEC && !v4 && v6)
+ ai->ai_family = PF_INET6;
+ }
+
/* Make sure there is at least a valid combination */
for (i = 0; matches[i].family != -1; i++)
if (MATCH_FAMILY(ai->ai_family, i) &&
diff --git a/lib/libc/net/getaddrinfo.3 b/lib/libc/net/getaddrinfo.3
index db4417ab358..33270dbdf67 100644
--- a/lib/libc/net/getaddrinfo.3
+++ b/lib/libc/net/getaddrinfo.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: getaddrinfo.3,v 1.54 2014/01/21 03:15:45 schwarze Exp $
+.\" $OpenBSD: getaddrinfo.3,v 1.55 2014/04/28 21:38:59 sperreault Exp $
.\" $KAME: getaddrinfo.3,v 1.36 2005/01/05 03:23:05 itojun Exp $
.\"
.\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
@@ -16,7 +16,7 @@
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
.\" PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: January 21 2014 $
+.Dd $Mdocdate: April 28 2014 $
.Dt GETADDRINFO 3
.Os
.Sh NAME
@@ -120,6 +120,14 @@ is formed by
.Tn OR Ns 'ing
the following values:
.Bl -tag -width "AI_CANONNAMEXX"
+.It Dv AI_ADDRCONFIG
+If the
+.Dv AI_ADDRCONFIG
+bit is set, IPv4 addresses will be returned only if an IPv4 address is
+configured on an interface, and IPv6 addresses will be returned only if an IPv6
+address is configured on an interface.
+Addresses on a loopback interface and link-local IPv6 addresses are not
+considered valid as configured addresses.
.It Dv AI_CANONNAME
If the
.Dv AI_CANONNAME
@@ -219,7 +227,10 @@ behaves as if the caller provided a
with
.Fa ai_family
set to
-.Dv PF_UNSPEC
+.Dv PF_UNSPEC ,
+.Fa ai_flags
+set to
+.Dv AI_ADDRCONFIG ,
and all other elements set to zero or
.Dv NULL .
.Pp