/*
 * 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 "DnsProxyListener.h"

#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 <resolv.h>  // b64_pton()
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>

#define LOG_TAG "resolv"

#include <algorithm>
#include <vector>

#include <NetdClient.h>  // NETID_USE_LOCAL_NAMESERVERS
#include <android-base/stringprintf.h>
#include <android/multinetwork.h>  // ResNsendFlags
#include <cutils/misc.h>           // FIRST_APPLICATION_UID
#include <cutils/multiuser.h>
#include <netdutils/InternetAddresses.h>
#include <netdutils/OperationLimiter.h>
#include <netdutils/ResponseCode.h>
#include <netdutils/Slice.h>
#include <netdutils/Stopwatch.h>
#include <netdutils/ThreadUtil.h>
#include <private/android_filesystem_config.h>  // AID_SYSTEM
#include <statslog_resolv.h>
#include <sysutils/SocketClient.h>

#include "DnsResolver.h"
#include "NetdPermissions.h"
#include "PrivateDnsConfiguration.h"
#include "ResolverEventReporter.h"
#include "getaddrinfo.h"
#include "gethnamaddr.h"
#include "res_send.h"
#include "resolv_cache.h"
#include "resolv_private.h"
#include "stats.h"  // RCODE_TIMEOUT
#include "stats.pb.h"

using aidl::android::net::metrics::INetdEventListener;
using android::net::NetworkDnsEventReported;

namespace android {

using netdutils::ResponseCode;
using netdutils::Stopwatch;

namespace net {
namespace {

// Limits the number of outstanding DNS queries by client UID.
constexpr int MAX_QUERIES_PER_UID = 256;

android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);

void logArguments(int argc, char** argv) {
    if (!WOULD_LOG(VERBOSE)) return;
    for (int i = 0; i < argc; i++) {
        LOG(VERBOSE) << __func__ << ": argv[" << i << "]=" << (argv[i] ? argv[i] : "null");
    }
}

template<typename T>
void tryThreadOrError(SocketClient* cli, T* handler) {
    cli->incRef();

    const int rval = netdutils::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;
}

bool queryingViaTls(unsigned dns_netid) {
    const auto privateDnsStatus = gPrivateDnsConfiguration.getStatus(dns_netid);
    switch (privateDnsStatus.mode) {
        case PrivateDnsMode::OPPORTUNISTIC:
            return !privateDnsStatus.validatedServers().empty();
        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 :
         {PERM_CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERM_NETWORK_BYPASS_PRIVATE_DNS,
          PERM_MAINLINE_NETWORK_STACK}) {
        if (gResNetdCallbacks.check_calling_permission(permission)) {
            return true;
        }
    }
    return false;
}

void maybeFixupNetContext(android_net_context* ctx, pid_t pid) {
    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_DNS_OVER_TLS | NET_CONTEXT_FLAG_USE_EDNS;
        }
    }
    ctx->pid = pid;
}

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 setQueryId(uint8_t* msg, size_t msgLen, uint16_t query_id) {
    if (msgLen < sizeof(HEADER)) {
        errno = EINVAL;
        return false;
    }
    auto hp = reinterpret_cast<HEADER*>(msg);
    hp->id = htons(query_id);
    return true;
}

bool parseQuery(const uint8_t* msg, size_t msgLen, uint16_t* query_id, 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;
    }
    *query_id = ns_msg_id(handle);
    *rr_name = ns_rr_name(rr);
    *rr_type = ns_rr_type(rr);
    return true;
}

// Note: Even if it returns PDM_OFF, it doesn't mean there's no DoT stats in the message
// because Private DNS mode can change at any time.
PrivateDnsModes getPrivateDnsModeForMetrics(uint32_t netId) {
    switch (gPrivateDnsConfiguration.getStatus(netId).mode) {
        case PrivateDnsMode::OFF:
            // It can also be due to netId not found.
            return PrivateDnsModes::PDM_OFF;
        case PrivateDnsMode::OPPORTUNISTIC:
            return PrivateDnsModes::PDM_OPPORTUNISTIC;
        case PrivateDnsMode::STRICT:
            return PrivateDnsModes::PDM_STRICT;
        default:
            return PrivateDnsModes::PDM_UNKNOWN;
    }
}

void initDnsEvent(NetworkDnsEventReported* event, const android_net_context& netContext) {
    // The value 0 has the special meaning of unset/unknown in Westworld atoms. So, we set both
    // flags to -1 as default value.
    //  1. The hints flag is only used in resolv_getaddrinfo. When user set it to -1 in
    //     resolv_getaddrinfo, the flag will cause validation (validateHints) failure in
    //     getaddrinfo, so it will not do DNS query and will upload DNS stats log with
    //     return_code = RC_EAI_BADFLAGS.
    //  2. The res_nsend flags are only used in resolv_res_nsend. When user set it to -1 in
    //     resolv_res_nsend,res_nsend will do nothing special by the setting.
    event->set_hints_ai_flags(-1);
    event->set_res_nsend_flags(-1);
    event->set_private_dns_modes(getPrivateDnsModeForMetrics(netContext.dns_netid));
}

// Return 0 if the event should not be logged.
// Otherwise, return subsampling_denom
uint32_t getDnsEventSubsamplingRate(int netid, int returnCode) {
    uint32_t subsampling_denom = resolv_cache_get_subsampling_denom(netid, returnCode);
    if (subsampling_denom == 0) return 0;
    // Sample the event with a chance of 1 / denom.
    return (arc4random_uniform(subsampling_denom) == 0) ? subsampling_denom : 0;
}

void maybeLogQuery(int eventType, const android_net_context& netContext,
                   const NetworkDnsEventReported& event, const std::string& query_name,
                   const std::vector<std::string>& ip_addrs) {
    // Skip reverse queries.
    if (eventType == INetdEventListener::EVENT_GETHOSTBYADDR) return;

    for (const auto& query : event.dns_query_events().dns_query_event()) {
        // Log it when the cache misses.
        if (query.cache_hit() != CS_FOUND) {
            const int timeTakenMs = event.latency_micros() / 1000;
            DnsQueryLog::Record record(netContext.dns_netid, netContext.uid, netContext.pid,
                                       query_name, ip_addrs, timeTakenMs);
            gDnsResolv->dnsQueryLog().push(std::move(record));
            return;
        }
    }
}

void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs,
                    int returnCode, NetworkDnsEventReported& event, const std::string& query_name,
                    const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) {
    if (uint32_t rate = getDnsEventSubsamplingRate(netContext.dns_netid, returnCode)) {
        const std::string& dnsQueryStats = event.dns_query_events().SerializeAsString();
        stats::BytesField dnsQueryBytesField{dnsQueryStats.c_str(), dnsQueryStats.size()};
        event.set_return_code(static_cast<ReturnCode>(returnCode));
        android::net::stats::stats_write(android::net::stats::NETWORK_DNS_EVENT_REPORTED,
                                         event.event_type(), event.return_code(),
                                         event.latency_micros(), event.hints_ai_flags(),
                                         event.res_nsend_flags(), event.network_type(),
                                         event.private_dns_modes(), dnsQueryBytesField, rate);
    }

    maybeLogQuery(eventType, netContext, event, query_name, ip_addrs);

    const auto& listeners = ResolverEventReporter::getInstance().getListeners();
    if (listeners.size() == 0) {
        LOG(ERROR) << __func__
                   << ": DNS event not sent since no INetdEventListener receiver is available.";
        return;
    }
    const int latencyMs = latencyUs / 1000;
    for (const auto& it : listeners) {
        it->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 (!WOULD_LOG(DEBUG)) return;
    if (hp == nullptr) return;

    LOG(DEBUG) << __func__ << ": 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) {
            LOG(DEBUG) << __func__ << ": [" << i << "] " << hp->h_addrtype;
        } else {
            PLOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail";
        }
    }
}

void logDnsQueryResult(const addrinfo* res) {
    if (!WOULD_LOG(DEBUG)) return;
    if (res == nullptr) return;

    int i;
    const addrinfo* ai;
    LOG(DEBUG) << __func__ << ": 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) {
            LOG(DEBUG) << __func__ << ": [" << i << "] " << ai->ai_flags << " " << ai->ai_family
                       << " " << ai->ai_socktype << " " << ai->ai_protocol;
        } else {
            LOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail " << ret;
        }
    }
}

bool isValidNat64Prefix(const netdutils::IPPrefix prefix) {
    if (prefix.family() != AF_INET6) {
        LOG(ERROR) << __func__ << ": Only IPv6 NAT64 prefixes are supported " << prefix.family();
        return false;
    }
    if (prefix.length() != 96) {
        LOG(ERROR) << __func__ << ": Only /96 NAT64 prefixes are supported " << 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 (WOULD_LOG(VERBOSE)) {
            char buf[INET6_ADDRSTRLEN];  // big enough for either IPv4 or IPv6
            inet_ntop(AF_INET, &iaOriginal.s_addr, buf, sizeof(buf));
            LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
            inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
            LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
            inet_ntop(AF_INET6, ia6, buf, sizeof(buf));
            LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
        }
    }
    hp->h_addrtype = AF_INET6;
    hp->h_length = sizeof(in6_addr);

    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 (WOULD_LOG(VERBOSE)) {
            char buf[INET6_ADDRSTRLEN];  // big enough for either IPv4 or IPv6
            inet_ntop(AF_INET, &sinOriginal.sin_addr.s_addr, buf, sizeof(buf));
            LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
            inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
            LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
            inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf));
            LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
        }
    }
    logDnsQueryResult(result);
    return true;
}

bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) {
    return !gDnsResolv->resolverCtrl.getPrefix64(netId, prefix);
}

std::string makeThreadName(unsigned netId, uint32_t uid) {
    // The maximum of netId and app_id are 5-digit numbers.
    return android::base::StringPrintf("Dns_%u_%u", netId, multiuser_get_app_id(uid));
}

}  // namespace

DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) {
    registerCmd(new GetAddrInfoCmd());
    registerCmd(new GetHostByAddrCmd());
    registerCmd(new GetHostByNameCmd());
    registerCmd(new ResNSendCommand());
    registerCmd(new GetDnsNetIdCommand());
}

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 evaluate_domain_name(const android_net_context &netcontext,
                                 const char *host) {
    if (!gResNetdCallbacks.evaluate_domain_name)
        return true;
    return gResNetdCallbacks.evaluate_domain_name(netcontext, host);
}

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,
                                                            NetworkDnsEventReported* event) {
    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 = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, res, event);
            queryLimiter.finish(uid);
            if (*rv) {
                *rv = EAI_NODATA;  // return original error code
                return;
            }
        } else {
            LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
            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() {
    LOG(DEBUG) << "GetAddrInfoHandler::run: {" << mNetContext.app_netid << " "
               << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
               << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";

    addrinfo* result = nullptr;
    Stopwatch s;
    maybeFixupNetContext(&mNetContext, mClient->getPid());
    const uid_t uid = mClient->getUid();
    int32_t rv = 0;
    NetworkDnsEventReported event;
    initDnsEvent(&event, mNetContext);
    if (queryLimiter.start(uid)) {
        if (evaluate_domain_name(mNetContext, mHost)) {
            rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result,
                                    &event);
        } else {
            rv = EAI_SYSTEM;
        }
        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;
        LOG(ERROR) << "GetAddrInfoHandler::run: from UID " << uid
                   << ", max concurrent queries reached";
    }

    doDns64Synthesis(&rv, &result, &event);
    const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
    event.set_latency_micros(latencyUs);
    event.set_event_type(EVENT_GETADDRINFO);
    event.set_hints_ai_flags((mHints ? mHints->ai_flags : 0));

    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) {
            LOG(WARNING) << "GetAddrInfoHandler::run: 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, event, mHost,
                   ip_addrs, total_ip_addr_count);
    freeaddrinfo(result);
    mClient->decRef();
}

std::string DnsProxyListener::GetAddrInfoHandler::threadName() {
    return makeThreadName(mNetContext.dns_netid, mClient->getUid());
}

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) {
    logArguments(argc, argv);

    if (argc != 8) {
        char* msg = nullptr;
        asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc);
        LOG(WARNING) << "GetAddrInfoCmd::runCommand: " << (msg ? msg : "null");
        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;
    gResNetdCallbacks.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;
    }

    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) {
    logArguments(argc, argv);

    const uid_t uid = cli->getUid();
    if (argc != 4) {
        LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
                     << ", invalid number of arguments to resnsend: " << argc;
        sendBE32(cli, -EINVAL);
        return -1;
    }

    unsigned netId;
    if (!simpleStrtoul(argv[1], &netId)) {
        LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
                     << ", invalid netId";
        sendBE32(cli, -EINVAL);
        return -1;
    }

    uint32_t flags;
    if (!simpleStrtoul(argv[2], &flags)) {
        LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
                     << ", invalid flags";
        sendBE32(cli, -EINVAL);
        return -1;
    }

    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);

    android_net_context netcontext;
    gResNetdCallbacks.get_network_context(netId, uid, &netcontext);

    if (useLocalNameservers) {
        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() {
    LOG(DEBUG) << "ResNSendHandler::run: " << mFlags << " / {" << mNetContext.app_netid << " "
               << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
               << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";

    Stopwatch s;
    maybeFixupNetContext(&mNetContext, mClient->getPid());

    // 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;
    uint16_t original_query_id = 0;

    // TODO: Handle the case which is msg contains more than one query
    if (!parseQuery(msg.data(), msgLen, &original_query_id, &rr_type, &rr_name) ||
        !setQueryId(msg.data(), msgLen, arc4random_uniform(65536))) {
        // If the query couldn't be parsed, block the request.
        LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", invalid query";
        sendBE32(mClient, -EINVAL);
        return;
    }

    // Send DNS query
    std::vector<uint8_t> ansBuf(MAXPACKET, 0);
    int rcode = ns_r_noerror;
    int nsendAns = -1;
    NetworkDnsEventReported event;
    initDnsEvent(&event, mNetContext);
    if (queryLimiter.start(uid)) {
        if (evaluate_domain_name(mNetContext, rr_name.c_str())) {
            nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET,
                                        &rcode, static_cast<ResNsendFlags>(mFlags), &event);
        } else {
            nsendAns = -EAI_SYSTEM;
        }
        queryLimiter.finish(uid);
    } else {
        LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid
                     << ", max concurrent queries reached";
        nsendAns = -EBUSY;
    }

    const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
    event.set_latency_micros(latencyUs);
    event.set_event_type(EVENT_RES_NSEND);
    event.set_res_nsend_flags(static_cast<ResNsendFlags>(mFlags));

    // 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, rcode), event, rr_name);
        }
        return;
    }

    // Send rcode
    if (!sendBE32(mClient, rcode)) {
        PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send rcode to uid " << uid;
        return;
    }

    // Restore query id and send answer
    if (!setQueryId(ansBuf.data(), nsendAns, original_query_id) ||
        !sendLenAndData(mClient, nsendAns, ansBuf.data())) {
        PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send answer to uid " << uid;
        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, rcode), event, rr_name, ip_addrs,
                       total_ip_addr_count);
    }
}

std::string DnsProxyListener::ResNSendHandler::threadName() {
    return makeThreadName(mNetContext.dns_netid, mClient->getUid());
}

namespace {

bool sendCodeAndBe32(SocketClient* c, int code, int data) {
    return !c->sendCode(code) && sendBE32(c, data);
}

}  // namespace

/*******************************************************
 *                  GetDnsNetId                        *
 *******************************************************/
