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;