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

#include "dns-proxy/proxy.h"

#include <fcntl.h>
#include <linux/rtnetlink.h>
#include <sys/stat.h>

#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include <base/functional/callback.h>
#include <chromeos/patchpanel/dbus/fake_client.h>
#include <chromeos/patchpanel/mock_message_dispatcher.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_object_proxy.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <net-base/ip_address.h>
#include <net-base/byte_utils.h>
#include <net-base/rtnl_message.h>
#include <shill/dbus/client/fake_client.h>
#include <shill/dbus-constants.h>
#include <shill/dbus-proxy-mocks.h>

#include "dns-proxy/ipc.pb.h"

namespace dns_proxy {
namespace {

constexpr net_base::IPv4Address kNetnsPeerIPv4Addr(100, 115, 92, 130);
constexpr net_base::IPv6Address kNetnsPeerIPv6Addr(
    0xfd, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01);
constexpr base::TimeDelta kRequestTimeout = base::Seconds(10000);
constexpr base::TimeDelta kRequestRetryDelay = base::Milliseconds(200);
constexpr int32_t kRequestMaxRetry = 1;

int make_fd() {
  std::string fn(
      ::testing::UnitTest::GetInstance()->current_test_info()->name());
  fn = "/tmp/" + fn;
  return open(fn.c_str(), O_CREAT, 0600);
}

// A helper function to convert a list of IP addresses from type std::string to
// net_base::IPAddress. If |list2| is provided, its elements will be appended to
// the results. This function assumes that all input strings are valid IP
// addresses, otherwise it will crash directly.
std::vector<net_base::IPAddress> StringsToIPAddressesChecked(
    const std::vector<std::string>& list1,
    const std::vector<std::string>& list2 = {}) {
  std::vector<net_base::IPAddress> ret;
  for (const auto& str : list1) {
    ret.push_back(*net_base::IPAddress::CreateFromString(str));
  }
  for (const auto& str : list2) {
    ret.push_back(*net_base::IPAddress::CreateFromString(str));
  }
  return ret;
}

}  // namespace

using org::chromium::flimflam::ManagerProxyInterface;
using org::chromium::flimflam::ManagerProxyMock;
using testing::_;
using testing::ByMove;
using testing::DoAll;
using testing::ElementsAre;
using testing::IsEmpty;
using testing::Return;
using testing::SetArgPointee;
using testing::StrEq;

MATCHER_P(EqualsProto,
          message,
          "Match a proto Message equal to the matcher's argument.") {
  std::string expected_serialized, actual_serialized;
  message.SerializeToString(&expected_serialized);
  arg.SerializeToString(&actual_serialized);
  return expected_serialized == actual_serialized;
}

patchpanel::Client::VirtualDevice virtualdev(
    patchpanel::Client::GuestType guest_type,
    const std::string& ifname,
    const std::string& phys_ifname) {
  patchpanel::Client::VirtualDevice device;
  device.ifname = ifname;
  device.phys_ifname = phys_ifname;
  device.guest_type = guest_type;
  return device;
}

class FakeShillClient : public shill::FakeClient {
 public:
  FakeShillClient(scoped_refptr<dbus::Bus> bus,
                  ManagerProxyInterface* manager_proxy)
      : shill::FakeClient(bus), manager_proxy_(manager_proxy) {}

  std::unique_ptr<shill::Client::ManagerPropertyAccessor> ManagerProperties(
      const base::TimeDelta& timeout) const override {
    return std::make_unique<shill::Client::ManagerPropertyAccessor>(
        manager_proxy_);
  }

  std::unique_ptr<shill::Client::Device> DefaultDevice(
      bool exclude_vpn) override {
    return std::move(default_device_);
  }

  ManagerProxyInterface* GetManagerProxy() const override {
    return manager_proxy_;
  }

  std::unique_ptr<shill::Client::Device> default_device_;

 private:
  ManagerProxyInterface* manager_proxy_;
};

class MockPatchpanelClient : public patchpanel::FakeClient {
 public:
  MockPatchpanelClient() = default;
  ~MockPatchpanelClient() override = default;

  MOCK_METHOD(
      (std::pair<base::ScopedFD, patchpanel::Client::ConnectedNamespace>),
      ConnectNamespace,
      (pid_t pid,
       const std::string& outbound_ifname,
       bool forward_user_traffic,
       bool route_on_vpn,
       patchpanel::Client::TrafficSource traffic_source,
       bool static_ipv6),
      (override));
  MOCK_METHOD(base::ScopedFD,
              RedirectDns,
              (patchpanel::Client::DnsRedirectionRequestType,
               const std::string&,
               const std::string&,
               const std::vector<std::string>&,
               const std::string&),
              (override));
  MOCK_METHOD(std::vector<patchpanel::Client::VirtualDevice>,
              GetDevices,
              (),
              (override));
};

class MockResolver : public Resolver {
 public:
  MockResolver()
      : Resolver(base::DoNothing(),
                 kRequestTimeout,
                 kRequestRetryDelay,
                 kRequestMaxRetry) {}
  ~MockResolver() override = default;

  MOCK_METHOD(bool, ListenUDP, (struct sockaddr*), (override));
  MOCK_METHOD(bool, ListenTCP, (struct sockaddr*), (override));
  MOCK_METHOD(void,
              SetNameServers,
              (const std::vector<std::string>&),
              (override));
  MOCK_METHOD(void,
              SetDoHProviders,
              (const std::vector<std::string>&, bool),
              (override));
};

class TestProxy : public Proxy {
 public:
  TestProxy(const Options& opts,
            std::unique_ptr<patchpanel::Client> patchpanel,
            std::unique_ptr<shill::Client> shill,
            std::unique_ptr<patchpanel::MessageDispatcher<ProxyAddrMessage>>
                msg_dispatcher)
      : Proxy(opts,
              std::move(patchpanel),
              std::move(shill),
              std::move(msg_dispatcher)) {}

  std::unique_ptr<Resolver> resolver;
  std::unique_ptr<Resolver> NewResolver(base::TimeDelta timeout,
                                        base::TimeDelta retry_delay,
                                        int max_num_retries) override {
    return std::move(resolver);
  }
};

class ProxyTest : public ::testing::Test {
 protected:
  ProxyTest()
      : mock_bus_(new dbus::MockBus{dbus::Bus::Options{}}),
        mock_proxy_(new dbus::MockObjectProxy(mock_bus_.get(),
                                              shill::kFlimflamServiceName,
                                              dbus::ObjectPath("/"))) {}
  ~ProxyTest() override { mock_bus_->ShutdownAndBlock(); }

  void SetUp() override {
    EXPECT_CALL(*mock_bus_, GetObjectProxy(_, _))
        .WillRepeatedly(Return(mock_proxy_.get()));
  }

