Use unique_ptr in dns_getaddrinfo()
This simplifies memory management a bit. In fact, we don't even bother
checking for memory allocation failures because 'new' aborts instead of
returning null to the caller.
Test: atest resolv_integration_test
Change-Id: I6456922f4ca6d04d67fedc8873b0c32becf1d3dc
diff --git a/resolv/getaddrinfo.cpp b/resolv/getaddrinfo.cpp
index 5e9d821..0a657df 100644
--- a/resolv/getaddrinfo.cpp
+++ b/resolv/getaddrinfo.cpp
@@ -233,7 +233,7 @@
* on the local system". However, bionic doesn't currently support getifaddrs,
* so checking for connectivity is the next best thing.
*/
-static int _have_ipv6(unsigned mark, uid_t uid) {
+static int have_ipv6(unsigned mark, uid_t uid) {
static const struct sockaddr_in6 sin6_test = {
.sin6_family = AF_INET6,
.sin6_addr.s6_addr = {// 2000::
@@ -242,7 +242,7 @@
return _find_src_addr(&addr.sa, NULL, mark, uid) == 1;
}
-static int _have_ipv4(unsigned mark, uid_t uid) {
+static int have_ipv4(unsigned mark, uid_t uid) {
static const struct sockaddr_in sin_test = {
.sin_family = AF_INET,
.sin_addr.s_addr = __constant_htonl(0x08080808L) // 8.8.8.8
@@ -425,7 +425,7 @@
if (error) {
freeaddrinfo(sentinel.ai_next);
- *res = NULL;
+ *res = nullptr;
} else {
*res = sentinel.ai_next;
}
@@ -1375,24 +1375,11 @@
static int dns_getaddrinfo(const char* name, const addrinfo* pai,
const android_net_context* netcontext, addrinfo** rv) {
- struct addrinfo *ai, *cur;
- struct addrinfo sentinel = {};
- struct res_target q, q2;
- res_state res;
+ res_target q = {};
+ res_target q2 = {};
- memset(&q, 0, sizeof(q));
- memset(&q2, 0, sizeof(q2));
- cur = &sentinel;
-
- querybuf* buf = (querybuf*) malloc(sizeof(*buf));
- if (buf == NULL) {
- return EAI_MEMORY;
- }
- querybuf* buf2 = (querybuf*) malloc(sizeof(*buf2));
- if (buf2 == NULL) {
- free(buf);
- return EAI_MEMORY;
- }
+ auto buf = std::make_unique<querybuf>();
+ auto buf2 = std::make_unique<querybuf>();
switch (pai->ai_family) {
case AF_UNSPEC: {
@@ -1403,8 +1390,8 @@
q.anslen = sizeof(buf->buf);
int query_ipv6 = 1, query_ipv4 = 1;
if (pai->ai_flags & AI_ADDRCONFIG) {
- query_ipv6 = _have_ipv6(netcontext->app_mark, netcontext->uid);
- query_ipv4 = _have_ipv4(netcontext->app_mark, netcontext->uid);
+ query_ipv6 = have_ipv6(netcontext->app_mark, netcontext->uid);
+ query_ipv4 = have_ipv4(netcontext->app_mark, netcontext->uid);
}
if (query_ipv6) {
q.qtype = T_AAAA;
@@ -1419,8 +1406,6 @@
} else if (query_ipv4) {
q.qtype = T_A;
} else {
- free(buf);
- free(buf2);
return EAI_NODATA;
}
break;
@@ -1440,17 +1425,11 @@
q.anslen = sizeof(buf->buf);
break;
default:
- free(buf);
- free(buf2);
return EAI_FAMILY;
}
- res = res_get_state();
- if (res == NULL) {
- free(buf);
- free(buf2);
- return EAI_MEMORY;
- }
+ res_state res = res_get_state();
+ if (!res) return EAI_MEMORY;
/* this just sets our netid val in the thread private data so we don't have to
* modify the api's all the way down to res_send.c's res_nsend. We could
@@ -1461,22 +1440,21 @@
int herrno = NETDB_INTERNAL;
if (res_searchN(name, &q, res, &herrno) < 0) {
- free(buf);
- free(buf2);
// Pass herrno to catch more detailed errors rather than EAI_NODATA.
return herrnoToAiErrno(herrno);
}
- ai = getanswer(buf, q.n, q.name, q.qtype, pai, &herrno);
+
+ addrinfo sentinel = {};
+ addrinfo* cur = &sentinel;
+ addrinfo* ai = getanswer(buf.get(), q.n, q.name, q.qtype, pai, &herrno);
if (ai) {
cur->ai_next = ai;
while (cur && cur->ai_next) cur = cur->ai_next;
}
if (q.next) {
- ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai, &herrno);
+ ai = getanswer(buf2.get(), q2.n, q2.name, q2.qtype, pai, &herrno);
if (ai) cur->ai_next = ai;
}
- free(buf);
- free(buf2);
if (sentinel.ai_next == NULL) {
return herrnoToAiErrno(herrno);
}
@@ -1531,7 +1509,6 @@
if (!cname) cname = cp;
tname = cp;
if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0';
- // fprintf(stderr, "\ttname = '%s'", tname);
if (strcasecmp(name, tname) == 0) goto found;
}
goto again;