// 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.h"

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/cancelable_callback.h"
#include "base/location.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_split.h"
#include "base/test/test_timeouts.h"
#include "base/thread_task_runner_handle.h"
#include "net/base/net_util.h"
#include "net/dns/dns_protocol.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

const NameServerClassifier::NameServersType kNone =
    NameServerClassifier::NAME_SERVERS_TYPE_NONE;
const NameServerClassifier::NameServersType kGoogle =
    NameServerClassifier::NAME_SERVERS_TYPE_GOOGLE_PUBLIC_DNS;
const NameServerClassifier::NameServersType kPrivate =
    NameServerClassifier::NAME_SERVERS_TYPE_PRIVATE;
const NameServerClassifier::NameServersType kPublic =
    NameServerClassifier::NAME_SERVERS_TYPE_PUBLIC;
const NameServerClassifier::NameServersType kMixed =
    NameServerClassifier::NAME_SERVERS_TYPE_MIXED;

class NameServerClassifierTest : public testing::Test {
 protected:
  NameServerClassifier::NameServersType Classify(
      const std::string& servers_string) {
    std::vector<IPEndPoint> servers;
    for (const base::StringPiece& server_str :
         base::SplitStringPiece(servers_string, " ", base::TRIM_WHITESPACE,
                                base::SPLIT_WANT_ALL)) {
      if (server_str.empty())
        continue;

      IPAddressNumber address;
      bool parsed = ParseIPLiteralToNumber(server_str, &address);
      EXPECT_TRUE(parsed);
      servers.push_back(IPEndPoint(address, dns_protocol::kDefaultPort));
    }

    return classifier_.GetNameServersType(servers);
  }

 private:
  NameServerClassifier classifier_;
};

TEST_F(NameServerClassifierTest, None) {
  EXPECT_EQ(kNone, Classify(""));
}

TEST_F(NameServerClassifierTest, Google) {
  EXPECT_EQ(kGoogle, Classify("8.8.8.8"));
  EXPECT_EQ(kGoogle, Classify("8.8.8.8 8.8.4.4"));
  EXPECT_EQ(kGoogle, Classify("2001:4860:4860::8888"));
  EXPECT_EQ(kGoogle, Classify("2001:4860:4860::8888 2001:4860:4860::8844"));
  EXPECT_EQ(kGoogle, Classify("2001:4860:4860::8888 8.8.8.8"));

  // Make sure nobody took any shortcuts on the IP matching:
  EXPECT_EQ(kPublic, Classify("8.8.8.4"));
  EXPECT_EQ(kPublic, Classify("8.8.4.8"));
  EXPECT_EQ(kPublic, Classify("2001:4860:4860::8884"));
  EXPECT_EQ(kPublic, Classify("2001:4860:4860::8848"));
  EXPECT_EQ(kPublic, Classify("2001:4860:4860::1:8888"));
  EXPECT_EQ(kPublic, Classify("2001:4860:4860:1::8888"));
}

TEST_F(NameServerClassifierTest, PrivateLocalhost) {
  EXPECT_EQ(kPrivate, Classify("127.0.0.1"));
  EXPECT_EQ(kPrivate, Classify("::1"));
}

TEST_F(NameServerClassifierTest, PrivateRfc1918) {
  EXPECT_EQ(kPrivate, Classify("10.0.0.0 10.255.255.255"));
  EXPECT_EQ(kPrivate, Classify("172.16.0.0 172.31.255.255"));
  EXPECT_EQ(kPrivate, Classify("192.168.0.0 192.168.255.255"));
  EXPECT_EQ(kPrivate, Classify("10.1.1.1 172.16.1.1 192.168.1.1"));
}

TEST_F(NameServerClassifierTest, PrivateIPv4LinkLocal) {
  EXPECT_EQ(kPrivate, Classify("169.254.0.0 169.254.255.255"));
}