  void SetUpProxy(const Proxy::Options& opts,
                  std::unique_ptr<shill::Client::Device> device = nullptr,
                  bool set_resolver = true) {
    // Set up mocks and fakes.
    patchpanel_client_ = new MockPatchpanelClient();
    shill_client_ = new FakeShillClient(
        mock_bus_, reinterpret_cast<ManagerProxyInterface*>(
                       const_cast<ManagerProxyMock*>(&mock_manager_)));
    msg_dispatcher_ = new patchpanel::MockMessageDispatcher<ProxyAddrMessage>();

    // Initialize Proxy instance.
    proxy_ = std::make_unique<TestProxy>(
        opts, base::WrapUnique(patchpanel_client_),
        base::WrapUnique(shill_client_), base::WrapUnique(msg_dispatcher_));

    // Initialize default proxy behaviors.
    proxy_->shill_ready_ = true;
    proxy_->device_ = std::move(device);
    if (set_resolver) {
      resolver_ = new MockResolver();
      proxy_->resolver_ = base::WrapUnique(resolver_);
      proxy_->doh_config_.set_resolver(resolver_);
    }

    // Initialize default mocks behavior.
    if (opts.type == Proxy::Type::kSystem) {
      ON_CALL(mock_manager_, SetDNSProxyAddresses(_, _, _))
          .WillByDefault(Return(true));
      ON_CALL(*msg_dispatcher_, SendMessage(_)).WillByDefault(Return(true));
    }
  }

  std::unique_ptr<shill::Client::Device> ShillDevice(
      shill::Client::Device::ConnectionState state =
          shill::Client::Device::ConnectionState::kOnline,
      shill::Client::Device::Type type = shill::Client::Device::Type::kEthernet,
      const std::string& ifname = "",
      std::vector<std::string> ipv4_nameservers = {"8.8.8.8"},
      std::vector<std::string> ipv6_nameservers = {"2001:4860:4860::8888"}) {
    auto dev = std::make_unique<shill::Client::Device>();
    dev->type = type;
    dev->state = state;
    dev->ifname = ifname;
    dev->network_config.dns_servers =
        StringsToIPAddressesChecked(ipv6_nameservers, ipv4_nameservers);
    return dev;
  }

  void SetNamespaceAddresses(
      const std::optional<net_base::IPv4Address>& ipv4_addr,
      const std::optional<net_base::IPv6Address>& ipv6_addr) {
    proxy_->ns_fd_ = base::ScopedFD(make_fd());
    if (ipv4_addr) {
      proxy_->ns_.peer_ipv4_address = *ipv4_addr;
    }
    if (ipv6_addr) {
      proxy_->ns_peer_ipv6_address_ = *ipv6_addr;
    }
  }

  void SetNameServers(const std::vector<std::string>& ipv4_nameservers,
                      const std::vector<std::string>& ipv6_nameservers) {
    EXPECT_TRUE(proxy_->device_);
    proxy_->device_->network_config.dns_servers =
        StringsToIPAddressesChecked(ipv6_nameservers, ipv4_nameservers);
    proxy_->UpdateNameServers();
  }

 protected:
  scoped_refptr<dbus::MockBus> mock_bus_;
  scoped_refptr<dbus::MockObjectProxy> mock_proxy_;
  ManagerProxyMock mock_manager_;

  MockResolver* resolver_;
  patchpanel::MockMessageDispatcher<ProxyAddrMessage>* msg_dispatcher_;
  FakeShillClient* shill_client_;
  MockPatchpanelClient* patchpanel_client_;
  std::unique_ptr<TestProxy> proxy_;
};

TEST_F(ProxyTest, SystemProxy_OnShutdownClearsAddressPropertyOnShill) {
  EXPECT_CALL(mock_manager_, ClearDNSProxyAddresses(_, _));
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});
  int unused;
  proxy_->OnShutdown(&unused);
}

TEST_F(ProxyTest, NonSystemProxy_OnShutdownDoesNotCallShill) {
  EXPECT_CALL(mock_manager_, SetDNSProxyAddresses(_, _, _)).Times(0);
  EXPECT_CALL(mock_manager_, ClearDNSProxyAddresses(_, _)).Times(0);
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault}, ShillDevice());
  int unused;
  proxy_->OnShutdown(&unused);
}

TEST_F(ProxyTest, SystemProxy_SetShillDNSProxyAddressesDoesntCrashIfDieFalse) {
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
  EXPECT_CALL(mock_manager_, SetProperty(_, _, _, _)).Times(0);
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});
  proxy_->SetShillDNSProxyAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr,
                                    /*die_on_failure=*/false,
                                    /*num_retries=*/0);
}

TEST_F(ProxyTest, SystemProxy_SetShillDNSProxyAddresses) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem}, ShillDevice());
  SetNameServers({"8.8.8.8"}, {"2001:4860:4860::8888"});
  EXPECT_CALL(mock_manager_,
              SetDNSProxyAddresses(ElementsAre(kNetnsPeerIPv4Addr.ToString(),
                                               kNetnsPeerIPv6Addr.ToString()),
                                   _, _))
      .WillOnce(Return(true));
  proxy_->SetShillDNSProxyAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);
}

TEST_F(ProxyTest, SystemProxy_SetShillDNSProxyAddressesEmptyNameserver) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem}, ShillDevice());

  // Only IPv4 nameserver.
  SetNameServers({"8.8.8.8"}, /*ipv6_nameservers=*/{});
  EXPECT_CALL(
      mock_manager_,
      SetDNSProxyAddresses(ElementsAre(kNetnsPeerIPv4Addr.ToString()), _, _))
      .WillOnce(Return(true));
  proxy_->SetShillDNSProxyAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // Only IPv6 nameserver.
  SetNameServers(/*ipv4_nameservers=*/{}, {"2001:4860:4860::8888"});
  EXPECT_CALL(
      mock_manager_,
      SetDNSProxyAddresses(ElementsAre(kNetnsPeerIPv6Addr.ToString()), _, _))
      .WillOnce(Return(true));
  proxy_->SetShillDNSProxyAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);
}

TEST_F(ProxyTest, SystemProxy_ClearShillDNSProxyAddresses) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});
  EXPECT_CALL(mock_manager_, ClearDNSProxyAddresses(_, _));
  proxy_->ClearShillDNSProxyAddresses();
}

TEST_F(ProxyTest, SystemProxy_SendIPAddressesToController) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem}, ShillDevice());
  SetNameServers({"8.8.8.8"}, {"2001:4860:4860::8888"});

  ProxyAddrMessage msg;
  msg.set_type(ProxyAddrMessage::SET_ADDRS);
  msg.add_addrs(kNetnsPeerIPv4Addr.ToString());
  msg.add_addrs(kNetnsPeerIPv6Addr.ToString());
  EXPECT_CALL(*msg_dispatcher_, SendMessage(EqualsProto(msg)))
      .WillOnce(Return(true));
  proxy_->SendIPAddressesToController(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);
}

TEST_F(ProxyTest, SystemProxy_SendIPAddressesToControllerEmptyNameserver) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem}, ShillDevice());

  // Only IPv4 nameserver.
  SetNameServers({"8.8.8.8"}, /*ipv6_nameservers=*/{});
  ProxyAddrMessage msg;
  msg.set_type(ProxyAddrMessage::SET_ADDRS);
  msg.add_addrs(kNetnsPeerIPv4Addr.ToString());
  EXPECT_CALL(*msg_dispatcher_, SendMessage(EqualsProto(msg)))
      .WillOnce(Return(true));
  proxy_->SendIPAddressesToController(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // Only IPv6 nameserver.
  SetNameServers(/*ipv4_nameservers=*/{}, {"2001:4860:4860::8888"});
  msg.Clear();
  msg.set_type(ProxyAddrMessage::SET_ADDRS);
  msg.add_addrs(kNetnsPeerIPv6Addr.ToString());
  EXPECT_CALL(*msg_dispatcher_, SendMessage(EqualsProto(msg)))
      .WillOnce(Return(true));
  proxy_->SendIPAddressesToController(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);
}

