diff --git a/Android.bp b/Android.bp
index ccea41f..ab333f4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -20,6 +20,7 @@
         "res_send.cpp",
         "res_state.cpp",
         "res_stats.cpp",
+        "DnsProxyListener.cpp",
         "DnsTlsDispatcher.cpp",
         "DnsTlsQueryMap.cpp",
         "DnsTlsTransport.cpp",
@@ -35,13 +36,21 @@
     static_libs: [
         "libbase",
         "libcrypto",
+        "libcutils",
         "liblog",
         "libnetdutils",
         "libssl",
+        "libsysutils",
         "netd_event_listener_interface-ndk_platform",
     ],
     shared_libs: [
         "libbinder_ndk",
+        "libstatslog",
+    ],
+    // TODO: Get rid of these include paths used in DnsProxyListener.
+    include_dirs: [
+        "system/netd/include",
+        "system/netd/server",
     ],
     export_include_dirs: ["include"],
     // TODO: pie in the sky: make this code clang-tidy clean
diff --git a/DnsProxyListener.cpp b/DnsProxyListener.cpp
new file mode 100644
index 0000000..18006f1
--- /dev/null
+++ b/DnsProxyListener.cpp
@@ -0,0 +1,1191 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <errno.h>
+#include <linux/if.h>
+#include <math.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#define LOG_TAG "DnsProxyListener"
+#define DBG 0
+#define VDBG 0
+
+#include <algorithm>
+#include <list>
+#include <vector>
+
+#include <android-base/stringprintf.h>
+#include <cutils/misc.h>
+#include <log/log.h>
+#include <netdutils/OperationLimiter.h>
+#include <netdutils/Slice.h>
+#include <private/android_filesystem_config.h>  // AID_SYSTEM
+#include <resolv.h>
+#include <statslog.h>
+#include <sysutils/SocketClient.h>
+
+// TODO: Considering moving ResponseCode.h Stopwatch.h thread_util.h to libnetdutils.
+#include "NetdClient.h"  // NETID_USE_LOCAL_NAMESERVERS
+#include "ResponseCode.h"
+#include "Stopwatch.h"
+#include "netd_resolv/DnsProxyListener.h"
+#include "netd_resolv/ResolverEventReporter.h"
+#include "netd_resolv/stats.h"  // RCODE_TIMEOUT
+#include "netdutils/InternetAddresses.h"
+#include "thread_util.h"
+
+using aidl::android::net::metrics::INetdEventListener;
+using android::base::StringPrintf;
+
+static android::net::DnsProxyListener gDnsProxyListener;
+
+bool resolv_init(const dnsproxylistener_callbacks& callbacks) {
+    if (!gDnsProxyListener.setCallbacks(callbacks)) {
+        ALOGE("Unable to set callbacks to DnsProxyListener");
+        return false;
+    }
+    if (gDnsProxyListener.startListener()) {
+        ALOGE("Unable to start DnsProxyListener (%s)", strerror(errno));
+        return false;
+    }
+    return true;
+}
+
+namespace android {
+namespace net {
+
+namespace {
+
+// TODO: move to a separate file (with other constants from FwmarkService and NetdNativeService)
+constexpr const char CONNECTIVITY_USE_RESTRICTED_NETWORKS[] =
+    "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS";
+constexpr const char NETWORK_BYPASS_PRIVATE_DNS[] =
+    "android.permission.NETWORK_BYPASS_PRIVATE_DNS";
+
+// Limits the number of outstanding DNS queries by client UID.
+constexpr int MAX_QUERIES_PER_UID = 256;
+
+// Max packet size for answer, sync with getaddrinfo.c
+constexpr int MAXPACKET = 8 * 1024;
+
+android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);
+
+void logArguments(int argc, char** argv) {
+    for (int i = 0; i < argc; i++) {
+        ALOGD("argv[%i]=%s", i, argv[i]);
+    }
+}
+
+template<typename T>
+void tryThreadOrError(SocketClient* cli, T* handler) {
+    cli->incRef();
+
+    const int rval = threadLaunch(handler);
+    if (rval == 0) {
+        // SocketClient decRef() happens in the handler's run() method.
+        return;
+    }
+
+    char* msg = nullptr;
+    asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
+    cli->sendMsg(ResponseCode::OperationFailed, msg, false);
+    free(msg);
+
+    delete handler;
+    cli->decRef();
+}
+
+bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
+    if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
+        return false;
+    }
+    *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
+    return true;
+}
+
+constexpr bool requestingUseLocalNameservers(unsigned flags) {
+    return (flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) != 0;
+}
+
+inline bool queryingViaTls(unsigned dns_netid) {
+    ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}};
+    resolv_get_private_dns_status_for_net(dns_netid, &privateDnsStatus);
+    switch (static_cast<PrivateDnsMode>(privateDnsStatus.mode)) {
+        case PrivateDnsMode::OPPORTUNISTIC:
+            for (int i = 0; i < privateDnsStatus.numServers; i++) {
+                if (privateDnsStatus.serverStatus[i].validation == Validation::success) {
+                    return true;
+                }
+            }
+            return false;
+        case PrivateDnsMode::STRICT:
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool hasPermissionToBypassPrivateDns(uid_t uid) {
+    static_assert(AID_SYSTEM >= 0 && AID_SYSTEM < FIRST_APPLICATION_UID,
+        "Calls from AID_SYSTEM must not result in a permission check to avoid deadlock.");
+    if (uid >= 0 && uid < FIRST_APPLICATION_UID) {
+        return true;
+    }
+
+    for (const char* const permission :
+         {CONNECTIVITY_USE_RESTRICTED_NETWORKS, NETWORK_BYPASS_PRIVATE_DNS}) {
+        if (gDnsProxyListener.mCallbacks.check_calling_permission(permission)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void maybeFixupNetContext(android_net_context* ctx) {
+    if (requestingUseLocalNameservers(ctx->flags) && !hasPermissionToBypassPrivateDns(ctx->uid)) {
+        // Not permitted; clear the flag.
+        ctx->flags &= ~NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
+    }
+
+    if (!requestingUseLocalNameservers(ctx->flags)) {
+        // If we're not explicitly bypassing DNS-over-TLS servers, check whether
+        // DNS-over-TLS is in use as an indicator for when to use more modern
+        // DNS resolution mechanics.
+        if (queryingViaTls(ctx->dns_netid)) {
+            ctx->flags |= NET_CONTEXT_FLAG_USE_EDNS;
+        }
+    }
+}
+
+void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
+                          socklen_t addrlen);
+
+int extractResNsendAnswers(const uint8_t* answer, size_t anslen, int ipType,
+                           std::vector<std::string>* ip_addrs) {
+    int total_ip_addr_count = 0;
+    ns_msg handle;
+    if (ns_initparse((const uint8_t*) answer, anslen, &handle) < 0) {
+        return 0;
+    }
+    int ancount = ns_msg_count(handle, ns_s_an);
+    ns_rr rr;
+    for (int i = 0; i < ancount; i++) {
+        if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
+            continue;
+        }
+        const uint8_t* rdata = ns_rr_rdata(rr);
+        if (ipType == ns_t_a) {
+            sockaddr_in sin = {.sin_family = AF_INET};
+            memcpy(&sin.sin_addr, rdata, sizeof(sin.sin_addr));
+            addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
+            total_ip_addr_count++;
+        } else if (ipType == ns_t_aaaa) {
+            sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
+            memcpy(&sin6.sin6_addr, rdata, sizeof(sin6.sin6_addr));
+            addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
+            total_ip_addr_count++;
+        }
+    }
+
+    return total_ip_addr_count;
+}
+
+int extractGetAddrInfoAnswers(const addrinfo* result, std::vector<std::string>* ip_addrs) {
+    int total_ip_addr_count = 0;
+    if (result == nullptr) {
+        return 0;
+    }
+    for (const addrinfo* ai = result; ai; ai = ai->ai_next) {
+        sockaddr* ai_addr = ai->ai_addr;
+        if (ai_addr) {
+            addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen);
+            total_ip_addr_count++;
+        }
+    }
+    return total_ip_addr_count;
+}
+
+int extractGetHostByNameAnswers(const hostent* hp, std::vector<std::string>* ip_addrs) {
+    int total_ip_addr_count = 0;
+    if (hp == nullptr) {
+        return 0;
+    }
+    if (hp->h_addrtype == AF_INET) {
+        in_addr** list = (in_addr**) hp->h_addr_list;
+        for (int i = 0; list[i] != nullptr; i++) {
+            sockaddr_in sin = {.sin_family = AF_INET, .sin_addr = *list[i]};
+            addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
+            total_ip_addr_count++;
+        }
+    } else if (hp->h_addrtype == AF_INET6) {
+        in6_addr** list = (in6_addr**) hp->h_addr_list;
+        for (int i = 0; list[i] != nullptr; i++) {
+            sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = *list[i]};
+            addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
+            total_ip_addr_count++;
+        }
+    }
+    return total_ip_addr_count;
+}
+
+int rcodeToAiError(int rcode) {
+    switch (rcode) {
+        case NOERROR:
+            return 0;
+        case RCODE_TIMEOUT:
+            return NETD_RESOLV_TIMEOUT;
+        default:
+            return EAI_NODATA;
+    }
+}
+
+int resNSendToAiError(int err, int rcode) {
+    if (err > 0) {
+        return rcodeToAiError(rcode);
+    }
+    if (err == -ETIMEDOUT) {
+        return NETD_RESOLV_TIMEOUT;
+    }
+    return EAI_SYSTEM;
+}
+
+template <typename IntegralType>
+bool simpleStrtoul(const char* input, IntegralType* output, int base = 10) {
+    char* endPtr;
+    errno = 0;
+    auto result = strtoul(input, &endPtr, base);
+    // Check the length in order to ensure there is no "-" sign
+    if (!*input || *endPtr || (endPtr - input) != static_cast<ptrdiff_t>(strlen(input)) ||
+        (errno == ERANGE && (result == ULONG_MAX))) {
+        return false;
+    }
+    *output = result;
+    return true;
+}
+
+bool parseQuery(const uint8_t* msg, size_t msgLen, int* rr_type, std::string* rr_name) {
+    ns_msg handle;
+    ns_rr rr;
+    if (ns_initparse((const uint8_t*) msg, msgLen, &handle) < 0 ||
+        ns_parserr(&handle, ns_s_qd, 0, &rr) < 0) {
+        return false;
+    }
+
+    *rr_name = ns_rr_name(rr);
+    *rr_type = ns_rr_type(rr);
+    return true;
+}
+
+void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs,
+                    int returnCode, const std::string& query_name,
+                    const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) {
+    android::util::stats_write(android::util::NETWORK_DNS_EVENT_REPORTED, eventType, returnCode,
+                               latencyUs);
+
+    const std::shared_ptr<INetdEventListener> listener = ResolverEventReporter::getListener();
+    if (!listener) return;
+    const int latencyMs = latencyUs / 1000;
+    listener->onDnsEvent(netContext.dns_netid, eventType, returnCode, latencyMs, query_name,
+                         ip_addrs, total_ip_addr_count, netContext.uid);
+}
+
+bool onlyIPv4Answers(const addrinfo* res) {
+    // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
+
+    for (const addrinfo* ai = res; ai; ai = ai->ai_next)
+        if (ai->ai_family != AF_INET) return false;
+
+    return true;
+}
+
+bool isSpecialUseIPv4Address(const struct in_addr& ia) {
+    const uint32_t addr = ntohl(ia.s_addr);
+
+    // Only check necessary IP ranges in RFC 5735 section 4
+    return ((addr & 0xff000000) == 0x00000000) ||  // "This" Network
+           ((addr & 0xff000000) == 0x7f000000) ||  // Loopback
+           ((addr & 0xffff0000) == 0xa9fe0000) ||  // Link Local
+           ((addr & 0xf0000000) == 0xe0000000) ||  // Multicast
+           (addr == INADDR_BROADCAST);             // Limited Broadcast
+}
+
+bool isSpecialUseIPv4Address(const struct sockaddr* sa) {
+    if (sa->sa_family != AF_INET) return false;
+
+    return isSpecialUseIPv4Address(((struct sockaddr_in*) sa)->sin_addr);
+}
+
+bool onlyNonSpecialUseIPv4Addresses(struct hostent* hp) {
+    // Null hostent pointer isn't checked because the caller doesn't pass null pointer.
+
+    if (hp->h_addrtype != AF_INET) return false;
+
+    for (int i = 0; hp->h_addr_list[i] != nullptr; i++)
+        if (isSpecialUseIPv4Address(*(struct in_addr*) hp->h_addr_list[i])) return false;
+
+    return true;
+}
+
+bool onlyNonSpecialUseIPv4Addresses(const addrinfo* res) {
+    // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
+
+    for (const addrinfo* ai = res; ai; ai = ai->ai_next) {
+        if (ai->ai_family != AF_INET) return false;
+        if (isSpecialUseIPv4Address(ai->ai_addr)) return false;
+    }
+
+    return true;
+}
+
+void logDnsQueryResult(const struct hostent* hp) {
+    if (hp == nullptr) return;
+
+    ALOGD("DNS records:");
+    for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
+        char ip_addr[INET6_ADDRSTRLEN];
+        if (inet_ntop(hp->h_addrtype, hp->h_addr_list[i], ip_addr, sizeof(ip_addr)) != nullptr) {
+            ALOGD("[%d] %s, %d, %d, %s (%p)", i, hp->h_name ? hp->h_name : "null", hp->h_addrtype,
+                  hp->h_length, ip_addr, hp->h_addr_list[i]);
+        } else {
+            ALOGD("[%d] numeric hostname translation fail (%d)", i, errno);
+        }
+    }
+}
+
+void logDnsQueryResult(const addrinfo* res) {
+    if (res == nullptr) return;
+
+    int i;
+    const addrinfo* ai;
+    ALOGD("DNS records:");
+    for (ai = res, i = 0; ai; ai = ai->ai_next, i++) {
+        if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) continue;
+        char ip_addr[INET6_ADDRSTRLEN];
+        int ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0,
+                              NI_NUMERICHOST);
+        if (!ret) {
+            ALOGD("[%d] 0x%x,%d,%d,%d,%d,%s,%s,%p", i, ai->ai_flags, ai->ai_family, ai->ai_socktype,
+                  ai->ai_protocol, ai->ai_addrlen, ai->ai_canonname ? ai->ai_canonname : "null",
+                  ip_addr, ai);
+        } else {
+            ALOGD("[%d] numeric hostname translation fail (%d)", i, ret);
+        }
+    }
+}
+
+bool isValidNat64Prefix(const netdutils::IPPrefix prefix) {
+    if (prefix.family() != AF_INET6) {
+        ALOGE("Only IPv6 NAT64 prefixes are supported (%u)", prefix.family());
+        return false;
+    }
+    if (prefix.length() != 96) {
+        ALOGE("Only /96 NAT64 prefixes are supported (%d)", prefix.length());
+        return false;
+    }
+    return true;
+}
+
+bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, struct hostent* hp) {
+    if (hp == nullptr) return false;
+    if (!onlyNonSpecialUseIPv4Addresses(hp)) return false;
+    if (!isValidNat64Prefix(prefix)) return false;
+
+    struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
+    struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
+    for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
+        struct in_addr iaOriginal = *(struct in_addr*) hp->h_addr_list[i];
+        struct in6_addr* ia6 = (struct in6_addr*) hp->h_addr_list[i];
+        memset(ia6, 0, sizeof(struct in6_addr));
+
+        // Synthesize /96 NAT64 prefix in place. The space has reserved by getanswer() and
+        // _hf_gethtbyname2() in system/netd/resolv/gethnamaddr.cpp and
+        // system/netd/resolv/sethostent.cpp.
+        *ia6 = v6prefix->sin6_addr;
+        ia6->s6_addr32[3] = iaOriginal.s_addr;
+
+        if (DBG) {
+            char buf[INET6_ADDRSTRLEN];  // big enough for either IPv4 or IPv6
+            inet_ntop(AF_INET, &iaOriginal.s_addr, buf, sizeof(buf));
+            ALOGD("DNS A record: %s", buf);
+            inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
+            ALOGD("NAT64 prefix: %s", buf);
+            inet_ntop(AF_INET6, ia6, buf, sizeof(buf));
+            ALOGD("DNS64 Synthesized AAAA record: %s", buf);
+        }
+    }
+    hp->h_addrtype = AF_INET6;
+    hp->h_length = sizeof(in6_addr);
+
+    if (DBG) logDnsQueryResult(hp);
+    return true;
+}
+
+bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, addrinfo* result) {
+    if (result == nullptr) return false;
+    if (!onlyNonSpecialUseIPv4Addresses(result)) return false;
+    if (!isValidNat64Prefix(prefix)) return false;
+
+    struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
+    struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
+    for (addrinfo* ai = result; ai; ai = ai->ai_next) {
+        struct sockaddr_in sinOriginal = *(struct sockaddr_in*) ai->ai_addr;
+        struct sockaddr_in6* sin6 = (struct sockaddr_in6*) ai->ai_addr;
+        memset(sin6, 0, sizeof(sockaddr_in6));
+
+        // Synthesize /96 NAT64 prefix in place. The space has reserved by get_ai() in
+        // system/netd/resolv/getaddrinfo.cpp.
+        sin6->sin6_addr = v6prefix->sin6_addr;
+        sin6->sin6_addr.s6_addr32[3] = sinOriginal.sin_addr.s_addr;
+        sin6->sin6_family = AF_INET6;
+        sin6->sin6_port = sinOriginal.sin_port;
+        ai->ai_addrlen = sizeof(struct sockaddr_in6);
+        ai->ai_family = AF_INET6;
+
+        if (DBG) {
+            char buf[INET6_ADDRSTRLEN];  // big enough for either IPv4 or IPv6
+            inet_ntop(AF_INET, &sinOriginal.sin_addr.s_addr, buf, sizeof(buf));
+            ALOGD("DNS A record: %s", buf);
+            inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
+            ALOGD("NAT64 prefix: %s", buf);
+            inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf));
+            ALOGD("DNS64 Synthesized AAAA record: %s", buf);
+        }
+    }
+    if (DBG) logDnsQueryResult(result);
+    return true;
+}
+
+bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) {
+    in6_addr v6addr{};
+    uint8_t prefixLen = 0;
+    if (!gDnsProxyListener.mCallbacks.get_dns64_prefix(netId, &v6addr, &prefixLen)) {
+        return false;
+    }
+    const netdutils::IPAddress ipv6(v6addr);
+    *prefix = netdutils::IPPrefix(ipv6, static_cast<int>(prefixLen));
+    return true;
+}
+
+}  // namespace
+
+bool DnsProxyListener::setCallbacks(const dnsproxylistener_callbacks& callbacks) {
+    mCallbacks = callbacks;
+    return mCallbacks.check_calling_permission && mCallbacks.get_network_context &&
+           mCallbacks.get_dns64_prefix;
+}
+
+DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) {
+    registerCmd(new GetAddrInfoCmd());
+    registerCmd(new GetHostByAddrCmd());
+    registerCmd(new GetHostByNameCmd());
+    registerCmd(new ResNSendCommand());
+}
+
+DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, char* host, char* service,
+                                                         addrinfo* hints,
+                                                         const android_net_context& netcontext)
+    : mClient(c), mHost(host), mService(service), mHints(hints), mNetContext(netcontext) {}
+
+DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() {
+    free(mHost);
+    free(mService);
+    free(mHints);
+}
+
+static bool sendBE32(SocketClient* c, uint32_t data) {
+    uint32_t be_data = htonl(data);
+    return c->sendData(&be_data, sizeof(be_data)) == 0;
+}
+
+// Sends 4 bytes of big-endian length, followed by the data.
+// Returns true on success.
+static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
+    return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
+}
+
+// Returns true on success
+static bool sendhostent(SocketClient* c, hostent* hp) {
+    bool success = true;
+    int i;
+    if (hp->h_name != nullptr) {
+        success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name);
+    } else {
+        success &= sendLenAndData(c, 0, "") == 0;
+    }
+
+    for (i=0; hp->h_aliases[i] != nullptr; i++) {
+        success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]);
+    }
+    success &= sendLenAndData(c, 0, ""); // null to indicate we're done
+
+    uint32_t buf = htonl(hp->h_addrtype);
+    success &= c->sendData(&buf, sizeof(buf)) == 0;
+
+    buf = htonl(hp->h_length);
+    success &= c->sendData(&buf, sizeof(buf)) == 0;
+
+    for (i=0; hp->h_addr_list[i] != nullptr; i++) {
+        success &= sendLenAndData(c, 16, hp->h_addr_list[i]);
+    }
+    success &= sendLenAndData(c, 0, ""); // null to indicate we're done
+    return success;
+}
+
+static bool sendaddrinfo(SocketClient* c, addrinfo* ai) {
+    // struct addrinfo {
+    //      int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
+    //      int     ai_family;      /* PF_xxx */
+    //      int     ai_socktype;    /* SOCK_xxx */
+    //      int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+    //      socklen_t ai_addrlen;   /* length of ai_addr */
+    //      char    *ai_canonname;  /* canonical name for hostname */
+    //      struct  sockaddr *ai_addr;      /* binary address */
+    //      struct  addrinfo *ai_next;      /* next structure in linked list */
+    // };
+
+    // Write the struct piece by piece because we might be a 64-bit netd
+    // talking to a 32-bit process.
+    bool success =
+            sendBE32(c, ai->ai_flags) &&
+            sendBE32(c, ai->ai_family) &&
+            sendBE32(c, ai->ai_socktype) &&
+            sendBE32(c, ai->ai_protocol);
+    if (!success) {
+        return false;
+    }
+
+    // ai_addrlen and ai_addr.
+    if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
+        return false;
+    }
+
+    // strlen(ai_canonname) and ai_canonname.
+    if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) {
+        return false;
+    }
+
+    return true;
+}
+
+void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res) {
+    if (mHost == nullptr) return;
+
+    const bool ipv6WantedButNoData = (mHints && mHints->ai_family == AF_INET6 && *rv == EAI_NODATA);
+    const bool unspecWantedButNoIPv6 =
+            ((!mHints || mHints->ai_family == AF_UNSPEC) && *rv == 0 && onlyIPv4Answers(*res));
+
+    if (!ipv6WantedButNoData && !unspecWantedButNoIPv6) {
+        return;
+    }
+
+    netdutils::IPPrefix prefix{};
+    if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
+        return;
+    }
+
+    if (ipv6WantedButNoData) {
+        // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
+        const uid_t uid = mClient->getUid();
+        if (queryLimiter.start(uid)) {
+            mHints->ai_family = AF_INET;
+            // Don't need to do freeaddrinfo(res) before starting new DNS lookup because previous
+            // DNS lookup is failed with error EAI_NODATA.
+            *rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, res);
+            queryLimiter.finish(uid);
+            if (*rv) {
+                *rv = EAI_NODATA;  // return original error code
+                return;
+            }
+        } else {
+            ALOGE("getaddrinfo: from UID %d, max concurrent queries reached", uid);
+            return;
+        }
+    }
+
+    if (!synthesizeNat64PrefixWithARecord(prefix, *res)) {
+        if (ipv6WantedButNoData) {
+            // If caller wants IPv6 answers but no data and failed to synthesize IPv6 answers,
+            // don't return the IPv4 answers.
+            *rv = EAI_NODATA;  // return original error code
+            if (*res) {
+                freeaddrinfo(*res);
+                *res = nullptr;
+            }
+        }
+    }
+}
+
+void DnsProxyListener::GetAddrInfoHandler::run() {
+    if (DBG) {
+        ALOGD("GetAddrInfoHandler, now for %s / %s / {%u,%u,%u,%u,%u,%u}", mHost, mService,
+                mNetContext.app_netid, mNetContext.app_mark,
+                mNetContext.dns_netid, mNetContext.dns_mark,
+                mNetContext.uid, mNetContext.flags);
+    }
+
+    addrinfo* result = nullptr;
+    Stopwatch s;
+    maybeFixupNetContext(&mNetContext);
+    const uid_t uid = mClient->getUid();
+    int32_t rv = 0;
+    if (queryLimiter.start(uid)) {
+        rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, &result);
+        queryLimiter.finish(uid);
+    } else {
+        // Note that this error code is currently not passed down to the client.
+        // android_getaddrinfo_proxy() returns EAI_NODATA on any error.
+        rv = EAI_MEMORY;
+        ALOGE("getaddrinfo: from UID %d, max concurrent queries reached", uid);
+    }
+
+    doDns64Synthesis(&rv, &result);
+    const int latencyUs = int(s.timeTakenUs());
+
+    if (rv) {
+        // getaddrinfo failed
+        mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv));
+    } else {
+        bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
+        addrinfo* ai = result;
+        while (ai && success) {
+            success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
+            ai = ai->ai_next;
+        }
+        success = success && sendBE32(mClient, 0);
+        if (!success) {
+            ALOGW("Error writing DNS result to client");
+        }
+    }
+    std::vector<std::string> ip_addrs;
+    const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs);
+    reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, mHost,
+                   ip_addrs, total_ip_addr_count);
+    freeaddrinfo(result);
+    mClient->decRef();
+}
+
+namespace {
+
+void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
+                          socklen_t addrlen) {
+    // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT
+    // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether
+    // some addresses didn't get logged.
+    if (ip_addrs->size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) {
+        char ip_addr[INET6_ADDRSTRLEN];
+        if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) {
+            ip_addrs->push_back(std::string(ip_addr));
+        }
+    }
+}
+
+}  // namespace
+
+DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : FrameworkCommand("getaddrinfo") {}
+
+int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
+                                            int argc, char **argv) {
+    if (DBG) logArguments(argc, argv);
+
+    if (argc != 8) {
+        char* msg = nullptr;
+        asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc);
+        ALOGW("%s", msg);
+        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
+        free(msg);
+        return -1;
+    }
+
+    char* name = argv[1];
+    if (strcmp("^", name) == 0) {
+        name = nullptr;
+    } else {
+        name = strdup(name);
+    }
+
+    char* service = argv[2];
+    if (strcmp("^", service) == 0) {
+        service = nullptr;
+    } else {
+        service = strdup(service);
+    }
+
+    addrinfo* hints = nullptr;
+    int ai_flags = strtol(argv[3], nullptr, 10);
+    int ai_family = strtol(argv[4], nullptr, 10);
+    int ai_socktype = strtol(argv[5], nullptr, 10);
+    int ai_protocol = strtol(argv[6], nullptr, 10);
+    unsigned netId = strtoul(argv[7], nullptr, 10);
+    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
+    const uid_t uid = cli->getUid();
+
+    android_net_context netcontext;
+    gDnsProxyListener.mCallbacks.get_network_context(netId, uid, &netcontext);
+
+    if (useLocalNameservers) {
+        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
+    }
+
+    if (ai_flags != -1 || ai_family != -1 ||
+        ai_socktype != -1 || ai_protocol != -1) {
+        hints = (addrinfo*) calloc(1, sizeof(addrinfo));
+        hints->ai_flags = ai_flags;
+        hints->ai_family = ai_family;
+        hints->ai_socktype = ai_socktype;
+        hints->ai_protocol = ai_protocol;
+    }
+
+    if (DBG) {
+        ALOGD("GetAddrInfoHandler for %s / %s / {%u,%u,%u,%u,%u}",
+             name ? name : "[nullhost]",
+             service ? service : "[nullservice]",
+             netcontext.app_netid, netcontext.app_mark,
+             netcontext.dns_netid, netcontext.dns_mark,
+             netcontext.uid);
+    }
+
+    DnsProxyListener::GetAddrInfoHandler* handler =
+            new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, netcontext);
+    tryThreadOrError(cli, handler);
+    return 0;
+}
+
+/*******************************************************
+ *                  ResNSendCommand                  *
+ *******************************************************/
+DnsProxyListener::ResNSendCommand::ResNSendCommand() : FrameworkCommand("resnsend") {}
+
+int DnsProxyListener::ResNSendCommand::runCommand(SocketClient* cli, int argc, char** argv) {
+    if (DBG) logArguments(argc, argv);
+
+    const uid_t uid = cli->getUid();
+    if (argc != 4) {
+        ALOGW("resnsend: from UID %d, invalid number of arguments to resnsend: %d", uid, argc);
+        sendBE32(cli, -EINVAL);
+        return -1;
+    }
+
+    unsigned netId;
+    if (!simpleStrtoul(argv[1], &netId)) {
+        ALOGW("resnsend: from UID %d, invalid netId", uid);
+        sendBE32(cli, -EINVAL);
+        return -1;
+    }
+
+    uint32_t flags;
+    if (!simpleStrtoul(argv[2], &flags)) {
+        ALOGW("resnsend: from UID %d, invalid flags", uid);
+        sendBE32(cli, -EINVAL);
+        return -1;
+    }
+
+    android_net_context netcontext;
+    gDnsProxyListener.mCallbacks.get_network_context(netId, uid, &netcontext);
+    if (checkAndClearUseLocalNameserversFlag(&netId)) {
+        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
+    }
+
+    DnsProxyListener::ResNSendHandler* handler =
+            new DnsProxyListener::ResNSendHandler(cli, argv[3], flags, netcontext);
+    tryThreadOrError(cli, handler);
+    return 0;
+}
+
+DnsProxyListener::ResNSendHandler::ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
+                                                   const android_net_context& netcontext)
+    : mClient(c), mMsg(std::move(msg)), mFlags(flags), mNetContext(netcontext) {}
+
+DnsProxyListener::ResNSendHandler::~ResNSendHandler() {
+    mClient->decRef();
+}
+
+void DnsProxyListener::ResNSendHandler::run() {
+    if (DBG) {
+        ALOGD("ResNSendHandler, now for %s %u/ {%u,%u,%u,%u,%u,%u}", mMsg.c_str(), mFlags,
+              mNetContext.app_netid, mNetContext.app_mark, mNetContext.dns_netid,
+              mNetContext.dns_mark, mNetContext.uid, mNetContext.flags);
+    }
+
+    Stopwatch s;
+    maybeFixupNetContext(&mNetContext);
+
+    // Decode
+    std::vector<uint8_t> msg(MAXPACKET, 0);
+
+    // Max length of mMsg is less than 1024 since the CMD_BUF_SIZE in FrameworkListener is 1024
+    int msgLen = b64_pton(mMsg.c_str(), msg.data(), MAXPACKET);
+    if (msgLen == -1) {
+        // Decode fail
+        sendBE32(mClient, -EILSEQ);
+        return;
+    }
+
+    const uid_t uid = mClient->getUid();
+    int rr_type = 0;
+    std::string rr_name;
+
+    // TODO: Handle the case which is msg contains more than one query
+    // Parse and store query type/name
+    if (!parseQuery(msg.data(), msgLen, &rr_type, &rr_name)) {
+        // If the query couldn't be parsed, block the request.
+        ALOGW("resnsend: from UID %d, invalid query", uid);
+        sendBE32(mClient, -EINVAL);
+        return;
+    }
+
+    // Send DNS query
+    std::vector<uint8_t> ansBuf(MAXPACKET, 0);
+    int arcode, nsendAns = -1;
+    if (queryLimiter.start(uid)) {
+        nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET,
+                                    &arcode, static_cast<ResNsendFlags>(mFlags));
+        queryLimiter.finish(uid);
+    } else {
+        ALOGW("resnsend: from UID %d, max concurrent queries reached", uid);
+        nsendAns = -EBUSY;
+    }
+
+    const int latencyUs = int(s.timeTakenUs());
+
+    // Fail, send -errno
+    if (nsendAns < 0) {
+        sendBE32(mClient, nsendAns);
+        if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
+            reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
+                           resNSendToAiError(nsendAns, arcode), rr_name);
+        }
+        return;
+    }
+
+    // Send rcode
+    if (!sendBE32(mClient, arcode)) {
+        ALOGW("resnsend: failed to send rcode to uid %d: %s", uid, strerror(errno));
+        return;
+    }
+
+    // Send answer
+    if (!sendLenAndData(mClient, nsendAns, ansBuf.data())) {
+        ALOGW("resnsend: failed to send answer to uid %d: %s", uid, strerror(errno));
+        return;
+    }
+
+    if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
+        std::vector<std::string> ip_addrs;
+        const int total_ip_addr_count =
+                extractResNsendAnswers((uint8_t*) ansBuf.data(), nsendAns, rr_type, &ip_addrs);
+        reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
+                       resNSendToAiError(nsendAns, arcode), rr_name, ip_addrs, total_ip_addr_count);
+    }
+}
+
+/*******************************************************
+ *                  GetHostByName                      *
+ *******************************************************/
+DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd() : FrameworkCommand("gethostbyname") {}
+
+int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
+                                            int argc, char **argv) {
+    if (DBG) logArguments(argc, argv);
+
+    if (argc != 4) {
+        char* msg = nullptr;
+        asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc);
+        ALOGW("%s", msg);
+        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
+        free(msg);
+        return -1;
+    }
+
+    uid_t uid = cli->getUid();
+    unsigned netId = strtoul(argv[1], nullptr, 10);
+    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
+    char* name = argv[2];
+    int af = strtol(argv[3], nullptr, 10);
+
+    if (strcmp(name, "^") == 0) {
+        name = nullptr;
+    } else {
+        name = strdup(name);
+    }
+
+    android_net_context netcontext;
+    gDnsProxyListener.mCallbacks.get_network_context(netId, uid, &netcontext);
+
+    if (useLocalNameservers) {
+        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
+    }
+
+    DnsProxyListener::GetHostByNameHandler* handler =
+            new DnsProxyListener::GetHostByNameHandler(cli, name, af, netcontext);
+    tryThreadOrError(cli, handler);
+    return 0;
+}
+
+DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, char* name, int af,
+                                                             const android_net_context& netcontext)
+    : mClient(c), mName(name), mAf(af), mNetContext(netcontext) {}
+
+DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() {
+    free(mName);
+}
+
+void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struct hostent** hpp) {
+    // Don't have to consider family AF_UNSPEC case because gethostbyname{, 2} only supports
+    // family AF_INET or AF_INET6.
+    const bool ipv6WantedButNoData = (mAf == AF_INET6 && *rv == EAI_NODATA);
+
+    if (!ipv6WantedButNoData) {
+        return;
+    }
+
+    netdutils::IPPrefix prefix{};
+    if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
+        return;
+    }
+
+    // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
+    const uid_t uid = mClient->getUid();
+    if (queryLimiter.start(uid)) {
+        *rv = android_gethostbynamefornetcontext(mName, AF_INET, &mNetContext, hpp);
+        queryLimiter.finish(uid);
+        if (*rv) {
+            *rv = EAI_NODATA;  // return original error code
+            return;
+        }
+    } else {
+        ALOGE("gethostbyname: from UID %d, max concurrent queries reached", uid);
+        return;
+    }
+
+    if (!synthesizeNat64PrefixWithARecord(prefix, *hpp)) {
+        // If caller wants IPv6 answers but no data and failed to synthesize IPv4 answers,
+        // don't return the IPv4 answers.
+        *hpp = nullptr;
+    }
+}
+
+void DnsProxyListener::GetHostByNameHandler::run() {
+    if (DBG) {
+        ALOGD("DnsProxyListener::GetHostByNameHandler::run");
+    }
+
+    Stopwatch s;
+    maybeFixupNetContext(&mNetContext);
+    const uid_t uid = mClient->getUid();
+    hostent* hp = nullptr;
+    int32_t rv = 0;
+    if (queryLimiter.start(uid)) {
+        rv = android_gethostbynamefornetcontext(mName, mAf, &mNetContext, &hp);
+        queryLimiter.finish(uid);
+    } else {
+        rv = EAI_MEMORY;
+        ALOGE("gethostbyname: from UID %d, max concurrent queries reached", uid);
+    }
+
+    doDns64Synthesis(&rv, &hp);
+    const int latencyUs = lround(s.timeTakenUs());
+
+    if (DBG) {
+        ALOGD("GetHostByNameHandler::run gethostbyname errno: %s hp->h_name = %s, name_len = %zu",
+                hp ? "success" : strerror(errno),
+                (hp && hp->h_name) ? hp->h_name : "null",
+                (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0);
+    }
+
+    bool success = true;
+    if (hp) {
+        // hp is not nullptr iff. rv is 0.
+        success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
+        success &= sendhostent(mClient, hp);
+    } else {
+        success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
+    }
+
+    if (!success) {
+        ALOGW("GetHostByNameHandler: Error writing DNS result to client");
+    }
+
+    std::vector<std::string> ip_addrs;
+    const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs);
+    reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, mName,
+                   ip_addrs, total_ip_addr_count);
+    mClient->decRef();
+}
+
+
+/*******************************************************
+ *                  GetHostByAddr                      *
+ *******************************************************/
+DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd() : FrameworkCommand("gethostbyaddr") {}
+
+int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
+                                            int argc, char **argv) {
+    if (DBG) logArguments(argc, argv);
+
+    if (argc != 5) {
+        char* msg = nullptr;
+        asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc);
+        ALOGW("%s", msg);
+        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
+        free(msg);
+        return -1;
+    }
+
+    char* addrStr = argv[1];
+    int addrLen = strtol(argv[2], nullptr, 10);
+    int addrFamily = strtol(argv[3], nullptr, 10);
+    uid_t uid = cli->getUid();
+    unsigned netId = strtoul(argv[4], nullptr, 10);
+    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
+
+    void* addr = malloc(sizeof(in6_addr));
+    errno = 0;
+    int result = inet_pton(addrFamily, addrStr, addr);
+    if (result <= 0) {
+        char* msg = nullptr;
+        asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno));
+        ALOGW("%s", msg);
+        cli->sendMsg(ResponseCode::OperationFailed, msg, false);
+        free(addr);
+        free(msg);
+        return -1;
+    }
+
+    android_net_context netcontext;
+    gDnsProxyListener.mCallbacks.get_network_context(netId, uid, &netcontext);
+
+    if (useLocalNameservers) {
+        netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
+    }
+
+    DnsProxyListener::GetHostByAddrHandler* handler = new DnsProxyListener::GetHostByAddrHandler(
+            cli, addr, addrLen, addrFamily, netcontext);
+    tryThreadOrError(cli, handler);
+    return 0;
+}
+
+DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, void* address,
+                                                             int addressLen, int addressFamily,
+                                                             const android_net_context& netcontext)
+    : mClient(c),
+      mAddress(address),
+      mAddressLen(addressLen),
+      mAddressFamily(addressFamily),
+      mNetContext(netcontext) {}
+
+DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() {
+    free(mAddress);
+}
+
+void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent** hpp) {
+    if (*hpp != nullptr || mAddressFamily != AF_INET6 || !mAddress) {
+        return;
+    }
+
+    netdutils::IPPrefix prefix{};
+    if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
+        return;
+    }
+
+    if (!isValidNat64Prefix(prefix)) {
+        return;
+    }
+
+    struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
+    struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
+    struct in6_addr v6addr = *(in6_addr*) mAddress;
+    // Check if address has NAT64 prefix. Only /96 IPv6 NAT64 prefixes are supported
+    if ((v6addr.s6_addr32[0] != v6prefix->sin6_addr.s6_addr32[0]) ||
+        (v6addr.s6_addr32[1] != v6prefix->sin6_addr.s6_addr32[1]) ||
+        (v6addr.s6_addr32[2] != v6prefix->sin6_addr.s6_addr32[2])) {
+        return;
+    }
+
+    const uid_t uid = mClient->getUid();
+    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);
+        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.
+            memcpy((*hpp)->h_addr_list[0], &v6addr, sizeof(v6addr));
+            (*hpp)->h_addrtype = AF_INET6;
+            (*hpp)->h_length = sizeof(struct in6_addr);
+        }
+    } else {
+        ALOGE("gethostbyaddr: from UID %d, max concurrent queries reached", uid);
+    }
+}
+
+void DnsProxyListener::GetHostByAddrHandler::run() {
+    if (DBG) {
+        ALOGD("DnsProxyListener::GetHostByAddrHandler::run");
+    }
+
+    Stopwatch s;
+    maybeFixupNetContext(&mNetContext);
+    const uid_t uid = mClient->getUid();
+    hostent* hp = nullptr;
+    int32_t rv = 0;
+    if (queryLimiter.start(uid)) {
+        rv = android_gethostbyaddrfornetcontext(mAddress, mAddressLen, mAddressFamily,
+                                                &mNetContext, &hp);
+        queryLimiter.finish(uid);
+    } else {
+        rv = EAI_MEMORY;
+        ALOGE("gethostbyaddr: from UID %d, max concurrent queries reached", uid);
+    }
+
+    doDns64ReverseLookup(&hp);
+    const int latencyUs = int(s.timeTakenUs());
+
+    if (DBG) {
+        ALOGD("GetHostByAddrHandler::run gethostbyaddr result: %s hp->h_name = %s, name_len = %zu",
+              hp ? "success" : gai_strerror(rv), (hp && hp->h_name) ? hp->h_name : "null",
+              (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0);
+    }
+
+    bool success = true;
+    if (hp) {
+        success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
+        success &= sendhostent(mClient, hp);
+    } else {
+        success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
+    }
+
+    if (!success) {
+        ALOGW("GetHostByAddrHandler: Error writing DNS result to client");
+    }
+
+    reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv,
+                   (hp && hp->h_name) ? hp->h_name : "null", {}, 0);
+    mClient->decRef();
+}
+
+}  // namespace net
+}  // namespace android
diff --git a/include/netd_resolv/DnsProxyListener.h b/include/netd_resolv/DnsProxyListener.h
new file mode 100644
index 0000000..ef9a3da
--- /dev/null
+++ b/include/netd_resolv/DnsProxyListener.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DNSPROXYLISTENER_H__
+#define _DNSPROXYLISTENER_H__
+
+#include <sysutils/FrameworkCommand.h>
+#include <sysutils/FrameworkListener.h>
+
+#include "resolv.h"  // android_net_context
+
+namespace android {
+namespace net {
+
+class DnsProxyListener : public FrameworkListener {
+  public:
+    DnsProxyListener();
+    virtual ~DnsProxyListener() {}
+
+    bool setCallbacks(const dnsproxylistener_callbacks& callbacks);
+
+    static constexpr const char* SOCKET_NAME = "dnsproxyd";
+
+    // TODO: Considering putting this callbacks structure in its own file.
+    dnsproxylistener_callbacks mCallbacks{};
+
+  private:
+    class GetAddrInfoCmd : public FrameworkCommand {
+      public:
+        GetAddrInfoCmd();
+        virtual ~GetAddrInfoCmd() {}
+        int runCommand(SocketClient* c, int argc, char** argv) override;
+    };
+
+    /* ------ getaddrinfo ------*/
+    class GetAddrInfoHandler {
+      public:
+        // Note: All of host, service, and hints may be NULL
+        GetAddrInfoHandler(SocketClient* c, char* host, char* service, addrinfo* hints,
+                           const android_net_context& netcontext);
+        ~GetAddrInfoHandler();
+
+        void run();
+
+      private:
+        void doDns64Synthesis(int32_t* rv, addrinfo** res);
+
+        SocketClient* mClient;  // ref counted
+        char* mHost;            // owned. TODO: convert to std::string.
+        char* mService;         // owned. TODO: convert to std::string.
+        addrinfo* mHints;       // owned
+        android_net_context mNetContext;
+    };
+
+    /* ------ gethostbyname ------*/
+    class GetHostByNameCmd : public FrameworkCommand {
+      public:
+        GetHostByNameCmd();
+        virtual ~GetHostByNameCmd() {}
+        int runCommand(SocketClient* c, int argc, char** argv) override;
+    };
+
+    class GetHostByNameHandler {
+      public:
+        GetHostByNameHandler(SocketClient* c, char* name, int af,
+                             const android_net_context& netcontext);
+        ~GetHostByNameHandler();
+
+        void run();
+
+      private:
+        void doDns64Synthesis(int32_t* rv, hostent** hpp);
+
+        SocketClient* mClient; //ref counted
+        char* mName;           // owned. TODO: convert to std::string.
+        int mAf;
+        android_net_context mNetContext;
+    };
+
+    /* ------ gethostbyaddr ------*/
+    class GetHostByAddrCmd : public FrameworkCommand {
+      public:
+        GetHostByAddrCmd();
+        virtual ~GetHostByAddrCmd() {}
+        int runCommand(SocketClient* c, int argc, char** argv) override;
+    };
+
+    class GetHostByAddrHandler {
+      public:
+        GetHostByAddrHandler(SocketClient* c, void* address, int addressLen, int addressFamily,
+                             const android_net_context& netcontext);
+        ~GetHostByAddrHandler();
+
+        void run();
+
+      private:
+        void doDns64ReverseLookup(hostent** hpp);
+
+        SocketClient* mClient;  // ref counted
+        void* mAddress;    // address to lookup; owned
+        int mAddressLen; // length of address to look up
+        int mAddressFamily;  // address family
+        android_net_context mNetContext;
+    };
+
+    /* ------ resnsend ------*/
+    class ResNSendCommand : public FrameworkCommand {
+      public:
+        ResNSendCommand();
+        ~ResNSendCommand() override {}
+        int runCommand(SocketClient* c, int argc, char** argv) override;
+    };
+
+    class ResNSendHandler {
+      public:
+        ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
+                        const android_net_context& netcontext);
+        ~ResNSendHandler();
+
+        void run();
+
+      private:
+        SocketClient* mClient;  // ref counted
+        std::string mMsg;
+        uint32_t mFlags;
+        android_net_context mNetContext;
+    };
+};
+
+}  // namespace net
+}  // namespace android
+
+#endif
diff --git a/include/netd_resolv/resolv.h b/include/netd_resolv/resolv.h
index 4f43107..dde600d 100644
--- a/include/netd_resolv/resolv.h
+++ b/include/netd_resolv/resolv.h
@@ -45,7 +45,7 @@
 } sockaddr_union;
 
 /*
- * Passing NETID_UNSET as the netId causes system/netd/server/DnsProxyListener.cpp to
+ * Passing NETID_UNSET as the netId causes system/netd/resolv/DnsProxyListener.cpp to
  * fill in the appropriate default netId for the query.
  */
 #define NETID_UNSET 0u