DnsProxyListener::GetDnsNetIdCommand::GetDnsNetIdCommand() : FrameworkCommand("getdnsnetid") {}

int DnsProxyListener::GetDnsNetIdCommand::runCommand(SocketClient* cli, int argc, char** argv) {
    logArguments(argc, argv);

    const uid_t uid = cli->getUid();
    if (argc != 2) {
        LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
                     << ", invalid number of arguments to getdnsnetid: " << argc;
        sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
        return -1;
    }

    unsigned netId;
    if (!simpleStrtoul(argv[1], &netId)) {
        LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
                     << ", invalid netId";
        sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
        return -1;
    }

    const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
    android_net_context netcontext;
    gResNetdCallbacks.get_network_context(netId, uid, &netcontext);

    if (useLocalNameservers) {
        netcontext.app_netid |= NETID_USE_LOCAL_NAMESERVERS;
    }

    return sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, netcontext.app_netid) ? 0 : -1;
}

/*******************************************************
 *                  GetHostByName                      *
 *******************************************************/
DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd() : FrameworkCommand("gethostbyname") {}

int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
                                            int argc, char **argv) {
    logArguments(argc, argv);

    if (argc != 4) {
        char* msg = nullptr;
        asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc);
        LOG(WARNING) << "GetHostByNameCmd::runCommand: " << (msg ? msg : "null");
        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;
    gResNetdCallbacks.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, hostent* hbuf, char* buf,
                                                              size_t buflen, struct hostent** hpp,
                                                              NetworkDnsEventReported* event) {
    // 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 = resolv_gethostbyname(mName, AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event);
        queryLimiter.finish(uid);
        if (*rv) {
            *rv = EAI_NODATA;  // return original error code
            return;
        }
    } else {
        LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
        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() {
    Stopwatch s;
    maybeFixupNetContext(&mNetContext, mClient->getPid());
    const uid_t uid = mClient->getUid();
    hostent* hp = nullptr;
    hostent hbuf;
    char tmpbuf[MAXPACKET];
    int32_t rv = 0;
    NetworkDnsEventReported event;
    initDnsEvent(&event, mNetContext);
    if (queryLimiter.start(uid)) {
        if (evaluate_domain_name(mNetContext, mName)) {
            rv = resolv_gethostbyname(mName, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp,
                                      &event);
        } else {
            rv = EAI_SYSTEM;
        }
        queryLimiter.finish(uid);
    } else {
        rv = EAI_MEMORY;
        LOG(ERROR) << "GetHostByNameHandler::run: from UID " << uid
                   << ", max concurrent queries reached";
    }

    doDns64Synthesis(&rv, &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_GETHOSTBYNAME);

    LOG(DEBUG) << "GetHostByNameHandler::run: result: " << gai_strerror(rv);

    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) {
        LOG(WARNING) << "GetHostByNameHandler::run: 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, event,
                   mName, ip_addrs, total_ip_addr_count);
    mClient->decRef();
}