TEST_F(ProxyTest, SystemProxy_ClearIPAddressesInController) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});
  EXPECT_CALL(*msg_dispatcher_, SendMessage(_)).WillOnce(Return(true));
  proxy_->ClearIPAddressesInController();
}

TEST_F(ProxyTest, ShillInitializedWhenReady) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});

  // Test class defaults to make shill client ready. Reset to false.
  proxy_->shill_ready_ = false;
  proxy_->OnShillReady(true);
  EXPECT_TRUE(proxy_->shill_ready_);
}

TEST_F(ProxyTest, SystemProxy_ConnectedNamedspace) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});

  EXPECT_CALL(
      *patchpanel_client_,
      ConnectNamespace(_, _, /*outbound_ifname=*/"", /*route_on_vpn=*/false,
                       patchpanel::Client::TrafficSource::kSystem, _))
      .WillOnce(
          Return(std::make_pair(base::ScopedFD(make_fd()),
                                patchpanel::Client::ConnectedNamespace{})));
  proxy_->OnPatchpanelReady(true);
}

TEST_F(ProxyTest, DefaultProxy_ConnectedNamedspace) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault}, ShillDevice());

  EXPECT_CALL(
      *patchpanel_client_,
      ConnectNamespace(_, _, /*outbound_ifname=*/"", /*route_on_vpn=*/true,
                       patchpanel::Client::TrafficSource::kUser, _))
      .WillOnce(
          Return(std::make_pair(base::ScopedFD(make_fd()),
                                patchpanel::Client::ConnectedNamespace{})));
  proxy_->OnPatchpanelReady(true);
}

TEST_F(ProxyTest, ArcProxy_ConnectedNamedspace) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kARC, .ifname = "eth0"});

  EXPECT_CALL(*patchpanel_client_,
              ConnectNamespace(_, _, /*outbound_ifname=*/"eth0",
                               /*route_on_vpn=*/false,
                               patchpanel::Client::TrafficSource::kArc, _))
      .WillOnce(
          Return(std::make_pair(base::ScopedFD(make_fd()),
                                patchpanel::Client::ConnectedNamespace{})));
  proxy_->OnPatchpanelReady(true);
}

TEST_F(ProxyTest, ShillResetRestoresAddressProperty) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem}, ShillDevice());
  SetNameServers({"8.8.8.8"}, {"2001:4860:4860::8888"});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  EXPECT_CALL(mock_manager_,
              SetDNSProxyAddresses(ElementsAre(kNetnsPeerIPv4Addr.ToString(),
                                               kNetnsPeerIPv6Addr.ToString()),
                                   _, _))
      .WillOnce(Return(true));
  proxy_->OnShillReset(true);
}

TEST_F(ProxyTest, StateClearedIfDefaultServiceDrops) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem}, ShillDevice());

  proxy_->OnDefaultDeviceChanged(nullptr /* no service */);
  EXPECT_FALSE(proxy_->device_);
  EXPECT_FALSE(proxy_->resolver_);
}

TEST_F(ProxyTest, ArcProxy_IgnoredIfDefaultServiceDrops) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kARC, .ifname = "eth0"},
             ShillDevice());

  proxy_->OnDefaultDeviceChanged(nullptr /* no service */);
  EXPECT_TRUE(proxy_->device_);
  EXPECT_TRUE(proxy_->resolver_);
}

TEST_F(ProxyTest, StateClearedIfDefaultServiceIsNotOnline) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem}, ShillDevice());

  auto dev = ShillDevice(shill::Client::Device::ConnectionState::kReady);
  proxy_->OnDefaultDeviceChanged(dev.get());

  EXPECT_FALSE(proxy_->device_);
  EXPECT_FALSE(proxy_->resolver_);
}

TEST_F(ProxyTest, NewResolverStartsListeningOnDefaultServiceComesOnline) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault},
             /*device=*/nullptr, /*set_resolver=*/false);

  auto* new_resolver = new MockResolver();
  proxy_->resolver = base::WrapUnique(new_resolver);
  EXPECT_CALL(*new_resolver, ListenUDP(_)).WillOnce(Return(true));
  EXPECT_CALL(*new_resolver, ListenTCP(_)).WillOnce(Return(true));

  auto dev = ShillDevice(shill::Client::Device::ConnectionState::kOnline);
  brillo::VariantDictionary props;
  EXPECT_CALL(mock_manager_, GetProperties(_, _, _))
      .WillOnce(DoAll(SetArgPointee<0>(props), Return(true)));
  proxy_->OnDefaultDeviceChanged(dev.get());
  EXPECT_TRUE(proxy_->resolver_);
}

TEST_F(ProxyTest, NameServersUpdatedOnDefaultServiceComesOnline) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault});

  auto dev = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kEthernet, "eth0",
                         {"8.8.8.8", "8.8.4.4"},
                         {"2001:4860:4860::8888", "2001:4860:4860::8844"});
  EXPECT_CALL(*resolver_,
              SetNameServers(ElementsAre(StrEq("8.8.8.8"), StrEq("8.8.4.4"),
                                         StrEq("2001:4860:4860::8888"),
                                         StrEq("2001:4860:4860::8844"))));
  proxy_->OnDefaultDeviceChanged(dev.get());
}

TEST_F(ProxyTest, SystemProxy_ShillPropertyUpdatedOnDefaultServiceComesOnline) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  auto dev = ShillDevice(shill::Client::Device::ConnectionState::kOnline);
  EXPECT_CALL(mock_manager_, SetDNSProxyAddresses(_, _, _))
      .WillOnce(Return(true));
  proxy_->OnDefaultDeviceChanged(dev.get());
}

TEST_F(ProxyTest, SystemProxy_IgnoresVPN) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // Expect default device changes to WiFi.
  auto wifi = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                          shill::Client::Device::Type::kWifi);
  proxy_->OnDefaultDeviceChanged(wifi.get());
  EXPECT_EQ(proxy_->device_->type, shill::Client::Device::Type::kWifi);

  // Expect default device to still be WiFi even when a VPN is active.
  auto vpn = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kVPN);
  proxy_->OnDefaultDeviceChanged(vpn.get());
  EXPECT_EQ(proxy_->device_->type, shill::Client::Device::Type::kWifi);
}

TEST_F(ProxyTest, SystemProxy_GetsPhysicalDeviceOnInitialVPN) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  shill_client_->default_device_ =
      ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                  shill::Client::Device::Type::kWifi);

  auto vpn = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kVPN);
  proxy_->OnDefaultDeviceChanged(vpn.get());
  EXPECT_TRUE(proxy_->device_);
  EXPECT_EQ(proxy_->device_->type, shill::Client::Device::Type::kWifi);
}

