0

Revert "Allow and sort multi-address hosts entries"

This reverts commit 59be7b29cd.

Reason for revert: Suspected to cause lots of flaky tests on Linux ASAN https://crbug.com/1266340

Original change's description:
> Allow and sort multi-address hosts entries
>
> Instead of a single IPAddress, HOSTS files are parsed to a
> std::vector<IPAddress> of all addresses for the same hostname, in the
> order they appear in the file. Any entry with 2 or more addresses is
> then run through the AddressSorter during the SerialWorker "followup"
> phase of HostsReader.
>
> Fixed: 1257639
> Change-Id: Iae36a1e22aa3a7cd985938de96acac101b01e824
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3226048
> Commit-Queue: Eric Orth <ericorth@chromium.org>
> Reviewed-by: Dan McArdle <dmcardle@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#937054}

Bug: 1266340, 1257639
Change-Id: Ib73ee34a74948733dc2c11444077b7ae5fd20855
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3259045
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Christian Dullweber <dullweber@chromium.org>
Commit-Queue: Lingqi Chi <lingqi@chromium.org>
Owners-Override: Christian Dullweber <dullweber@chromium.org>
Auto-Submit: Christian Dullweber <dullweber@chromium.org>
Reviewed-by: Lingqi Chi <lingqi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#937822}
This commit is contained in:
Christian Dullweber
2021-11-03 11:37:35 +00:00
committed by Chromium LUCI CQ
parent bc28ed33bb
commit 1b2df5916d
22 changed files with 98 additions and 613 deletions

@ -6,7 +6,6 @@
#include <algorithm>
#include <climits>
#include <ostream>
#include "base/check_op.h"
#include "base/containers/stack_container.h"
@ -504,8 +503,4 @@ size_t MaskPrefixLength(const IPAddress& mask) {
IPAddress(all_ones->data(), all_ones->size()));
}
std::ostream& operator<<(std::ostream& os, const IPAddress& ip_address) {
return os << ip_address.ToString();
}
} // namespace net

@ -9,7 +9,6 @@
#include <stdint.h>
#include <array>
#include <ostream>
#include <string>
#include <vector>
@ -300,9 +299,6 @@ bool IPAddressStartsWith(const IPAddress& address, const uint8_t (&prefix)[N]) {
return std::equal(prefix, prefix + N, address.bytes().begin());
}
NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
const IPAddress& ip_address);
} // namespace net
#endif // NET_BASE_IP_ADDRESS_H_

