// 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 "base/logging.h"
#include "base/memory/free_deleter.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/dns/dns_protocol.h"
#include "starboard/memory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

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

  for (const auto& t : cases) {
    std::vector<std::string> actual_output, expected_output;
    actual_output.push_back("UNSET");
    for (const char* const* output = t.output; *output; ++output) {
      expected_output.push_back(*output);
    }
    bool result = internal::ParseSearchList(t.input, &actual_output);
    if (!expected_output.empty()) {
      EXPECT_TRUE(result);
      EXPECT_EQ(expected_output, actual_output);
    } else {
      EXPECT_FALSE(result) << "Unexpected parse success on " << t.input;
    }
  }
}

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*>(SbMemoryAllocate(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 = NULL;
    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));
    }

    DnsConfig config;
    internal::ConfigParseWinResult result =
        internal::ConvertSettingsToDnsConfig(settings, &config);
    internal::ConfigParseWinResult expected_result =
        expected_nameservers.empty() ? internal::CONFIG_PARSE_WIN_NO_NAMESERVERS
            : internal::CONFIG_PARSE_WIN_OK;
    EXPECT_EQ(expected_result, result);
    EXPECT_EQ(expected_nameservers, config.nameservers);
    if (result == internal::CONFIG_PARSE_WIN_OK) {
      ASSERT_EQ(1u, config.search.size());
      EXPECT_EQ(t.expected_suffix, config.search[0]);
    }
  }
}

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::string expected_search[5];
  } 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;

    DnsConfig config;
    EXPECT_EQ(internal::CONFIG_PARSE_WIN_OK,
              internal::ConvertSettingsToDnsConfig(settings, &config));
    std::vector<std::string> expected_search;
    for (size_t j = 0; !t.expected_search[j].empty(); ++j) {
      expected_search.push_back(t.expected_search[j]);
    }
    EXPECT_EQ(expected_search, config.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;
    DnsConfig config;
    EXPECT_EQ(internal::CONFIG_PARSE_WIN_OK,
              internal::ConvertSettingsToDnsConfig(settings, &config));
    EXPECT_EQ(t.expected_output, config.append_to_multi_label_name);
  }
}

// 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;
    internal::ConfigParseWinResult result;
  } cases[] = {
    { false, false, internal::CONFIG_PARSE_WIN_OK },
    { true, true, internal::CONFIG_PARSE_WIN_UNHANDLED_OPTIONS },
  };

  for (const auto& t : cases) {
    internal::DnsSystemSettings settings;
    settings.addresses = CreateAdapterAddresses(infos);
    settings.have_name_resolution_policy = t.have_nrpt;
    DnsConfig config;
    EXPECT_EQ(t.result,
              internal::ConvertSettingsToDnsConfig(settings, &config));
    EXPECT_EQ(t.unhandled_options, config.unhandled_options);
    EXPECT_EQ(t.have_nrpt, config.use_local_ipv6);
  }
}


}  // namespace

}  // namespace net
