// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/dns/dns_config_service_win.h"

#include <string>
#include <vector>

#include "base/check.h"
#include "base/memory/free_deleter.h"
#include "base/optional.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/dns/public/dns_protocol.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

TEST(DnsConfigServiceWinTest, ParseSearchList) {
  const struct TestCase {
    const wchar_t* input;
    std::vector<std::string> expected;
  } cases[] = {
      {L"chromium.org", {"chromium.org"}},
      {L"chromium.org,org", {"chromium.org", "org"}},
      // Empty suffixes terminate the list
      {L"crbug.com,com,,org", {"crbug.com", "com"}},
      // IDN are converted to punycode
      {L"\u017c\xf3\u0142ta.pi\u0119\u015b\u0107.pl,pl",
       {"xn--ta-4ja03asj.xn--pi-wla5e0q.pl", "pl"}},
      // Empty search list is invalid
      {L"", {}},
      {L",,", {}},
  };

  for (const auto& t : cases) {
    EXPECT_EQ(internal::ParseSearchList(t.input), t.expected);
  }
}

struct AdapterInfo {
  IFTYPE if_type;
  IF_OPER_STATUS oper_status;
  const WCHAR* dns_suffix;
  std::string dns_server_addresses[4];  // Empty string indicates end.
  uint16_t ports[4];
};

std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> CreateAdapterAddresses(
    const AdapterInfo* infos) {
  size_t num_adapters = 0;
  size_t num_addresses = 0;
  for (size_t i = 0; infos[i].if_type; ++i) {
    ++num_adapters;
    for (size_t j = 0; !infos[i].dns_server_addresses[j].empty(); ++j) {
      ++num_addresses;
    }
  }

  size_t heap_size = num_adapters * sizeof(IP_ADAPTER_ADDRESSES) +
                     num_addresses * (sizeof(IP_ADAPTER_DNS_SERVER_ADDRESS) +
                                      sizeof(struct sockaddr_storage));
  std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> heap(
      static_cast<IP_ADAPTER_ADDRESSES*>(malloc(heap_size)));
  CHECK(heap.get());
  memset(heap.get(), 0, heap_size);

  IP_ADAPTER_ADDRESSES* adapters = heap.get();
  IP_ADAPTER_DNS_SERVER_ADDRESS* addresses =
      reinterpret_cast<IP_ADAPTER_DNS_SERVER_ADDRESS*>(adapters + num_adapters);
  struct sockaddr_storage* storage =
      reinterpret_cast<struct sockaddr_storage*>(addresses + num_addresses);

  for (size_t i = 0; i < num_adapters; ++i) {
    const AdapterInfo& info = infos[i];
    IP_ADAPTER_ADDRESSES* adapter = adapters + i;
    if (i + 1 < num_adapters)
      adapter->Next = adapter + 1;
    adapter->IfType = info.if_type;
    adapter->OperStatus = info.oper_status;
    adapter->DnsSuffix = const_cast<PWCHAR>(info.dns_suffix);
    IP_ADAPTER_DNS_SERVER_ADDRESS* address = nullptr;
    for (size_t j = 0; !info.dns_server_addresses[j].empty(); ++j) {
      --num_addresses;
      if (j == 0) {
        address = adapter->FirstDnsServerAddress = addresses + num_addresses;
      } else {
        // Note that |address| is moving backwards.
        address = address->Next = address - 1;
      }
      IPAddress ip;
      CHECK(ip.AssignFromIPLiteral(info.dns_server_addresses[j]));
      IPEndPoint ipe = IPEndPoint(ip, info.ports[j]);
      address->Address.lpSockaddr =
          reinterpret_cast<LPSOCKADDR>(storage + num_addresses);
      socklen_t length = sizeof(struct sockaddr_storage);
      CHECK(ipe.ToSockAddr(address->Address.lpSockaddr, &length));
      address->Address.iSockaddrLength = static_cast<int>(length);
    }
  }

  return heap;
}

