Make resolv_gethostbyaddr() re-entrant

The new call signature is closer to gethostbyaddr_r() and no longer
relies on thread-local storage for its buffers. This is the last nail
in the coffin of res_get_static().

Change-Id: I0673dd5a566e53a47a1c7a5b0afc67f5f28d1361
diff --git a/DnsProxyListener.cpp b/DnsProxyListener.cpp
index e1a3b89..ce6081d 100644
--- a/DnsProxyListener.cpp
+++ b/DnsProxyListener.cpp
@@ -1186,7 +1186,9 @@
     free(mAddress);
 }
 
-void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent** hpp,
+void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, char* buf,
+                                                                  size_t buflen,
+                                                                  struct hostent** hpp,
                                                                   NetworkDnsEventReported* event) {
     if (*hpp != nullptr || mAddressFamily != AF_INET6 || !mAddress) {
         return;
@@ -1215,14 +1217,14 @@
     if (queryLimiter.start(uid)) {
         // Remove NAT64 prefix and do reverse DNS query
         struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]};
-        android_gethostbyaddrfornetcontext(&v4addr, sizeof(v4addr), AF_INET, &mNetContext, hpp,
-                                           event);
+        resolv_gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET, hbuf, buf, buflen, &mNetContext, hpp,
+                             event);
         queryLimiter.finish(uid);
         if (*hpp) {
             // Replace IPv4 address with original queried IPv6 address in place. The space has
             // reserved by dns_gethtbyaddr() and netbsd_gethostent_r() in
             // system/netd/resolv/gethnamaddr.cpp.
-            // Note that android_gethostbyaddrfornetcontext returns only one entry in result.
+            // Note that resolv_gethostbyaddr() returns only one entry in result.
             memcpy((*hpp)->h_addr_list[0], &v6addr, sizeof(v6addr));
             (*hpp)->h_addrtype = AF_INET6;
             (*hpp)->h_length = sizeof(struct in6_addr);
@@ -1237,12 +1239,14 @@
     maybeFixupNetContext(&mNetContext);
     const uid_t uid = mClient->getUid();
     hostent* hp = nullptr;
+    hostent hbuf;
+    char tmpbuf[MAXPACKET];
     int32_t rv = 0;
     NetworkDnsEventReported event;
     initDnsEvent(&event);
     if (queryLimiter.start(uid)) {
-        rv = android_gethostbyaddrfornetcontext(mAddress, mAddressLen, mAddressFamily, &mNetContext,
-                                                &hp, &event);
+        rv = resolv_gethostbyaddr(mAddress, mAddressLen, mAddressFamily, &hbuf, tmpbuf,
+                                  sizeof tmpbuf, &mNetContext, &hp, &event);
         queryLimiter.finish(uid);
     } else {
         rv = EAI_MEMORY;
@@ -1250,12 +1254,12 @@
                    << ", max concurrent queries reached";
     }
 
-    doDns64ReverseLookup(&hp, &event);
+    doDns64ReverseLookup(&hbuf, tmpbuf, sizeof tmpbuf, &hp, &event);
     const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
     event.set_latency_micros(latencyUs);
     event.set_event_type(EVENT_GETHOSTBYADDR);
 
-    LOG(DEBUG) << "GetHostByAddrHandler::run: result: " << (hp ? "success" : gai_strerror(rv));
+    LOG(DEBUG) << "GetHostByAddrHandler::run: result: " << gai_strerror(rv);
 
     bool success = true;
     if (hp) {
diff --git a/DnsProxyListener.h b/DnsProxyListener.h
index 7af36c5..34340a0 100644
--- a/DnsProxyListener.h
+++ b/DnsProxyListener.h
@@ -111,7 +111,8 @@
         std::string threadName();
 
       private:
-        void doDns64ReverseLookup(hostent** hpp, NetworkDnsEventReported* event);
+        void doDns64ReverseLookup(hostent* hbuf, char* buf, size_t buflen, hostent** hpp,
+                                  NetworkDnsEventReported* event);
 
         SocketClient* mClient;  // ref counted
         void* mAddress;         // address to lookup; owned
diff --git a/gethnamaddr.cpp b/gethnamaddr.cpp
index 13f3b19..442355a 100644
--- a/gethnamaddr.cpp
+++ b/gethnamaddr.cpp
@@ -117,14 +117,6 @@
                            NetworkDnsEventReported* event);
 static int dns_gethtbyname(const char* name, int af, getnamaddr* info);
 
-static int android_gethostbyaddrfornetcontext_proxy_internal(const void*, socklen_t, int,
-                                                             struct hostent*, char*, size_t,
-                                                             const struct android_net_context*,
-                                                             NetworkDnsEventReported* event);
-static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
-                                                    const struct android_net_context* netcontext,
-                                                    hostent** hp, NetworkDnsEventReported* event);
-
 #define BOUNDED_INCR(x)      \
     do {                     \
         BOUNDS_CHECK(cp, x); \
@@ -483,10 +475,9 @@
     return 0;
 }
 