TEST_F(ProxyTest, DefaultProxy_UsesVPN) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault});

  auto wifi = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                          shill::Client::Device::Type::kWifi);
  proxy_->OnDefaultDeviceChanged(wifi.get());
  EXPECT_TRUE(proxy_->device_);
  EXPECT_EQ(proxy_->device_->type, shill::Client::Device::Type::kWifi);

  auto vpn = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kVPN);
  proxy_->OnDefaultDeviceChanged(vpn.get());
  EXPECT_TRUE(proxy_->device_);
  EXPECT_EQ(proxy_->device_->type, shill::Client::Device::Type::kVPN);
}

TEST_F(ProxyTest, ArcProxy_NameServersUpdatedOnDeviceChangeEvent) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kARC, .ifname = "wlan0"});

  // Set name servers on device change event.
  auto wifi = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                          shill::Client::Device::Type::kWifi, "wlan0",
                          {"8.8.8.8"}, {"2001:4860:4860::8888"});
  EXPECT_CALL(*resolver_,
              SetNameServers(ElementsAre(StrEq("8.8.8.8"),
                                         StrEq("2001:4860:4860::8888"))));
  proxy_->OnDeviceChanged(wifi.get());

  // Verify it only applies changes for the correct interface.
  auto eth = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kEthernet, "eth0",
                         {"8.8.8.8", "8.8.4.4"},
                         {"2001:4860:4860::8888", "2001:4860:4860::8844"});
  EXPECT_CALL(*resolver_, SetNameServers(_)).Times(0);
  proxy_->OnDeviceChanged(eth.get());

  // Update WiFi device nameservers.
  wifi->network_config.dns_servers = StringsToIPAddressesChecked(
      {"2001:4860:4860::8888", "2001:4860:4860::8844", "8.8.8.8", "8.8.4.4"});
  EXPECT_CALL(*resolver_,
              SetNameServers(ElementsAre(StrEq("8.8.8.8"), StrEq("8.8.4.4"),
                                         StrEq("2001:4860:4860::8888"),
                                         StrEq("2001:4860:4860::8844"))));
  proxy_->OnDeviceChanged(wifi.get());
}

TEST_F(ProxyTest, SystemProxy_NameServersUpdatedOnDeviceChangeEvent) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // Set name servers on device change event.
  auto dev = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kEthernet, "eth0",
                         {"8.8.8.8"}, {"2001:4860:4860::8888"});
  EXPECT_CALL(*resolver_,
              SetNameServers(ElementsAre(StrEq("8.8.8.8"),
                                         StrEq("2001:4860:4860::8888"))));
  proxy_->OnDefaultDeviceChanged(dev.get());

  // Now trigger an NetworkConfig change.
  dev->network_config.dns_servers = StringsToIPAddressesChecked(
      {"2001:4860:4860::8888", "2001:4860:4860::8844", "8.8.8.8", "8.8.4.4"});
  EXPECT_CALL(*resolver_,
              SetNameServers(ElementsAre(StrEq("8.8.8.8"), StrEq("8.8.4.4"),
                                         StrEq("2001:4860:4860::8888"),
                                         StrEq("2001:4860:4860::8844"))));
  proxy_->OnDeviceChanged(dev.get());
}

TEST_F(ProxyTest, DeviceChangeEventIgnored) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  auto dev = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kEthernet, "eth0");

  // Set name servers on device change event.
  EXPECT_CALL(*resolver_, SetNameServers(_)).Times(1);
  proxy_->OnDefaultDeviceChanged(dev.get());

  // No change to NetworkConfig, no call to SetNameServers
  EXPECT_CALL(*resolver_, SetNameServers(_)).Times(0);
  proxy_->OnDeviceChanged(dev.get());

  // Different ifname, no call to SetNameServers
  EXPECT_CALL(*resolver_, SetNameServers(_)).Times(0);
  dev->ifname = "eth1";
  proxy_->OnDeviceChanged(dev.get());
}

TEST_F(ProxyTest, BasicDoHDisable) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));

  EXPECT_CALL(*resolver_, SetDoHProviders(IsEmpty(), false));
  brillo::VariantDictionary props;
  proxy_->OnDoHProvidersChanged(props);
}

TEST_F(ProxyTest, BasicDoHAlwaysOn) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));

  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(ElementsAre(StrEq("https://dns.google.com")), true));
  brillo::VariantDictionary props;
  props["https://dns.google.com"] = std::string("");
  proxy_->OnDoHProvidersChanged(props);
}

TEST_F(ProxyTest, BasicDoHAutomatic) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));
  SetNameServers({"8.8.4.4"}, /*ipv6_nameservers=*/{});

  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(ElementsAre(StrEq("https://dns.google.com")), false));
  brillo::VariantDictionary props;
  props["https://dns.google.com"] = std::string("8.8.8.8, 8.8.4.4");
  proxy_->OnDoHProvidersChanged(props);
}

TEST_F(ProxyTest, BasicDoHSecureWithFallback) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));
  SetNameServers({"8.8.4.4"}, /*ipv6_nameservers=*/{});

  EXPECT_CALL(*resolver_,
              SetDoHProviders(ElementsAre(StrEq("https://custom-provider.com")),
                              false));
  brillo::VariantDictionary props;
  props["https://custom-provider.com"] =
      std::string(shill::kDNSProxyDOHProvidersMatchAnyIPAddress);
  proxy_->OnDoHProvidersChanged(props);
}

TEST_F(ProxyTest, RemovesDNSQueryParameterTemplate_AlwaysOn) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));

  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(ElementsAre(StrEq("https://dns.google.com")), true));
  brillo::VariantDictionary props;
  props["https://dns.google.com{?dns}"] = std::string("");
  proxy_->OnDoHProvidersChanged(props);
}

TEST_F(ProxyTest, RemovesDNSQueryParameterTemplate_Automatic) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));
  SetNameServers({"8.8.4.4"}, /*ipv6_nameservers=*/{});

  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(ElementsAre(StrEq("https://dns.google.com")), false));
  brillo::VariantDictionary props;
  props["https://dns.google.com{?dns}"] = std::string("8.8.8.8, 8.8.4.4");
  proxy_->OnDoHProvidersChanged(props);
}

TEST_F(ProxyTest, RemovesDNSQueryParameterTemplate_SecureWithFallback) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));
  SetNameServers({"8.8.4.4"}, /*ipv6_nameservers=*/{});

  EXPECT_CALL(*resolver_,
              SetDoHProviders(ElementsAre(StrEq("https://custom-provider.com")),
                              false));
  brillo::VariantDictionary props;
  props["https://custom-provider.com{?dns}"] =
      std::string(shill::kDNSProxyDOHProvidersMatchAnyIPAddress);
  proxy_->OnDoHProvidersChanged(props);
}

