diff options
author | Ulrich Drepper <drepper@gmail.com> | 2011-06-21 17:03:38 -0400 |
---|---|---|
committer | Ulrich Drepper <drepper@gmail.com> | 2011-06-21 17:03:38 -0400 |
commit | c0244a9dedce43a4b950d91451b16a7cf5408476 (patch) | |
tree | 49e776a11f30fbe72341d873f071145983701c2d | |
parent | c5e3c2ae59cc8c5d3ad5e1adfd099c726baad862 (diff) | |
download | glibc-c0244a9dedce43a4b950d91451b16a7cf5408476.tar.gz glibc-c0244a9dedce43a4b950d91451b16a7cf5408476.tar.xz glibc-c0244a9dedce43a4b950d91451b16a7cf5408476.zip |
Fix IPv6-only lookups through getaddrinfo
A recent patch introduced a problem where IPv6 lookups happily returned IPv4 addresses.
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | sysdeps/posix/getaddrinfo.c | 34 |
3 files changed, 40 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog index 19807a9150..abc4894493 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2011-06-21 Ulrich Drepper <drepper@gmail.com> + [BZ #12885] + * sysdeps/posix/getaddrinfo.c (gaih_inet): When looking up only IPv6 + addresses using gethostbyname4_r ignore IPv4 addresses. + * sysdeps/posix/getaddrinfo.c (gaih_inet): After the last change the branch using gethostbyname2 is only for AF_INET. Optimize accordingly. diff --git a/NEWS b/NEWS index dd00b7b93c..9e6832c167 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -GNU C Library NEWS -- history of user-visible changes. 2011-6-15 +GNU C Library NEWS -- history of user-visible changes. 2011-6-21 Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc. See the end for copying conditions. @@ -7,6 +7,10 @@ using `glibc' in the "product" field. Version 2.15 +* The following bugs are resolved with this release: + + 12885 + * New program pldd to list loaded object of a process Implemented by Ulrich Drepper. diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index d68ac839a5..3a2737e2cb 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -871,16 +871,44 @@ gaih_inet (const char *name, const struct gaih_service *service, } } - no_inet6_data = no_data; - if (status == NSS_STATUS_SUCCESS) { + assert (!no_data); + no_data = 1; + if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL) canon = (*pat)->name; while (*pat != NULL) - pat = &((*pat)->next); + { + if ((*pat)->family == AF_INET + && req->ai_family == AF_INET6 + && (req->ai_flags & AI_V4MAPPED) != 0) + { + uint32_t *pataddr = (*pat)->addr; + (*pat)->family = AF_INET6; + pataddr[3] = pataddr[0]; + pataddr[2] = htonl (0xffff); + pataddr[1] = 0; + pataddr[0] = 0; + pat = &((*pat)->next); + no_data = 0; + } + else if ((*pat)->family == AF_UNSPEC + || (*pat)->family == req->ai_family) + { + pat = &((*pat)->next); + + no_data = 0; + if (req->ai_family == AF_INET6) + got_ipv6 = true; + } + else + *pat = ((*pat)->next); + } } + + no_inet6_data = no_data; } else { |