Unify DNS error codes reporting to the metrics
gethostbyname and getaddrinfo have their own error codes. Unify
these error codes to be POSIX EAI_*. This change is for better
and even more detailed DNS metrics, and will not impact on
applications.
Also clean up no-op code:
- res_put_state
Bug: 113916551
Test: system/netd/tests/runtests.sh passed
Change-Id: Id4bbabc8d4dd5f2fdc8fabd38dab753cbb07d691
diff --git a/resolv/gethnamaddr.cpp b/resolv/gethnamaddr.cpp
index 834a962..b36f5c8 100644
--- a/resolv/gethnamaddr.cpp
+++ b/resolv/gethnamaddr.cpp
@@ -137,10 +137,13 @@
static bool _dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
const android_net_context* netcontext, getnamaddr* info);
-static bool _dns_gethtbyname(const char* name, int af, getnamaddr* info);
+static int _dns_gethtbyname(const char* name, int af, getnamaddr* info);
-static struct hostent* gethostbyname_internal(const char*, int, res_state, struct hostent*, char*,
- size_t, int*, const struct android_net_context*);
+static int gethostbyname_internal(const char* name, int af, res_state res, hostent* hp, char* hbuf,
+ size_t hbuflen, int* errorp,
+ const android_net_context* netcontext);
+static int gethostbyname_internal_real(const char* name, int af, res_state res, hostent* hp,
+ char* buf, size_t buflen, int* he);
static struct hostent* android_gethostbyaddrfornetcontext_proxy_internal(
const void*, socklen_t, int, struct hostent*, char*, size_t, int*,
const struct android_net_context*);
@@ -466,10 +469,9 @@
return NULL;
}
-static struct hostent* gethostbyname_internal_real(const char* name, int af, res_state res,
- struct hostent* hp, char* buf, size_t buflen,
- int* he) {
- struct getnamaddr info;
+static int gethostbyname_internal_real(const char* name, int af, res_state res, hostent* hp,
+ char* buf, size_t buflen, int* he) {
+ getnamaddr info;
size_t size;
_DIAGASSERT(name != NULL);
@@ -484,7 +486,7 @@
default:
*he = NETDB_INTERNAL;
errno = EAFNOSUPPORT;
- return NULL;
+ return EAI_FAMILY;
}
if (buflen < size) goto nospc;
@@ -530,16 +532,18 @@
info.buflen = buflen;
info.he = he;
if (!_hf_gethtbyname2(name, af, &info)) {
- if (!_dns_gethtbyname(name, af, &info)) {
- return NULL;
+ int error = _dns_gethtbyname(name, af, &info);
+ if (error != 0) {
+ return error;
}
}
*he = NETDB_SUCCESS;
- return hp;
+ return 0;
nospc:
*he = NETDB_INTERNAL;
errno = ENOSPC;
- return NULL;
+ // Bad arguments
+ return EAI_FAIL;
fake:
HENT_ARRAY(hp->h_addr_list, 1, buf, buflen);
HENT_ARRAY(hp->h_aliases, 0, buf, buflen);
@@ -549,7 +553,7 @@
if (inet_pton(af, name, buf) <= 0) {
*he = HOST_NOT_FOUND;
- return NULL;
+ return EAI_NODATA;
}
hp->h_addr_list[0] = buf;
hp->h_addr_list[1] = NULL;
@@ -558,14 +562,13 @@
HENT_SCOPY(hp->h_name, name, buf, buflen);
if (res->options & RES_USE_INET6) map_v4v6_hostent(hp, &buf, buf + buflen);
*he = NETDB_SUCCESS;
- return hp;
+ return 0;
}
// very similar in proxy-ness to android_getaddrinfo_proxy
-static struct hostent* gethostbyname_internal(const char* name, int af, res_state res,
- struct hostent* hp, char* hbuf, size_t hbuflen,
- int* errorp,
- const struct android_net_context* netcontext) {
+static int gethostbyname_internal(const char* name, int af, res_state res, hostent* hp, char* hbuf,
+ size_t hbuflen, int* errorp,
+ const android_net_context* netcontext) {
res_setnetcontext(res, netcontext);
return gethostbyname_internal_real(name, af, res, hp, hbuf, hbuflen, errorp);
}
@@ -691,7 +694,6 @@
af = AF_INET;
len = NS_INADDRSZ;
}
- res_put_state(res);
}
/* if this is not something we're looking for, skip it. */
@@ -841,7 +843,7 @@
}
}
-static bool _dns_gethtbyname(const char* name, int addr_type, getnamaddr* info) {
+static int _dns_gethtbyname(const char* name, int addr_type, getnamaddr* info) {
int n, type;
struct hostent* hp;
res_state res;
@@ -858,32 +860,37 @@
type = T_AAAA;
break;
default:
- return false;
+ return EAI_FAMILY;
}
querybuf* buf = (querybuf*) malloc(sizeof(querybuf));
if (buf == NULL) {
*info->he = NETDB_INTERNAL;
- return false;
+ return EAI_MEMORY;
}
res = res_get_state();
if (res == NULL) {
free(buf);
- return false;
+ return EAI_MEMORY;
}
n = res_nsearch(res, name, C_IN, type, buf->buf, (int) sizeof(buf->buf));
if (n < 0) {
free(buf);
debugprintf("res_nsearch failed (%d)\n", res, n);
- res_put_state(res);
- return false;
+ return EAI_NODATA;
}
hp = getanswer(buf, n, name, type, res, info->hp, info->buf, info->buflen, info->he);
free(buf);
- res_put_state(res);
if (hp == NULL) {
- return false;
+ switch (h_errno) {
+ case HOST_NOT_FOUND:
+ return EAI_NODATA;
+ case TRY_AGAIN:
+ return EAI_AGAIN;
+ default:
+ return EAI_FAIL;
+ }
}
- return true;
+ return 0;
}
static bool _dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
@@ -940,13 +947,11 @@
if (n < 0) {
free(buf);
debugprintf("res_nquery failed (%d)\n", res, n);
- res_put_state(res);
return false;
}
hp = getanswer(buf, n, qbuf, T_PTR, res, info->hp, info->buf, info->buflen, info->he);
free(buf);
if (hp == NULL) {
- res_put_state(res);
return false;
}
@@ -970,7 +975,6 @@
memcpy(bf + NS_INADDRSZ, NAT64_PAD, sizeof(NAT64_PAD));
}
- res_put_state(res);
*info->he = NETDB_SUCCESS;
return true;
@@ -984,16 +988,18 @@
* Non-reentrant versions.
*/
-struct hostent* android_gethostbynamefornetcontext(const char* name, int af,
- const struct android_net_context* netcontext) {
- struct hostent* hp;
+int android_gethostbynamefornetcontext(const char* name, int af,
+ const struct android_net_context* netcontext, hostent** hp) {
+ int error;
res_state res = res_get_state();
- if (res == NULL) return NULL;
- struct res_static* rs = res_get_static(); // For thread-safety.
- hp = gethostbyname_internal(name, af, res, &rs->host, rs->hostbuf, sizeof(rs->hostbuf),
- &h_errno, netcontext);
- res_put_state(res);
- return hp;
+ if (res == NULL) return EAI_MEMORY;
+ res_static* rs = res_get_static(); // For thread-safety.
+ error = gethostbyname_internal(name, af, res, &rs->host, rs->hostbuf, sizeof(rs->hostbuf),
+ &h_errno, netcontext);
+ if (error == 0) {
+ *hp = &rs->host;
+ }
+ return error;
}
struct hostent* android_gethostbyaddrfornetcontext(const void* addr, socklen_t len, int af,