std::string DnsProxyListener::GetHostByNameHandler::threadName() {
    return makeThreadName(mNetContext.dns_netid, mClient->getUid());
}

/*******************************************************
 *                  GetHostByAddr                      *
 *******************************************************/
DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd() : FrameworkCommand("gethostbyaddr") {}

int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
                                            int argc, char **argv) {
    logArguments(argc, argv);

    if (argc != 5) {
        char* msg = nullptr;
        asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc);
        LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
        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));
        LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
        cli->sendMsg(ResponseCode::OperationFailed, msg, false);
        free(addr);
        free(msg);
        return -1;
    }

    android_net_context netcontext;
    gResNetdCallbacks.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(hostent* hbuf, char* buf,
                                                                  size_t buflen,
                                                                  struct hostent** hpp,
                                                                  NetworkDnsEventReported* event) {
    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]};
        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 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);
        }
    } else {
        LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
    }
}

void DnsProxyListener::GetHostByAddrHandler::run() {
    Stopwatch s;
    maybeFixupNetContext(&mNetContext, mClient->getPid());
    const uid_t uid = mClient->getUid();
    hostent* hp = nullptr;
    hostent hbuf;
    char tmpbuf[MAXPACKET];
    int32_t rv = 0;
    NetworkDnsEventReported event;
    initDnsEvent(&event, mNetContext);
    if (queryLimiter.start(uid)) {
        rv = resolv_gethostbyaddr(mAddress, mAddressLen, mAddressFamily, &hbuf, tmpbuf,
                                  sizeof tmpbuf, &mNetContext, &hp, &event);
        queryLimiter.finish(uid);
    } else {
        rv = EAI_MEMORY;
        LOG(ERROR) << "GetHostByAddrHandler::run: from UID " << uid
                   << ", max concurrent queries reached";
    }

    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: " << gai_strerror(rv);

    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) {
        LOG(WARNING) << "GetHostByAddrHandler::run: Error writing DNS result to client";
    }

    reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event,
                   (hp && hp->h_name) ? hp->h_name : "null", {}, 0);
    mClient->decRef();
}

std::string DnsProxyListener::GetHostByAddrHandler::threadName() {
    return makeThreadName(mNetContext.dns_netid, mClient->getUid());
}

}  // namespace net
}  // namespace android
