// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/dns/address_info.h"

#include <memory>

#include "base/logging.h"
#include "base/notreached.h"
#include "base/sys_byteorder.h"
#include "build/build_config.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/base/sys_addrinfo.h"

#if BUILDFLAG(IS_ANDROID)
#include "net/android/network_library.h"
#endif  // BUILDFLAG(IS_ANDROID)

namespace net {

namespace {

const addrinfo* Next(const addrinfo* ai) {
  return ai->ai_next;
}

}  // namespace

//// iterator

AddressInfo::const_iterator::const_iterator(const addrinfo* ai) : ai_(ai) {}

bool AddressInfo::const_iterator::operator!=(
    const AddressInfo::const_iterator& o) const {
  return ai_ != o.ai_;
}

AddressInfo::const_iterator& AddressInfo::const_iterator::operator++() {
  ai_ = Next(ai_);
  return *this;
}

const addrinfo* AddressInfo::const_iterator::operator->() const {
  return ai_;
}

const addrinfo& AddressInfo::const_iterator::operator*() const {
  return *ai_;
}

//// constructors

AddressInfo::AddressInfoAndResult AddressInfo::Get(
    const std::string& host,
    const addrinfo& hints,
    std::unique_ptr<AddrInfoGetter> getter,
    handles::NetworkHandle network) {
  if (getter == nullptr)
    getter = std::make_unique<AddrInfoGetter>();
  int err = OK;
  int os_error = 0;
  std::unique_ptr<addrinfo, FreeAddrInfoFunc> ai =
      getter->getaddrinfo(host, &hints, &os_error, network);

  if (!ai) {
    err = ERR_NAME_NOT_RESOLVED;

    // If the call to getaddrinfo() failed because of a system error, report
    // it separately from ERR_NAME_NOT_RESOLVED.
#if BUILDFLAG(IS_WIN)
    if (os_error != WSAHOST_NOT_FOUND && os_error != WSANO_DATA)
      err = ERR_NAME_RESOLUTION_FAILED;
#elif BUILDFLAG(IS_ANDROID)
    // Workaround for Android's getaddrinfo leaving ai==nullptr without an
    // error.
    // http://crbug.com/134142
    err = ERR_NAME_NOT_RESOLVED;
#elif BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_FREEBSD)
    if (os_error != EAI_NONAME && os_error != EAI_NODATA)
      err = ERR_NAME_RESOLUTION_FAILED;
#endif

    return AddressInfoAndResult(absl::optional<AddressInfo>(), err, os_error);
  }

  return AddressInfoAndResult(absl::optional<AddressInfo>(AddressInfo(
                                  std::move(ai), std::move(getter))),
                              OK, 0);
}

AddressInfo::AddressInfo(AddressInfo&& other) = default;

AddressInfo& AddressInfo::operator=(AddressInfo&& other) = default;

AddressInfo::~AddressInfo() = default;

//// public methods

AddressInfo::const_iterator AddressInfo::begin() const {
  return const_iterator(ai_.get());
}

AddressInfo::const_iterator AddressInfo::end() const {
  return const_iterator(nullptr);
}

absl::optional<std::string> AddressInfo::GetCanonicalName() const {
  return (ai_->ai_canonname != nullptr)
             ? absl::optional<std::string>(std::string(ai_->ai_canonname))
             : absl::optional<std::string>();
}

bool AddressInfo::IsAllLocalhostOfOneFamily() const {
  bool saw_v4_localhost = false;
  bool saw_v6_localhost = false;
  const auto* ai = ai_.get();
  for (; ai != nullptr; ai = Next(ai)) {
    switch (ai->ai_family) {
      case AF_INET: {
        const struct sockaddr_in* addr_in =
            reinterpret_cast<struct sockaddr_in*>(ai->ai_addr);
        if ((base::NetToHost32(addr_in->sin_addr.s_addr) & 0xff000000) ==
            0x7f000000)
          saw_v4_localhost = true;
        else
          return false;
        break;
      }
      case AF_INET6: {
        const struct sockaddr_in6* addr_in6 =
            reinterpret_cast<struct sockaddr_in6*>(ai->ai_addr);
        if (IN6_IS_ADDR_LOOPBACK(&addr_in6->sin6_addr))
          saw_v6_localhost = true;
        else
          return false;
        break;
      }
      default:
        NOTREACHED();
        return false;
    }
  }

  return saw_v4_localhost != saw_v6_localhost;
}

AddressList AddressInfo::CreateAddressList() const {
  AddressList list;
  auto canonical_name = GetCanonicalName();
  if (canonical_name) {
    std::vector<std::string> aliases({*canonical_name});
    list.SetDnsAliases(std::move(aliases));
  }
  for (auto&& ai : *this) {
    IPEndPoint ipe;
    // NOTE: Ignoring non-INET* families.
    if (ipe.FromSockAddr(ai.ai_addr, ai.ai_addrlen))
      list.push_back(ipe);
    else
      DLOG(WARNING) << "Unknown family found in addrinfo: " << ai.ai_family;
  }
  return list;
}

//// private methods

AddressInfo::AddressInfo(std::unique_ptr<addrinfo, FreeAddrInfoFunc> ai,
                         std::unique_ptr<AddrInfoGetter> getter)
    : ai_(std::move(ai)), getter_(std::move(getter)) {}

//// AddrInfoGetter

AddrInfoGetter::AddrInfoGetter() = default;
AddrInfoGetter::~AddrInfoGetter() = default;

std::unique_ptr<addrinfo, FreeAddrInfoFunc> AddrInfoGetter::getaddrinfo(
    const std::string& host,
    const addrinfo* hints,
    int* out_os_error,
    handles::NetworkHandle network) {
  addrinfo* ai;
  // We wrap freeaddrinfo() in a lambda just in case some operating systems use
  // a different signature for it.
  FreeAddrInfoFunc deleter = [](addrinfo* ai) { ::freeaddrinfo(ai); };

  std::unique_ptr<addrinfo, FreeAddrInfoFunc> rv = {nullptr, deleter};

  if (network != handles::kInvalidNetworkHandle) {
    // Currently, only Android supports lookups for a specific network.
#if BUILDFLAG(IS_ANDROID)
    *out_os_error = android::GetAddrInfoForNetwork(network, host.c_str(),
                                                   nullptr, hints, &ai);
#elif BUILDFLAG(IS_WIN) || defined(COMPILER_MSVC)
    *out_os_error = WSAEOPNOTSUPP;
    return rv;
#else
    errno = ENOSYS;
    *out_os_error = EAI_SYSTEM;
    return rv;
#endif  // BUILDFLAG(IS_ANDROID)
  } else {
    *out_os_error = ::getaddrinfo(host.c_str(), nullptr, hints, &ai);
  }

  if (*out_os_error) {
#if BUILDFLAG(IS_WIN)
    *out_os_error = WSAGetLastError();
#endif
    return rv;
  }

  rv.reset(ai);
  return rv;
}

}  // namespace net