TEST_F(NameServerClassifierTest, PrivateIPv6LinkLocal) {
  EXPECT_EQ(kPrivate,
      Classify("fe80:: fe80:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
}

TEST_F(NameServerClassifierTest, Public) {
  EXPECT_EQ(kPublic, Classify("4.2.2.1"));
  EXPECT_EQ(kPublic, Classify("4.2.2.1 4.2.2.2"));
}

TEST_F(NameServerClassifierTest, Mixed) {
  EXPECT_EQ(kMixed, Classify("8.8.8.8 192.168.1.1"));
  EXPECT_EQ(kMixed, Classify("8.8.8.8 4.2.2.1"));
  EXPECT_EQ(kMixed, Classify("192.168.1.1 4.2.2.1"));
  EXPECT_EQ(kMixed, Classify("8.8.8.8 192.168.1.1 4.2.2.1"));
}

class DnsConfigServiceTest : public testing::Test {
 public:
  void OnConfigChanged(const DnsConfig& config) {
    last_config_ = config;
    if (quit_on_config_)
      base::MessageLoop::current()->Quit();
  }

 protected:
  class TestDnsConfigService : public DnsConfigService {
   public:
    void ReadNow() override {}
    bool StartWatching() override { return true; }

    // Expose the protected methods to this test suite.
    void InvalidateConfig() {
      DnsConfigService::InvalidateConfig();
    }

    void InvalidateHosts() {
      DnsConfigService::InvalidateHosts();
    }

    void OnConfigRead(const DnsConfig& config) {
      DnsConfigService::OnConfigRead(config);
    }

    void OnHostsRead(const DnsHosts& hosts) {
      DnsConfigService::OnHostsRead(hosts);
    }

    void set_watch_failed(bool value) {
      DnsConfigService::set_watch_failed(value);
    }
  };

  void WaitForConfig(base::TimeDelta timeout) {
    base::CancelableClosure closure(base::MessageLoop::QuitClosure());
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, closure.callback(), timeout);
    quit_on_config_ = true;
    base::MessageLoop::current()->Run();
    quit_on_config_ = false;
    closure.Cancel();
  }

  // Generate a config using the given seed..
  DnsConfig MakeConfig(unsigned seed) {
    DnsConfig config;
    IPAddressNumber ip;
    CHECK(ParseIPLiteralToNumber("1.2.3.4", &ip));
    config.nameservers.push_back(IPEndPoint(ip, seed & 0xFFFF));
    EXPECT_TRUE(config.IsValid());
    return config;
  }

  // Generate hosts using the given seed.
  DnsHosts MakeHosts(unsigned seed) {
    DnsHosts hosts;
    std::string hosts_content = "127.0.0.1 localhost";
    hosts_content.append(seed, '1');
    ParseHosts(hosts_content, &hosts);
    EXPECT_FALSE(hosts.empty());
    return hosts;
  }

  void SetUp() override {
    quit_on_config_ = false;

    service_.reset(new TestDnsConfigService());
    service_->WatchConfig(base::Bind(&DnsConfigServiceTest::OnConfigChanged,
                                     base::Unretained(this)));
    EXPECT_FALSE(last_config_.IsValid());
  }

  DnsConfig last_config_;
  bool quit_on_config_;

  // Service under test.
  scoped_ptr<TestDnsConfigService> service_;
};

}  // namespace

TEST_F(DnsConfigServiceTest, FirstConfig) {
  DnsConfig config = MakeConfig(1);

  service_->OnConfigRead(config);
  // No hosts yet, so no config.
  EXPECT_TRUE(last_config_.Equals(DnsConfig()));

  service_->OnHostsRead(config.hosts);
  EXPECT_TRUE(last_config_.Equals(config));
}

TEST_F(DnsConfigServiceTest, Timeout) {
  DnsConfig config = MakeConfig(1);
  config.hosts = MakeHosts(1);
  ASSERT_TRUE(config.IsValid());

  service_->OnConfigRead(config);
  service_->OnHostsRead(config.hosts);
  EXPECT_FALSE(last_config_.Equals(DnsConfig()));
  EXPECT_TRUE(last_config_.Equals(config));

  service_->InvalidateConfig();
  WaitForConfig(TestTimeouts::action_timeout());
  EXPECT_FALSE(last_config_.Equals(config));
  EXPECT_TRUE(last_config_.Equals(DnsConfig()));

  service_->OnConfigRead(config);
  EXPECT_FALSE(last_config_.Equals(DnsConfig()));
  EXPECT_TRUE(last_config_.Equals(config));

  service_->InvalidateHosts();
  WaitForConfig(TestTimeouts::action_timeout());
  EXPECT_FALSE(last_config_.Equals(config));
  EXPECT_TRUE(last_config_.Equals(DnsConfig()));

  DnsConfig bad_config = last_config_ = MakeConfig(0xBAD);
  service_->InvalidateConfig();
  // We don't expect an update. This should time out.
  WaitForConfig(base::TimeDelta::FromMilliseconds(100) +
                TestTimeouts::tiny_timeout());
  EXPECT_TRUE(last_config_.Equals(bad_config)) << "Unexpected change";

  last_config_ = DnsConfig();
  service_->OnConfigRead(config);
  service_->OnHostsRead(config.hosts);
  EXPECT_FALSE(last_config_.Equals(DnsConfig()));
  EXPECT_TRUE(last_config_.Equals(config));
}