TEST_F(ProxyTest, NewResolverConfiguredWhenSet) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));

  brillo::VariantDictionary props;
  props["https://dns.google.com"] = std::string("8.8.8.8, 8.8.4.4");
  props["https://chrome.cloudflare-dns.com/dns-query"] =
      std::string("1.1.1.1,2606:4700:4700::1111");
  proxy_->OnDoHProvidersChanged(props);

  SetNameServers({"1.0.0.1", "1.1.1.1"}, /*ipv6_nameservers=*/{});
  EXPECT_CALL(*resolver_, SetNameServers(UnorderedElementsAre(
                              StrEq("1.1.1.1"), StrEq("1.0.0.1"))));
  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(
          ElementsAre(StrEq("https://chrome.cloudflare-dns.com/dns-query")),
          false));
  proxy_->doh_config_.set_resolver(resolver_);
}

TEST_F(ProxyTest, DoHModeChangingFixedNameServers) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));

  // Initially off.
  EXPECT_CALL(*resolver_, SetDoHProviders(IsEmpty(), false));
  SetNameServers({"1.1.1.1", "9.9.9.9"}, /*ipv6_nameservers=*/{});

  // Automatic mode - matched cloudflare.
  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(
          ElementsAre(StrEq("https://chrome.cloudflare-dns.com/dns-query")),
          false));
  brillo::VariantDictionary props;
  props["https://dns.google.com"] = std::string("8.8.8.8, 8.8.4.4");
  props["https://chrome.cloudflare-dns.com/dns-query"] =
      std::string("1.1.1.1,2606:4700:4700::1111");
  proxy_->OnDoHProvidersChanged(props);

  // Automatic mode - no match.
  EXPECT_CALL(*resolver_, SetDoHProviders(IsEmpty(), false));
  SetNameServers({"10.10.10.1"}, /*ipv6_nameservers=*/{});

  // Automatic mode - matched google.
  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(ElementsAre(StrEq("https://dns.google.com")), false));
  SetNameServers({"8.8.4.4", "10.10.10.1", "8.8.8.8"}, /*ipv6_nameservers=*/{});

  // Automatic mode - secure DNS with fallback.
  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(
          ElementsAre(StrEq("https://custom-provider.com/dns-query")), false));
  props["https://custom-provider.com/dns-query"] =
      std::string(shill::kDNSProxyDOHProvidersMatchAnyIPAddress);
  proxy_->OnDoHProvidersChanged(props);

  // Explicitly turned off.
  EXPECT_CALL(*resolver_, SetDoHProviders(IsEmpty(), false));
  props.clear();
  proxy_->OnDoHProvidersChanged(props);

  // Still off - even switching ns back.
  EXPECT_CALL(*resolver_, SetDoHProviders(IsEmpty(), false));
  SetNameServers({"8.8.4.4", "10.10.10.1", "8.8.8.8"}, /*ipv6_nameservers=*/{});

  // Always-on mode.
  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(ElementsAre(StrEq("https://doh.opendns.com/dns-query")),
                      true));
  props.clear();
  props["https://doh.opendns.com/dns-query"] = std::string("");
  proxy_->OnDoHProvidersChanged(props);

  // Back to automatic mode, though no matching ns.
  EXPECT_CALL(*resolver_, SetDoHProviders(IsEmpty(), false));
  props.clear();
  props["https://doh.opendns.com/dns-query"] = std::string(
      "208.67.222.222,208.67.220.220,2620:119:35::35, 2620:119:53::53");
  proxy_->OnDoHProvidersChanged(props);

  // Automatic mode working on ns update.
  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(ElementsAre(StrEq("https://doh.opendns.com/dns-query")),
                      false));
  SetNameServers({"8.8.8.8"}, {"2620:119:35::35"});
}

TEST_F(ProxyTest, MultipleDoHProvidersForAlwaysOnMode) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));

  EXPECT_CALL(*resolver_, SetDoHProviders(UnorderedElementsAre(
                                              StrEq("https://dns.google.com"),
                                              StrEq("https://doh.opendns.com")),
                                          true));
  brillo::VariantDictionary props;
  props["https://dns.google.com"] = std::string("");
  props["https://doh.opendns.com"] = std::string("");
  proxy_->OnDoHProvidersChanged(props);
}

TEST_F(ProxyTest, MultipleDoHProvidersForAutomaticMode) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));

  SetNameServers({"1.1.1.1", "10.10.10.10"}, /*ipv6_nameservers=*/{});

  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(
          ElementsAre(StrEq("https://chrome.cloudflare-dns.com/dns-query")),
          false));
  brillo::VariantDictionary props;
  props["https://dns.google.com"] = std::string("8.8.8.8, 8.8.4.4");
  props["https://dns.quad9.net/dns-query"] = std::string("9.9.9.9,2620:fe::9");
  props["https://chrome.cloudflare-dns.com/dns-query"] =
      std::string("1.1.1.1,2606:4700:4700::1111");
  props["https://doh.opendns.com/dns-query"] = std::string(
      "208.67.222.222,208.67.220.220,2620:119:35::35, 2620:119:53::53");
  proxy_->OnDoHProvidersChanged(props);

  EXPECT_CALL(*resolver_,
              SetDoHProviders(UnorderedElementsAre(
                                  StrEq("https://dns.google.com"),
                                  StrEq("https://doh.opendns.com/dns-query"),
                                  StrEq("https://dns.quad9.net/dns-query")),
                              false));
  SetNameServers({"8.8.8.8", "10.10.10.10"}, {"2620:fe::9", "2620:119:53::53"});
}

TEST_F(ProxyTest, MultipleDoHProvidersForSecureWithFallbackMode) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));

  SetNameServers({"1.1.1.1", "10.10.10.10"}, /*ipv6_nameservers=*/{});

  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(UnorderedElementsAre(
                          StrEq("https://custom-provider-1.com"),
                          StrEq("https://custom-provider-2.com/dns-query")),
                      false));
  brillo::VariantDictionary props;
  props["https://custom-provider-1.com"] =
      std::string(shill::kDNSProxyDOHProvidersMatchAnyIPAddress);
  props["https://custom-provider-2.com/dns-query"] =
      std::string(shill::kDNSProxyDOHProvidersMatchAnyIPAddress);
  proxy_->OnDoHProvidersChanged(props);
}

TEST_F(ProxyTest, DoHBadAlwaysOnConfigSetsAutomaticMode) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline));
  SetNameServers({"1.1.1.1", "10.10.10.10"}, /*ipv6_nameservers=*/{});

  EXPECT_CALL(
      *resolver_,
      SetDoHProviders(
          ElementsAre(StrEq("https://chrome.cloudflare-dns.com/dns-query")),
          false));
  brillo::VariantDictionary props;
  props["https://dns.opendns.com"] = std::string("");
  props["https://dns.google.com"] = std::string("8.8.8.8, 8.8.4.4");
  props["https://dns.quad9.net/dns-query"] = std::string("9.9.9.9,2620:fe::9");
  props["https://chrome.cloudflare-dns.com/dns-query"] =
      std::string("1.1.1.1,2606:4700:4700::1111");
  props["https://doh.opendns.com/dns-query"] = std::string(
      "208.67.222.222,208.67.220.220,2620:119:35::35, 2620:119:53::53");
  proxy_->OnDoHProvidersChanged(props);

  EXPECT_CALL(*resolver_,
              SetDoHProviders(UnorderedElementsAre(
                                  StrEq("https://dns.google.com"),
                                  StrEq("https://doh.opendns.com/dns-query"),
                                  StrEq("https://dns.quad9.net/dns-query")),
                              false));
  SetNameServers({"8.8.8.8", "10.10.10.10"}, {"2620:fe::9", "2620:119:53::53"});
}