@ -106,10 +106,6 @@ source_set("dns") {
]
}
if (is_ios) {
sources += [ "address_sorter_ios.cc" ]
}
if (is_android) {
sources += [
"dns_config_service_android.cc",
@ -419,7 +415,7 @@ source_set("tests") {
sources += [ "dns_config_service_android_unittest.cc" ]
} else if (is_linux) {
sources += [ "dns_config_service_linux_unittest.cc" ]
} else if (is_posix && !is_ios) {
} else if (is_posix) {
sources += [ "dns_config_service_posix_unittest.cc" ]
}

@ -9,18 +9,20 @@
#include "base/callback.h"
#include "base/macros.h"
#include "net/base/address_list.h"
#include "net/base/net_export.h"
namespace net {
class AddressList;
// Sorts AddressList according to RFC3484, by likelihood of successful
// connection. Depending on the platform, the sort could be performed
// asynchronously by the OS, or synchronously by local implementation.
// AddressSorter does not necessarily preserve port numbers on the sorted list.
class NET_EXPORT AddressSorter {
public:
using CallbackType = base::OnceCallback<void(bool success, AddressList list)>;
using CallbackType =
base::OnceCallback<void(bool success, const AddressList& list)>;
AddressSorter(const AddressSorter&) = delete;
AddressSorter& operator=(const AddressSorter&) = delete;

@ -1,20 +0,0 @@
// Copyright 2021 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/address_sorter.h"
#include <memory>
#include "base/notreached.h"
namespace net {
// static
std::unique_ptr<AddressSorter> AddressSorter::CreateAddressSorter() {
// Not expected to ever need an AddressSorter on iOS.
NOTREACHED();
return nullptr;
}
} // namespace net

@ -264,13 +264,13 @@ AddressSorterPosix::AddressSorterPosix(ClientSocketFactory* socket_factory)
}
AddressSorterPosix::~AddressSorterPosix() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
NetworkChangeNotifier::RemoveIPAddressObserver(this);
}
void AddressSorterPosix::Sort(const AddressList& list,
CallbackType callback) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
std::vector<std::unique_ptr<DestinationInfo>> sort_list;
for (size_t i = 0; i < list.size(); ++i) {
@ -325,11 +325,11 @@ void AddressSorterPosix::Sort(const AddressList& list,
for (size_t i = 0; i < sort_list.size(); ++i)
result.push_back(IPEndPoint(sort_list[i]->address, 0 /* port */));
std::move(callback).Run(true, std::move(result));
std::move(callback).Run(true, result);
}
void AddressSorterPosix::OnIPAddressChanged() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
source_map_.clear();
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
const internal::AddressTrackerLinux* tracker =
@ -399,7 +399,7 @@ void AddressSorterPosix::OnIPAddressChanged() {
void AddressSorterPosix::FillPolicy(const IPAddress& address,
SourceAddressInfo* info) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
info->scope = GetScope(ipv4_scope_table_, address);
info->label = GetPolicyValue(label_table_, address);
}

@ -9,7 +9,7 @@
#include <vector>
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "base/threading/thread_checker.h"
#include "net/base/address_list.h"
#include "net/base/ip_address.h"
#include "net/base/net_export.h"
@ -87,7 +87,7 @@ class NET_EXPORT_PRIVATE AddressSorterPosix
PolicyTable label_table_;
PolicyTable ipv4_scope_table_;
SEQUENCE_CHECKER(sequence_checker_);
THREAD_CHECKER(thread_checker_);
};
} // namespace net

@ -199,10 +199,10 @@ class TestSocketFactory : public ClientSocketFactory {
void OnSortComplete(AddressList* result_buf,
CompletionOnceCallback callback,
bool success,
AddressList result) {
const AddressList& result) {
EXPECT_TRUE(success);
if (success)
*result_buf = std::move(result);
*result_buf = result;
std::move(callback).Run(OK);
}

@ -37,9 +37,9 @@ IPEndPoint MakeEndPoint(const std::string& str) {
void OnSortComplete(AddressList* result_buf,
CompletionOnceCallback callback,
bool success,
AddressList result) {
const AddressList& result) {
if (success)
*result_buf = std::move(result);
*result_buf = result;
std::move(callback).Run(success ? OK : ERR_FAILED);
}

@ -132,7 +132,7 @@ class AddressSorterWin : public AddressSorter {
list.push_back(ipe);
}
}
std::move(callback_).Run(success_, std::move(list));
std::move(callback_).Run(success_, list);
}
CallbackType callback_;

@ -6,11 +6,8 @@
#include <memory>
#include <string>
#include <utility>
#include "base/barrier_callback.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/check_op.h"
#include "base/files/file_path.h"
#include "base/location.h"
@ -20,8 +17,6 @@
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
#include "net/base/address_list.h"
#include "net/dns/address_sorter.h"
#include "net/dns/dns_hosts.h"
#include "net/dns/serial_worker.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
@ -104,12 +99,9 @@ DnsConfigService::HostsReader::HostsReader(
DnsConfigService::HostsReader::~HostsReader() = default;
DnsConfigService::HostsReader::WorkItem::WorkItem(
std::unique_ptr<DnsHostsParser> dns_hosts_parser,
std::unique_ptr<AddressSorter> address_sorter)
: dns_hosts_parser_(std::move(dns_hosts_parser)),
address_sorter_(std::move(address_sorter)) {
std::unique_ptr<DnsHostsParser> dns_hosts_parser)
: dns_hosts_parser_(std::move(dns_hosts_parser)) {
DCHECK(dns_hosts_parser_);
DCHECK(address_sorter_);
}
DnsConfigService::HostsReader::WorkItem::~WorkItem() = default;
@ -139,89 +131,10 @@ void DnsConfigService::HostsReader::WorkItem::DoWork() {
hosts_.reset();
}
void DnsConfigService::HostsReader::WorkItem::FollowupWork(
base::OnceClosure closure) {
if (!hosts_.has_value()) {
std::move(closure).Run();
return;
}
std::vector<const DnsHosts::value_type*> to_sort;
for (const auto& host : hosts_.value()) {
const std::vector<IPAddress>& addresses = host.second;
if (addresses.size() >= 2) {
to_sort.push_back(&host);
}
}
// This `sort_barrier` is called when each individual sort operation
// completes. It accumulates all of the inputs it is given into a vector. When
// it is called for the last time (after `to_sort.size()` calls), it invokes
// `OnAddressSortComplete()` with that vector of inputs. Should immediately
// trigger `OnAddressSortComplete()` if `to_sort` is empty.
SortBarrier sort_barrier =
base::BarrierCallback<std::pair<DnsHostsKey, AddressList>>(
to_sort.size(),
base::BindOnce(&WorkItem::OnAddressSortComplete,
weak_ptr_factory_.GetWeakPtr(), std::move(closure)));
for (const auto* sort_entry : to_sort) {
const DnsHostsKey& key = sort_entry->first;
const std::vector<IPAddress>& addresses = sort_entry->second;
address_sorter_->Sort(
AddressList::CreateFromIPAddressList(addresses,
/*aliases=*/{}),
base::BindOnce(&WorkItem::OnIndividualAddressSortComplete,
weak_ptr_factory_.GetWeakPtr(), key, sort_barrier));
}
}
void DnsConfigService::HostsReader::WorkItem::OnIndividualAddressSortComplete(
DnsHostsKey key,
SortBarrier barrier,
bool sort_success,
AddressList sorted) {
DCHECK(hosts_.has_value());
DCHECK(hosts_.value().find(key) != hosts_.value().end());
DCHECK_GE(hosts_.value()[key].size(), 2u);
if (sort_success) {
barrier.Run(std::make_pair(std::move(key), std::move(sorted)));
} else {
barrier.Run(std::make_pair(std::move(key), AddressList()));
}
}
void DnsConfigService::HostsReader::WorkItem::OnAddressSortComplete(
base::OnceClosure closure,
std::vector<std::pair<DnsHostsKey, AddressList>> sorted) {
DCHECK(hosts_.has_value());
for (const std::pair<DnsHostsKey, AddressList>& sorted_host : sorted) {
auto it = hosts_.value().find(sorted_host.first);
DCHECK(it != hosts_.value().end());
DCHECK_GE(it->second.size(), 2u);
if (sorted_host.second.empty()) {
// Empty list means sort failure. Remove from hosts.
hosts_.value().erase(it);
} else {
// Replace `hosts_` entry with addresses from `sorted_host`.
it->second.clear();
for (const IPEndPoint& endpoint : sorted_host.second) {
it->second.push_back(endpoint.address());
}
}
}
std::move(closure).Run();
}
std::unique_ptr<SerialWorker::WorkItem>
DnsConfigService::HostsReader::CreateWorkItem() {
return std::make_unique<WorkItem>(
std::make_unique<DnsHostsFileParser>(hosts_file_path_),
AddressSorter::CreateAddressSorter());
std::make_unique<DnsHostsFileParser>(hosts_file_path_));
}
void DnsConfigService::HostsReader::OnWorkFinished(

@ -7,9 +7,7 @@
#include <map>
#include <memory>
#include <utility>
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
@ -17,7 +15,6 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/net_export.h"
#include "net/dns/address_sorter.h"
#include "net/dns/dns_config.h"
#include "net/dns/dns_hosts.h"
#include "net/dns/serial_worker.h"
@ -26,8 +23,6 @@
namespace net {
class AddressList;
// Service for reading system DNS settings, on demand or when signalled by
// internal watchers and NetworkChangeNotifier. This object is not thread-safe
// and methods may perform blocking I/O so methods must be called on a sequence
@ -136,8 +131,7 @@ class NET_EXPORT_PRIVATE DnsConfigService {
protected:
class NET_EXPORT_PRIVATE WorkItem : public SerialWorker::WorkItem {
public:
WorkItem(std::unique_ptr<DnsHostsParser> dns_hosts_parser,
std::unique_ptr<AddressSorter> address_sorter);
explicit WorkItem(std::unique_ptr<DnsHostsParser> dns_hosts_parser);
~WorkItem() override;
// Override if needed to implement platform-specific behavior, e.g. for a
@ -152,28 +146,12 @@ class NET_EXPORT_PRIVATE DnsConfigService {
// SerialWorker::WorkItem:
void DoWork() final;
void FollowupWork(base::OnceClosure closure) final;
private:
friend HostsReader;
using SortBarrier =
base::RepeatingCallback<void(std::pair<DnsHostsKey, AddressList>)>;
void OnIndividualAddressSortComplete(DnsHostsKey key,
SortBarrier barrier,
bool success,
AddressList sorted);
void OnAddressSortComplete(
base::OnceClosure closure,
std::vector<std::pair<DnsHostsKey, AddressList>> sorted);
absl::optional<DnsHosts> hosts_;
std::unique_ptr<DnsHostsParser> dns_hosts_parser_;
std::unique_ptr<AddressSorter> address_sorter_;
base::WeakPtrFactory<WorkItem> weak_ptr_factory_{this};
};
// SerialWorker:

@ -7,14 +7,10 @@
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/cancelable_callback.h"
#include "base/immediate_crash.h"
#include "base/location.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
@ -22,14 +18,10 @@
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "net/base/address_family.h"
#include "net/base/address_list.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/dns/address_sorter.h"
#include "net/dns/dns_hosts.h"
#include "net/dns/public/dns_protocol.h"
#include "net/dns/test_dns_config_service.h"
@ -43,7 +35,6 @@ namespace {
using testing::_;
using testing::DoAll;
using testing::InvokeWithoutArgs;
using testing::Return;
using testing::SetArgPointee;
@ -184,54 +175,9 @@ MockHostsParserFactory::GetFactory() {
DnsHosts::value_type CreateHostsEntry(base::StringPiece name,
AddressFamily family,
std::vector<IPAddress> addresses) {
IPAddress address) {
DnsHostsKey key = std::make_pair(std::string(name), family);
return std::make_pair(std::move(key), std::move(addresses));
}
// `AddressSorter` that will always crash if invoked. Useful to validate cases
// where no sort is expected to be needed.
class CrashingAddressSorter : public AddressSorter {
public:
void Sort(const AddressList& list, CallbackType callback) const override {
IMMEDIATE_CRASH();
}
static HostsReadingTestDnsConfigService::AddressSorterFactory GetFactory() {
return base::BindRepeating([]() -> std::unique_ptr<AddressSorter> {
return std::make_unique<CrashingAddressSorter>();
});
}
};
class MockAddressSorterFactory : public AddressSorter {
public:
HostsReadingTestDnsConfigService::AddressSorterFactory GetFactory();
MOCK_METHOD(void,
Sort,
(const AddressList&, CallbackType),
(const, override));
private:
class Delegator : public AddressSorter {
public:
explicit Delegator(MockAddressSorterFactory* factory) : factory_(factory) {}
void Sort(const AddressList& list, CallbackType callback) const override {
return factory_->Sort(list, std::move(callback));
}
private:
MockAddressSorterFactory* factory_;
};
};
HostsReadingTestDnsConfigService::AddressSorterFactory
MockAddressSorterFactory::GetFactory() {
return base::BindLambdaForTesting([this]() -> std::unique_ptr<AddressSorter> {
return std::make_unique<Delegator>(this);
});
return std::make_pair(std::move(key), address);
}
} // namespace
@ -377,8 +323,8 @@ TEST_F(DnsConfigServiceTest, HostsReadFailure) {
EXPECT_CALL(parser, ParseHosts(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(DnsHosts()), Return(false)));
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), CrashingAddressSorter::GetFactory());
auto service =
std::make_unique<HostsReadingTestDnsConfigService>(parser.GetFactory());
SetUpService(*service);
service->OnConfigRead(MakeConfig(1));
@ -396,8 +342,8 @@ TEST_F(DnsConfigServiceTest, ReadEmptyHosts) {
EXPECT_CALL(parser, ParseHosts(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(DnsHosts()), Return(true)));
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), CrashingAddressSorter::GetFactory());
auto service =
std::make_unique<HostsReadingTestDnsConfigService>(parser.GetFactory());
SetUpService(*service);
// Expect immediate result on reading config because HOSTS should already have
@ -422,8 +368,8 @@ TEST_F(DnsConfigServiceTest, ReadSingleHosts) {
EXPECT_CALL(parser, ParseHosts(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(hosts), Return(true)));
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), CrashingAddressSorter::GetFactory());
auto service =
std::make_unique<HostsReadingTestDnsConfigService>(parser.GetFactory());
SetUpService(*service);
// Expect immediate result on reading config because HOSTS should already have
@ -452,8 +398,8 @@ TEST_F(DnsConfigServiceTest, ReadMultipleHosts) {
EXPECT_CALL(parser, ParseHosts(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(hosts), Return(true)));
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), CrashingAddressSorter::GetFactory());
auto service =
std::make_unique<HostsReadingTestDnsConfigService>(parser.GetFactory());
SetUpService(*service);
// Expect immediate result on reading config because HOSTS should already have
@ -479,8 +425,8 @@ TEST_F(DnsConfigServiceTest, HostsReadSubsequentFailure) {
.WillOnce(DoAll(SetArgPointee<0>(hosts), Return(true)))
.WillOnce(DoAll(SetArgPointee<0>(DnsHosts()), Return(false)));
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), CrashingAddressSorter::GetFactory());
auto service =
std::make_unique<HostsReadingTestDnsConfigService>(parser.GetFactory());
SetUpService(*service);
// Expect immediate result on reading config because HOSTS should already have
@ -505,8 +451,8 @@ TEST_F(DnsConfigServiceTest, HostsReadSubsequentSuccess) {
.WillOnce(DoAll(SetArgPointee<0>(DnsHosts()), Return(false)))
.WillOnce(DoAll(SetArgPointee<0>(hosts), Return(true)));
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), CrashingAddressSorter::GetFactory());
auto service =
std::make_unique<HostsReadingTestDnsConfigService>(parser.GetFactory());
SetUpService(*service);
DnsConfig config = MakeConfig(1);
@ -529,8 +475,8 @@ TEST_F(DnsConfigServiceTest, ConfigReadDuringHostsReRead) {
EXPECT_CALL(parser, ParseHosts(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(hosts), Return(true)));
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), CrashingAddressSorter::GetFactory());
auto service =
std::make_unique<HostsReadingTestDnsConfigService>(parser.GetFactory());
SetUpService(*service);
// Expect immediate result on reading config because HOSTS should already have
@ -566,8 +512,8 @@ TEST_F(DnsConfigServiceTest, HostsWatcherFailure) {
EXPECT_CALL(parser, ParseHosts(_))
.WillOnce(DoAll(SetArgPointee<0>(hosts), Return(true)));
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), CrashingAddressSorter::GetFactory());
auto service =
std::make_unique<HostsReadingTestDnsConfigService>(parser.GetFactory());
SetUpService(*service);
// Expect immediate result on reading config because HOSTS should already have
@ -583,282 +529,4 @@ TEST_F(DnsConfigServiceTest, HostsWatcherFailure) {
EXPECT_EQ(last_config_, DnsConfig());
}
TEST_F(DnsConfigServiceTest, ReadMultiAddressHosts) {
DnsHosts hosts = {
CreateHostsEntry(
"name1", ADDRESS_FAMILY_IPV4,
{IPAddress(1, 1, 1, 1), IPAddress(2, 2, 2, 2), IPAddress(3, 3, 3, 3),
IPAddress(4, 4, 4, 4), IPAddress(5, 5, 5, 5)}),
CreateHostsEntry("name2", ADDRESS_FAMILY_IPV4, {IPAddress(6, 6, 6, 6)})};
MockHostsParserFactory parser;
EXPECT_CALL(parser, ParseHosts(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(hosts), Return(true)));
// AddressSorter that reverses order and then removes element 3 (if 4 or more
// elements). Really just an arbitrary operation to prove the sort occurred.
MockAddressSorterFactory sorter;
EXPECT_CALL(sorter, Sort(_, _))
.WillRepeatedly(
[](const AddressList& list, AddressSorter::CallbackType callback) {
std::vector<IPEndPoint> reversed = list.endpoints();
base::ranges::reverse(reversed);
AddressList sorted;
for (size_t i = 0; i < reversed.size(); ++i) {
if (i == 3)
continue;
sorted.push_back(reversed[i]);
}
std::move(callback).Run(/*success=*/true, sorted);
});
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), sorter.GetFactory());
SetUpService(*service);
DnsConfig config = MakeConfig(1);
service->OnConfigRead(config);
DnsHosts expected_hosts = {
CreateHostsEntry("name1", ADDRESS_FAMILY_IPV4,
{IPAddress(5, 5, 5, 5), IPAddress(4, 4, 4, 4),
IPAddress(3, 3, 3, 3), IPAddress(1, 1, 1, 1)}),
CreateHostsEntry("name2", ADDRESS_FAMILY_IPV4, {IPAddress(6, 6, 6, 6)})};
// Expect immediate result on reading config because HOSTS should already have
// been read on initting watch in `SetUpService()`.
EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config));
EXPECT_EQ(last_config_.hosts, expected_hosts);
// No change from retriggering read.
service->TriggerHostsChangeNotification(/*success=*/true);
ValidateNoNotification();
EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config));
EXPECT_EQ(last_config_.hosts, expected_hosts);
}
TEST_F(DnsConfigServiceTest, ReadMultipleMultiAddressHosts) {
DnsHosts hosts = {
CreateHostsEntry(
"name1", ADDRESS_FAMILY_IPV4,
{IPAddress(1, 1, 1, 1), IPAddress(2, 2, 2, 2), IPAddress(3, 3, 3, 3),
IPAddress(4, 4, 4, 4), IPAddress(5, 5, 5, 5)}),
CreateHostsEntry("name2", ADDRESS_FAMILY_IPV4, {IPAddress(6, 6, 6, 6)}),
CreateHostsEntry("name3", ADDRESS_FAMILY_IPV4,
{IPAddress(7, 7, 7, 7), IPAddress(8, 8, 8, 8)})};
MockHostsParserFactory parser;
EXPECT_CALL(parser, ParseHosts(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(hosts), Return(true)));
// AddressSorter that reverses order and then removes element 3 (if 4 or more
// elements). Really just an arbitrary operation to prove the sort occurred.
MockAddressSorterFactory sorter;
EXPECT_CALL(sorter, Sort(_, _))
.WillRepeatedly(
[](const AddressList& list, AddressSorter::CallbackType callback) {
std::vector<IPEndPoint> reversed = list.endpoints();
base::ranges::reverse(reversed);
AddressList sorted;
for (size_t i = 0; i < reversed.size(); ++i) {
if (i == 3)
continue;
sorted.push_back(reversed[i]);
}
std::move(callback).Run(/*success=*/true, sorted);
});
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), sorter.GetFactory());
SetUpService(*service);
DnsConfig config = MakeConfig(1);
service->OnConfigRead(config);
DnsHosts expected_hosts = {
CreateHostsEntry("name1", ADDRESS_FAMILY_IPV4,
{IPAddress(5, 5, 5, 5), IPAddress(4, 4, 4, 4),
IPAddress(3, 3, 3, 3), IPAddress(1, 1, 1, 1)}),
CreateHostsEntry("name2", ADDRESS_FAMILY_IPV4, {IPAddress(6, 6, 6, 6)}),
CreateHostsEntry("name3", ADDRESS_FAMILY_IPV4,
{IPAddress(8, 8, 8, 8), IPAddress(7, 7, 7, 7)})};
// Expect immediate result on reading config because HOSTS should already have
// been read on initting watch in `SetUpService()`.
EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config));
EXPECT_EQ(last_config_.hosts, expected_hosts);
// No change from retriggering read.
service->TriggerHostsChangeNotification(/*success=*/true);
ValidateNoNotification();
EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config));
EXPECT_EQ(last_config_.hosts, expected_hosts);
}
TEST_F(DnsConfigServiceTest, FailedSortResultsAreExcluded) {
DnsHosts hosts = {
CreateHostsEntry("name1", ADDRESS_FAMILY_IPV4,
{IPAddress(1, 1, 1, 1), IPAddress(2, 2, 2, 2)}),
CreateHostsEntry("name2", ADDRESS_FAMILY_IPV4, {IPAddress(3, 3, 3, 3)})};
MockHostsParserFactory parser;
EXPECT_CALL(parser, ParseHosts(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(hosts), Return(true)));
// AddressSorter that always fails.
MockAddressSorterFactory sorter;
EXPECT_CALL(sorter, Sort(_, _))
.WillRepeatedly(
[](const AddressList& list, AddressSorter::CallbackType callback) {
std::move(callback).Run(/*success=*/false, AddressList());
});
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), sorter.GetFactory());
SetUpService(*service);
DnsConfig config = MakeConfig(1);
service->OnConfigRead(config);
// Expect only the unsorted single-address entry.
DnsHosts expected_hosts = {
CreateHostsEntry("name2", ADDRESS_FAMILY_IPV4, {IPAddress(3, 3, 3, 3)})};
// Expect immediate result on reading config because HOSTS should already have
// been read on initting watch in `SetUpService()`.
EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config));
EXPECT_EQ(last_config_.hosts, expected_hosts);
// No change from retriggering read.
service->TriggerHostsChangeNotification(/*success=*/true);
ValidateNoNotification();
EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config));
EXPECT_EQ(last_config_.hosts, expected_hosts);
}
TEST_F(DnsConfigServiceTest, HandlesAsyncSort) {
DnsHosts hosts = {
CreateHostsEntry("name1", ADDRESS_FAMILY_IPV4,
{IPAddress(1, 1, 1, 1), IPAddress(2, 2, 2, 2)}),
CreateHostsEntry("name2", ADDRESS_FAMILY_IPV4, {IPAddress(3, 3, 3, 3)})};
MockHostsParserFactory parser;
EXPECT_CALL(parser, ParseHosts(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(hosts), Return(true)));
// Noop sorter that always succeeds and doesn't change any ordering, but does
// so asynchronously.
MockAddressSorterFactory sorter;
EXPECT_CALL(sorter, Sort(_, _))
.WillRepeatedly(
[](const AddressList& list, AddressSorter::CallbackType callback) {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), /*success=*/true, list));
});
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), sorter.GetFactory());
SetUpService(*service);
DnsConfig config = MakeConfig(1);
service->OnConfigRead(config);
// Expect immediate result on reading config because HOSTS should already have
// been read on initting watch in `SetUpService()`.
EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config));
EXPECT_EQ(last_config_.hosts, hosts);
// No change from retriggering read.
service->TriggerHostsChangeNotification(/*success=*/true);
ValidateNoNotification();
EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config));
EXPECT_EQ(last_config_.hosts, hosts);
}
TEST_F(DnsConfigServiceTest, DestroyServiceDuringSort) {
DnsHosts hosts = {
CreateHostsEntry("name1", ADDRESS_FAMILY_IPV4,
{IPAddress(1, 1, 1, 1), IPAddress(2, 2, 2, 2)}),
CreateHostsEntry("name2", ADDRESS_FAMILY_IPV4, {IPAddress(3, 3, 3, 3)})};
MockHostsParserFactory parser;
EXPECT_CALL(parser, ParseHosts(_))
.WillOnce(DoAll(SetArgPointee<0>(hosts), Return(true)));
// Sorter that saves out the callback and never invokes it itself.
MockAddressSorterFactory sorter;
AddressSorter::CallbackType saved_callback;
EXPECT_CALL(sorter, Sort(_, _))
.WillOnce([&saved_callback](const AddressList& list,
AddressSorter::CallbackType callback) {
saved_callback = std::move(callback);
});
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(), sorter.GetFactory());
SetUpService(*service);
DnsConfig config = MakeConfig(1);
service->OnConfigRead(config);
// Expect hung sorting.
EXPECT_EQ(last_config_, DnsConfig());
ASSERT_TRUE(saved_callback);
// Destroy the service and then resume the sort.
service.reset();
std::move(saved_callback).Run(/*success=*/true, AddressList());
ValidateNoNotification();
EXPECT_EQ(last_config_, DnsConfig());
}
// Only test actual platform sort on platforms with a sort implementation.
#if !defined(OS_IOS)
TEST_F(DnsConfigServiceTest, ActualPlatformSort) {
DnsHosts hosts = {
CreateHostsEntry("name1", ADDRESS_FAMILY_IPV4,
{IPAddress(1, 1, 1, 1), IPAddress(2, 2, 2, 2)}),
CreateHostsEntry("name2", ADDRESS_FAMILY_IPV4, {IPAddress(3, 3, 3, 3)})};
MockHostsParserFactory parser;
EXPECT_CALL(parser, ParseHosts(_))
.WillOnce(DoAll(SetArgPointee<0>(hosts), Return(true)));
auto service = std::make_unique<HostsReadingTestDnsConfigService>(
parser.GetFactory(),
base::BindRepeating(&AddressSorter::CreateAddressSorter));
SetUpService(*service);
DnsConfig config = MakeConfig(1);
service->OnConfigRead(config);
// Expect immediate result on reading config because HOSTS should already have
// been read on initting watch in `SetUpService()`.
EXPECT_TRUE(last_config_.EqualsIgnoreHosts(config));
// Expect results to at least contain the single-address result.
EXPECT_LE(last_config_.hosts.size(), 2u);
EXPECT_THAT(last_config_.hosts,
testing::Contains(CreateHostsEntry("name2", ADDRESS_FAMILY_IPV4,
{IPAddress(3, 3, 3, 3)})));
// Expect results to maybe contain the multi-address result with 1 or 2 of the
// addresses. Specific addresses and order could depend on system
// configuration.
auto multi_address_entry =
last_config_.hosts.find(DnsHostsKey("name1", ADDRESS_FAMILY_IPV4));
if (multi_address_entry != last_config_.hosts.end()) {
EXPECT_FALSE(multi_address_entry->second.empty());
EXPECT_THAT(
multi_address_entry->second,
testing::IsSubsetOf({IPAddress(1, 1, 1, 1), IPAddress(2, 2, 2, 2)}));
}
}
#endif // !defined(OS_IOS)
} // namespace net

