/*
 * 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 <statslog_resolv.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,
               int* 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 revision_id = android_net_res_stats_get_info_for_net(netId, &nscount, res_servers, &dcount,
                                                             res_domains, params, res_stats,
                                                             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]);
    }

    return 0;
}

}  // namespace

ResolverController::ResolverController()
    : mDns64Configuration(
              [](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;

    // Report NetworkDnsServerSupportReported metrics before the cleanup.
    auto& privateDnsConfiguration = PrivateDnsConfiguration::getInstance();
    NetworkDnsServerSupportReported event = privateDnsConfiguration.getStatusForMetrics(netId);
    const std::string str = event.servers().SerializeAsString();
    stats::BytesField bytesField{str.c_str(), str.size()};
    android::net::stats::stats_write(android::net::stats::NETWORK_DNS_SERVER_SUPPORT_REPORTED,
                                     event.network_type(), event.private_dns_modes(), bytesField);

    resolv_delete_cache_for_net(netId);
    mDns64Configuration.stopPrefixDiscovery(netId);
    privateDnsConfiguration.clear(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,
                                          resolverParams.servers, tlsServers,
                                          resolverParams.tlsName, resolverParams.caCertificate);

    if (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;
        }
    }

    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,
                                        int* 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;
    int wait_for_pending_req_timeout_count = 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);
        resolv_netconfig_dump(dw, netId);
    }
    dw.decIndent();
}

}  // namespace net
}  // namespace android