TEST(DnsConfigServiceWinTest, ConvertAdapterAddresses) {
  // Check nameservers and connection-specific suffix.
  const struct TestCase {
    AdapterInfo input_adapters[4];        // |if_type| == 0 indicates end.
    std::string expected_nameservers[4];  // Empty string indicates end.
    std::string expected_suffix;
    uint16_t expected_ports[4];
  } cases[] = {
    {  // Ignore loopback and inactive adapters.
      {
        { IF_TYPE_SOFTWARE_LOOPBACK, IfOperStatusUp, L"funnyloop",
          { "2.0.0.2" } },
        { IF_TYPE_FASTETHER, IfOperStatusDormant, L"example.com",
          { "1.0.0.1" } },
        { IF_TYPE_USB, IfOperStatusUp, L"chromium.org",
          { "10.0.0.10", "2001:FFFF::1111" } },
        { 0 },
      },
      { "10.0.0.10", "2001:FFFF::1111" },
      "chromium.org",
    },
    {  // Respect configured ports.
      {
        { IF_TYPE_USB, IfOperStatusUp, L"chromium.org",
        { "10.0.0.10", "2001:FFFF::1111" }, { 1024, 24 } },
        { 0 },
      },
      { "10.0.0.10", "2001:FFFF::1111" },
      "chromium.org",
      { 1024, 24 },
    },
    {  // Use the preferred adapter (first in binding order) and filter
       // stateless DNS discovery addresses.
      {
        { IF_TYPE_SOFTWARE_LOOPBACK, IfOperStatusUp, L"funnyloop",
          { "2.0.0.2" } },
        { IF_TYPE_FASTETHER, IfOperStatusUp, L"example.com",
          { "1.0.0.1", "fec0:0:0:ffff::2", "8.8.8.8" } },
        { IF_TYPE_USB, IfOperStatusUp, L"chromium.org",
          { "10.0.0.10", "2001:FFFF::1111" } },
        { 0 },
      },
      { "1.0.0.1", "8.8.8.8" },
      "example.com",
    },
    {  // No usable adapters.
      {
        { IF_TYPE_SOFTWARE_LOOPBACK, IfOperStatusUp, L"localhost",
          { "2.0.0.2" } },
        { IF_TYPE_FASTETHER, IfOperStatusDormant, L"example.com",
          { "1.0.0.1" } },
        { IF_TYPE_USB, IfOperStatusUp, L"chromium.org" },
        { 0 },
      },
    },
  };

  for (const auto& t : cases) {
    internal::DnsSystemSettings settings;
    settings.addresses = CreateAdapterAddresses(t.input_adapters);
    // Default settings for the rest.
    std::vector<IPEndPoint> expected_nameservers;
    for (size_t j = 0; !t.expected_nameservers[j].empty(); ++j) {
      IPAddress ip;
      ASSERT_TRUE(ip.AssignFromIPLiteral(t.expected_nameservers[j]));
      uint16_t port = t.expected_ports[j];
      if (!port)
        port = dns_protocol::kDefaultPort;
      expected_nameservers.push_back(IPEndPoint(ip, port));
    }

    base::Optional<DnsConfig> config =
        internal::ConvertSettingsToDnsConfig(settings);
    bool expected_success = !expected_nameservers.empty();
    EXPECT_EQ(expected_success, config.has_value());
    if (config.has_value()) {
      EXPECT_EQ(expected_nameservers, config->nameservers);
      EXPECT_THAT(config->search, testing::ElementsAre(t.expected_suffix));
    }
  }
}

TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
  AdapterInfo infos[2] = {
    { IF_TYPE_USB, IfOperStatusUp, L"connection.suffix", { "1.0.0.1" } },
    { 0 },
  };

  const struct TestCase {
    struct {
      internal::DnsSystemSettings::RegString policy_search_list;
      internal::DnsSystemSettings::RegString tcpip_search_list;
      internal::DnsSystemSettings::RegString tcpip_domain;
      internal::DnsSystemSettings::RegString primary_dns_suffix;
      internal::DnsSystemSettings::DevolutionSetting policy_devolution;
      internal::DnsSystemSettings::DevolutionSetting dnscache_devolution;
      internal::DnsSystemSettings::DevolutionSetting tcpip_devolution;
    } input_settings;
    std::vector<std::string> expected_search;
  } cases[] = {
      {
          // Policy SearchList override.
          {
              {true, L"policy.searchlist.a,policy.searchlist.b"},
              {true, L"tcpip.searchlist.a,tcpip.searchlist.b"},
              {true, L"tcpip.domain"},
              {true, L"primary.dns.suffix"},
          },
          {"policy.searchlist.a", "policy.searchlist.b"},
      },
      {
          // User-specified SearchList override.
          {
              {false},
              {true, L"tcpip.searchlist.a,tcpip.searchlist.b"},
              {true, L"tcpip.domain"},
              {true, L"primary.dns.suffix"},
          },
          {"tcpip.searchlist.a", "tcpip.searchlist.b"},
      },
      {
          // Void SearchList. Using tcpip.domain
          {
              {true, L",bad.searchlist,parsed.as.empty"},
              {true, L"tcpip.searchlist,good.but.overridden"},
              {true, L"tcpip.domain"},
              {false},
          },
          {"tcpip.domain", "connection.suffix"},
      },
      {
          // Void SearchList. Using primary.dns.suffix
          {
              {true, L",bad.searchlist,parsed.as.empty"},
              {true, L"tcpip.searchlist,good.but.overridden"},
              {true, L"tcpip.domain"},
              {true, L"primary.dns.suffix"},
          },
          {"primary.dns.suffix", "connection.suffix"},
      },
      {
          // Void SearchList. Using tcpip.domain when primary.dns.suffix is
          // empty
          {
              {true, L",bad.searchlist,parsed.as.empty"},
              {true, L"tcpip.searchlist,good.but.overridden"},
              {true, L"tcpip.domain"},
              {true, L""},
          },
          {"tcpip.domain", "connection.suffix"},
      },
      {
          // Void SearchList. Using tcpip.domain when primary.dns.suffix is NULL
          {
              {true, L",bad.searchlist,parsed.as.empty"},
              {true, L"tcpip.searchlist,good.but.overridden"},
              {true, L"tcpip.domain"},
              {true},
          },
          {"tcpip.domain", "connection.suffix"},
      },
      {
          // No primary suffix. Devolution does not matter.
          {
              {false},
              {false},
              {true},
              {true},
              {{true, 1}, {true, 2}},
          },
          {"connection.suffix"},
      },
      {
          // Devolution enabled by policy, level by dnscache.
          {
              {false},
              {false},
              {true, L"a.b.c.d.e"},
              {false},
              {{true, 1}, {false}},    // policy_devolution: enabled, level
              {{true, 0}, {true, 3}},  // dnscache_devolution
              {{true, 0}, {true, 1}},  // tcpip_devolution
          },
          {"a.b.c.d.e", "connection.suffix", "b.c.d.e", "c.d.e"},
      },
      {
          // Devolution enabled by dnscache, level by policy.
          {
              {false},
              {false},
              {true, L"a.b.c.d.e"},
              {true, L"f.g.i.l.j"},
              {{false}, {true, 4}},
              {{true, 1}, {false}},
              {{true, 0}, {true, 3}},
          },
          {"f.g.i.l.j", "connection.suffix", "g.i.l.j"},
      },
      {
          // Devolution enabled by default.
          {
              {false},
              {false},
              {true, L"a.b.c.d.e"},
              {false},
              {{false}, {false}},
              {{false}, {true, 3}},
              {{false}, {true, 1}},
          },
          {"a.b.c.d.e", "connection.suffix", "b.c.d.e", "c.d.e"},
      },
      {
          // Devolution enabled at level = 2, but nothing to devolve.
          {
              {false},
              {false},
              {true, L"a.b"},
              {false},
              {{false}, {false}},
              {{false}, {true, 2}},
              {{false}, {true, 2}},
          },
          {"a.b", "connection.suffix"},
      },
      {
          // Devolution disabled when no explicit level.
          {
              {false},
              {false},
              {true, L"a.b.c.d.e"},
              {false},
              {{true, 1}, {false}},
              {{true, 1}, {false}},
              {{true, 1}, {false}},
          },
          {"a.b.c.d.e", "connection.suffix"},
      },
      {
          // Devolution disabled by policy level.
          {
              {false},
              {false},
              {true, L"a.b.c.d.e"},
              {false},
              {{false}, {true, 1}},
              {{true, 1}, {true, 3}},
              {{true, 1}, {true, 4}},
          },
          {"a.b.c.d.e", "connection.suffix"},
      },
      {
          // Devolution disabled by user setting.
          {
              {false},
              {false},
              {true, L"a.b.c.d.e"},
              {false},
              {{false}, {true, 3}},
              {{false}, {true, 3}},
              {{true, 0}, {true, 3}},
          },
          {"a.b.c.d.e", "connection.suffix"},
      },
  };

  for (auto& t : cases) {
    internal::DnsSystemSettings settings;
    settings.addresses = CreateAdapterAddresses(infos);
    settings.policy_search_list = t.input_settings.policy_search_list;
    settings.tcpip_search_list = t.input_settings.tcpip_search_list;
    settings.tcpip_domain = t.input_settings.tcpip_domain;
    settings.primary_dns_suffix = t.input_settings.primary_dns_suffix;
    settings.policy_devolution = t.input_settings.policy_devolution;
    settings.dnscache_devolution = t.input_settings.dnscache_devolution;
    settings.tcpip_devolution = t.input_settings.tcpip_devolution;

    EXPECT_THAT(
        internal::ConvertSettingsToDnsConfig(settings),
        testing::Optional(testing::Field(
            &DnsConfig::search, testing::ElementsAreArray(t.expected_search))));
  }
}

