When trying to resolve a hostname by getaddrinfo() using some specific
settings, it will always return -EAI_NONAME (Name or service not known).
To reproduce this behavior, you need to request an IPv6 address with
the additional v4mapped flag set from an non IPv6 capable hostname. If
you choose a IPv6 capable hostname like
google.com, everything works fine.
To go a bit deeper, e.g. gethostbyname2_r will always return HOST_NOT_FOUND,
which in our example is wrong. The hostname is existent but doesn't provide
an IPv6 address. So NO_DATA would be correct, which is present in the h_errno
variable set by __dns_lookup.
---- 8< ----
int ret;
struct addrinfo* result;
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET6;
hints.ai_flags = AI_V4MAPPED;
ret = getaddrinfo("test.com", NULL, &hints, &result);
printf("getaddrinfo(): %i", ret);
---- 8< ----
Signed-off-by: Alexander Wenzel <alexander.wenzel(a)qsc.de>
---
libc/inet/resolv.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index e3ad513..176fd78 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -2118,7 +2118,7 @@ int gethostbyname_r(const char *name,
a.add_count = 0;
packet_len = __dns_lookup(name, T_A, &packet, &a);
if (packet_len < 0) {
- *h_errnop = HOST_NOT_FOUND;
+ *h_errnop = h_errno;
DPRINTF("__dns_lookup returned < 0\n");
return TRY_AGAIN;
}
@@ -2316,7 +2316,7 @@ int gethostbyname2_r(const char *name,
a.add_count = 0;
packet_len = __dns_lookup(name, T_AAAA, &packet, &a);
if (packet_len < 0) {
- *h_errnop = HOST_NOT_FOUND;
+ *h_errnop = h_errno;
DPRINTF("__dns_lookup returned < 0\n");
return TRY_AGAIN;
}
@@ -2504,7 +2504,7 @@ int gethostbyaddr_r(const void *addr, socklen_t addrlen,
/* Hmm why we memset(a) to zeros only once? */
packet_len = __dns_lookup(buf, T_PTR, &packet, &a);
if (packet_len < 0) {
- *h_errnop = HOST_NOT_FOUND;
+ *h_errnop = h_errno;
return TRY_AGAIN;
}
--
2.1.4