@@ -101,9 +101,31 @@
     } serverStatus[MAXNS];
 };
 
+/*
+ * Some of functions (e.g. checkCallingPermission()) require the dependency on libbinder.so,
+ * but we can't include the library since it's not stable. Move the functions to netd and use
+ * these function pointers pointing to them.
+ */
+typedef void (*get_network_context_callback)(unsigned netid, uid_t uid,
+                                             android_net_context* netcontext);
+
+// TODO: investigate having the resolver check permissions itself, either by adding support to
+// libbinder_ndk or by converting IPermissionController into a stable AIDL interface.
+typedef bool (*check_calling_permission_callback)(const char* permission);
+
+// TODO: Remove the callback.
 typedef void (*private_dns_validated_callback)(unsigned netid, const char* server,
                                                const char* hostname, bool success);
 
+// TODO: Remove the callback after moving NAT64 prefix discovery out of netd to libnetd_resolv.
+typedef bool (*get_dns64_prefix_callback)(unsigned netid, in6_addr* prefix, uint8_t* prefix_len);
+
+struct dnsproxylistener_callbacks {
+    check_calling_permission_callback check_calling_permission;
+    get_network_context_callback get_network_context;
+    get_dns64_prefix_callback get_dns64_prefix;
+};
+
 LIBNETD_RESOLV_PUBLIC int android_gethostbyaddrfornetcontext(const void*, socklen_t, int,
                                                              const android_net_context*, hostent**);
 LIBNETD_RESOLV_PUBLIC int android_gethostbynamefornetcontext(const char*, int,
@@ -136,10 +158,14 @@
                                                                  ExternalPrivateDnsStatus* status);
 
 // Register callback to listen whether private DNS validated
