aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2018-09-19 18:03:22 -0400
committerRich Felker <dalias@aerifal.cx>2018-09-19 18:03:22 -0400
commitf381c118b2d4f7d914481d3cdc830ce41369b002 (patch)
tree2e0390caf1f9020eef4bad24ef06a47952cd37ec /src
parentdffc20591873ede1ec4b30634fc91ba3daa372eb (diff)
downloadmusl-f381c118b2d4f7d914481d3cdc830ce41369b002.zip
musl-f381c118b2d4f7d914481d3cdc830ce41369b002.tar.gz
musl-f381c118b2d4f7d914481d3cdc830ce41369b002.tar.bz2
fix getaddrinfo regression with AI_ADDRCONFIG on some configurations
despite not being documented to do so in the standard or Linux documentation, attempts to udp connect to 127.0.0.1 or ::1 generate EADDRNOTAVAIL when the loopback device is not configured and there is no default route for IPv6. this caused getaddrinfo with AI_ADDRCONFIG to fail with EAI_SYSTEM and EADDRNOTAVAIL on some no-IPv6 configurations, rather than the intended behavior of detecting IPv6 as unsuppported and producing IPv4-only results. previously, only EAFNOSUPPORT was treated as unavailability of the address family being probed. instead, treat all errors related to inability to get an address or route as conclusive that the family being probed is unsupported, and only fail with EAI_SYSTEM on other errors. further improvements may be desirable, such as reporting EAI_AGAIN instead of EAI_SYSTEM for errors which are expected to be transient, but this patch should suffice to fix the serious regression.
Diffstat (limited to 'src')
-rw-r--r--src/network/getaddrinfo.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c
index ba26847..e33bfa2 100644
--- a/src/network/getaddrinfo.c
+++ b/src/network/getaddrinfo.c
@@ -76,7 +76,16 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru
close(s);
if (!r) continue;
}
- if (errno != EAFNOSUPPORT) return EAI_SYSTEM;
+ switch (errno) {
+ case EADDRNOTAVAIL:
+ case EAFNOSUPPORT:
+ case EHOSTUNREACH:
+ case ENETDOWN:
+ case ENETUNREACH:
+ break;
+ default:
+ return EAI_SYSTEM;
+ }
if (family == tf[i]) return EAI_NONAME;
family = tf[1-i];
}