TEST_F(ProxyTest, SystemProxy_SetsDnsRedirectionRule) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // System proxy requests a DnsRedirectionRule to exclude traffic destined
  // not to the underlying network's name server.
  auto dev = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kEthernet, "eth0");
  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(
          patchpanel::Client::DnsRedirectionRequestType::kExcludeDestination, _,
          kNetnsPeerIPv4Addr.ToString(), _, _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(
          patchpanel::Client::DnsRedirectionRequestType::kExcludeDestination, _,
          kNetnsPeerIPv6Addr.ToString(), _, _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  proxy_->OnDefaultDeviceChanged(dev.get());

  // System proxy does not call patchpanel on Parallels VM started.
  EXPECT_CALL(*patchpanel_client_, RedirectDns(_, _, _, _, _)).Times(0);
  proxy_->OnVirtualDeviceChanged(
      patchpanel::Client::VirtualDeviceEvent::kAdded,
      virtualdev(patchpanel::Client::GuestType::kParallelsVm, "vmtap1",
                 "eth0"));

  // System proxy does not call patchpanel on ARC started.
  EXPECT_CALL(*patchpanel_client_, RedirectDns(_, _, _, _, _)).Times(0);
  proxy_->OnVirtualDeviceChanged(
      patchpanel::Client::VirtualDeviceEvent::kAdded,
      virtualdev(patchpanel::Client::GuestType::kArcContainer, "arc_eth0",
                 "eth0"));
}

TEST_F(ProxyTest, DefaultProxy_SetDnsRedirectionRuleDeviceAlreadyStarted) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault}, ShillDevice());
  SetNameServers({"8.8.8.8"}, {"2001:4860:4860::8888"});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // Set DNS redirection rule.
  EXPECT_CALL(*patchpanel_client_,
              RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kUser,
                          _, _, ElementsAre("8.8.8.8"), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  EXPECT_CALL(*patchpanel_client_,
              RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kUser,
                          _, _, ElementsAre("2001:4860:4860::8888"), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  proxy_->Enable();
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 2);
}

TEST_F(ProxyTest, DefaultProxy_SetDnsRedirectionRuleNewDeviceStarted) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // Empty active device.
  EXPECT_CALL(*patchpanel_client_, RedirectDns(_, _, _, _, _)).Times(0);
  proxy_->Enable();
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 0);

  // Default device changed.
  auto dev = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kEthernet, "eth0",
                         {"8.8.8.8"}, {"2001:4860:4860::8888"});
  EXPECT_CALL(*patchpanel_client_,
              RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kUser,
                          _, _, ElementsAre("8.8.8.8"), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  EXPECT_CALL(*patchpanel_client_,
              RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kUser,
                          _, _, ElementsAre("2001:4860:4860::8888"), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  proxy_->OnDefaultDeviceChanged(dev.get());
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 2);
}

TEST_F(ProxyTest, DefaultProxy_SetDnsRedirectionRuleGuest) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kEthernet, "eth0"));
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // Guest started.
  auto plugin_vm_dev =
      virtualdev(patchpanel::Client::GuestType::kParallelsVm, "vmtap0", "eth0");
  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kDefault,
                  "vmtap0", kNetnsPeerIPv4Addr.ToString(), IsEmpty(), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kDefault,
                  "vmtap0", kNetnsPeerIPv6Addr.ToString(), IsEmpty(), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  proxy_->OnVirtualDeviceChanged(patchpanel::Client::VirtualDeviceEvent::kAdded,
                                 plugin_vm_dev);
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 2);

  // Guest stopped.
  proxy_->OnVirtualDeviceChanged(
      patchpanel::Client::VirtualDeviceEvent::kRemoved, plugin_vm_dev);
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 0);
}

TEST_F(ProxyTest, DefaultProxy_NeverSetsDnsRedirectionRuleOtherGuest) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault},
             ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kEthernet, "eth0"));
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // Other guest started.
  EXPECT_CALL(*patchpanel_client_, RedirectDns(_, _, _, _, _)).Times(0);
  proxy_->OnVirtualDeviceChanged(
      patchpanel::Client::VirtualDeviceEvent::kAdded,
      virtualdev(patchpanel::Client::GuestType::kArcContainer, "arc_eth0",
                 "eth0"));
}

TEST_F(ProxyTest, SystemProxy_SetDnsRedirectionRuleIPv6Added) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem}, ShillDevice());
  SetNameServers({"8.8.8.8"}, {"2001:4860:4860::8888"});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, /*ipv6_addr=*/std::nullopt);

  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(
          patchpanel::Client::DnsRedirectionRequestType::kExcludeDestination, _,
          kNetnsPeerIPv6Addr.ToString(), _, _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));

  // Proxy's ConnectedNamespace peer interface name is set to empty and
  // RTNL message's interface index is set to 0 in order to match.
  // if_nametoindex which is used to get the interface index will return 0 on
  // error.
  net_base::RTNLMessage msg(net_base::RTNLMessage::kTypeAddress,
                            net_base::RTNLMessage::kModeAdd, 0 /* flags */,
                            0 /* seq */, 0 /* pid */, 0 /* interface_index */,
                            AF_INET6);
  msg.set_address_status(
      net_base::RTNLMessage::AddressStatus(0, 0, RT_SCOPE_UNIVERSE));
  msg.SetAttribute(IFA_ADDRESS, kNetnsPeerIPv6Addr.ToBytes());
  proxy_->RTNLMessageHandler(msg);
}

TEST_F(ProxyTest, SystemProxy_SetDnsRedirectionRuleIPv6Deleted) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem}, ShillDevice());

  proxy_->lifeline_fds_.emplace(std::make_pair("", AF_INET6),
                                base::ScopedFD(make_fd()));

  net_base::RTNLMessage msg(net_base::RTNLMessage::kTypeAddress,
                            net_base::RTNLMessage::kModeDelete, 0 /* flags */,
                            0 /* seq */, 0 /* pid */, 0 /* interface_index */,
                            AF_INET6);
  msg.set_address_status(
      net_base::RTNLMessage::AddressStatus(0, 0, RT_SCOPE_UNIVERSE));
  proxy_->RTNLMessageHandler(msg);
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 0);
}

TEST_F(ProxyTest, DefaultProxy_SetDnsRedirectionRuleWithoutIPv6) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, /*ipv6_addr=*/std::nullopt);

  // Default device changed.
  auto dev = ShillDevice(shill::Client::Device::ConnectionState::kOnline,
                         shill::Client::Device::Type::kEthernet, "eth0",
                         {"8.8.8.8"}, {"2001:4860:4860::8888"});
  EXPECT_CALL(*patchpanel_client_,
              RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kUser,
                          _, _, ElementsAre("8.8.8.8"), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  proxy_->OnDefaultDeviceChanged(dev.get());
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 1);

  // Guest started.
  auto plugin_vm_dev =
      virtualdev(patchpanel::Client::GuestType::kParallelsVm, "vmtap0", "eth0");
  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kDefault,
                  "vmtap0", kNetnsPeerIPv4Addr.ToString(), IsEmpty(), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  proxy_->OnVirtualDeviceChanged(patchpanel::Client::VirtualDeviceEvent::kAdded,
                                 plugin_vm_dev);
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 2);

  // Guest stopped.
  proxy_->OnVirtualDeviceChanged(
      patchpanel::Client::VirtualDeviceEvent::kRemoved, plugin_vm_dev);
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 1);
}

