getaddrinfo(AF_INET6) does not return scope_id info provided by NSS modules

This commit is contained in:
Maciej Babinski 2011-05-02 21:11:17 -04:00 committed by Ulrich Drepper
parent 6e04cbbe79
commit 0b592a30f5
3 changed files with 35 additions and 46 deletions

View File

@ -1,3 +1,9 @@
2011-04-28 Maciej Babinski <mbabinski@google.com>
[BZ #12714]
* sysdeps/posix/getaddrinfo.c (gaih_inet): Don't bypass
gethostbyname4_r when IPv6 results are possible.
2011-05-02 Ulrich Drepper <drepper@gmail.com> 2011-05-02 Ulrich Drepper <drepper@gmail.com>
[BZ #12723] [BZ #12723]

2
NEWS
View File

@ -19,7 +19,7 @@ Version 2.14
* The following bugs are resolved with this release: * The following bugs are resolved with this release:
11724, 12420, 12445, 12454, 12460, 12469, 12489, 12509, 12510, 12518, 12583, 11724, 12420, 12445, 12454, 12460, 12469, 12489, 12509, 12510, 12518, 12583,
12587, 12597, 12631, 12650, 12653, 12655, 12685, 12717, 12723 12587, 12597, 12631, 12650, 12653, 12655, 12685, 12714, 12717, 12723
Version 2.13 Version 2.13

View File

@ -510,12 +510,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
int no_more; int no_more;
int old_res_options; int old_res_options;
/* If we do not have to look for IPv4 and IPv6 together, use /* If we do not have to look for IPv6 addresses, use
the simple, old functions. */ the simple, old functions, which do not support
if (req->ai_family == AF_INET IPv6 scope ids. */
|| (req->ai_family == AF_INET6 if (req->ai_family == AF_INET)
&& ((req->ai_flags & AI_V4MAPPED) == 0
|| (req->ai_flags & AI_ALL) == 0)))
{ {
int family = req->ai_family; int family = req->ai_family;
size_t tmpbuflen = 512; size_t tmpbuflen = 512;
@ -525,7 +523,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
struct hostent *h; struct hostent *h;
int herrno; int herrno;
simple_again:
while (1) while (1)
{ {
rc = __gethostbyname2_r (name, family, &th, tmpbuf, rc = __gethostbyname2_r (name, family, &th, tmpbuf,
@ -537,44 +534,30 @@ gaih_inet (const char *name, const struct gaih_service *service,
if (rc == 0) if (rc == 0)
{ {
if (h == NULL) if (h != NULL)
{ /* We found data, now convert it into the list. */
if (req->ai_family == AF_INET6 for (int i = 0; h->h_addr_list[i]; ++i)
&& (req->ai_flags & AI_V4MAPPED) {
&& family == AF_INET6) if (*pat == NULL)
{ {
/* Try again, this time looking for IPv4 *pat = __alloca (sizeof (struct gaih_addrtuple));
addresses. */ (*pat)->scopeid = 0;
family = AF_INET; }
goto simple_again; (*pat)->next = NULL;
} (*pat)->family = req->ai_family;
} if (family == req->ai_family)
else memcpy ((*pat)->addr, h->h_addr_list[i],
{ h->h_length);
/* We found data, now convert it into the list. */ else
for (int i = 0; h->h_addr_list[i]; ++i) {
{ uint32_t *addr = (uint32_t *) (*pat)->addr;
if (*pat == NULL) addr[3] = *(uint32_t *) h->h_addr_list[i];
{ addr[2] = htonl (0xffff);
*pat = __alloca (sizeof (struct gaih_addrtuple)); addr[1] = 0;
(*pat)->scopeid = 0; addr[0] = 0;
} }
(*pat)->next = NULL; pat = &((*pat)->next);
(*pat)->family = req->ai_family; }
if (family == req->ai_family)
memcpy ((*pat)->addr, h->h_addr_list[i],
h->h_length);
else
{
uint32_t *addr = (uint32_t *) (*pat)->addr;
addr[3] = *(uint32_t *) h->h_addr_list[i];
addr[2] = htonl (0xffff);
addr[1] = 0;
addr[0] = 0;
}
pat = &((*pat)->next);
}
}
} }
else else
{ {