TEST_F(DnsConfigServiceTest, SameConfig) {
  DnsConfig config = MakeConfig(1);
  config.hosts = MakeHosts(1);

  service_->OnConfigRead(config);
  service_->OnHostsRead(config.hosts);
  EXPECT_FALSE(last_config_.Equals(DnsConfig()));
  EXPECT_TRUE(last_config_.Equals(config));

  last_config_ = DnsConfig();
  service_->OnConfigRead(config);
  EXPECT_TRUE(last_config_.Equals(DnsConfig())) << "Unexpected change";

  service_->OnHostsRead(config.hosts);
  EXPECT_TRUE(last_config_.Equals(DnsConfig())) << "Unexpected change";
}

TEST_F(DnsConfigServiceTest, DifferentConfig) {
  DnsConfig config1 = MakeConfig(1);
  DnsConfig config2 = MakeConfig(2);
  DnsConfig config3 = MakeConfig(1);
  config1.hosts = MakeHosts(1);
  config2.hosts = MakeHosts(1);
  config3.hosts = MakeHosts(2);
  ASSERT_TRUE(config1.EqualsIgnoreHosts(config3));
  ASSERT_FALSE(config1.Equals(config2));
  ASSERT_FALSE(config1.Equals(config3));
  ASSERT_FALSE(config2.Equals(config3));

  service_->OnConfigRead(config1);
  service_->OnHostsRead(config1.hosts);
  EXPECT_FALSE(last_config_.Equals(DnsConfig()));
  EXPECT_TRUE(last_config_.Equals(config1));

  // It doesn't matter for this tests, but increases coverage.
  service_->InvalidateConfig();
  service_->InvalidateHosts();

  service_->OnConfigRead(config2);
  EXPECT_TRUE(last_config_.Equals(config1)) << "Unexpected change";
  service_->OnHostsRead(config2.hosts);  // Not an actual change.
  EXPECT_FALSE(last_config_.Equals(config1));
  EXPECT_TRUE(last_config_.Equals(config2));

  service_->OnConfigRead(config3);
  EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config3));
  service_->OnHostsRead(config3.hosts);
  EXPECT_FALSE(last_config_.Equals(config2));
  EXPECT_TRUE(last_config_.Equals(config3));
}

TEST_F(DnsConfigServiceTest, WatchFailure) {
  DnsConfig config1 = MakeConfig(1);
  DnsConfig config2 = MakeConfig(2);
  config1.hosts = MakeHosts(1);
  config2.hosts = MakeHosts(2);

  service_->OnConfigRead(config1);
  service_->OnHostsRead(config1.hosts);
  EXPECT_FALSE(last_config_.Equals(DnsConfig()));
  EXPECT_TRUE(last_config_.Equals(config1));

  // Simulate watch failure.
  service_->set_watch_failed(true);
  service_->InvalidateConfig();
  WaitForConfig(TestTimeouts::action_timeout());
  EXPECT_FALSE(last_config_.Equals(config1));
  EXPECT_TRUE(last_config_.Equals(DnsConfig()));

  DnsConfig bad_config = last_config_ = MakeConfig(0xBAD);
  // Actual change in config, so expect an update, but it should be empty.
  service_->OnConfigRead(config1);
  EXPECT_FALSE(last_config_.Equals(bad_config));
  EXPECT_TRUE(last_config_.Equals(DnsConfig()));

  last_config_ = bad_config;
  // Actual change in config, so expect an update, but it should be empty.
  service_->InvalidateConfig();
  service_->OnConfigRead(config2);
  EXPECT_FALSE(last_config_.Equals(bad_config));
  EXPECT_TRUE(last_config_.Equals(DnsConfig()));

  last_config_ = bad_config;
  // No change, so no update.
  service_->InvalidateConfig();
  service_->OnConfigRead(config2);
  EXPECT_TRUE(last_config_.Equals(bad_config));
}

}  // namespace net