-static int android_gethostbyaddrfornetcontext_real(const void* addr, socklen_t len, int af,
-                                                   struct hostent* hp, char* buf, size_t buflen,
-                                                   const struct android_net_context* netcontext,
-                                                   NetworkDnsEventReported* event) {
+int resolv_gethostbyaddr(const void* addr, socklen_t len, int af, hostent* hp, char* buf,
+                         size_t buflen, const struct android_net_context* netcontext,
+                         hostent** result, NetworkDnsEventReported* event) {
     const uint8_t* uaddr = (const uint8_t*)addr;
     socklen_t size;
     struct getnamaddr info;
@@ -531,16 +522,10 @@
         int error = dns_gethtbyaddr(uaddr, len, af, netcontext, &info, event);
         if (error != 0) return error;
     }
+    *result = hp;
     return 0;
 }
 
-static int android_gethostbyaddrfornetcontext_proxy_internal(
-        const void* addr, socklen_t len, int af, struct hostent* hp, char* hbuf, size_t hbuflen,
-        const struct android_net_context* netcontext, NetworkDnsEventReported* event) {
-    return android_gethostbyaddrfornetcontext_real(addr, len, af, hp, hbuf, hbuflen, netcontext,
-                                                   event);
-}
-
 // TODO: Consider leaving function without returning error code as _gethtent() does because
 // the error code of the caller does not currently return to netd.
 struct hostent* netbsd_gethostent_r(FILE* hf, struct hostent* hent, char* buf, size_t buflen,
@@ -584,9 +569,6 @@
             len = NS_IN6ADDRSZ;
         } else {
             if (inet_pton(AF_INET, p, &host_addr) <= 0) continue;
-
-            res_state res = res_get_state();
-            if (res == NULL) goto nospc;
             af = AF_INET;
             len = NS_INADDRSZ;
         }
@@ -787,24 +769,6 @@
     return EAI_MEMORY;
 }
 
-int android_gethostbyaddrfornetcontext(const void* addr, socklen_t len, int af,
-                                       const struct android_net_context* netcontext, hostent** hp,
-                                       NetworkDnsEventReported* event) {
-    return android_gethostbyaddrfornetcontext_proxy(addr, len, af, netcontext, hp, event);
-}
-
-static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
-                                                    const struct android_net_context* netcontext,
-                                                    hostent** hp, NetworkDnsEventReported* event) {
-    assert(event != nullptr);
-
-    struct res_static* rs = res_get_static();  // For thread-safety.
-    int error = android_gethostbyaddrfornetcontext_proxy_internal(
-            addr, len, af, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), netcontext, event);
-    if (error == 0) *hp = &rs->host;
-    return error;
-}
-
 int herrnoToAiErrno(int he) {
     switch (he) {
         // extended h_errno
diff --git a/gethnamaddr.h b/gethnamaddr.h
index d328536..0654612 100644
--- a/gethnamaddr.h
+++ b/gethnamaddr.h
@@ -30,8 +30,9 @@
 // This is the entry point for the gethostbyname() family of legacy calls.
 int resolv_gethostbyname(const char* name, int af, hostent* hp, char* buf, size_t buflen,
                          const android_net_context* netcontext, hostent** result,
-                         android::net::NetworkDnsEventReported*);
+                         android::net::NetworkDnsEventReported* event);
 
 // This is the entry point for the gethostbyaddr() family of legacy calls.
-int android_gethostbyaddrfornetcontext(const void*, socklen_t, int, const android_net_context*,
-                                       hostent**, android::net::NetworkDnsEventReported*);
+int resolv_gethostbyaddr(const void* addr, socklen_t len, int af, hostent* hp, char* buf,
+                         size_t buflen, const android_net_context* netcontext, hostent** result,
+                         android::net::NetworkDnsEventReported* event);
diff --git a/resolv_unit_test.cpp b/resolv_unit_test.cpp
index 691b978..0c1de0b 100644
--- a/resolv_unit_test.cpp
+++ b/resolv_unit_test.cpp
@@ -968,7 +968,7 @@
 //           - Invalid length CNAME, or QNAME.
 //           - Unexpected amount of questions.
 //       - CNAME RDATA with the domain name which has null label(s).
-// TODO: Add test for android_gethostbyaddrfornetcontext().
+// TODO: Add test for resolv_gethostbyaddr().
 
 }  // end of namespace net
 }  // end of namespace android