Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 660514 Details for
Bug 721350
getaddrinfo ("127.0.0.1") and/or getaddrinfo ("::1) may fail with AI_ADDRCONFIG
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Proposed solution 1B
glibc-improve-addrconfig.patch (text/plain), 6.50 KB, created by
Tore Anderson
on 2012-12-09 23:48:22 UTC
(
hide
)
Description:
Proposed solution 1B
Filename:
MIME Type:
Creator:
Tore Anderson
Created:
2012-12-09 23:48:22 UTC
Size:
6.50 KB
patch
obsolete
>diff -ru glibc-2.16.90-67cbf9a2.orig/sysdeps/posix/getaddrinfo.c glibc-2.16.90-67cbf9a2/sysdeps/posix/getaddrinfo.c >--- glibc-2.16.90-67cbf9a2.orig/sysdeps/posix/getaddrinfo.c 2012-12-07 21:55:19.000000000 +0000 >+++ glibc-2.16.90-67cbf9a2/sysdeps/posix/getaddrinfo.c 2012-12-09 23:24:47.615410906 +0000 >@@ -829,14 +829,47 @@ > } > } > >+ /* AI_ADDRCONFIG determines whether or not we should suppress any >+ * hostname lookups. If the local host has only IPv4 interfaces, >+ * then suppress lookups for IPv6 addresses, and vice versa; if >+ * the local host has only IPv6 interfaces, suppress any lookups >+ * for IPv4 addresses.. >+ * >+ * Link-local IPv6 addresses and loopback addresses of either >+ * family are ignored when determining whether or not the host has >+ * an interface of the given address family, cf. __check_pf(). >+ * >+ * This logic is only applied for AF_UNSPEC. If the caller >+ * explicitly requested an address family, give him what he asked >+ * for. >+ * >+ * If we didn't find any interfaces of either address family, >+ * we ignore AI_ADDRCONFIG and return all available resutlts. */ >+ int suppress_af = 0; >+ if (req->ai_family == AF_UNSPEC && req->ai_flags & AI_ADDRCONFIG) >+ { >+ struct in6addrinfo *in6ai = NULL; >+ size_t in6ailen = 0; >+ bool seen_ipv4 = false; >+ bool seen_ipv6 = false; >+ __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); >+ __free_in6ai (in6ai); >+ >+ if(seen_ipv4 && !seen_ipv6) >+ suppress_af = AF_INET6; >+ else if(seen_ipv6 && !seen_ipv4) >+ suppress_af = AF_INET; >+ } >+ > while (!no_more) > { > no_data = 0; > nss_gethostbyname4_r fct4 = NULL; > > /* gethostbyname4_r sends out parallel A and AAAA queries and >- is thus only suitable for PF_UNSPEC. */ >- if (req->ai_family == PF_UNSPEC) >+ is thus only suitable for PF_UNSPEC, and only if we're not >+ suppressing lookups for IPv4 or IPv6 addresses. */ >+ if (req->ai_family == PF_UNSPEC && !suppress_af) > fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); > > if (fct4 != NULL) >@@ -941,20 +974,22 @@ > > if (fct != NULL) > { >- if (req->ai_family == AF_INET6 >- || req->ai_family == AF_UNSPEC) >+ if ((req->ai_family == AF_INET6 >+ || req->ai_family == AF_UNSPEC) >+ && suppress_af != AF_INET6) > { > gethosts (AF_INET6, struct in6_addr); > no_inet6_data = no_data; > inet6_status = status; > } >- if (req->ai_family == AF_INET >- || req->ai_family == AF_UNSPEC >- || (req->ai_family == AF_INET6 >- && (req->ai_flags & AI_V4MAPPED) >- /* Avoid generating the mapped addresses if we >- know we are not going to need them. */ >- && ((req->ai_flags & AI_ALL) || !got_ipv6))) >+ if ((req->ai_family == AF_INET >+ || req->ai_family == AF_UNSPEC >+ || (req->ai_family == AF_INET6 >+ && (req->ai_flags & AI_V4MAPPED) >+ /* Avoid generating the mapped addresses if we >+ know we are not going to need them. */ >+ && ((req->ai_flags & AI_ALL) || !got_ipv6))) >+ && suppress_af != AF_INET) > { > gethosts (AF_INET, struct in_addr); > >@@ -2373,7 +2408,6 @@ > int nresults = 0; > struct addrinfo *p = NULL; > struct gaih_service gaih_service, *pservice; >- struct addrinfo local_hints; > > if (name != NULL && name[0] == '*' && name[1] == 0) > name = NULL; >@@ -2399,42 +2433,6 @@ > if ((hints->ai_flags & AI_CANONNAME) && name == NULL) > return EAI_BADFLAGS; > >- struct in6addrinfo *in6ai = NULL; >- size_t in6ailen = 0; >- bool seen_ipv4 = false; >- bool seen_ipv6 = false; >- bool check_pf_called = false; >- >- if (hints->ai_flags & AI_ADDRCONFIG) >- { >- /* We might need information about what interfaces are available. >- Also determine whether we have IPv4 or IPv6 interfaces or both. We >- cannot cache the results since new interfaces could be added at >- any time. */ >- __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); >- check_pf_called = true; >- >- /* Now make a decision on what we return, if anything. */ >- if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6)) >- { >- /* If we haven't seen both IPv4 and IPv6 interfaces we can >- narrow down the search. */ >- if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6)) >- { >- local_hints = *hints; >- local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6; >- hints = &local_hints; >- } >- } >- else if ((hints->ai_family == PF_INET && ! seen_ipv4) >- || (hints->ai_family == PF_INET6 && ! seen_ipv6)) >- { >- /* We cannot possibly return a valid answer. */ >- __free_in6ai (in6ai); >- return EAI_NONAME; >- } >- } >- > if (service && service[0]) > { > char *c; >@@ -2443,10 +2441,7 @@ > if (*c != '\0') > { > if (hints->ai_flags & AI_NUMERICSERV) >- { >- __free_in6ai (in6ai); > return EAI_NONAME; >- } > > gaih_service.num = -1; > } >@@ -2466,7 +2461,6 @@ > if (last_i != 0) > { > freeaddrinfo (p); >- __free_in6ai (in6ai); > > return -(last_i & GAIH_EAI); > } >@@ -2477,10 +2471,7 @@ > } > } > else >- { >- __free_in6ai (in6ai); > return EAI_FAMILY; >- } > > if (naddrs > 1) > { >@@ -2495,9 +2486,12 @@ > struct addrinfo *last = NULL; > char *canonname = NULL; > >- /* Now we definitely need the interface information. */ >- if (! check_pf_called) >- __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); >+ /* Now we need the interface information. */ >+ struct in6addrinfo *in6ai = NULL; >+ size_t in6ailen = 0; >+ bool seen_ipv4 = false; >+ bool seen_ipv6 = false; >+ __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen); > > /* If we have information about deprecated and temporary addresses > sort the array now. */ >@@ -2664,9 +2658,9 @@ > > /* Fill in the canonical name into the new first entry. */ > p->ai_canonname = canonname; >- } > >- __free_in6ai (in6ai); >+ __free_in6ai (in6ai); >+ } > > if (p) > { >diff -ru glibc-2.16.90-67cbf9a2.orig/sysdeps/unix/sysv/linux/check_pf.c glibc-2.16.90-67cbf9a2/sysdeps/unix/sysv/linux/check_pf.c >--- glibc-2.16.90-67cbf9a2.orig/sysdeps/unix/sysv/linux/check_pf.c 2012-12-07 21:55:19.000000000 +0000 >+++ glibc-2.16.90-67cbf9a2/sysdeps/unix/sysv/linux/check_pf.c 2012-12-09 11:50:36.176246801 +0000 >@@ -233,7 +233,8 @@ > } > else > { >- if (!IN6_IS_ADDR_LOOPBACK (address)) >+ if (!IN6_IS_ADDR_LOOPBACK (address) && >+ !IN6_IS_ADDR_LINKLOCAL (address)) > seen_ipv6 = true; > } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 721350
:
512857
|
513595
| 660514