TEST_F(ProxyTest, DefaultProxy_SetDnsRedirectionRuleIPv6Added) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault}, ShillDevice());
  SetNameServers({"8.8.8.8"}, {"2001:4860:4860::8888"});
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, /*ipv6_addr=*/std::nullopt);

  EXPECT_CALL(*patchpanel_client_, GetDevices())
      .WillOnce(
          Return(std::vector<patchpanel::Client::VirtualDevice>{virtualdev(
              patchpanel::Client::GuestType::kTerminaVm, "vmtap0", "eth0")}));
  EXPECT_CALL(*patchpanel_client_,
              RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kUser,
                          _, kNetnsPeerIPv6Addr.ToString(), _, _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kDefault,
                  "vmtap0", kNetnsPeerIPv6Addr.ToString(), IsEmpty(), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));

  // Proxy's ConnectedNamespace peer interface name is set to empty and
  // RTNL message's interface index is set to 0 in order to match.
  // if_nametoindex which is used to get the interface index will return 0 on
  // error.
  net_base::RTNLMessage msg(net_base::RTNLMessage::kTypeAddress,
                            net_base::RTNLMessage::kModeAdd, 0 /* flags */,
                            0 /* seq */, 0 /* pid */, 0 /* interface_index */,
                            AF_INET6);
  msg.set_address_status(
      net_base::RTNLMessage::AddressStatus(0, 0, RT_SCOPE_UNIVERSE));
  msg.SetAttribute(IFA_ADDRESS, kNetnsPeerIPv6Addr.ToBytes());
  proxy_->RTNLMessageHandler(msg);
}

TEST_F(ProxyTest, DefaultProxy_SetDnsRedirectionRuleIPv6Deleted) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault}, ShillDevice());

  proxy_->lifeline_fds_.emplace(std::make_pair("", AF_INET6),
                                base::ScopedFD(make_fd()));
  proxy_->lifeline_fds_.emplace(std::make_pair("vmtap0", AF_INET6),
                                base::ScopedFD(make_fd()));

  EXPECT_CALL(*patchpanel_client_, GetDevices())
      .WillOnce(
          Return(std::vector<patchpanel::Client::VirtualDevice>{virtualdev(
              patchpanel::Client::GuestType::kTerminaVm, "vmtap0", "eth0")}));

  net_base::RTNLMessage msg(net_base::RTNLMessage::kTypeAddress,
                            net_base::RTNLMessage::kModeDelete, 0 /* flags */,
                            0 /* seq */, 0 /* pid */, 0 /* interface_index */,
                            AF_INET6);
  msg.set_address_status(
      net_base::RTNLMessage::AddressStatus(0, 0, RT_SCOPE_UNIVERSE));
  proxy_->RTNLMessageHandler(msg);
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 0);
}

TEST_F(ProxyTest, DefaultProxy_SetDnsRedirectionRuleUnrelatedIPv6Added) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kDefault}, ShillDevice());

  EXPECT_CALL(*patchpanel_client_, GetDevices())
      .WillRepeatedly(
          Return(std::vector<patchpanel::Client::VirtualDevice>{virtualdev(
              patchpanel::Client::GuestType::kTerminaVm, "vmtap0", "eth0")}));
  EXPECT_CALL(*patchpanel_client_, RedirectDns(_, _, _, _, _)).Times(0);

  // Proxy's ConnectedNamespace peer interface name is set to empty and
  // RTNL message's interface index is set to -1 in order to not match.
  // if_nametoindex which is used to get the interface index will return 0 on
  // error.
  net_base::RTNLMessage msg_unrelated_ifindex(
      net_base::RTNLMessage::kTypeAddress, net_base::RTNLMessage::kModeAdd,
      0 /* flags */, 0 /* seq */, 0 /* pid */, -1 /* interface_index */,
      AF_INET6);
  msg_unrelated_ifindex.set_address_status(
      net_base::RTNLMessage::AddressStatus(0, 0, RT_SCOPE_UNIVERSE));
  msg_unrelated_ifindex.SetAttribute(IFA_ADDRESS, kNetnsPeerIPv6Addr.ToBytes());
  proxy_->RTNLMessageHandler(msg_unrelated_ifindex);

  net_base::RTNLMessage msg_unrelated_scope(
      net_base::RTNLMessage::kTypeAddress, net_base::RTNLMessage::kModeAdd,
      0 /* flags */, 0 /* seq */, 0 /* pid */, -1 /* interface_index */,
      AF_INET6);
  msg_unrelated_scope.set_address_status(
      net_base::RTNLMessage::AddressStatus(0, 0, RT_SCOPE_LINK));
  msg_unrelated_scope.SetAttribute(IFA_ADDRESS, kNetnsPeerIPv6Addr.ToBytes());
  proxy_->RTNLMessageHandler(msg_unrelated_scope);
}

TEST_F(ProxyTest, ArcProxy_SetDnsRedirectionRuleDeviceAlreadyStarted) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kARC, .ifname = "eth0"},
             ShillDevice());
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // Set devices created before the proxy started.
  EXPECT_CALL(*patchpanel_client_, GetDevices())
      .WillOnce(
          Return(std::vector<patchpanel::Client::VirtualDevice>{virtualdev(
              patchpanel::Client::GuestType::kArcVm, "arc_eth0", "eth0")}));
  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kArc,
                  "arc_eth0", kNetnsPeerIPv4Addr.ToString(), IsEmpty(), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kArc,
                  "arc_eth0", kNetnsPeerIPv6Addr.ToString(), IsEmpty(), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  proxy_->Enable();
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 2);
}

TEST_F(ProxyTest, ArcProxy_SetDnsRedirectionRuleNewDeviceStarted) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kARC, .ifname = "eth0"},
             ShillDevice());
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // Guest started.
  auto arc_dev = virtualdev(patchpanel::Client::GuestType::kArcContainer,
                            "arc_eth0", "eth0");
  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kArc,
                  "arc_eth0", kNetnsPeerIPv4Addr.ToString(), IsEmpty(), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kArc,
                  "arc_eth0", kNetnsPeerIPv6Addr.ToString(), IsEmpty(), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));
  proxy_->OnVirtualDeviceChanged(patchpanel::Client::VirtualDeviceEvent::kAdded,
                                 arc_dev);
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 2);

  // Guest stopped.
  proxy_->OnVirtualDeviceChanged(
      patchpanel::Client::VirtualDeviceEvent::kRemoved, arc_dev);
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 0);
}