TEST(DnsConfigServiceWinTest, AppendToMultiLabelName) {
  AdapterInfo infos[2] = {
    { IF_TYPE_USB, IfOperStatusUp, L"connection.suffix", { "1.0.0.1" } },
    { 0 },
  };

  const struct TestCase {
    internal::DnsSystemSettings::RegDword input;
    bool expected_output;
  } cases[] = {
      {{true, 0}, false}, {{true, 1}, true}, {{false, 0}, false},
  };

  for (const auto& t : cases) {
    internal::DnsSystemSettings settings;
    settings.addresses = CreateAdapterAddresses(infos);
    settings.append_to_multi_label_name = t.input;
    EXPECT_THAT(
        internal::ConvertSettingsToDnsConfig(settings),
        testing::Optional(testing::Field(&DnsConfig::append_to_multi_label_name,
                                         testing::Eq(t.expected_output))));
  }
}

// Setting have_name_resolution_policy_table should set unhandled_options.
TEST(DnsConfigServiceWinTest, HaveNRPT) {
  AdapterInfo infos[2] = {
    { IF_TYPE_USB, IfOperStatusUp, L"connection.suffix", { "1.0.0.1" } },
    { 0 },
  };

  const struct TestCase {
    bool have_nrpt;
    bool unhandled_options;
  } cases[] = {
      {false, false},
      {true, true},
  };

  for (const auto& t : cases) {
    internal::DnsSystemSettings settings;
    settings.addresses = CreateAdapterAddresses(infos);
    settings.have_name_resolution_policy = t.have_nrpt;
    base::Optional<DnsConfig> config =
        internal::ConvertSettingsToDnsConfig(settings);
    ASSERT_TRUE(config.has_value());
    EXPECT_EQ(t.unhandled_options, config->unhandled_options);
    EXPECT_EQ(t.have_nrpt, config->use_local_ipv6);
  }
}

// Setting have_proxy should set unhandled_options.
TEST(DnsConfigServiceWinTest, HaveProxy) {
  AdapterInfo infos[2] = {
      {IF_TYPE_USB, IfOperStatusUp, L"connection.suffix", {"1.0.0.1"}},
      {0},
  };

  const struct TestCase {
    bool have_proxy;
    bool unhandled_options;
  } cases[] = {
      {false, false},
      {true, true},
  };

  for (const auto& t : cases) {
    internal::DnsSystemSettings settings;
    settings.addresses = CreateAdapterAddresses(infos);
    settings.have_proxy = t.have_proxy;
    EXPECT_THAT(
        internal::ConvertSettingsToDnsConfig(settings),
        testing::Optional(testing::Field(&DnsConfig::unhandled_options,
                                         testing::Eq(t.unhandled_options))));
  }
}

// Setting uses_vpn should set unhandled_options.
TEST(DnsConfigServiceWinTest, UsesVpn) {
  AdapterInfo infos[3] = {
      {IF_TYPE_USB, IfOperStatusUp, L"connection.suffix", {"1.0.0.1"}},
      {IF_TYPE_PPP, IfOperStatusUp, L"connection.suffix", {"1.0.0.1"}},
      {0},
  };

  internal::DnsSystemSettings settings;
  settings.addresses = CreateAdapterAddresses(infos);
  EXPECT_THAT(internal::ConvertSettingsToDnsConfig(settings),
              testing::Optional(testing::Field(&DnsConfig::unhandled_options,
                                               testing::IsTrue())));
}

}  // namespace

}  // namespace net
