/*	$NetBSD: res_query.c,v 1.7 2006/01/24 17:41:25 christos Exp $	*/

/*
 * Copyright (c) 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. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 * 	This product includes software developed by the University of
 * 	California, Berkeley and its contributors.
 * 4. 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 (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
 *
 * 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.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC 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.
 */

#define LOG_TAG "resolv"

#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/param.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <android-base/logging.h>

#include "res_debug.h"
#include "resolv_cache.h"
#include "resolv_private.h"

/*
 * Formulate a normal query, send, and await answer.
 * Returned answer is placed in supplied buffer "answer".
 * Perform preliminary check of answer, returning success only
 * if no error is indicated and the answer count is nonzero.
 * Return the size of the response on success, -1 on error.
 * Error number is left in *herrno.
 *
 * Caller must parse answer and determine whether it answers the question.
 */
int res_nquery(ResState* statp, const char* name,  // domain name
               int cl, int type,                   // class and type of query
               std::span<uint8_t> answer,          // buffer to put answer
               int* herrno)                        // legacy and extended h_errno
                                                   // NETD_RESOLV_H_ERRNO_EXT_*
{
    uint8_t buf[MAXPACKET];
    HEADER* hp = reinterpret_cast<HEADER*>(answer.data());
    int n;
    int rcode = NOERROR;
    bool retried = false;

again:
    hp->rcode = NOERROR;  // default

    LOG(DEBUG) << __func__ << ": (" << cl << ", " << type << ")";
    n = res_nmkquery(QUERY, name, cl, type, {}, buf, statp->netcontext_flags);
    if (n > 0 &&
        (statp->netcontext_flags &
         (NET_CONTEXT_FLAG_USE_DNS_OVER_TLS | NET_CONTEXT_FLAG_USE_EDNS)) &&
        !retried)
        n = res_nopt(statp, n, buf, answer.size());
    if (n <= 0) {
        LOG(DEBUG) << __func__ << ": mkquery failed";
        *herrno = NO_RECOVERY;
        return n;
    }
    n = res_nsend(statp, {buf, n}, answer, &rcode, 0);
    if (n < 0) {
        // If the query choked with EDNS0, retry without EDNS0 that when the server
        // has no response, resovler won't retry and do nothing. Even fallback to UDP,
        // we also has the same symptom if EDNS is enabled.
        if ((statp->netcontext_flags &
             (NET_CONTEXT_FLAG_USE_DNS_OVER_TLS | NET_CONTEXT_FLAG_USE_EDNS)) &&
            (statp->flags & RES_F_EDNS0ERR) && !retried) {
            LOG(DEBUG) << __func__ << ": retry without EDNS0";
            retried = true;
            goto again;
        }
        LOG(DEBUG) << __func__ << ": send error";

        // Note that rcodes SERVFAIL, NOTIMP, REFUSED may cause res_nquery() to return a general
        // error code EAI_AGAIN, but mapping the error code from rcode as res_queryN() does for
        // getaddrinfo(). Different rcodes trigger different behaviors:
        //
        // - SERVFAIL, NOTIMP, REFUSED
        //   These result in send_dg() returning 0, causing res_nsend() to try the next
        //   nameserver. After all nameservers failed, res_nsend() returns -ETIMEDOUT, causing
        //   res_nquery() to return EAI_AGAIN here regardless of the rcode from the DNS response.
        //
        // - NXDOMAIN, FORMERR
        //   These rcodes may cause res_nsend() to return successfully (i.e. the result is a
        //   positive integer). In this case, res_nquery() returns error number by referring
        //   the rcode from the DNS response.
        switch (rcode) {
            case RCODE_TIMEOUT:  // Not defined in RFC.
                // DNS metrics monitors DNS query timeout.
                *herrno = NETD_RESOLV_H_ERRNO_EXT_TIMEOUT;  // extended h_errno.
                break;
            default:
                *herrno = TRY_AGAIN;
                break;
        }
        return n;
    }

    if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
        LOG(DEBUG) << __func__ << ": rcode = (" << p_rcode(hp->rcode)
                   << "), counts = an:" << ntohs(hp->ancount) << " ns:" << ntohs(hp->nscount)
                   << " ar:" << ntohs(hp->arcount);

        switch (hp->rcode) {
            case NXDOMAIN:
                *herrno = HOST_NOT_FOUND;
                break;
            case SERVFAIL:
                *herrno = TRY_AGAIN;
                break;
            case NOERROR:
                *herrno = NO_DATA;
                break;
            case FORMERR:
            case NOTIMP:
            case REFUSED:
            default:
                *herrno = NO_RECOVERY;
                break;
        }
        return -1;
    }
    return n;
}

/*
 * Formulate a normal query, send, and retrieve answer in supplied buffer.
 * Return the size of the response on success, -1 on error.
 * If enabled, implement search rules until answer or unrecoverable failure
 * is detected.  Error code, if any, is left in *herrno.
 */
