/*	$NetBSD: gethnamaddr.c,v 1.91 2014/06/19 15:08:18 christos Exp $	*/

/*
 * ++Copyright++ 1985, 1988, 1993
 * -
 * Copyright (c) 1985, 1988, 1993
 *    The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * -
 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies, and that
 * the name of Digital Equipment Corporation not be used in advertising or
 * publicity pertaining to distribution of the document or software without
 * specific, written prior permission.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 * -
 * --Copyright--
 */

#include "gethnamaddr.h"

#include <android-base/logging.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <functional>
#include <vector>

#include "hostent.h"
#include "netd_resolv/resolv.h"
#include "resolv_cache.h"
#include "resolv_private.h"
#include "resolv_static.h"
#include "stats.pb.h"

using android::net::NetworkDnsEventReported;

// NetBSD uses _DIAGASSERT to null-check arguments and the like,
// but it's clear from the number of mistakes in their assertions
// that they don't actually test or ship with this.
#define _DIAGASSERT(e) /* nothing */

// TODO: unify macro ALIGNBYTES and ALIGN for all possible data type alignment of hostent
// buffer.
#define ALIGNBYTES (sizeof(uintptr_t) - 1)
#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) & ~ALIGNBYTES)

#define maybe_ok(res, nm, ok) ((ok)(nm) != 0)
#define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok)
#define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok)

#define MAXPACKET (8 * 1024)

typedef union {
    HEADER hdr;
    uint8_t buf[MAXPACKET];
} querybuf;

typedef union {
    int32_t al;
    char ac;
} align;

static void convert_v4v6_hostent(struct hostent* hp, char** bpp, char* ep,
                                 const std::function<void(struct hostent* hp)>& mapping_param,
                                 const std::function<void(char* src, char* dst)>& mapping_addr);
static void pad_v4v6_hostent(struct hostent* hp, char** bpp, char* ep);

static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
                           const android_net_context* netcontext, getnamaddr* info,
                           NetworkDnsEventReported* event);
static int dns_gethtbyname(const char* name, int af, getnamaddr* info);

static int android_gethostbyaddrfornetcontext_proxy_internal(const void*, socklen_t, int,
                                                             struct hostent*, char*, size_t,
                                                             const struct android_net_context*,
                                                             NetworkDnsEventReported* event);
static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
                                                    const struct android_net_context* netcontext,
                                                    hostent** hp, NetworkDnsEventReported* event);

#define BOUNDED_INCR(x)      \
    do {                     \
        BOUNDS_CHECK(cp, x); \
        cp += (x);           \
    } while (0)

#define BOUNDS_CHECK(ptr, count)                     \
    do {                                             \
        if (eom - (ptr) < (count)) goto no_recovery; \
    } while (0)

