From 0b592a30f5e3133bde98551fd524085359c3177a Mon Sep 17 00:00:00 2001 From: Maciej Babinski Date: Mon, 2 May 2011 21:11:17 -0400 Subject: [PATCH] getaddrinfo(AF_INET6) does not return scope_id info provided by NSS modules --- ChangeLog | 6 +++ NEWS | 2 +- sysdeps/posix/getaddrinfo.c | 73 ++++++++++++++----------------------- 3 files changed, 35 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3840eeb9b3..bd08c7d983 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-04-28 Maciej Babinski + + [BZ #12714] + * sysdeps/posix/getaddrinfo.c (gaih_inet): Don't bypass + gethostbyname4_r when IPv6 results are possible. + 2011-05-02 Ulrich Drepper [BZ #12723] diff --git a/NEWS b/NEWS index d30a8a97b7..2750e852d6 100644 --- a/NEWS +++ b/NEWS @@ -19,7 +19,7 @@ Version 2.14 * The following bugs are resolved with this release: 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 diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index c61c72a24a..7bd89c45c0 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -510,12 +510,10 @@ gaih_inet (const char *name, const struct gaih_service *service, int no_more; int old_res_options; - /* If we do not have to look for IPv4 and IPv6 together, use - the simple, old functions. */ - if (req->ai_family == AF_INET - || (req->ai_family == AF_INET6 - && ((req->ai_flags & AI_V4MAPPED) == 0 - || (req->ai_flags & AI_ALL) == 0))) + /* If we do not have to look for IPv6 addresses, use + the simple, old functions, which do not support + IPv6 scope ids. */ + if (req->ai_family == AF_INET) { int family = req->ai_family; size_t tmpbuflen = 512; @@ -525,7 +523,6 @@ gaih_inet (const char *name, const struct gaih_service *service, struct hostent *h; int herrno; - simple_again: while (1) { 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 (h == NULL) - { - if (req->ai_family == AF_INET6 - && (req->ai_flags & AI_V4MAPPED) - && family == AF_INET6) - { - /* Try again, this time looking for IPv4 - addresses. */ - family = AF_INET; - goto simple_again; - } - } - else - { - /* We found data, now convert it into the list. */ - for (int i = 0; h->h_addr_list[i]; ++i) - { - if (*pat == NULL) - { - *pat = __alloca (sizeof (struct gaih_addrtuple)); - (*pat)->scopeid = 0; - } - (*pat)->next = NULL; - (*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); - } - } + if (h != NULL) + /* We found data, now convert it into the list. */ + for (int i = 0; h->h_addr_list[i]; ++i) + { + if (*pat == NULL) + { + *pat = __alloca (sizeof (struct gaih_addrtuple)); + (*pat)->scopeid = 0; + } + (*pat)->next = NULL; + (*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 {