@ -91,13 +91,11 @@ bool AddLocalhostEntriesTo(DnsHosts& in_out_hosts) {
IPAddress loopback_ipv4 = IPAddress::IPv4Localhost();
IPAddress loopback_ipv6 = IPAddress::IPv6Localhost();
// Should only add "localhost" entries if not already present in the file.
// Accomplish this by relying on `std::map::emplace()`s behavior of not
// modifying the map when the key is already present.
in_out_hosts.emplace(DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4),
std::vector<IPAddress>{loopback_ipv4});
in_out_hosts.emplace(DnsHostsKey("localhost", ADDRESS_FAMILY_IPV6),
std::vector<IPAddress>{loopback_ipv6});
// This does not override any pre-existing entries from the HOSTS file.
in_out_hosts.insert(std::make_pair(
DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4), loopback_ipv4));
in_out_hosts.insert(std::make_pair(
DnsHostsKey("localhost", ADDRESS_FAMILY_IPV6), loopback_ipv6));
wchar_t buffer[MAX_PATH];
DWORD size = MAX_PATH;
@ -141,12 +139,12 @@ bool AddLocalhostEntriesTo(DnsHosts& in_out_hosts) {
}
if (!have_ipv4 && (ipe.GetFamily() == ADDRESS_FAMILY_IPV4)) {
have_ipv4 = true;
in_out_hosts[DnsHostsKey(localname, ADDRESS_FAMILY_IPV4)] = {
ipe.address()};
in_out_hosts[DnsHostsKey(localname, ADDRESS_FAMILY_IPV4)] =
ipe.address();
} else if (!have_ipv6 && (ipe.GetFamily() == ADDRESS_FAMILY_IPV6)) {
have_ipv6 = true;
in_out_hosts[DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)] = {
ipe.address()};
in_out_hosts[DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)] =
ipe.address();
}
}
}
@ -562,8 +560,8 @@ class DnsConfigServiceWin::HostsReader : public DnsConfigService::HostsReader {
public:
explicit WorkItem(base::FilePath hosts_file_path)
: DnsConfigService::HostsReader::WorkItem(
std::make_unique<DnsHostsFileParser>(std::move(hosts_file_path)),
AddressSorter::CreateAddressSorter()) {}
std::make_unique<DnsHostsFileParser>(
std::move(hosts_file_path))) {}
~WorkItem() override = default;