static struct hostent* getanswer(const querybuf* answer, int anslen, const char* qname, int qtype,
                                 struct hostent* hent, char* buf, size_t buflen, int* he) {
    const HEADER* hp;
    const uint8_t* cp;
    int n;
    size_t qlen;
    const uint8_t *eom, *erdata;
    char *bp, **hap, *ep;
    int ancount, qdcount;
    int haveanswer, had_error;
    int toobig = 0;
    char tbuf[MAXDNAME];
    char* addr_ptrs[MAXADDRS];
    const char* tname;
    int (*name_ok)(const char*);
    std::vector<char*> aliases;

    _DIAGASSERT(answer != NULL);
    _DIAGASSERT(qname != NULL);

    tname = qname;
    hent->h_name = NULL;
    eom = answer->buf + anslen;
    switch (qtype) {
        case T_A:
        case T_AAAA:
            name_ok = res_hnok;
            break;
        case T_PTR:
            name_ok = res_dnok;
            break;
        default:
            *he = NO_RECOVERY;
            return NULL; /* XXX should be abort(); */
    }

    /*
     * find first satisfactory answer
     */
    hp = &answer->hdr;
    ancount = ntohs(hp->ancount);
    qdcount = ntohs(hp->qdcount);
    bp = buf;
    ep = buf + buflen;
    cp = answer->buf;
    BOUNDED_INCR(HFIXEDSZ);
    if (qdcount != 1) goto no_recovery;

    n = dn_expand(answer->buf, eom, cp, bp, (int) (ep - bp));
    if ((n < 0) || !maybe_ok(res, bp, name_ok)) goto no_recovery;

    BOUNDED_INCR(n + QFIXEDSZ);
    if (qtype == T_A || qtype == T_AAAA) {
        /* res_send() has already verified that the query name is the
         * same as the one we sent; this just gets the expanded name
         * (i.e., with the succeeding search-domain tacked on).
         */
        n = (int) strlen(bp) + 1; /* for the \0 */
        if (n >= MAXHOSTNAMELEN) goto no_recovery;
        hent->h_name = bp;
        bp += n;
        /* The qname can be abbreviated, but h_name is now absolute. */
        qname = hent->h_name;
    }
    hent->h_addr_list = hap = addr_ptrs;
    *hap = NULL;
    haveanswer = 0;
    had_error = 0;
    while (ancount-- > 0 && cp < eom && !had_error) {
        n = dn_expand(answer->buf, eom, cp, bp, (int) (ep - bp));
        if ((n < 0) || !maybe_ok(res, bp, name_ok)) {
            had_error++;
            continue;
        }
        cp += n; /* name */
        BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
        int type = ntohs(*reinterpret_cast<const uint16_t*>(cp));
        cp += INT16SZ; /* type */
        int cl = ntohs(*reinterpret_cast<const uint16_t*>(cp));
        cp += INT16SZ + INT32SZ; /* class, TTL */
        n = ntohs(*reinterpret_cast<const uint16_t*>(cp));
        cp += INT16SZ; /* len */
        BOUNDS_CHECK(cp, n);
        erdata = cp + n;
        if (cl != C_IN) {
            /* XXX - debug? syslog? */
            cp += n;
            continue; /* XXX - had_error++ ? */
        }
        if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
            n = dn_expand(answer->buf, eom, cp, tbuf, (int) sizeof tbuf);
            if ((n < 0) || !maybe_ok(res, tbuf, name_ok)) {
                had_error++;
                continue;
            }
            cp += n;
            if (cp != erdata) goto no_recovery;
            /* Store alias. */
            aliases.push_back(bp);
            n = (int) strlen(bp) + 1; /* for the \0 */
            if (n >= MAXHOSTNAMELEN) {
                had_error++;
                continue;
            }
            bp += n;
            /* Get canonical name. */
            n = (int) strlen(tbuf) + 1; /* for the \0 */
            if (n > ep - bp || n >= MAXHOSTNAMELEN) {
                had_error++;
                continue;
            }
            strlcpy(bp, tbuf, (size_t)(ep - bp));
            hent->h_name = bp;
            bp += n;
            continue;
        }
        if (qtype == T_PTR && type == T_CNAME) {
            n = dn_expand(answer->buf, eom, cp, tbuf, (int) sizeof tbuf);
            if (n < 0 || !maybe_dnok(res, tbuf)) {
                had_error++;
                continue;
            }
            cp += n;
            if (cp != erdata) goto no_recovery;
            /* Get canonical name. */
            n = (int) strlen(tbuf) + 1; /* for the \0 */
            if (n > ep - bp || n >= MAXHOSTNAMELEN) {
                had_error++;
                continue;
            }
            strlcpy(bp, tbuf, (size_t)(ep - bp));
            tname = bp;
            bp += n;
            continue;
        }
        if (type != qtype) {
            if (type != T_KEY && type != T_SIG)
                LOG(DEBUG) << __func__ << ": asked for \"" << qname << " " << p_class(C_IN) << " "
                           << p_type(qtype) << "\", got type \"" << p_type(type) << "\"";
            cp += n;
            continue; /* XXX - had_error++ ? */
        }
        switch (type) {
            case T_PTR:
                if (strcasecmp(tname, bp) != 0) {
                    LOG(DEBUG) << __func__ << ": asked for \"" << qname << "\", got \"" << bp
                               << "\"";
                    cp += n;
                    continue; /* XXX - had_error++ ? */
                }
                n = dn_expand(answer->buf, eom, cp, bp, (int) (ep - bp));
                if ((n < 0) || !maybe_hnok(res, bp)) {
                    had_error++;
                    break;
                }
                cp += n;
                if (cp != erdata) goto no_recovery;
                if (!haveanswer)
                    hent->h_name = bp;
                else
                    aliases.push_back(bp);
                if (n != -1) {
                    n = (int) strlen(bp) + 1; /* for the \0 */
                    if (n >= MAXHOSTNAMELEN) {
                        had_error++;
                        break;
                    }
                    bp += n;
                }
                break;
            case T_A:
            case T_AAAA:
                if (strcasecmp(hent->h_name, bp) != 0) {
                    LOG(DEBUG) << __func__ << ": asked for \"" << hent->h_name << "\", got \"" << bp
                               << "\"";
                    cp += n;
                    continue; /* XXX - had_error++ ? */
                }
                if (n != hent->h_length) {
                    cp += n;
                    continue;
                }
                if (type == T_AAAA) {
                    struct in6_addr in6;
                    memcpy(&in6, cp, NS_IN6ADDRSZ);
                    if (IN6_IS_ADDR_V4MAPPED(&in6)) {
                        cp += n;
                        continue;
                    }
                }
                if (!haveanswer) {
                    int nn;

                    hent->h_name = bp;
                    nn = (int) strlen(bp) + 1; /* for the \0 */
                    bp += nn;
                }

                bp += sizeof(align) - (size_t)((uintptr_t)bp % sizeof(align));

                if (bp + n >= ep) {
                    LOG(DEBUG) << __func__ << ": size (" << n << ") too big";
                    had_error++;
                    continue;
                }
                if (hap >= &addr_ptrs[MAXADDRS - 1]) {
                    if (!toobig++) {
                        LOG(DEBUG) << __func__ << ": Too many addresses (" << MAXADDRS << ")";
                    }
                    cp += n;
                    continue;
                }
                (void) memcpy(*hap++ = bp, cp, (size_t) n);
                bp += n;
                cp += n;
                if (cp != erdata) goto no_recovery;
                break;
            default:
                abort();
        }
        if (!had_error) haveanswer++;
    }
    if (haveanswer) {
        *hap = NULL;
        if (!hent->h_name) {
            n = (int) strlen(qname) + 1; /* for the \0 */
            if (n > ep - bp || n >= MAXHOSTNAMELEN) goto no_recovery;
            strlcpy(bp, qname, (size_t)(ep - bp));
            hent->h_name = bp;
            bp += n;
        }
        if (hent->h_addrtype == AF_INET) pad_v4v6_hostent(hent, &bp, ep);
        goto success;
    }
