SHA256
1
0
forked from pool/glibc
glibc/getaddrinfo-ipv6-sanity.diff

48 lines
1.8 KiB
Diff

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 1a023f9..c8af8b9 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -269,7 +269,7 @@ extern service_user *__nss_hosts_database attribute_hidden;
static int
gaih_inet (const char *name, const struct gaih_service *service,
const struct addrinfo *req, struct addrinfo **pai,
- unsigned int *naddrs)
+ unsigned int *naddrs, bool usable_ipv6)
{
const struct gaih_typeproto *tp = gaih_inet_typeproto;
struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
@@ -832,7 +832,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
no_data = 0;
nss_gethostbyname4_r fct4
= __nss_lookup_function (nip, "gethostbyname4_r");
- if (fct4 != NULL)
+ /* If we don't want ipv6, don't use gethostbyname4_r,
+ as it's using T_UNSPEC to libc_res_nsearch, which always
+ create T_A and T_AAAA queries. */
+ if (usable_ipv6 && fct4 != NULL)
{
int herrno;
@@ -935,7 +938,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
if (fct != NULL)
{
if (req->ai_family == AF_INET6
- || req->ai_family == AF_UNSPEC)
+ || (req->ai_family == AF_UNSPEC && usable_ipv6))
{
gethosts (AF_INET6, struct in6_addr);
no_inet6_data = no_data;
@@ -2418,7 +2421,11 @@ getaddrinfo (const char *name, const char *service,
if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
|| hints->ai_family == AF_INET6)
{
- last_i = gaih_inet (name, pservice, hints, end, &naddrs);
+ if (!check_pf_called)
+ __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
+ check_pf_called = true;
+
+ last_i = gaih_inet (name, pservice, hints, end, &naddrs, seen_ipv6);
if (last_i != 0)
{
freeaddrinfo (p);