/*
 * Copyright (C) 2019 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.
 */

#define LOG_TAG "resolv"

#include "ResolverController.h"

#include <set>
#include <string>
#include <vector>

#include <aidl/android/net/IDnsResolver.h>
#include <android-base/logging.h>
#include <android-base/strings.h>

#include "Dns64Configuration.h"
#include "DnsResolver.h"
#include "DnsTlsDispatcher.h"
#include "PrivateDnsConfiguration.h"
#include "ResolverEventReporter.h"
#include "ResolverStats.h"
#include "resolv_cache.h"
#include "stats.h"
#include "util.h"

using aidl::android::net::ResolverParamsParcel;
using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener;
using aidl::android::net::resolv::aidl::Nat64PrefixEventParcel;

namespace android {

using netdutils::DumpWriter;

namespace net {

namespace {

void sendNat64PrefixEvent(const Dns64Configuration::Nat64PrefixInfo& args) {
    LOG(DEBUG) << "Sending Nat64Prefix " << (args.added ? "added" : "removed") << " event on netId "
               << args.netId << " with prefix " << args.prefixString << "/"
               << (int)(args.prefixLength);
    // Send a nat64 prefix event to NetdEventListenerService.
    const auto& listeners = ResolverEventReporter::getInstance().getListeners();
    if (listeners.empty()) {
        LOG(ERROR) << __func__ << ": No available listener. Skipping NAT64 prefix event";
    }
    for (const auto& it : listeners) {
        it->onNat64PrefixEvent(args.netId, args.added, args.prefixString, args.prefixLength);
    }

    const auto& unsolEventListeners = ResolverEventReporter::getInstance().getUnsolEventListeners();
    const Nat64PrefixEventParcel nat64PrefixEvent = {
            .netId = static_cast<int32_t>(args.netId),
            .prefixOperation =
                    args.added ? IDnsResolverUnsolicitedEventListener::PREFIX_OPERATION_ADDED
                               : IDnsResolverUnsolicitedEventListener::PREFIX_OPERATION_REMOVED,
            .prefixAddress = args.prefixString,
            .prefixLength = args.prefixLength,
    };
    for (const auto& it : unsolEventListeners) {
        it->onNat64PrefixEvent(nat64PrefixEvent);
    }
}

int getDnsInfo(unsigned netId, std::vector<std::string>* servers, std::vector<std::string>* domains,
               res_params* params, std::vector<android::net::ResolverStats>* stats,
               std::vector<int32_t>* wait_for_pending_req_timeout_count) {
    using aidl::android::net::IDnsResolver;
    using android::net::ResolverStats;
    static_assert(ResolverStats::STATS_SUCCESSES == IDnsResolver::RESOLVER_STATS_SUCCESSES &&
                          ResolverStats::STATS_ERRORS == IDnsResolver::RESOLVER_STATS_ERRORS &&
                          ResolverStats::STATS_TIMEOUTS == IDnsResolver::RESOLVER_STATS_TIMEOUTS &&
                          ResolverStats::STATS_INTERNAL_ERRORS ==
                                  IDnsResolver::RESOLVER_STATS_INTERNAL_ERRORS &&
                          ResolverStats::STATS_RTT_AVG == IDnsResolver::RESOLVER_STATS_RTT_AVG &&
                          ResolverStats::STATS_LAST_SAMPLE_TIME ==
                                  IDnsResolver::RESOLVER_STATS_LAST_SAMPLE_TIME &&
                          ResolverStats::STATS_USABLE == IDnsResolver::RESOLVER_STATS_USABLE &&
                          ResolverStats::STATS_COUNT == IDnsResolver::RESOLVER_STATS_COUNT,
                  "AIDL and ResolverStats.h out of sync");
    int nscount = -1;
    sockaddr_storage res_servers[MAXNS];
    int dcount = -1;
    char res_domains[MAXDNSRCH][MAXDNSRCHPATH];
    res_stats res_stats[MAXNS];
    servers->clear();
    domains->clear();
    *params = res_params{};
    stats->clear();
    int res_wait_for_pending_req_timeout_count;
    int revision_id = android_net_res_stats_get_info_for_net(
            netId, &nscount, res_servers, &dcount, res_domains, params, res_stats,
            &res_wait_for_pending_req_timeout_count);

    // If the netId is unknown (which can happen for valid net IDs for which no DNS servers have
    // yet been configured), there is no revision ID. In this case there is no data to return.
    if (revision_id < 0) {
        return 0;
    }

    // Verify that the returned data is valid.
    if (nscount < 0 || nscount > MAXNS || dcount < 0 || dcount > MAXDNSRCH) {
        LOG(ERROR) << __func__ << ": nscount = " << nscount << ", dcount = " << dcount;
        return -ENOTRECOVERABLE;
    }

    // Determine which servers are considered usable by the resolver.
    bool valid_servers[MAXNS];
    std::fill_n(valid_servers, MAXNS, false);
    android_net_res_stats_get_usable_servers(params, res_stats, nscount, valid_servers);

    // Convert the server sockaddr structures to std::string.
    stats->resize(nscount);
    for (int i = 0; i < nscount; ++i) {
        char hbuf[NI_MAXHOST];
        int rv =
                getnameinfo(reinterpret_cast<const sockaddr*>(&res_servers[i]),
                            sizeof(res_servers[i]), hbuf, sizeof(hbuf), nullptr, 0, NI_NUMERICHOST);
        std::string server_str;
        if (rv == 0) {
            server_str.assign(hbuf);
        } else {
            LOG(ERROR) << "getnameinfo() failed for server #" << i << ": " << gai_strerror(rv);
            server_str.assign("<invalid>");
        }
        servers->push_back(std::move(server_str));
        android::net::ResolverStats& cur_stats = (*stats)[i];
        android_net_res_stats_aggregate(&res_stats[i], &cur_stats.successes, &cur_stats.errors,
                                        &cur_stats.timeouts, &cur_stats.internal_errors,
                                        &cur_stats.rtt_avg, &cur_stats.last_sample_time);
        cur_stats.usable = valid_servers[i];
    }

    // Convert the stack-allocated search domain strings to std::string.
    for (int i = 0; i < dcount; ++i) {
        domains->push_back(res_domains[i]);
    }

    (*wait_for_pending_req_timeout_count)[0] = res_wait_for_pending_req_timeout_count;
    return 0;
}

}  // namespace

ResolverController::ResolverController()
    : mDns64Configuration(new Dns64Configuration(
              [](uint32_t netId, uint32_t uid, android_net_context* netcontext) {
                  gResNetdCallbacks.get_network_context(netId, uid, netcontext);
              },
              std::bind(sendNat64PrefixEvent, std::placeholders::_1))) {}

void ResolverController::destroyNetworkCache(unsigned netId) {
    LOG(VERBOSE) << __func__ << ": netId = " << netId;

    resolv_delete_cache_for_net(netId);
    mDns64Configuration->stopPrefixDiscovery(netId);
    PrivateDnsConfiguration::getInstance().clear(netId);
    if (isDoHEnabled()) PrivateDnsConfiguration::getInstance().clearDoh(netId);

    // Don't get this instance in PrivateDnsConfiguration. It's probe to deadlock.
    DnsTlsDispatcher::getInstance().forceCleanup(netId);
}

int ResolverController::createNetworkCache(unsigned netId) {
    LOG(VERBOSE) << __func__ << ": netId = " << netId;

    return resolv_create_cache_for_net(netId);
}

int ResolverController::flushNetworkCache(unsigned netId) {
    LOG(VERBOSE) << __func__ << ": netId = " << netId;
    return resolv_flush_cache_for_net(netId);
}

int ResolverController::setResolverConfiguration(const ResolverParamsParcel& resolverParams) {
    using aidl::android::net::IDnsResolver;

    if (!has_named_cache(resolverParams.netId)) {
        return -ENOENT;
    }

    // Expect to get the mark with system permission.
    android_net_context netcontext;
    gResNetdCallbacks.get_network_context(resolverParams.netId, 0 /* uid */, &netcontext);

    // Allow at most MAXNS private DNS servers in a network to prevent too many broken servers.
    std::vector<std::string> tlsServers = resolverParams.tlsServers;
    if (tlsServers.size() > MAXNS) {
        tlsServers.resize(MAXNS);
    }

    // Use app_mark for DoT connection. Using dns_mark might result in reaching the DoT servers
    // through a different network. For example, on a VPN with no DNS servers (Do53), if the VPN
    // applies to UID 0, dns_mark is assigned for default network rathan the VPN. (note that it's
    // possible that a VPN doesn't have any DNS servers but DoT servers in DNS strict mode)
    auto& privateDnsConfiguration = PrivateDnsConfiguration::getInstance();
    int err = privateDnsConfiguration.set(resolverParams.netId, netcontext.app_mark, tlsServers,
                                          resolverParams.tlsName, resolverParams.caCertificate);

    if (err != 0) {
        return err;
    }

    if (err = resolv_stats_set_addrs(resolverParams.netId, PROTO_DOT, tlsServers, 853);
        err != 0) {
        return err;
    }

    if (is_mdns_supported_transport_types(resolverParams.transportTypes)) {
        if (err = resolv_stats_set_addrs(resolverParams.netId, PROTO_MDNS,
                                         {"ff02::fb", "224.0.0.251"}, 5353);
            err != 0) {
            return err;
        }
    }

    if (isDoHEnabled()) {
        err = privateDnsConfiguration.setDoh(resolverParams.netId, netcontext.app_mark, tlsServers,
                                             resolverParams.tlsName, resolverParams.caCertificate);

        if (err != 0) {
            return err;
        }
    }

    res_params res_params = {};
    res_params.sample_validity = resolverParams.sampleValiditySeconds;
    res_params.success_threshold = resolverParams.successThreshold;
    res_params.min_samples = resolverParams.minSamples;
    res_params.max_samples = resolverParams.maxSamples;
    res_params.base_timeout_msec = resolverParams.baseTimeoutMsec;
    res_params.retry_count = resolverParams.retryCount;

    return resolv_set_nameservers(resolverParams.netId, resolverParams.servers,
                                  resolverParams.domains, res_params,
                                  resolverParams.resolverOptions, resolverParams.transportTypes);
}

int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* servers,
                                        std::vector<std::string>* domains,
                                        std::vector<std::string>* tlsServers,
                                        std::vector<int32_t>* params, std::vector<int32_t>* stats,
                                        std::vector<int32_t>* wait_for_pending_req_timeout_count) {
    using aidl::android::net::IDnsResolver;
    using android::net::ResolverStats;
    res_params res_params;
    std::vector<ResolverStats> res_stats;
    int ret = getDnsInfo(netId, servers, domains, &res_params, &res_stats,
                         wait_for_pending_req_timeout_count);
    if (ret != 0) {
        return ret;
    }

    // Serialize the information for binder.
    ResolverStats::encodeAll(res_stats, stats);

    const auto privateDnsStatus = PrivateDnsConfiguration::getInstance().getStatus(netId);
    for (const auto& [server, _] : privateDnsStatus.dotServersMap) {
        tlsServers->push_back(server.toIpString());
    }

    params->resize(IDnsResolver::RESOLVER_PARAMS_COUNT);
    (*params)[IDnsResolver::RESOLVER_PARAMS_SAMPLE_VALIDITY] = res_params.sample_validity;
    (*params)[IDnsResolver::RESOLVER_PARAMS_SUCCESS_THRESHOLD] = res_params.success_threshold;
    (*params)[IDnsResolver::RESOLVER_PARAMS_MIN_SAMPLES] = res_params.min_samples;
    (*params)[IDnsResolver::RESOLVER_PARAMS_MAX_SAMPLES] = res_params.max_samples;
    (*params)[IDnsResolver::RESOLVER_PARAMS_BASE_TIMEOUT_MSEC] = res_params.base_timeout_msec;
    (*params)[IDnsResolver::RESOLVER_PARAMS_RETRY_COUNT] = res_params.retry_count;
    return 0;
}

void ResolverController::startPrefix64Discovery(int32_t netId) {
    mDns64Configuration->startPrefixDiscovery(netId);
}

void ResolverController::stopPrefix64Discovery(int32_t netId) {
    return mDns64Configuration->stopPrefixDiscovery(netId);
}

// TODO: use StatusOr<T> to wrap the result.
int ResolverController::getPrefix64(unsigned netId, netdutils::IPPrefix* prefix) {
    netdutils::IPPrefix p = mDns64Configuration->getPrefix64(netId);
    if (p.family() != AF_INET6 || p.length() == 0) {
        return -ENOENT;
    }
    *prefix = p;
    return 0;
}

void ResolverController::dump(DumpWriter& dw, unsigned netId) {
    // No lock needed since Bionic's resolver locks all accessed data structures internally.
    using android::net::ResolverStats;
    std::vector<std::string> servers;
    std::vector<std::string> domains;
    res_params params = {};
    std::vector<ResolverStats> stats;
    std::vector<int32_t> wait_for_pending_req_timeout_count(1, 0);
    time_t now = time(nullptr);
    int rv = getDnsInfo(netId, &servers, &domains, &params, &stats,
                        &wait_for_pending_req_timeout_count);
    dw.incIndent();
    if (rv != 0) {
        dw.println("getDnsInfo() failed for netid %u", netId);
    } else {
        if (servers.empty()) {
            dw.println("No DNS servers defined");
        } else {
            dw.println("DnsEvent subsampling map: " +
                       android::base::Join(resolv_cache_dump_subsampling_map(netId, false), ' '));
            dw.println("DnsEvent subsampling map for MDNS: " +
                       android::base::Join(resolv_cache_dump_subsampling_map(netId, true), ' '));
            dw.println(
                    "DNS servers: # IP (total, successes, errors, timeouts, internal errors, "
                    "RTT avg, last sample)");
            dw.incIndent();
            for (size_t i = 0; i < servers.size(); ++i) {
                if (i < stats.size()) {
                    const ResolverStats& s = stats[i];
                    int total = s.successes + s.errors + s.timeouts + s.internal_errors;
                    if (total > 0) {
                        int time_delta = (s.last_sample_time > 0) ? now - s.last_sample_time : -1;
                        dw.println("%s (%d, %d, %d, %d, %d, %dms, %ds)%s", servers[i].c_str(),
                                   total, s.successes, s.errors, s.timeouts, s.internal_errors,
                                   s.rtt_avg, time_delta, s.usable ? "" : " BROKEN");
                    } else {
                        dw.println("%s <no data>", servers[i].c_str());
                    }
                } else {
                    dw.println("%s <no stats>", servers[i].c_str());
                }
            }
            dw.decIndent();
        }
        if (domains.empty()) {
            dw.println("No search domains defined");
        } else {
            std::string domains_str = android::base::Join(domains, ", ");
            dw.println("search domains: %s", domains_str.c_str());
        }
        if (params.sample_validity != 0) {
            dw.println(
                    "DNS parameters: sample validity = %us, success threshold = %u%%, "
                    "samples (min, max) = (%u, %u), base_timeout = %dmsec, retry count = "
                    "%dtimes",
                    params.sample_validity, params.success_threshold, params.min_samples,
                    params.max_samples, params.base_timeout_msec, params.retry_count);
        }
        mDns64Configuration->dump(dw, netId);
        const auto privateDnsStatus = PrivateDnsConfiguration::getInstance().getStatus(netId);
        dw.println("Private DNS mode: %s", getPrivateDnsModeString(privateDnsStatus.mode));
        if (privateDnsStatus.dotServersMap.size() == 0) {
            dw.println("No Private DNS servers configured");
        } else {
            dw.println("Private DNS configuration (%u entries)",
                       static_cast<uint32_t>(privateDnsStatus.dotServersMap.size()));
            dw.incIndent();
            for (const auto& [server, validation] : privateDnsStatus.dotServersMap) {
                dw.println("%s name{%s} status{%s}", server.toIpString().c_str(),
                           server.name.c_str(), validationStatusToString(validation));
            }
            dw.decIndent();
        }
        dw.println("Concurrent DNS query timeout: %d", wait_for_pending_req_timeout_count[0]);
        resolv_netconfig_dump(dw, netId);
    }
    dw.decIndent();
}

}  // namespace net
}  // namespace android