no_recovery:
    *he = NO_RECOVERY;
    return NULL;
success:
    bp = (char*) ALIGN(bp);
    aliases.push_back(nullptr);
    qlen = aliases.size() * sizeof(*hent->h_aliases);
    if ((size_t)(ep - bp) < qlen) goto nospc;
    hent->h_aliases = (char**) bp;
    memcpy(bp, aliases.data(), qlen);

    bp += qlen;
    n = (int) (hap - addr_ptrs);
    qlen = (n + 1) * sizeof(*hent->h_addr_list);
    if ((size_t)(ep - bp) < qlen) goto nospc;
    hent->h_addr_list = (char**) bp;
    memcpy(bp, addr_ptrs, qlen);
    *he = NETDB_SUCCESS;
    return hent;
nospc:
    errno = ENOSPC;
    *he = NETDB_INTERNAL;
    return NULL;
}

int resolv_gethostbyname(const char* name, int af, hostent* hp, char* buf, size_t buflen,
                         const android_net_context* netcontext, hostent** result,
                         NetworkDnsEventReported* event) {
    getnamaddr info;

    res_state res = res_get_state();
    if (res == nullptr) return EAI_MEMORY;
    res_setnetcontext(res, netcontext, event);

    size_t size;
    switch (af) {
        case AF_INET:
            size = NS_INADDRSZ;
            break;
        case AF_INET6:
            size = NS_IN6ADDRSZ;
            break;
        default:
            return EAI_FAMILY;
    }
    if (buflen < size) goto nospc;

    hp->h_addrtype = af;
    hp->h_length = (int) size;

    /*
     * disallow names consisting only of digits/dots, unless
     * they end in a dot.
     */
    if (isdigit((uint8_t)name[0])) {
        for (const char* cp = name;; ++cp) {
            if (!*cp) {
                if (*--cp == '.') break;
                /*
                 * All-numeric, no dot at the end.
                 * Fake up a hostent as if we'd actually
                 * done a lookup.
                 */
                goto fake;
            }
            if (!isdigit((uint8_t)*cp) && *cp != '.') break;
        }
    }
    if ((isxdigit((uint8_t)name[0]) && strchr(name, ':') != NULL) || name[0] == ':') {
        for (const char* cp = name;; ++cp) {
            if (!*cp) {
                if (*--cp == '.') break;
                /*
                 * All-IPv6-legal, no dot at the end.
                 * Fake up a hostent as if we'd actually
                 * done a lookup.
                 */
                goto fake;
            }
            if (!isxdigit((uint8_t)*cp) && *cp != ':' && *cp != '.') break;
        }
    }

    info.hp = hp;
    info.buf = buf;
    info.buflen = buflen;
    if (_hf_gethtbyname2(name, af, &info)) {
        int error = dns_gethtbyname(name, af, &info);
        if (error != 0) return error;
    }
    *result = hp;
    return 0;
nospc:
    return EAI_MEMORY;
fake:
    HENT_ARRAY(hp->h_addr_list, 1, buf, buflen);
    HENT_ARRAY(hp->h_aliases, 0, buf, buflen);

    hp->h_aliases[0] = NULL;
    if (size > buflen) goto nospc;

    if (inet_pton(af, name, buf) <= 0) {
        return EAI_NODATA;
    }
    hp->h_addr_list[0] = buf;
    hp->h_addr_list[1] = NULL;
    buf += size;
    buflen -= size;
    HENT_SCOPY(hp->h_name, name, buf, buflen);
    *result = hp;
    return 0;
}