int res_nsearch(ResState* statp, const char* name, /* domain name */
                int cl, int type,                  /* class and type of query */
                std::span<uint8_t> answer,         /* buffer to put answer */
                int* herrno)                       /* legacy and extended
                                                      h_errno NETD_RESOLV_H_ERRNO_EXT_* */
{
    const char* cp;
    HEADER* hp = reinterpret_cast<HEADER*>(answer.data());
    uint32_t dots;
    int ret, saved_herrno;
    int got_nodata = 0, got_servfail = 0, root_on_list = 0;
    int tried_as_is = 0;

    errno = 0;
    *herrno = HOST_NOT_FOUND; /* True if we never query. */

    dots = 0;
    for (cp = name; *cp != '\0'; cp++) dots += (*cp == '.');
    const bool trailing_dot = (cp > name && *--cp == '.') ? true : false;

    /*
     * If there are enough dots in the name, let's just give it a
     * try 'as is'. The threshold can be set with the "ndots" option.
     * Also, query 'as is', if there is a trailing dot in the name.
     */
    saved_herrno = -1;
    if (dots >= statp->ndots || trailing_dot) {
        ret = res_nquerydomain(statp, name, NULL, cl, type, answer, herrno);
        if (ret > 0 || trailing_dot) return ret;
        saved_herrno = *herrno;
        tried_as_is++;
    }

    /*
     * We do at least one level of search if
     *	- there is no dot, or
     *	- there is at least one dot and there is no trailing dot.
     */
    if ((!dots || (dots && !trailing_dot)) && !isMdnsResolution(statp->flags)) {
        int done = 0;

        /* Unfortunately we need to load network-specific info
         * (dns servers, search domains) before
         * the domain stuff is tried.  Will have a better
         * fix after thread pools are used as this will
         * be loaded once for the thread instead of each
         * time a query is tried.
         */
        resolv_populate_res_for_net(statp);

        for (const auto& domain : statp->search_domains) {
            if (domain == "." || domain == "") ++root_on_list;

            ret = res_nquerydomain(statp, name, domain.c_str(), cl, type, answer, herrno);
            if (ret > 0) return ret;

            /*
             * If no server present, give up.
             * If name isn't found in this domain,
             * keep trying higher domains in the search list
             * (if that's enabled).
             * On a NO_DATA error, keep trying, otherwise
             * a wildcard entry of another type could keep us
             * from finding this entry higher in the domain.
             * If we get some other error (negative answer or
             * server failure), then stop searching up,
             * but try the input name below in case it's
             * fully-qualified.
             */
            if (errno == ECONNREFUSED) {
                *herrno = TRY_AGAIN;
                return -1;
            }

            switch (*herrno) {
                case NO_DATA:
                    got_nodata++;
                    break;
                case HOST_NOT_FOUND:
                    /* keep trying */
                    break;
                case TRY_AGAIN:
                    if (hp->rcode == SERVFAIL) {
                        /* try next search element, if any */
                        got_servfail++;
                        break;
                    }
                    [[fallthrough]];
                default:
                    /* anything else implies that we're done */
                    done++;
            }
        }
    }

    // if we have not already tried the name "as is", do that now.
    // note that we do this regardless of how many dots were in the
    // name or whether it ends with a dot.
    if (!tried_as_is && !root_on_list) {
        ret = res_nquerydomain(statp, name, NULL, cl, type, answer, herrno);
        if (ret > 0) return ret;
    }

    /* if we got here, we didn't satisfy the search.
     * if we did an initial full query, return that query's H_ERRNO
     * (note that we wouldn't be here if that query had succeeded).
     * else if we ever got a nodata, send that back as the reason.
     * else send back meaningless H_ERRNO, that being the one from
     * the last DNSRCH we did.
     */
    if (saved_herrno != -1)
        *herrno = saved_herrno;
    else if (got_nodata)
        *herrno = NO_DATA;
    else if (got_servfail)
        *herrno = TRY_AGAIN;
    return -1;
}

/*
 * Perform a call on res_query on the concatenation of name and domain,
 * removing a trailing dot from name if domain is NULL.
 */
int res_nquerydomain(ResState* statp, const char* name, const char* domain, int cl,
                     int type,                  /* class and type of query */
                     std::span<uint8_t> answer, /* buffer to put answer */
                     int* herrno) /* legacy and extended h_errno NETD_RESOLV_H_ERRNO_EXT_* */
{
    char nbuf[MAXDNAME];
    const char* longname = nbuf;
    int n, d;

    if (domain == NULL) {
        LOG(DEBUG) << __func__ << ": (null, " << cl << ", " << type << ")";
        /*
         * Check for trailing '.';
         * copy without '.' if present.
         */
        n = strlen(name);
        if (n >= MAXDNAME) {
            *herrno = NO_RECOVERY;
            return -1;
        }
        n--;
        if (n >= 0 && name[n] == '.') {
            strncpy(nbuf, name, (size_t) n);
            nbuf[n] = '\0';
        } else
            longname = name;
    } else {
        LOG(DEBUG) << __func__ << ": (" << cl << ", " << type << ")";
        n = strlen(name);
        d = strlen(domain);
        if (n + d + 1 >= MAXDNAME) {
            *herrno = NO_RECOVERY;
            return -1;
        }
        snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
    }
    return res_nquery(statp, longname, cl, type, answer, herrno);
}