TEST_F(ProxyTest, ArcProxy_NeverSetsDnsRedirectionRuleOtherGuest) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kARC, .ifname = "eth0"},
             ShillDevice());
  proxy_->ns_peer_ipv6_address_ = kNetnsPeerIPv6Addr;

  // Other guest started.
  EXPECT_CALL(*patchpanel_client_, RedirectDns(_, _, _, _, _)).Times(0);
  proxy_->OnVirtualDeviceChanged(
      patchpanel::Client::VirtualDeviceEvent::kAdded,
      virtualdev(patchpanel::Client::GuestType::kTerminaVm, "vmtap0", "eth0"));
}

TEST_F(ProxyTest, ArcProxy_NeverSetsDnsRedirectionRuleOtherIfname) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kARC, .ifname = "wlan0"});
  proxy_->device_ = ShillDevice();
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, kNetnsPeerIPv6Addr);

  // ARC guest with other interface started.
  EXPECT_CALL(*patchpanel_client_, RedirectDns(_, _, _, _, _)).Times(0);
  proxy_->OnVirtualDeviceChanged(
      patchpanel::Client::VirtualDeviceEvent::kAdded,
      virtualdev(patchpanel::Client::GuestType::kArcVm, "arc_eth0", "eth0"));
}

TEST_F(ProxyTest, ArcProxy_SetDnsRedirectionRuleIPv6Added) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kARC, .ifname = "eth0"},
             ShillDevice());
  SetNamespaceAddresses(kNetnsPeerIPv4Addr, /*ipv6_addr=*/std::nullopt);

  EXPECT_CALL(*patchpanel_client_, GetDevices())
      .WillOnce(
          Return(std::vector<patchpanel::Client::VirtualDevice>{virtualdev(
              patchpanel::Client::GuestType::kArcVm, "arc_eth0", "eth0")}));
  EXPECT_CALL(
      *patchpanel_client_,
      RedirectDns(patchpanel::Client::DnsRedirectionRequestType::kArc,
                  "arc_eth0", kNetnsPeerIPv6Addr.ToString(), IsEmpty(), _))
      .WillOnce(Return(ByMove(base::ScopedFD(make_fd()))));

  // Proxy's ConnectedNamespace peer interface name is set to empty and
  // RTNL message's interface index is set to 0 in order to match.
  // if_nametoindex which is used to get the interface index will return 0 on
  // error.
  net_base::RTNLMessage msg(net_base::RTNLMessage::kTypeAddress,
                            net_base::RTNLMessage::kModeAdd, 0 /* flags */,
                            0 /* seq */, 0 /* pid */, 0 /* interface_index */,
                            AF_INET6);
  msg.set_address_status(
      net_base::RTNLMessage::AddressStatus(0, 0, RT_SCOPE_UNIVERSE));
  msg.SetAttribute(IFA_ADDRESS, kNetnsPeerIPv6Addr.ToBytes());
  proxy_->RTNLMessageHandler(msg);
}

TEST_F(ProxyTest, ArcProxy_SetDnsRedirectionRuleIPv6Deleted) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kARC, .ifname = "eth0"},
             ShillDevice());

  proxy_->lifeline_fds_.emplace(std::make_pair("arc_eth0", AF_INET6),
                                base::ScopedFD(make_fd()));

  EXPECT_CALL(*patchpanel_client_, GetDevices())
      .WillOnce(
          Return(std::vector<patchpanel::Client::VirtualDevice>{virtualdev(
              patchpanel::Client::GuestType::kArcVm, "arc_eth0", "eth0")}));

  net_base::RTNLMessage msg(net_base::RTNLMessage::kTypeAddress,
                            net_base::RTNLMessage::kModeDelete, 0 /* flags */,
                            0 /* seq */, 0 /* pid */, 0 /* interface_index */,
                            AF_INET6);
  msg.set_address_status(
      net_base::RTNLMessage::AddressStatus(0, 0, RT_SCOPE_UNIVERSE));
  proxy_->RTNLMessageHandler(msg);
  EXPECT_EQ(proxy_->lifeline_fds_.size(), 0);
}

TEST_F(ProxyTest, ArcProxy_SetDnsRedirectionRuleUnrelatedIPv6Added) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kARC, .ifname = "eth0"},
             ShillDevice());

  EXPECT_CALL(*patchpanel_client_, GetDevices())
      .WillRepeatedly(
          Return(std::vector<patchpanel::Client::VirtualDevice>{virtualdev(
              patchpanel::Client::GuestType::kArcVm, "arc_eth0", "eth0")}));
  EXPECT_CALL(*patchpanel_client_, RedirectDns(_, _, _, _, _)).Times(0);

  // Proxy's ConnectedNamespace peer interface name is set to empty and
  // RTNL message's interface index is set to -1 in order to not match.
  // if_nametoindex which is used to get the interface index will return 0 on
  // error.
  net_base::RTNLMessage msg_unrelated_ifindex(
      net_base::RTNLMessage::kTypeAddress, net_base::RTNLMessage::kModeAdd,
      0 /* flags */, 0 /* seq */, 0 /* pid */, -1 /* interface_index */,
      AF_INET6);
  msg_unrelated_ifindex.set_address_status(
      net_base::RTNLMessage::AddressStatus(0, 0, RT_SCOPE_UNIVERSE));
  msg_unrelated_ifindex.SetAttribute(IFA_ADDRESS, kNetnsPeerIPv6Addr.ToBytes());
  proxy_->RTNLMessageHandler(msg_unrelated_ifindex);

  net_base::RTNLMessage msg_unrelated_scope(
      net_base::RTNLMessage::kTypeAddress, net_base::RTNLMessage::kModeAdd,
      0 /* flags */, 0 /* seq */, 0 /* pid */, -1 /* interface_index */,
      AF_INET6);
  msg_unrelated_scope.set_address_status(
      net_base::RTNLMessage::AddressStatus(0, 0, RT_SCOPE_LINK));
  msg_unrelated_scope.SetAttribute(IFA_ADDRESS, kNetnsPeerIPv6Addr.ToBytes());
  proxy_->RTNLMessageHandler(msg_unrelated_scope);
}

TEST_F(ProxyTest, UpdateNameServers) {
  SetUpProxy(Proxy::Options{.type = Proxy::Type::kSystem}, ShillDevice());
  proxy_->device_->network_config.dns_servers = StringsToIPAddressesChecked(
      {// IPv4 name servers.
       "8.8.8.8", "192.168.1.1",
       // IPv6 name servers.
       "eeb0:117e:92ee:ad3d:ce0d:a646:95ea:a16e", "::2"});
  proxy_->UpdateNameServers();

  const std::vector<net_base::IPv4Address> expected_ipv4_dns_addresses = {
      net_base::IPv4Address(8, 8, 8, 8), net_base::IPv4Address(192, 168, 1, 1)};
  const std::vector<net_base::IPv6Address> expected_ipv6_dns_addresses = {
      *net_base::IPv6Address::CreateFromString(
          "eeb0:117e:92ee:ad3d:ce0d:a646:95ea:a16e"),
      *net_base::IPv6Address::CreateFromString("::2")};

  EXPECT_THAT(proxy_->doh_config_.ipv4_nameservers(),
              expected_ipv4_dns_addresses);
  EXPECT_THAT(proxy_->doh_config_.ipv6_nameservers(),
              expected_ipv6_dns_addresses);
}
}  // namespace dns_proxy