static int android_gethostbyaddrfornetcontext_real(const void* addr, socklen_t len, int af,
                                                   struct hostent* hp, char* buf, size_t buflen,
                                                   const struct android_net_context* netcontext,
                                                   NetworkDnsEventReported* event) {
    const uint8_t* uaddr = (const uint8_t*)addr;
    socklen_t size;
    struct getnamaddr info;

    _DIAGASSERT(addr != NULL);

    if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
        (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr*) addr) ||
         IN6_IS_ADDR_SITELOCAL((const struct in6_addr*) addr))) {
        return EAI_NODATA;
    }
    if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
        (IN6_IS_ADDR_V4MAPPED((const struct in6_addr*) addr) ||
         IN6_IS_ADDR_V4COMPAT((const struct in6_addr*) addr))) {
        /* Unmap. */
        uaddr += NS_IN6ADDRSZ - NS_INADDRSZ;
        addr = uaddr;
        af = AF_INET;
        len = NS_INADDRSZ;
    }
    switch (af) {
        case AF_INET:
            size = NS_INADDRSZ;
            break;
        case AF_INET6:
            size = NS_IN6ADDRSZ;
            break;
        default:
            return EAI_FAMILY;
    }
    if (size != len) {
        // TODO: Consider converting to a private extended EAI_* error code.
        // Currently, the EAI_* value has no corresponding error code for invalid argument socket
        // length. In order to not rely on errno, convert the original error code pair, EAI_SYSTEM
        // and EINVAL, to EAI_FAIL.
        return EAI_FAIL;
    }
    info.hp = hp;
    info.buf = buf;
    info.buflen = buflen;
    if (_hf_gethtbyaddr(uaddr, len, af, &info)) {
        int error = dns_gethtbyaddr(uaddr, len, af, netcontext, &info, event);
        if (error != 0) return error;
    }
    return 0;
}

