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