+// TODO: Remove it. Use ResolverEventReporter instead.
 LIBNETD_RESOLV_PUBLIC void resolv_register_private_dns_callback(
         private_dns_validated_callback callback);
 
 // Delete the cache associated with a certain network
 LIBNETD_RESOLV_PUBLIC void resolv_delete_cache_for_net(unsigned netid);
 
+// Set callbacks to DnsProxyListener, and bring it up.
+LIBNETD_RESOLV_PUBLIC bool resolv_init(const dnsproxylistener_callbacks& callbacks);
+
 #endif  // NETD_RESOLV_RESOLV_H
diff --git a/include/netd_resolv/resolv_stub.h b/include/netd_resolv/resolv_stub.h
index b4364ba..9e09b44 100644
--- a/include/netd_resolv/resolv_stub.h
+++ b/include/netd_resolv/resolv_stub.h
@@ -63,6 +63,8 @@
 
     bool (*resolv_has_nameservers)(unsigned netid);
 
+    bool (*resolv_init)(const dnsproxylistener_callbacks& callbacks);
+
     void (*resolv_register_private_dns_callback)(private_dns_validated_callback callback);
 
     int (*resolv_res_nsend)(const android_net_context* netContext, const u_char* msg, int msgLen,
diff --git a/libnetd_resolv.map.txt b/libnetd_resolv.map.txt
index 175e3d8..336a7a9 100644
--- a/libnetd_resolv.map.txt
+++ b/libnetd_resolv.map.txt
@@ -30,6 +30,7 @@
     resolv_delete_private_dns_for_net;
     resolv_get_private_dns_status_for_net;
     resolv_has_nameservers;
+    resolv_init;
     resolv_register_private_dns_callback;
     resolv_res_nsend;
     resolv_set_nameservers_for_net;