static int android_gethostbyaddrfornetcontext_proxy_internal(
        const void* addr, socklen_t len, int af, struct hostent* hp, char* hbuf, size_t hbuflen,
        const struct android_net_context* netcontext, NetworkDnsEventReported* event) {
    return android_gethostbyaddrfornetcontext_real(addr, len, af, hp, hbuf, hbuflen, netcontext,
                                                   event);
}

// TODO: Consider leaving function without returning error code as _gethtent() does because
// the error code of the caller does not currently return to netd.
struct hostent* netbsd_gethostent_r(FILE* hf, struct hostent* hent, char* buf, size_t buflen,
                                    int* he) {
    char *name;
    char* cp;
    int af, len;
    size_t anum;
    struct in6_addr host_addr;
    std::vector<char*> aliases;

    if (hf == NULL) {
        *he = NETDB_INTERNAL;
        errno = EINVAL;
        return NULL;
    }
    char* p = NULL;

    // Allocate a new space to read file lines like upstream does.
    const size_t line_buf_size = MAXPACKET;
    if ((p = (char*) malloc(line_buf_size)) == NULL) {
        goto nospc;
    }
    for (;;) {
        if (!fgets(p, line_buf_size, hf)) {
            free(p);
            *he = HOST_NOT_FOUND;
            return NULL;
        }
        if (*p == '#') {
            continue;
        }
        if (!(cp = strpbrk(p, "#\n"))) {
            continue;
        }
        *cp = '\0';
        if (!(cp = strpbrk(p, " \t"))) continue;
        *cp++ = '\0';
        if (inet_pton(AF_INET6, p, &host_addr) > 0) {
            af = AF_INET6;
            len = NS_IN6ADDRSZ;
        } else {
            if (inet_pton(AF_INET, p, &host_addr) <= 0) continue;

            res_state res = res_get_state();
            if (res == NULL) goto nospc;
            af = AF_INET;
            len = NS_INADDRSZ;
        }

        /* if this is not something we're looking for, skip it. */
        if (hent->h_addrtype != 0 && hent->h_addrtype != af) continue;
        if (hent->h_length != 0 && hent->h_length != len) continue;

        while (*cp == ' ' || *cp == '\t') cp++;
        if ((cp = strpbrk(name = cp, " \t")) != NULL) *cp++ = '\0';
        while (cp && *cp) {
            if (*cp == ' ' || *cp == '\t') {
                cp++;
                continue;
            }
            aliases.push_back(cp);
            if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0';
        }
        break;
    }
    hent->h_length = len;
    hent->h_addrtype = af;
    HENT_ARRAY(hent->h_addr_list, 1, buf, buflen);
    anum = aliases.size();
    HENT_ARRAY(hent->h_aliases, anum, buf, buflen);
    HENT_COPY(hent->h_addr_list[0], &host_addr, hent->h_length, buf, buflen);
    hent->h_addr_list[1] = NULL;

    /* Reserve space for mapping IPv4 address to IPv6 address in place */
    if (hent->h_addrtype == AF_INET) {
        HENT_COPY(buf, NAT64_PAD, sizeof(NAT64_PAD), buf, buflen);
    }

    HENT_SCOPY(hent->h_name, name, buf, buflen);
    for (size_t i = 0; i < anum; i++) HENT_SCOPY(hent->h_aliases[i], aliases[i], buf, buflen);
    hent->h_aliases[anum] = NULL;
    *he = NETDB_SUCCESS;
    free(p);
    return hent;
nospc:
    free(p);
    errno = ENOSPC;
    *he = NETDB_INTERNAL;
    return NULL;
}

