diff options
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/asr/getaddrinfo_async.c | 41 | ||||
-rw-r--r-- | lib/libc/net/getaddrinfo.3 | 17 |
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 |