@ -165,7 +165,10 @@ void ParseHostsWithCommaMode(const std::string& contents,
if (!IsValidDNSDomain(key.first))
continue;
key.first = base::ToLowerASCII(key.first);
(*dns_hosts)[key].push_back(ip);
IPAddress* mapped_ip = &(*dns_hosts)[key];
if (mapped_ip->empty())
*mapped_ip = ip;
// else ignore this entry (first hit counts)
}
}
}

@ -43,12 +43,14 @@ enum ParseHostsCommaMode {
// Parsed results of a Hosts file.
//
// Although Hosts files map IP address to a list of domain names, for name
// resolution the desired mapping direction is: (domain name, address family) to
// IP address. A (domain name, address family) pair may match with multiple IP
// addresses (stored as a `std::vector`) if the same name appears in multiple
// (IP address) -> hostname mapping entries for the same family.
using DnsHosts =
std::unordered_map<DnsHostsKey, std::vector<IPAddress>, DnsHostsKeyHash>;
// resolution the desired mapping direction is: domain name to IP address.
// When parsing Hosts, we apply the "first hit" rule as Windows and glibc do.
// With a Hosts file of:
// 300.300.300.300 localhost # bad ip
// 127.0.0.1 localhost
// 10.0.0.1 localhost
// The expected resolution of localhost is 127.0.0.1.
using DnsHosts = std::unordered_map<DnsHostsKey, IPAddress, DnsHostsKeyHash>;
// Parses |contents| (as read from /etc/hosts or equivalent) and stores results
// in |dns_hosts|. Invalid lines are ignored (as in most implementations).
@ -60,8 +62,7 @@ void NET_EXPORT_PRIVATE ParseHostsWithCommaModeForTesting(
ParseHostsCommaMode comma_mode);
// Parses |contents| (as read from /etc/hosts or equivalent) and stores results
// in |dns_hosts|, with addresses in the order in which they were read. Invalid
// lines are ignored (as in most implementations).
// in |dns_hosts|. Invalid lines are ignored (as in most implementations).
void NET_EXPORT_PRIVATE ParseHosts(const std::string& contents,
DnsHosts* dns_hosts);

@ -5,7 +5,6 @@
#include "net/dns/dns_hosts.h"
#include "base/cxx17_backports.h"
#include "build/build_config.h"
#include "net/base/ip_address.h"
#include "testing/gtest/include/gtest/gtest.h"
@ -24,10 +23,11 @@ void PopulateExpectedHosts(const ExpectedHostsEntry* entries,
DnsHosts* expected_hosts_out) {
for (size_t i = 0; i < num_entries; ++i) {
DnsHostsKey key(entries[i].host, entries[i].family);
IPAddress ip;
ASSERT_TRUE(ip.AssignFromIPLiteral(entries[i].ip));
ASSERT_EQ(ip.size(), (entries[i].family == ADDRESS_FAMILY_IPV4) ? 4u : 16u);
(*expected_hosts_out)[key].push_back(ip);
IPAddress& ip_ref = (*expected_hosts_out)[key];
ASSERT_TRUE(ip_ref.empty());
ASSERT_TRUE(ip_ref.AssignFromIPLiteral(entries[i].ip));
ASSERT_EQ(ip_ref.size(),
(entries[i].family == ADDRESS_FAMILY_IPV4) ? 4u : 16u);
}
}
@ -35,7 +35,7 @@ TEST(DnsHostsTest, ParseHosts) {
const std::string kContents =
"127.0.0.1 localhost # standard\n"
"\n"
"1.0.0.1 localhost\n"
"1.0.0.1 localhost # ignored, first hit above\n"
"fe00::x example company # ignored, malformed IPv6\n"
"1.0.0.300 company # ignored, malformed IPv4\n"
"1.0.0.1 # ignored, missing hostname\n"
@ -43,7 +43,7 @@ TEST(DnsHostsTest, ParseHosts) {
"::1\tlocalhost ip6-localhost ip6-loopback # comment # within a comment\n"
"\t fe00::0 ip6-localnet\r\n"
"2048::2 example\n"
"2048::1 company example\n"
"2048::1 company example # ignored for 'example' \n"
"127.0.0.1 cache1\n"
"127.0.0.1 cache2 # should reuse parsed IP\n"
"256.0.0.0 cache3 # bogus IP should not clear parsed IP cache\n"
@ -56,7 +56,6 @@ TEST(DnsHostsTest, ParseHosts) {
const ExpectedHostsEntry kEntries[] = {
{"localhost", ADDRESS_FAMILY_IPV4, "127.0.0.1"},
{"localhost", ADDRESS_FAMILY_IPV4, "1.0.0.1"},
{"company", ADDRESS_FAMILY_IPV4, "1.0.0.1"},
{"localhost", ADDRESS_FAMILY_IPV6, "::1"},
{"ip6-localhost", ADDRESS_FAMILY_IPV6, "::1"},
@ -64,7 +63,6 @@ TEST(DnsHostsTest, ParseHosts) {
{"ip6-localnet", ADDRESS_FAMILY_IPV6, "fe00::0"},
{"company", ADDRESS_FAMILY_IPV6, "2048::1"},
{"example", ADDRESS_FAMILY_IPV6, "2048::2"},
{"example", ADDRESS_FAMILY_IPV6, "2048::1"},
{"cache1", ADDRESS_FAMILY_IPV4, "127.0.0.1"},
{"cache2", ADDRESS_FAMILY_IPV4, "127.0.0.1"},
{"cache4", ADDRESS_FAMILY_IPV4, "127.0.0.1"},

@ -123,8 +123,8 @@ DnsConfig GetFuzzedDnsConfig(FuzzedDataProvider* data_provider) {
"bar", "localhost", "localhost6"};
const char* hostname = data_provider->PickValueInArray(kHostnames);
net::IPAddress address = FuzzIPAddress(data_provider);
config.hosts[net::DnsHostsKey(hostname, net::GetAddressFamily(address))]
.push_back(address);
config.hosts[net::DnsHostsKey(hostname, net::GetAddressFamily(address))] =
address;
}
config.unhandled_options = data_provider->ConsumeBool();

@ -1726,7 +1726,7 @@ class HostResolverManager::DnsTask : public base::SupportsWeakPtr<DnsTask> {
HostCache::Entry results,
bool secure,
bool success,
AddressList addr_list) {
const AddressList& addr_list) {
results.set_addresses(addr_list);
if (!success) {
@ -3385,23 +3385,15 @@ absl::optional<HostCache::Entry> HostResolverManager::ServeFromHosts(
if (query_type == DnsQueryType::AAAA ||
query_type == DnsQueryType::UNSPECIFIED) {
auto it = hosts->find(DnsHostsKey(effective_hostname, ADDRESS_FAMILY_IPV6));
if (it != hosts->end()) {
for (const IPAddress& ip : it->second) {
DCHECK(ip.IsIPv6());
addresses.push_back(IPEndPoint(ip, 0));
}
}
if (it != hosts->end())
addresses.push_back(IPEndPoint(it->second, 0));
}
if (query_type == DnsQueryType::A ||
query_type == DnsQueryType::UNSPECIFIED) {
auto it = hosts->find(DnsHostsKey(effective_hostname, ADDRESS_FAMILY_IPV4));
if (it != hosts->end()) {
for (const IPAddress& ip : it->second) {
DCHECK(ip.IsIPv4());
addresses.push_back(IPEndPoint(ip, 0));
}
}
if (it != hosts->end())
addresses.push_back(IPEndPoint(it->second, 0));
}
// If got only loopback addresses and the family was restricted, resolve

@ -4324,10 +4324,10 @@ TEST_F(HostResolverManagerDnsTest, LocalhostLookup) {
// file is active.
TEST_F(HostResolverManagerDnsTest, LocalhostLookupWithHosts) {
DnsHosts hosts;
hosts[DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4)] = {
IPAddress({192, 168, 1, 1})};
hosts[DnsHostsKey("foo.localhost", ADDRESS_FAMILY_IPV4)] = {
IPAddress({192, 168, 1, 2})};
hosts[DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4)] =
IPAddress({192, 168, 1, 1});
hosts[DnsHostsKey("foo.localhost", ADDRESS_FAMILY_IPV4)] =
IPAddress({192, 168, 1, 2});
DnsConfig config = CreateValidDnsConfig();
config.hosts = hosts;
@ -4715,10 +4715,10 @@ TEST_F(HostResolverManagerDnsTest, ServeFromHosts) {
IPAddress local_ipv6 = IPAddress::IPv6Localhost();
DnsHosts hosts;
hosts[DnsHostsKey("nx_ipv4", ADDRESS_FAMILY_IPV4)] = {local_ipv4};
hosts[DnsHostsKey("nx_ipv6", ADDRESS_FAMILY_IPV6)] = {local_ipv6};
hosts[DnsHostsKey("nx_both", ADDRESS_FAMILY_IPV4)] = {local_ipv4};
hosts[DnsHostsKey("nx_both", ADDRESS_FAMILY_IPV6)] = {local_ipv6};
hosts[DnsHostsKey("nx_ipv4", ADDRESS_FAMILY_IPV4)] = local_ipv4;
hosts[DnsHostsKey("nx_ipv6", ADDRESS_FAMILY_IPV6)] = local_ipv6;
hosts[DnsHostsKey("nx_both", ADDRESS_FAMILY_IPV4)] = local_ipv4;
hosts[DnsHostsKey("nx_both", ADDRESS_FAMILY_IPV6)] = local_ipv6;
// Update HOSTS file.
config.hosts = hosts;
@ -4786,28 +4786,6 @@ TEST_F(HostResolverManagerDnsTest, ServeFromHosts) {
EXPECT_FALSE(response_upper.request()->GetDnsAliasResults());
}
TEST_F(HostResolverManagerDnsTest, ServeMultiAddressEntryFromHosts) {
DnsHosts hosts;
hosts[DnsHostsKey("multi_address", ADDRESS_FAMILY_IPV4)] = {
IPAddress(1, 1, 1, 1), IPAddress(2, 2, 2, 2)};
// Update HOSTS file.
DnsConfig config = CreateValidDnsConfig();
config.hosts = std::move(hosts);
ChangeDnsConfig(config);
ResolveHostResponseHelper response(resolver_->CreateRequest(
HostPortPair("multi_address", 443), NetworkIsolationKey(),
NetLogWithSource(),
/*optional_parameters=*/absl::nullopt, resolve_context_.get(),
resolve_context_->host_cache()));
EXPECT_THAT(response.result_error(), IsOk());
EXPECT_THAT(response.request()->GetAddressResults().value().endpoints(),
testing::UnorderedElementsAre(CreateExpected("1.1.1.1", 443),
CreateExpected("2.2.2.2", 443)));
EXPECT_FALSE(response.request()->GetDnsAliasResults());
}
TEST_F(HostResolverManagerDnsTest, SkipHostsWithUpcomingProcTask) {
// Disable the DnsClient.
resolver_->SetInsecureDnsClientEnabled(
@ -4820,8 +4798,7 @@ TEST_F(HostResolverManagerDnsTest, SkipHostsWithUpcomingProcTask) {
DnsConfig config = CreateValidDnsConfig();
DnsHosts hosts;
hosts[DnsHostsKey("hosts", ADDRESS_FAMILY_IPV4)] = {
IPAddress::IPv4Localhost()};
hosts[DnsHostsKey("hosts", ADDRESS_FAMILY_IPV4)] = IPAddress::IPv4Localhost();
// Update HOSTS file.
config.hosts = hosts;
@ -7580,7 +7557,7 @@ TEST_F(HostResolverManagerDnsTest, SetDnsConfigOverrides) {
DnsConfig original_config = CreateValidDnsConfig();
original_config.hosts = {
{DnsHostsKey("host", ADDRESS_FAMILY_IPV4), {IPAddress(192, 168, 1, 1)}}};
{DnsHostsKey("host", ADDRESS_FAMILY_IPV4), IPAddress(192, 168, 1, 1)}};
ChangeDnsConfig(original_config);
// Confirm pre-override state.

@ -9,7 +9,6 @@
#include "base/check.h"
#include "base/files/file_path.h"
#include "net/dns/address_sorter.h"
#include "net/dns/dns_hosts.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
@ -35,12 +34,10 @@ void TestDnsConfigService::RefreshConfig() {
}
HostsReadingTestDnsConfigService::HostsReadingTestDnsConfigService(
HostsParserFactory hosts_parser_factory,
AddressSorterFactory address_sorter_factory)
HostsParserFactory hosts_parser_factory)
: hosts_reader_(
std::make_unique<HostsReader>(*this,
std::move(hosts_parser_factory),
std::move(address_sorter_factory))) {}
std::move(hosts_parser_factory))) {}
HostsReadingTestDnsConfigService::~HostsReadingTestDnsConfigService() = default;
@ -55,20 +52,17 @@ bool HostsReadingTestDnsConfigService::StartWatching() {
HostsReadingTestDnsConfigService::HostsReader::HostsReader(
TestDnsConfigService& service,
HostsParserFactory hosts_parser_factory,
AddressSorterFactory address_sorter_factory)
HostsParserFactory hosts_parser_factory)
: DnsConfigService::HostsReader(
/*hosts_file_path=*/base::FilePath::StringPieceType(),
service),
hosts_parser_factory_(std::move(hosts_parser_factory)),
address_sorter_factory_(std::move(address_sorter_factory)) {}
hosts_parser_factory_(std::move(hosts_parser_factory)) {}
HostsReadingTestDnsConfigService::HostsReader::~HostsReader() = default;
std::unique_ptr<SerialWorker::WorkItem>
HostsReadingTestDnsConfigService::HostsReader::CreateWorkItem() {
return std::make_unique<WorkItem>(hosts_parser_factory_.Run(),
address_sorter_factory_.Run());
return std::make_unique<WorkItem>(hosts_parser_factory_.Run());
}
HostsReadingTestDnsConfigService::Watcher::Watcher(DnsConfigService& service)

@ -16,7 +16,6 @@
namespace net {
class AddressSorter;
class DnsHostsParser;
// Simple test implementation of DnsConfigService that will trigger
@ -55,18 +54,15 @@ class TestDnsConfigService : public DnsConfigService {
};
// Test implementation of `DnsConfigService` that exercises the
// `DnsConfigService::HostsReader`. Uses an injected `DnsHostsParser` and
// `AddressSorter`. `Watcher` change notifications are simulated using
// `TriggerHostsChangeNotification()`.
// `DnsConfigService::HostsReader`. Uses an injected `DnsHostsParser`. `Watcher`
// change notifications are simulated using `TriggerHostsChangeNotification()`.
class HostsReadingTestDnsConfigService : public TestDnsConfigService {
public:
using HostsParserFactory =
base::RepeatingCallback<std::unique_ptr<DnsHostsParser>(void)>;
using AddressSorterFactory =
base::RepeatingCallback<std::unique_ptr<AddressSorter>(void)>;
HostsReadingTestDnsConfigService(HostsParserFactory hosts_parser_factory,
AddressSorterFactory address_sorter_factory);
explicit HostsReadingTestDnsConfigService(
HostsParserFactory hosts_parser_factory);
~HostsReadingTestDnsConfigService() override;
// Simulate a `Watcher` change notification for the HOSTS file.
@ -82,8 +78,7 @@ class HostsReadingTestDnsConfigService : public TestDnsConfigService {
class HostsReader : public DnsConfigService::HostsReader {
public:
HostsReader(TestDnsConfigService& service,
HostsParserFactory hosts_parser_factory,
AddressSorterFactory address_sorter_factory);
HostsParserFactory hosts_parser_factory);
~HostsReader() override;
// DnsConfigService::HostsReader:
@ -91,7 +86,6 @@ class HostsReadingTestDnsConfigService : public TestDnsConfigService {
private:
HostsParserFactory hosts_parser_factory_;
AddressSorterFactory address_sorter_factory_;
};
class Watcher : public DnsConfigService::Watcher {