static void convert_v4v6_hostent(struct hostent* hp, char** bpp, char* ep,
                                 const std::function<void(struct hostent* hp)>& map_param,
                                 const std::function<void(char* src, char* dst)>& map_addr) {
    _DIAGASSERT(hp != NULL);
    _DIAGASSERT(bpp != NULL);
    _DIAGASSERT(ep != NULL);

    if (hp->h_addrtype != AF_INET || hp->h_length != NS_INADDRSZ) return;
    map_param(hp);
    for (char** ap = hp->h_addr_list; *ap; ap++) {
        int i = (int)(sizeof(align) - (size_t)((uintptr_t)*bpp % sizeof(align)));

        if (ep - *bpp < (i + NS_IN6ADDRSZ)) {
            /* Out of memory.  Truncate address list here.  XXX */
            *ap = NULL;
            return;
        }
        *bpp += i;
        map_addr(*ap, *bpp);
        *ap = *bpp;
        *bpp += NS_IN6ADDRSZ;
    }
}

/* Reserve space for mapping IPv4 address to IPv6 address in place */
static void pad_v4v6_hostent(struct hostent* hp, char** bpp, char* ep) {
    convert_v4v6_hostent(hp, bpp, ep,
                         [](struct hostent* hp) {
                             (void) hp; /* unused */
                         },
                         [](char* src, char* dst) {
                             memcpy(dst, src, NS_INADDRSZ);
                             memcpy(dst + NS_INADDRSZ, NAT64_PAD, sizeof(NAT64_PAD));
                         });
}

static int dns_gethtbyname(const char* name, int addr_type, getnamaddr* info) {
    int n, type;
    info->hp->h_addrtype = addr_type;

    switch (info->hp->h_addrtype) {
        case AF_INET:
            info->hp->h_length = NS_INADDRSZ;
            type = T_A;
            break;
        case AF_INET6:
            info->hp->h_length = NS_IN6ADDRSZ;
            type = T_AAAA;
            break;
        default:
            return EAI_FAMILY;
    }
    auto buf = std::make_unique<querybuf>();

    res_state res = res_get_state();
    if (!res) return EAI_MEMORY;

    int he;
    n = res_nsearch(res, name, C_IN, type, buf->buf, (int)sizeof(buf->buf), &he);
    if (n < 0) {
        LOG(DEBUG) << __func__ << ": res_nsearch failed (" << n << ")";
        // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA.
        // Note that res_nsearch() doesn't set the pair NETDB_INTERNAL and errno.
        // See also herrnoToAiErrno().
        return herrnoToAiErrno(he);
    }
    hostent* hp = getanswer(buf.get(), n, name, type, info->hp, info->buf, info->buflen, &he);
    if (hp == NULL) return herrnoToAiErrno(he);

    return 0;
}

static int dns_gethtbyaddr(const unsigned char* uaddr, int len, int af,
                           const android_net_context* netcontext, getnamaddr* info,
                           NetworkDnsEventReported* event) {
    char qbuf[MAXDNAME + 1], *qp, *ep;
    int n;
    int advance;

    info->hp->h_length = len;
    info->hp->h_addrtype = af;

    switch (info->hp->h_addrtype) {
        case AF_INET:
            (void) snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa", (uaddr[3] & 0xff),
                            (uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff));
            break;

        case AF_INET6:
            qp = qbuf;
            ep = qbuf + sizeof(qbuf) - 1;
            for (n = NS_IN6ADDRSZ - 1; n >= 0; n--) {
                advance = snprintf(qp, (size_t)(ep - qp), "%x.%x.", uaddr[n] & 0xf,
                                   ((unsigned int) uaddr[n] >> 4) & 0xf);
                if (advance > 0 && qp + advance < ep)
                    qp += advance;
                else {
                    // TODO: Consider converting to a private extended EAI_* error code.
                    // Currently, the EAI_* value has no corresponding error code for an internal
                    // out of buffer space. In order to not rely on errno, convert the original
                    // error code EAI_SYSTEM to EAI_MEMORY.
                    return EAI_MEMORY;
                }
            }
            if (strlcat(qbuf, "ip6.arpa", sizeof(qbuf)) >= sizeof(qbuf)) {
                // TODO: Consider converting to a private extended EAI_* error code.
                // Currently, the EAI_* value has no corresponding error code for an internal
                // out of buffer space. In order to not rely on errno, convert the original
                // error code EAI_SYSTEM to EAI_MEMORY.
                return EAI_MEMORY;
            }
            break;
        default:
            return EAI_FAMILY;
    }

    auto buf = std::make_unique<querybuf>();

    res_state res = res_get_state();
    if (!res) return EAI_MEMORY;

    res_setnetcontext(res, netcontext, event);
    int he;
    n = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, (int)sizeof(buf->buf), &he);
    if (n < 0) {
        LOG(DEBUG) << __func__ << ": res_nquery failed (" << n << ")";
        // Note that res_nquery() doesn't set the pair NETDB_INTERNAL and errno.
        // Return h_errno (he) to catch more detailed errors rather than EAI_NODATA.
        // See also herrnoToAiErrno().
        return herrnoToAiErrno(he);
    }
    hostent* hp = getanswer(buf.get(), n, qbuf, T_PTR, info->hp, info->buf, info->buflen, &he);
    if (hp == NULL) return herrnoToAiErrno(he);

    char* bf = (char*) (hp->h_addr_list + 2);
    size_t blen = (size_t)(bf - info->buf);
    if (blen + info->hp->h_length > info->buflen) goto nospc;
    hp->h_addr_list[0] = bf;
    hp->h_addr_list[1] = NULL;
    memcpy(bf, uaddr, (size_t) info->hp->h_length);

    /* Reserve enough space for mapping IPv4 address to IPv6 address in place */
    if (info->hp->h_addrtype == AF_INET) {
        if (blen + NS_IN6ADDRSZ > info->buflen) goto nospc;
        // Pad zero to the unused address space
        memcpy(bf + NS_INADDRSZ, NAT64_PAD, sizeof(NAT64_PAD));
    }

    return 0;

nospc:
    return EAI_MEMORY;
}

int android_gethostbyaddrfornetcontext(const void* addr, socklen_t len, int af,
                                       const struct android_net_context* netcontext, hostent** hp,
                                       NetworkDnsEventReported* event) {
    return android_gethostbyaddrfornetcontext_proxy(addr, len, af, netcontext, hp, event);
}

static int android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af,
                                                    const struct android_net_context* netcontext,
                                                    hostent** hp, NetworkDnsEventReported* event) {
    assert(event != nullptr);

    struct res_static* rs = res_get_static();  // For thread-safety.
    int error = android_gethostbyaddrfornetcontext_proxy_internal(
            addr, len, af, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), netcontext, event);
    if (error == 0) *hp = &rs->host;
    return error;
}

int herrnoToAiErrno(int he) {
    switch (he) {
        // extended h_errno
        case NETD_RESOLV_H_ERRNO_EXT_TIMEOUT:
            return NETD_RESOLV_TIMEOUT;
        // legacy h_errno
        case NETDB_SUCCESS:
            return 0;
        case HOST_NOT_FOUND:  // TODO: Perhaps convert HOST_NOT_FOUND to EAI_NONAME instead
        case NO_DATA:         // NO_ADDRESS
            return EAI_NODATA;
        case TRY_AGAIN:
            return EAI_AGAIN;
        case NETDB_INTERNAL:
            // TODO: Remove ENOSPC and call abort() immediately whenever any allocation fails.
            if (errno == ENOSPC) return EAI_MEMORY;
            // Theoretically, this should not happen. Leave this here just in case.
            // Currently, getanswer() of {gethnamaddr, getaddrinfo}.cpp, res_nsearch() and
            // res_searchN() use this function to convert error code. Only getanswer()
            // of gethnamaddr.cpp may return the error code pair, herrno NETDB_INTERNAL and
            // errno ENOSPC, which has already converted to EAI_MEMORY. The remaining functions
            // don't set the pair herrno and errno.
            return EAI_SYSTEM;  // see errno for detail
        case NO_RECOVERY:
        default:
            return EAI_FAIL;  // TODO: Perhaps convert default to EAI_MAX (unknown error) instead
    }
}
