Commit d80e414e authored by Eric Orth's avatar Eric Orth Committed by Chromium LUCI CQ

Fixup inputs and outputs in DnsConfigService

Updating everything to match the latest style guide preferences, mostly
using references much more liberally and converting output params to
returns wherever reasonable.

Also switching from copies to moves in a couple places that I happened
to notice, and a couple more random cleanups to make Tricium happy.

Change-Id: I999f511835e70e61ee8c0e7c5dd7e6b7f2396aea
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2626786Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Commit-Queue: Eric Orth <ericorth@chromium.org>
Cr-Commit-Position: refs/heads/master@{#844119}
parent bac2056e
...@@ -70,8 +70,8 @@ void DnsConfigService::RefreshConfig() { ...@@ -70,8 +70,8 @@ void DnsConfigService::RefreshConfig() {
NOTREACHED(); NOTREACHED();
} }
DnsConfigService::Watcher::Watcher(DnsConfigService* service) DnsConfigService::Watcher::Watcher(DnsConfigService& service)
: service_(service) {} : service_(&service) {}
DnsConfigService::Watcher::~Watcher() { DnsConfigService::Watcher::~Watcher() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
...@@ -92,31 +92,41 @@ void DnsConfigService::Watcher::CheckOnCorrectSequence() { ...@@ -92,31 +92,41 @@ void DnsConfigService::Watcher::CheckOnCorrectSequence() {
} }
DnsConfigService::HostsReader::HostsReader( DnsConfigService::HostsReader::HostsReader(
DnsConfigService* service, base::FilePath::StringPieceType hosts_file_path,
base::FilePath::StringPieceType hosts_file_path) DnsConfigService& service)
: service_(service), hosts_file_path_(hosts_file_path) {} : service_(&service), hosts_file_path_(hosts_file_path) {}
DnsConfigService::HostsReader::~HostsReader() = default; DnsConfigService::HostsReader::~HostsReader() = default;
bool DnsConfigService::HostsReader::ReadHosts(DnsHosts* out_dns_hosts) { base::Optional<DnsHosts> DnsConfigService::HostsReader::ReadHosts() {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK); base::BlockingType::MAY_BLOCK);
DCHECK(!hosts_file_path_.empty()); DCHECK(!hosts_file_path_.empty());
return ParseHostsFile(hosts_file_path_, out_dns_hosts); DnsHosts dns_hosts;
if (!ParseHostsFile(hosts_file_path_, &dns_hosts))
return base::nullopt;
return dns_hosts;
} }
bool DnsConfigService::HostsReader::AddAdditionalHostsTo(DnsHosts& dns_hosts) { bool DnsConfigService::HostsReader::AddAdditionalHostsTo(
DnsHosts& in_out_dns_hosts) {
// Nothing to add in base implementation. // Nothing to add in base implementation.
return true; return true;
} }
void DnsConfigService::HostsReader::DoWork() { void DnsConfigService::HostsReader::DoWork() {
success_ = ReadHosts(&hosts_) && AddAdditionalHostsTo(hosts_); hosts_ = ReadHosts();
if (!hosts_.has_value())
return;
if (!AddAdditionalHostsTo(hosts_.value()))
hosts_.reset();
} }
void DnsConfigService::HostsReader::OnWorkFinished() { void DnsConfigService::HostsReader::OnWorkFinished() {
if (success_) { if (hosts_.has_value()) {
service_->OnHostsRead(hosts_); service_->OnHostsRead(std::move(hosts_).value());
} else { } else {
LOG(WARNING) << "Failed to read DnsHosts."; LOG(WARNING) << "Failed to read DnsHosts.";
} }
...@@ -128,7 +138,7 @@ void DnsConfigService::ReadHostsNow() { ...@@ -128,7 +138,7 @@ void DnsConfigService::ReadHostsNow() {
if (!hosts_reader_) { if (!hosts_reader_) {
DCHECK(!hosts_file_path_.empty()); DCHECK(!hosts_file_path_.empty());
hosts_reader_ = hosts_reader_ =
base::MakeRefCounted<HostsReader>(this, hosts_file_path_.value()); base::MakeRefCounted<HostsReader>(hosts_file_path_.value(), *this);
} }
hosts_reader_->WorkNow(); hosts_reader_->WorkNow();
} }
...@@ -149,7 +159,7 @@ void DnsConfigService::InvalidateHosts() { ...@@ -149,7 +159,7 @@ void DnsConfigService::InvalidateHosts() {
StartTimer(); StartTimer();
} }
void DnsConfigService::OnConfigRead(const DnsConfig& config) { void DnsConfigService::OnConfigRead(DnsConfig config) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(config.IsValid()); DCHECK(config.IsValid());
...@@ -163,11 +173,11 @@ void DnsConfigService::OnConfigRead(const DnsConfig& config) { ...@@ -163,11 +173,11 @@ void DnsConfigService::OnConfigRead(const DnsConfig& config) {
OnCompleteConfig(); OnCompleteConfig();
} }
void DnsConfigService::OnHostsRead(const DnsHosts& hosts) { void DnsConfigService::OnHostsRead(DnsHosts hosts) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (hosts != dns_config_.hosts) { if (hosts != dns_config_.hosts) {
dns_config_.hosts = hosts; dns_config_.hosts = std::move(hosts);
need_update_ = true; need_update_ = true;
} }
......
...@@ -80,7 +80,7 @@ class NET_EXPORT_PRIVATE DnsConfigService { ...@@ -80,7 +80,7 @@ class NET_EXPORT_PRIVATE DnsConfigService {
public: public:
// `service` is expected to own the created Watcher and thus stay valid for // `service` is expected to own the created Watcher and thus stay valid for
// the lifetime of the created Watcher. // the lifetime of the created Watcher.
explicit Watcher(DnsConfigService* service); explicit Watcher(DnsConfigService& service);
virtual ~Watcher(); virtual ~Watcher();
Watcher(const Watcher&) = delete; Watcher(const Watcher&) = delete;
...@@ -108,11 +108,13 @@ class NET_EXPORT_PRIVATE DnsConfigService { ...@@ -108,11 +108,13 @@ class NET_EXPORT_PRIVATE DnsConfigService {
// Reader of HOSTS files. In this base implementation, uses standard logic // Reader of HOSTS files. In this base implementation, uses standard logic
// appropriate to most platforms to read the HOSTS file located at // appropriate to most platforms to read the HOSTS file located at
// `service->GetHostsFilePath()`. // `hosts_file_path`.
class HostsReader : public SerialWorker { class HostsReader : public SerialWorker {
public: public:
HostsReader(DnsConfigService* service, // `service` is expected to own the created reader and thus stay valid for
base::FilePath::StringPieceType hosts_file_path); // the lifetime of the created reader.
HostsReader(base::FilePath::StringPieceType hosts_file_path,
DnsConfigService& service);
HostsReader(const HostsReader&) = delete; HostsReader(const HostsReader&) = delete;
HostsReader& operator=(const HostsReader&) = delete; HostsReader& operator=(const HostsReader&) = delete;
...@@ -120,19 +122,19 @@ class NET_EXPORT_PRIVATE DnsConfigService { ...@@ -120,19 +122,19 @@ class NET_EXPORT_PRIVATE DnsConfigService {
protected: protected:
~HostsReader() override; ~HostsReader() override;
// Reads the HOSTS file and parses to a `DnsHosts`. Returns false on // Reads the HOSTS file and parses to a `DnsHosts`. Returns nullopt on
// failure. Will be called on a separate blockable ThreadPool thread. // failure. Will be called on a separate blockable ThreadPool thread.
// //
// Override if needed to implement platform-specific behavior, e.g. for a // Override if needed to implement platform-specific behavior, e.g. for a
// platform-specific HOSTS format. // platform-specific HOSTS format.
virtual bool ReadHosts(DnsHosts* out_dns_hosts); virtual base::Optional<DnsHosts> ReadHosts();
// Adds any necessary additional entries to the given `DnsHosts`. Returns // Adds any necessary additional entries to the given `DnsHosts`. Returns
// false on failure. Will be called on a separate blockable ThreadPool // false on failure. Will be called on a separate blockable ThreadPool
// thread. // thread.
// //
// Override if needed to implement platform-specific behavior. // Override if needed to implement platform-specific behavior.
virtual bool AddAdditionalHostsTo(DnsHosts& dns_hosts); virtual bool AddAdditionalHostsTo(DnsHosts& in_out_dns_hosts);
// SerialWorker: // SerialWorker:
void DoWork() final; void DoWork() final;
...@@ -144,8 +146,7 @@ class NET_EXPORT_PRIVATE DnsConfigService { ...@@ -144,8 +146,7 @@ class NET_EXPORT_PRIVATE DnsConfigService {
// running on worker thread. // running on worker thread.
DnsConfigService* const service_; DnsConfigService* const service_;
// Written in DoWork, read in OnWorkFinished, no locking necessary. // Written in DoWork, read in OnWorkFinished, no locking necessary.
DnsHosts hosts_; base::Optional<DnsHosts> hosts_;
bool success_ = false;
const base::FilePath hosts_file_path_; const base::FilePath hosts_file_path_;
}; };
...@@ -162,9 +163,9 @@ class NET_EXPORT_PRIVATE DnsConfigService { ...@@ -162,9 +163,9 @@ class NET_EXPORT_PRIVATE DnsConfigService {
void InvalidateHosts(); void InvalidateHosts();
// Called with new config. |config|.hosts is ignored. // Called with new config. |config|.hosts is ignored.
void OnConfigRead(const DnsConfig& config); void OnConfigRead(DnsConfig config);
// Called with new hosts. Rest of the config is assumed unchanged. // Called with new hosts. Rest of the config is assumed unchanged.
void OnHostsRead(const DnsHosts& hosts); void OnHostsRead(DnsHosts hosts);
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/files/file.h" #include "base/files/file.h"
...@@ -15,6 +16,7 @@ ...@@ -15,6 +16,7 @@
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/optional.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/threading/scoped_blocking_call.h" #include "base/threading/scoped_blocking_call.h"
...@@ -143,24 +145,24 @@ bool IsVpnPresent() { ...@@ -143,24 +145,24 @@ bool IsVpnPresent() {
} }
#endif // defined(OS_ANDROID) #endif // defined(OS_ANDROID)
bool ReadDnsConfig(DnsConfig* dns_config) { base::Optional<DnsConfig> ReadDnsConfig() {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK); base::BlockingType::MAY_BLOCK);
dns_config->unhandled_options = false;
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
bool success = false; base::Optional<DnsConfig> dns_config;
// TODO(fuchsia): Use res_ninit() when it's implemented on Fuchsia. // TODO(fuchsia): Use res_ninit() when it's implemented on Fuchsia.
#if defined(OS_OPENBSD) || defined(OS_FUCHSIA) #if defined(OS_OPENBSD) || defined(OS_FUCHSIA)
// Note: res_ninit in glibc always returns 0 and sets RES_INIT. // Note: res_ninit in glibc always returns 0 and sets RES_INIT.
// res_init behaves the same way. // res_init behaves the same way.
memset(&_res, 0, sizeof(_res)); memset(&_res, 0, sizeof(_res));
if (res_init() == 0) if (res_init() == 0)
success = ConvertResStateToDnsConfig(_res, dns_config); dns_config = ConvertResStateToDnsConfig(_res);
#else // all other OS_POSIX #else // all other OS_POSIX
struct __res_state res; struct __res_state res;
memset(&res, 0, sizeof(res)); memset(&res, 0, sizeof(res));
if (res_ninit(&res) == 0) if (res_ninit(&res) == 0)
success = ConvertResStateToDnsConfig(res, dns_config); dns_config = ConvertResStateToDnsConfig(res);
// Prefer res_ndestroy where available. // Prefer res_ndestroy where available.
#if defined(OS_APPLE) || defined(OS_FREEBSD) #if defined(OS_APPLE) || defined(OS_FREEBSD)
res_ndestroy(&res); res_ndestroy(&res);
...@@ -169,26 +171,34 @@ bool ReadDnsConfig(DnsConfig* dns_config) { ...@@ -169,26 +171,34 @@ bool ReadDnsConfig(DnsConfig* dns_config) {
#endif // defined(OS_APPLE) || defined(OS_FREEBSD) #endif // defined(OS_APPLE) || defined(OS_FREEBSD)
#endif // defined(OS_OPENBSD) #endif // defined(OS_OPENBSD)
if (!dns_config.has_value())
return dns_config;
#if defined(OS_MAC) #if defined(OS_MAC)
if (!DnsConfigWatcher::CheckDnsConfig(&dns_config->unhandled_options)) if (!DnsConfigWatcher::CheckDnsConfig(
return false; dns_config->unhandled_options /* out_unhandled_options */)) {
return base::nullopt;
}
#endif // defined(OS_MAC) #endif // defined(OS_MAC)
// Override |fallback_period| value to match default setting on Windows. // Override |fallback_period| value to match default setting on Windows.
dns_config->fallback_period = kDnsDefaultFallbackPeriod; dns_config->fallback_period = kDnsDefaultFallbackPeriod;
return success; return dns_config;
#else // defined(OS_ANDROID) #else // defined(OS_ANDROID)
dns_config->nameservers.clear(); DnsConfig dns_config;
if (base::android::BuildInfo::GetInstance()->sdk_int() >= if (base::android::BuildInfo::GetInstance()->sdk_int() >=
base::android::SDK_VERSION_MARSHMALLOW) { base::android::SDK_VERSION_MARSHMALLOW) {
return net::android::GetDnsServers(&dns_config->nameservers, if (net::android::GetDnsServers(&dns_config.nameservers,
&dns_config->dns_over_tls_active, &dns_config.dns_over_tls_active,
&dns_config->dns_over_tls_hostname); &dns_config.dns_over_tls_hostname)) {
return dns_config;
}
return base::nullopt;
} }
if (IsVpnPresent()) { if (IsVpnPresent()) {
dns_config->unhandled_options = true; dns_config.unhandled_options = true;
return true; return dns_config;
} }
// NOTE(pauljensen): __system_property_get and the net.dns1/2 properties are // NOTE(pauljensen): __system_property_get and the net.dns1/2 properties are
...@@ -200,25 +210,25 @@ bool ReadDnsConfig(DnsConfig* dns_config) { ...@@ -200,25 +210,25 @@ bool ReadDnsConfig(DnsConfig* dns_config) {
__system_property_get("net.dns2", property_value); __system_property_get("net.dns2", property_value);
std::string dns2_string = property_value; std::string dns2_string = property_value;
if (dns1_string.empty() && dns2_string.empty()) if (dns1_string.empty() && dns2_string.empty())
return false; return base::nullopt;
IPAddress dns1_address; IPAddress dns1_address;
IPAddress dns2_address; IPAddress dns2_address;
bool parsed1 = dns1_address.AssignFromIPLiteral(dns1_string); bool parsed1 = dns1_address.AssignFromIPLiteral(dns1_string);
bool parsed2 = dns2_address.AssignFromIPLiteral(dns2_string); bool parsed2 = dns2_address.AssignFromIPLiteral(dns2_string);
if (!parsed1 && !parsed2) if (!parsed1 && !parsed2)
return false; return base::nullopt;
if (parsed1) { if (parsed1) {
IPEndPoint dns1(dns1_address, dns_protocol::kDefaultPort); IPEndPoint dns1(dns1_address, dns_protocol::kDefaultPort);
dns_config->nameservers.push_back(dns1); dns_config.nameservers.push_back(dns1);
} }
if (parsed2) { if (parsed2) {
IPEndPoint dns2(dns2_address, dns_protocol::kDefaultPort); IPEndPoint dns2(dns2_address, dns_protocol::kDefaultPort);
dns_config->nameservers.push_back(dns2); dns_config.nameservers.push_back(dns2);
} }
return true; return dns_config;
#endif // !defined(OS_ANDROID) #endif // !defined(OS_ANDROID)
} }
...@@ -226,7 +236,7 @@ bool ReadDnsConfig(DnsConfig* dns_config) { ...@@ -226,7 +236,7 @@ bool ReadDnsConfig(DnsConfig* dns_config) {
class DnsConfigServicePosix::Watcher : public DnsConfigService::Watcher { class DnsConfigServicePosix::Watcher : public DnsConfigService::Watcher {
public: public:
explicit Watcher(DnsConfigServicePosix* service) explicit Watcher(DnsConfigServicePosix& service)
: DnsConfigService::Watcher(service) {} : DnsConfigService::Watcher(service) {}
~Watcher() override = default; ~Watcher() override = default;
...@@ -274,19 +284,18 @@ class DnsConfigServicePosix::Watcher : public DnsConfigService::Watcher { ...@@ -274,19 +284,18 @@ class DnsConfigServicePosix::Watcher : public DnsConfigService::Watcher {
// net.dns1 and net.dns2; see #if around ReadDnsConfig above.) // net.dns1 and net.dns2; see #if around ReadDnsConfig above.)
class DnsConfigServicePosix::ConfigReader : public SerialWorker { class DnsConfigServicePosix::ConfigReader : public SerialWorker {
public: public:
explicit ConfigReader(DnsConfigServicePosix* service) explicit ConfigReader(DnsConfigServicePosix& service) : service_(&service) {
: service_(service), success_(false) {
// Allow execution on another thread; nothing thread-specific about // Allow execution on another thread; nothing thread-specific about
// constructor. // constructor.
DETACH_FROM_SEQUENCE(sequence_checker_); DETACH_FROM_SEQUENCE(sequence_checker_);
} }
void DoWork() override { success_ = ReadDnsConfig(&dns_config_); } void DoWork() override { dns_config_ = ReadDnsConfig(); }
void OnWorkFinished() override { void OnWorkFinished() override {
DCHECK(!IsCancelled()); DCHECK(!IsCancelled());
if (success_) { if (dns_config_.has_value()) {
service_->OnConfigRead(dns_config_); service_->OnConfigRead(std::move(dns_config_).value());
} else { } else {
LOG(WARNING) << "Failed to read DnsConfig."; LOG(WARNING) << "Failed to read DnsConfig.";
} }
...@@ -300,8 +309,7 @@ class DnsConfigServicePosix::ConfigReader : public SerialWorker { ...@@ -300,8 +309,7 @@ class DnsConfigServicePosix::ConfigReader : public SerialWorker {
// on worker thread. // on worker thread.
DnsConfigServicePosix* const service_; DnsConfigServicePosix* const service_;
// Written in DoWork, read in OnWorkFinished, no locking necessary. // Written in DoWork, read in OnWorkFinished, no locking necessary.
DnsConfig dns_config_; base::Optional<DnsConfig> dns_config_;
bool success_;
DISALLOW_COPY_AND_ASSIGN(ConfigReader); DISALLOW_COPY_AND_ASSIGN(ConfigReader);
}; };
...@@ -330,25 +338,24 @@ void DnsConfigServicePosix::ReadConfigNow() { ...@@ -330,25 +338,24 @@ void DnsConfigServicePosix::ReadConfigNow() {
bool DnsConfigServicePosix::StartWatching() { bool DnsConfigServicePosix::StartWatching() {
CreateReader(); CreateReader();
// TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139 // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139
watcher_.reset(new Watcher(this)); watcher_ = std::make_unique<Watcher>(*this);
return watcher_->Watch(); return watcher_->Watch();
} }
void DnsConfigServicePosix::CreateReader() { void DnsConfigServicePosix::CreateReader() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!config_reader_); DCHECK(!config_reader_);
config_reader_ = base::MakeRefCounted<ConfigReader>(this); config_reader_ = base::MakeRefCounted<ConfigReader>(*this);
} }
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
bool ConvertResStateToDnsConfig(const struct __res_state& res, base::Optional<DnsConfig> ConvertResStateToDnsConfig(
DnsConfig* dns_config) { const struct __res_state& res) {
DCHECK(dns_config); DnsConfig dns_config;
dns_config.unhandled_options = false;
if (!(res.options & RES_INIT)) if (!(res.options & RES_INIT))
return false; return base::nullopt;
dns_config->nameservers.clear();
#if defined(OS_APPLE) || defined(OS_FREEBSD) #if defined(OS_APPLE) || defined(OS_FREEBSD)
union res_sockaddr_union addresses[MAXNS]; union res_sockaddr_union addresses[MAXNS];
...@@ -360,9 +367,9 @@ bool ConvertResStateToDnsConfig(const struct __res_state& res, ...@@ -360,9 +367,9 @@ bool ConvertResStateToDnsConfig(const struct __res_state& res,
if (!ipe.FromSockAddr( if (!ipe.FromSockAddr(
reinterpret_cast<const struct sockaddr*>(&addresses[i]), reinterpret_cast<const struct sockaddr*>(&addresses[i]),
sizeof addresses[i])) { sizeof addresses[i])) {
return false; return base::nullopt;
} }
dns_config->nameservers.push_back(ipe); dns_config.nameservers.push_back(ipe);
} }
#elif defined(OS_LINUX) || defined(OS_CHROMEOS) #elif defined(OS_LINUX) || defined(OS_CHROMEOS)
static_assert(std::extent<decltype(res.nsaddr_list)>() >= MAXNS && static_assert(std::extent<decltype(res.nsaddr_list)>() >= MAXNS &&
...@@ -383,11 +390,11 @@ bool ConvertResStateToDnsConfig(const struct __res_state& res, ...@@ -383,11 +390,11 @@ bool ConvertResStateToDnsConfig(const struct __res_state& res,
addr = reinterpret_cast<const struct sockaddr*>(res._u._ext.nsaddrs[i]); addr = reinterpret_cast<const struct sockaddr*>(res._u._ext.nsaddrs[i]);
addr_len = sizeof *res._u._ext.nsaddrs[i]; addr_len = sizeof *res._u._ext.nsaddrs[i];
} else { } else {
return false; return base::nullopt;
} }
if (!ipe.FromSockAddr(addr, addr_len)) if (!ipe.FromSockAddr(addr, addr_len))
return false; return base::nullopt;
dns_config->nameservers.push_back(ipe); dns_config.nameservers.push_back(ipe);
} }
#else // !(defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_APPLE) || #else // !(defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_APPLE) ||
// defined(OS_FREEBSD)) // defined(OS_FREEBSD))
...@@ -397,22 +404,22 @@ bool ConvertResStateToDnsConfig(const struct __res_state& res, ...@@ -397,22 +404,22 @@ bool ConvertResStateToDnsConfig(const struct __res_state& res,
if (!ipe.FromSockAddr( if (!ipe.FromSockAddr(
reinterpret_cast<const struct sockaddr*>(&res.nsaddr_list[i]), reinterpret_cast<const struct sockaddr*>(&res.nsaddr_list[i]),
sizeof res.nsaddr_list[i])) { sizeof res.nsaddr_list[i])) {
return false; return base::nullopt;
} }
dns_config->nameservers.push_back(ipe); dns_config.nameservers.push_back(ipe);
} }
#endif // defined(OS_APPLE) || defined(OS_FREEBSD) #endif // defined(OS_APPLE) || defined(OS_FREEBSD)
dns_config->search.clear(); dns_config.search.clear();
for (int i = 0; (i < MAXDNSRCH) && res.dnsrch[i]; ++i) { for (int i = 0; (i < MAXDNSRCH) && res.dnsrch[i]; ++i) {
dns_config->search.push_back(std::string(res.dnsrch[i])); dns_config.search.emplace_back(res.dnsrch[i]);
} }
dns_config->ndots = res.ndots; dns_config.ndots = res.ndots;
dns_config->fallback_period = base::TimeDelta::FromSeconds(res.retrans); dns_config.fallback_period = base::TimeDelta::FromSeconds(res.retrans);
dns_config->attempts = res.retry; dns_config.attempts = res.retry;
#if defined(RES_ROTATE) #if defined(RES_ROTATE)
dns_config->rotate = res.options & RES_ROTATE; dns_config.rotate = res.options & RES_ROTATE;
#endif #endif
#if !defined(RES_USE_DNSSEC) #if !defined(RES_USE_DNSSEC)
// Some versions of libresolv don't have support for the DO bit. In this // Some versions of libresolv don't have support for the DO bit. In this
...@@ -424,26 +431,26 @@ bool ConvertResStateToDnsConfig(const struct __res_state& res, ...@@ -424,26 +431,26 @@ bool ConvertResStateToDnsConfig(const struct __res_state& res,
// cannot be overwritten by /etc/resolv.conf // cannot be overwritten by /etc/resolv.conf
const unsigned kRequiredOptions = RES_RECURSE | RES_DEFNAMES | RES_DNSRCH; const unsigned kRequiredOptions = RES_RECURSE | RES_DEFNAMES | RES_DNSRCH;
if ((res.options & kRequiredOptions) != kRequiredOptions) { if ((res.options & kRequiredOptions) != kRequiredOptions) {
dns_config->unhandled_options = true; dns_config.unhandled_options = true;
return true; return dns_config;
} }
const unsigned kUnhandledOptions = RES_USEVC | RES_IGNTC | RES_USE_DNSSEC; const unsigned kUnhandledOptions = RES_USEVC | RES_IGNTC | RES_USE_DNSSEC;
if (res.options & kUnhandledOptions) { if (res.options & kUnhandledOptions) {
dns_config->unhandled_options = true; dns_config.unhandled_options = true;
return true; return dns_config;
} }
if (dns_config->nameservers.empty()) if (dns_config.nameservers.empty())
return false; return base::nullopt;
// If any name server is 0.0.0.0, assume the configuration is invalid. // If any name server is 0.0.0.0, assume the configuration is invalid.
// TODO(szym): Measure how often this happens. http://crbug.com/125599 // TODO(szym): Measure how often this happens. http://crbug.com/125599
for (unsigned i = 0; i < dns_config->nameservers.size(); ++i) { for (const IPEndPoint& nameserver : dns_config.nameservers) {
if (dns_config->nameservers[i].address().IsZero()) if (nameserver.address().IsZero())
return false; return base::nullopt;
} }
return true; return dns_config;
} }
#endif // !defined(OS_ANDROID) #endif // !defined(OS_ANDROID)
......
...@@ -59,11 +59,9 @@ class NET_EXPORT_PRIVATE DnsConfigServicePosix : public DnsConfigService { ...@@ -59,11 +59,9 @@ class NET_EXPORT_PRIVATE DnsConfigServicePosix : public DnsConfigService {
}; };
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
// Fills in |dns_config| from |res|. Returns false iff a valid config could not // Returns nullopt iff a valid config could not be determined.
// be determined. base::Optional<DnsConfig> NET_EXPORT_PRIVATE
bool NET_EXPORT_PRIVATE ConvertResStateToDnsConfig(const struct __res_state& res);
ConvertResStateToDnsConfig(const struct __res_state& res,
DnsConfig* dns_config);
#endif #endif
} // namespace internal } // namespace internal
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/cancelable_callback.h" #include "base/cancelable_callback.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/optional.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/stl_util.h" #include "base/stl_util.h"
...@@ -146,17 +147,16 @@ void InitializeExpectedConfig(DnsConfig* config) { ...@@ -146,17 +147,16 @@ void InitializeExpectedConfig(DnsConfig* config) {
TEST(DnsConfigServicePosixTest, ConvertResStateToDnsConfig) { TEST(DnsConfigServicePosixTest, ConvertResStateToDnsConfig) {
struct __res_state res; struct __res_state res;
DnsConfig config;
EXPECT_FALSE(config.IsValid());
InitializeResState(&res); InitializeResState(&res);
ASSERT_TRUE(internal::ConvertResStateToDnsConfig(res, &config)); base::Optional<DnsConfig> config = internal::ConvertResStateToDnsConfig(res);
CloseResState(&res); CloseResState(&res);
EXPECT_TRUE(config.IsValid()); ASSERT_TRUE(config.has_value());
EXPECT_TRUE(config->IsValid());
DnsConfig expected_config; DnsConfig expected_config;
EXPECT_FALSE(expected_config.EqualsIgnoreHosts(config)); EXPECT_FALSE(expected_config.EqualsIgnoreHosts(config.value()));
InitializeExpectedConfig(&expected_config); InitializeExpectedConfig(&expected_config);
EXPECT_TRUE(expected_config.EqualsIgnoreHosts(config)); EXPECT_TRUE(expected_config.EqualsIgnoreHosts(config.value()));
} }
TEST(DnsConfigServicePosixTest, RejectEmptyNameserver) { TEST(DnsConfigServicePosixTest, RejectEmptyNameserver) {
...@@ -175,12 +175,11 @@ TEST(DnsConfigServicePosixTest, RejectEmptyNameserver) { ...@@ -175,12 +175,11 @@ TEST(DnsConfigServicePosixTest, RejectEmptyNameserver) {
res.nsaddr_list[1] = sa; res.nsaddr_list[1] = sa;
res.nscount = 2; res.nscount = 2;
DnsConfig config; EXPECT_FALSE(internal::ConvertResStateToDnsConfig(res));
EXPECT_FALSE(internal::ConvertResStateToDnsConfig(res, &config));
sa.sin_addr.s_addr = 0xDEADBEEF; sa.sin_addr.s_addr = 0xDEADBEEF;
res.nsaddr_list[0] = sa; res.nsaddr_list[0] = sa;
EXPECT_TRUE(internal::ConvertResStateToDnsConfig(res, &config)); EXPECT_TRUE(internal::ConvertResStateToDnsConfig(res));
} }
TEST(DnsConfigServicePosixTest, DestroyWhileJobsWorking) { TEST(DnsConfigServicePosixTest, DestroyWhileJobsWorking) {
......
...@@ -74,42 +74,53 @@ const wchar_t kDnsConnectionsProxies[] = ...@@ -74,42 +74,53 @@ const wchar_t kDnsConnectionsProxies[] =
// Convenience for reading values using RegKey. // Convenience for reading values using RegKey.
class RegistryReader { class RegistryReader {
public: public:
explicit RegistryReader(const wchar_t* key) { explicit RegistryReader(const wchar_t key[]) {
// Ignoring the result. |key_.Valid()| will catch failures. // Ignoring the result. |key_.Valid()| will catch failures.
key_.Open(HKEY_LOCAL_MACHINE, key, KEY_QUERY_VALUE); key_.Open(HKEY_LOCAL_MACHINE, key, KEY_QUERY_VALUE);
} }
~RegistryReader() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } ~RegistryReader() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); }
bool ReadString(const wchar_t* name, base::Optional<DnsSystemSettings::RegString> ReadString(
DnsSystemSettings::RegString* out) const { const wchar_t name[]) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
out->set = false; DnsSystemSettings::RegString reg_string;
reg_string.set = false;
if (!key_.Valid()) { if (!key_.Valid()) {
// Assume that if the |key_| is invalid then the key is missing. // Assume that if the |key_| is invalid then the key is missing.
return true; return reg_string;
} }
LONG result = key_.ReadValue(name, &out->value); LONG result = key_.ReadValue(name, &reg_string.value);
if (result == ERROR_SUCCESS) { if (result == ERROR_SUCCESS) {
out->set = true; reg_string.set = true;
return true; return reg_string;
} }
return (result == ERROR_FILE_NOT_FOUND);
if (result == ERROR_FILE_NOT_FOUND)
return reg_string;
return base::nullopt;
} }
bool ReadDword(const wchar_t* name, DnsSystemSettings::RegDword* out) const { base::Optional<DnsSystemSettings::RegDword> ReadDword(
const wchar_t name[]) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
out->set = false; DnsSystemSettings::RegDword reg_dword;
reg_dword.set = false;
if (!key_.Valid()) { if (!key_.Valid()) {
// Assume that if the |key_| is invalid then the key is missing. // Assume that if the |key_| is invalid then the key is missing.
return true; return reg_dword;
} }
LONG result = key_.ReadValueDW(name, &out->value); LONG result = key_.ReadValueDW(name, &reg_dword.value);
if (result == ERROR_SUCCESS) { if (result == ERROR_SUCCESS) {
out->set = true; reg_dword.set = true;
return true; return reg_dword;
} }
return (result == ERROR_FILE_NOT_FOUND);
if (result == ERROR_FILE_NOT_FOUND)
return reg_dword;
return base::nullopt;
} }
private: private:
...@@ -141,22 +152,35 @@ std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> ReadIpHelper( ...@@ -141,22 +152,35 @@ std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> ReadIpHelper(
return out; return out;
} }
bool ReadDevolutionSetting(const RegistryReader& reader, base::Optional<DnsSystemSettings::DevolutionSetting> ReadDevolutionSetting(
DnsSystemSettings::DevolutionSetting* setting) { const RegistryReader& reader) {
return reader.ReadDword(L"UseDomainNameDevolution", &setting->enabled) && DnsSystemSettings::DevolutionSetting setting;
reader.ReadDword(L"DomainNameDevolutionLevel", &setting->level);
base::Optional<DnsSystemSettings::RegDword> reg_value =
reader.ReadDword(L"UseDomainNameDevolution");
if (!reg_value)
return base::nullopt;
setting.enabled = reg_value.value();
reg_value = reader.ReadDword(L"DomainNameDevolutionLevel");
if (!reg_value)
return base::nullopt;
setting.level = reg_value.value();
return setting;
} }
// Reads DnsSystemSettings from IpHelper and registry. // Reads DnsSystemSettings from IpHelper and registry.
bool ReadSystemSettings(DnsSystemSettings* settings) { base::Optional<DnsSystemSettings> ReadSystemSettings() {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK); base::BlockingType::MAY_BLOCK);
settings->addresses = ReadIpHelper(GAA_FLAG_SKIP_ANYCAST | DnsSystemSettings settings;
GAA_FLAG_SKIP_UNICAST |
GAA_FLAG_SKIP_MULTICAST | settings.addresses =
GAA_FLAG_SKIP_FRIENDLY_NAME); ReadIpHelper(GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_UNICAST |
if (!settings->addresses.get()) GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME);
return false; if (!settings.addresses.get())
return base::nullopt;
RegistryReader tcpip_reader(kTcpipPath); RegistryReader tcpip_reader(kTcpipPath);
RegistryReader tcpip6_reader(kTcpip6Path); RegistryReader tcpip6_reader(kTcpip6Path);
...@@ -164,76 +188,91 @@ bool ReadSystemSettings(DnsSystemSettings* settings) { ...@@ -164,76 +188,91 @@ bool ReadSystemSettings(DnsSystemSettings* settings) {
RegistryReader policy_reader(kPolicyPath); RegistryReader policy_reader(kPolicyPath);
RegistryReader primary_dns_suffix_reader(kPrimaryDnsSuffixPath); RegistryReader primary_dns_suffix_reader(kPrimaryDnsSuffixPath);
if (!policy_reader.ReadString(L"SearchList", &settings->policy_search_list)) { base::Optional<DnsSystemSettings::RegString> reg_string =
return false; policy_reader.ReadString(L"SearchList");
} if (!reg_string)
return base::nullopt;
if (!tcpip_reader.ReadString(L"SearchList", &settings->tcpip_search_list)) settings.policy_search_list = std::move(reg_string).value();
return false;
reg_string = tcpip_reader.ReadString(L"SearchList");
if (!tcpip_reader.ReadString(L"Domain", &settings->tcpip_domain)) if (!reg_string)
return false; return base::nullopt;
settings.tcpip_search_list = std::move(reg_string).value();
if (!ReadDevolutionSetting(policy_reader, &settings->policy_devolution))
return false; reg_string = tcpip_reader.ReadString(L"Domain");
if (!reg_string)
if (!ReadDevolutionSetting(dnscache_reader, &settings->dnscache_devolution)) return base::nullopt;
return false; settings.tcpip_domain = std::move(reg_string).value();
if (!ReadDevolutionSetting(tcpip_reader, &settings->tcpip_devolution)) base::Optional<DnsSystemSettings::DevolutionSetting> devolution_setting =
return false; ReadDevolutionSetting(policy_reader);
if (!devolution_setting)
if (!policy_reader.ReadDword(L"AppendToMultiLabelName", return base::nullopt;
&settings->append_to_multi_label_name)) { settings.policy_devolution = devolution_setting.value();
return false;
} devolution_setting = ReadDevolutionSetting(dnscache_reader);
if (!devolution_setting)
if (!primary_dns_suffix_reader.ReadString(L"PrimaryDnsSuffix", return base::nullopt;
&settings->primary_dns_suffix)) { settings.dnscache_devolution = devolution_setting.value();
return false;
devolution_setting = ReadDevolutionSetting(tcpip_reader);
if (!devolution_setting)
return base::nullopt;
settings.tcpip_devolution = devolution_setting.value();
base::Optional<DnsSystemSettings::RegDword> reg_dword =
policy_reader.ReadDword(L"AppendToMultiLabelName");
if (!reg_dword)
return base::nullopt;
settings.append_to_multi_label_name = reg_dword.value();
reg_string = primary_dns_suffix_reader.ReadString(L"PrimaryDnsSuffix");
if (!reg_string) {
return base::nullopt;
} }
settings.primary_dns_suffix = std::move(reg_string).value();
base::win::RegistryKeyIterator nrpt_rules(HKEY_LOCAL_MACHINE, kNrptPath); base::win::RegistryKeyIterator nrpt_rules(HKEY_LOCAL_MACHINE, kNrptPath);
base::win::RegistryKeyIterator cs_nrpt_rules(HKEY_LOCAL_MACHINE, base::win::RegistryKeyIterator cs_nrpt_rules(HKEY_LOCAL_MACHINE,
kControlSetNrptPath); kControlSetNrptPath);
settings->have_name_resolution_policy = settings.have_name_resolution_policy =
(nrpt_rules.SubkeyCount() > 0 || cs_nrpt_rules.SubkeyCount() > 0); (nrpt_rules.SubkeyCount() > 0 || cs_nrpt_rules.SubkeyCount() > 0);
base::win::RegistryKeyIterator dns_connections(HKEY_LOCAL_MACHINE, base::win::RegistryKeyIterator dns_connections(HKEY_LOCAL_MACHINE,
kDnsConnectionsPath); kDnsConnectionsPath);
base::win::RegistryKeyIterator dns_connections_proxies( base::win::RegistryKeyIterator dns_connections_proxies(
HKEY_LOCAL_MACHINE, kDnsConnectionsProxies); HKEY_LOCAL_MACHINE, kDnsConnectionsProxies);
settings->have_proxy = (dns_connections.SubkeyCount() > 0 || settings.have_proxy = (dns_connections.SubkeyCount() > 0 ||
dns_connections_proxies.SubkeyCount() > 0); dns_connections_proxies.SubkeyCount() > 0);
return true; return settings;
} }
// Default address of "localhost" and local computer name can be overridden // Default address of "localhost" and local computer name can be overridden
// by the HOSTS file, but if it's not there, then we need to fill it in. // by the HOSTS file, but if it's not there, then we need to fill it in.
bool AddLocalhostEntries(DnsHosts* hosts) { bool AddLocalhostEntriesTo(DnsHosts& in_out_hosts) {
IPAddress loopback_ipv4 = IPAddress::IPv4Localhost(); IPAddress loopback_ipv4 = IPAddress::IPv4Localhost();
IPAddress loopback_ipv6 = IPAddress::IPv6Localhost(); IPAddress loopback_ipv6 = IPAddress::IPv6Localhost();
// This does not override any pre-existing entries from the HOSTS file. // This does not override any pre-existing entries from the HOSTS file.
hosts->insert(std::make_pair(DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4), in_out_hosts.insert(std::make_pair(
loopback_ipv4)); DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4), loopback_ipv4));
hosts->insert(std::make_pair(DnsHostsKey("localhost", ADDRESS_FAMILY_IPV6), in_out_hosts.insert(std::make_pair(
loopback_ipv6)); DnsHostsKey("localhost", ADDRESS_FAMILY_IPV6), loopback_ipv6));
wchar_t buffer[MAX_PATH]; wchar_t buffer[MAX_PATH];
DWORD size = MAX_PATH; DWORD size = MAX_PATH;
std::string localname; if (!GetComputerNameExW(ComputerNameDnsHostname, buffer, &size))
if (!GetComputerNameExW(ComputerNameDnsHostname, buffer, &size) || return false;
!ParseDomainASCII(buffer, &localname)) { std::string localname = ParseDomainASCII(buffer);
if (localname.empty())
return false; return false;
}
localname = base::ToLowerASCII(localname); localname = base::ToLowerASCII(localname);
bool have_ipv4 = bool have_ipv4 =
hosts->count(DnsHostsKey(localname, ADDRESS_FAMILY_IPV4)) > 0; in_out_hosts.count(DnsHostsKey(localname, ADDRESS_FAMILY_IPV4)) > 0;
bool have_ipv6 = bool have_ipv6 =
hosts->count(DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)) > 0; in_out_hosts.count(DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)) > 0;
if (have_ipv4 && have_ipv6) if (have_ipv4 && have_ipv6)
return true; return true;
...@@ -264,10 +303,12 @@ bool AddLocalhostEntries(DnsHosts* hosts) { ...@@ -264,10 +303,12 @@ bool AddLocalhostEntries(DnsHosts* hosts) {
} }
if (!have_ipv4 && (ipe.GetFamily() == ADDRESS_FAMILY_IPV4)) { if (!have_ipv4 && (ipe.GetFamily() == ADDRESS_FAMILY_IPV4)) {
have_ipv4 = true; have_ipv4 = true;
(*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)) { } else if (!have_ipv6 && (ipe.GetFamily() == ADDRESS_FAMILY_IPV6)) {
have_ipv6 = true; have_ipv6 = true;
(*hosts)[DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)] = ipe.address(); in_out_hosts[DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)] =
ipe.address();
} }
} }
} }
...@@ -282,7 +323,7 @@ class RegistryWatcher { ...@@ -282,7 +323,7 @@ class RegistryWatcher {
~RegistryWatcher() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } ~RegistryWatcher() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); }
bool Watch(const wchar_t* key, const CallbackType& callback) { bool Watch(const wchar_t key[], const CallbackType& callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!callback.is_null()); DCHECK(!callback.is_null());
DCHECK(callback_.is_null()); DCHECK(callback_.is_null());
...@@ -336,19 +377,21 @@ base::FilePath GetHostsPath() { ...@@ -336,19 +377,21 @@ base::FilePath GetHostsPath() {
} }
void ConfigureSuffixSearch(const DnsSystemSettings& settings, void ConfigureSuffixSearch(const DnsSystemSettings& settings,
DnsConfig* config) { DnsConfig& in_out_config) {
// SearchList takes precedence, so check it first. // SearchList takes precedence, so check it first.
if (settings.policy_search_list.set) { if (settings.policy_search_list.set) {
std::vector<std::string> search; std::vector<std::string> search =
if (ParseSearchList(settings.policy_search_list.value, &search)) { ParseSearchList(settings.policy_search_list.value);
config->search.swap(search); if (!search.empty()) {
in_out_config.search = std::move(search);
return; return;
} }
// Even if invalid, the policy disables the user-specified setting below. // Even if invalid, the policy disables the user-specified setting below.
} else if (settings.tcpip_search_list.set) { } else if (settings.tcpip_search_list.set) {
std::vector<std::string> search; std::vector<std::string> search =
if (ParseSearchList(settings.tcpip_search_list.value, &search)) { ParseSearchList(settings.tcpip_search_list.value);
config->search.swap(search); if (!search.empty()) {
in_out_config.search = std::move(search);
return; return;
} }
} }
...@@ -365,15 +408,14 @@ void ConfigureSuffixSearch(const DnsSystemSettings& settings, ...@@ -365,15 +408,14 @@ void ConfigureSuffixSearch(const DnsSystemSettings& settings,
// The user setting (tcpip_domain) can be configurred at Computer Name in // The user setting (tcpip_domain) can be configurred at Computer Name in
// System Settings // System Settings
std::string primary_suffix; std::string primary_suffix;
if ((settings.primary_dns_suffix.set && if (settings.primary_dns_suffix.set)
ParseDomainASCII(settings.primary_dns_suffix.value, &primary_suffix)) || primary_suffix = ParseDomainASCII(settings.primary_dns_suffix.value);
(settings.tcpip_domain.set && if (primary_suffix.empty() && settings.tcpip_domain.set)
ParseDomainASCII(settings.tcpip_domain.value, &primary_suffix))) { primary_suffix = ParseDomainASCII(settings.tcpip_domain.value);
// Primary suffix goes in front. if (primary_suffix.empty())
config->search.insert(config->search.begin(), primary_suffix);
} else {
return; // No primary suffix, hence no devolution. return; // No primary suffix, hence no devolution.
} // Primary suffix goes in front.
in_out_config.search.insert(in_out_config.search.begin(), primary_suffix);
// Devolution is determined by precedence: policy > dnscache > tcpip. // Devolution is determined by precedence: policy > dnscache > tcpip.
// |enabled|: UseDomainNameDevolution and |level|: DomainNameDevolutionLevel // |enabled|: UseDomainNameDevolution and |level|: DomainNameDevolutionLevel
...@@ -415,7 +457,7 @@ void ConfigureSuffixSearch(const DnsSystemSettings& settings, ...@@ -415,7 +457,7 @@ void ConfigureSuffixSearch(const DnsSystemSettings& settings,
for (size_t offset = 0; num_dots >= devolution.level.value; --num_dots) { for (size_t offset = 0; num_dots >= devolution.level.value; --num_dots) {
offset = primary_suffix.find('.', offset + 1); offset = primary_suffix.find('.', offset + 1);
config->search.push_back(primary_suffix.substr(offset + 1)); in_out_config.search.push_back(primary_suffix.substr(offset + 1));
} }
} }
...@@ -448,39 +490,40 @@ DnsSystemSettings::DnsSystemSettings() ...@@ -448,39 +490,40 @@ DnsSystemSettings::DnsSystemSettings()
DnsSystemSettings::~DnsSystemSettings() { DnsSystemSettings::~DnsSystemSettings() {
} }
bool ParseDomainASCII(base::WStringPiece widestr, std::string* domain) { DnsSystemSettings::DnsSystemSettings(DnsSystemSettings&&) = default;
DCHECK(domain); DnsSystemSettings& DnsSystemSettings::operator=(DnsSystemSettings&&) = default;
std::string ParseDomainASCII(base::WStringPiece widestr) {
if (widestr.empty()) if (widestr.empty())
return false; return "";
// Check if already ASCII. // Check if already ASCII.
if (base::IsStringASCII(base::AsStringPiece16(widestr))) { if (base::IsStringASCII(base::AsStringPiece16(widestr))) {
domain->assign(widestr.begin(), widestr.end()); return std::string(widestr.begin(), widestr.end());
return true;
} }
// Otherwise try to convert it from IDN to punycode. // Otherwise try to convert it from IDN to punycode.
const int kInitialBufferSize = 256; const int kInitialBufferSize = 256;
url::RawCanonOutputT<base::char16, kInitialBufferSize> punycode; url::RawCanonOutputT<base::char16, kInitialBufferSize> punycode;
if (!url::IDNToASCII(base::as_u16cstr(widestr), widestr.length(), &punycode)) if (!url::IDNToASCII(base::as_u16cstr(widestr), widestr.length(), &punycode))
return false; return "";
// |punycode_output| should now be ASCII; convert it to a std::string. // |punycode_output| should now be ASCII; convert it to a std::string.
// (We could use UTF16ToASCII() instead, but that requires an extra string // (We could use UTF16ToASCII() instead, but that requires an extra string
// copy. Since ASCII is a subset of UTF8 the following is equivalent). // copy. Since ASCII is a subset of UTF8 the following is equivalent).
bool success = base::UTF16ToUTF8(punycode.data(), punycode.length(), domain); std::string converted;
bool success =
base::UTF16ToUTF8(punycode.data(), punycode.length(), &converted);
DCHECK(success); DCHECK(success);
DCHECK(base::IsStringASCII(*domain)); DCHECK(base::IsStringASCII(converted));
return success && !domain->empty(); return converted;
} }
bool ParseSearchList(const std::wstring& value, std::vector<std::string> ParseSearchList(base::WStringPiece value) {
std::vector<std::string>* output) {
DCHECK(output);
if (value.empty()) if (value.empty())
return false; return {};
output->clear(); std::vector<std::string> output;
// If the list includes an empty hostname (",," or ", ,"), it is terminated. // If the list includes an empty hostname (",," or ", ,"), it is terminated.
// Although nslookup and network connection property tab ignore such // Although nslookup and network connection property tab ignore such
...@@ -490,18 +533,19 @@ bool ParseSearchList(const std::wstring& value, ...@@ -490,18 +533,19 @@ bool ParseSearchList(const std::wstring& value,
value, L",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { value, L",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
// Convert non-ASCII to punycode, although getaddrinfo does not properly // Convert non-ASCII to punycode, although getaddrinfo does not properly
// handle such suffixes. // handle such suffixes.
std::string parsed; std::string parsed = ParseDomainASCII(t);
if (!ParseDomainASCII(t, &parsed)) if (parsed.empty())
break; break;
output->push_back(parsed); output.push_back(std::move(parsed));
} }
return !output->empty(); return output;
} }
bool ConvertSettingsToDnsConfig(const DnsSystemSettings& settings, base::Optional<DnsConfig> ConvertSettingsToDnsConfig(
DnsConfig* config) { const DnsSystemSettings& settings) {
bool uses_vpn = false; bool uses_vpn = false;
*config = DnsConfig();
DnsConfig dns_config;
// Use GetAdapterAddresses to get effective DNS server order and // Use GetAdapterAddresses to get effective DNS server order and
// connection-specific DNS suffix. Ignore disconnected and loopback adapters. // connection-specific DNS suffix. Ignore disconnected and loopback adapters.
...@@ -519,7 +563,7 @@ bool ConvertSettingsToDnsConfig(const DnsSystemSettings& settings, ...@@ -519,7 +563,7 @@ bool ConvertSettingsToDnsConfig(const DnsSystemSettings& settings,
// previously found, skip processing another adapter. // previously found, skip processing another adapter.
if (adapter->OperStatus != IfOperStatusUp || if (adapter->OperStatus != IfOperStatusUp ||
adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK || adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK ||
!config->nameservers.empty()) !dns_config.nameservers.empty())
continue; continue;
for (const IP_ADAPTER_DNS_SERVER_ADDRESS* address = for (const IP_ADAPTER_DNS_SERVER_ADDRESS* address =
...@@ -533,9 +577,9 @@ bool ConvertSettingsToDnsConfig(const DnsSystemSettings& settings, ...@@ -533,9 +577,9 @@ bool ConvertSettingsToDnsConfig(const DnsSystemSettings& settings,
// Override unset port. // Override unset port.
if (!ipe.port()) if (!ipe.port())
ipe = IPEndPoint(ipe.address(), dns_protocol::kDefaultPort); ipe = IPEndPoint(ipe.address(), dns_protocol::kDefaultPort);
config->nameservers.push_back(ipe); dns_config.nameservers.push_back(ipe);
} else { } else {
return false; return base::nullopt;
} }
} }
...@@ -544,34 +588,34 @@ bool ConvertSettingsToDnsConfig(const DnsSystemSettings& settings, ...@@ -544,34 +588,34 @@ bool ConvertSettingsToDnsConfig(const DnsSystemSettings& settings,
// |DnsSuffix| stores the effective connection-specific suffix, which is // |DnsSuffix| stores the effective connection-specific suffix, which is
// obtained via DHCP (regkey: Tcpip\Parameters\Interfaces\{XXX}\DhcpDomain) // obtained via DHCP (regkey: Tcpip\Parameters\Interfaces\{XXX}\DhcpDomain)
// or specified by the user (regkey: Tcpip\Parameters\Domain). // or specified by the user (regkey: Tcpip\Parameters\Domain).
std::string dns_suffix; std::string dns_suffix = ParseDomainASCII(adapter->DnsSuffix);
if (ParseDomainASCII(adapter->DnsSuffix, &dns_suffix)) if (!dns_suffix.empty())
config->search.push_back(dns_suffix); dns_config.search.push_back(std::move(dns_suffix));
} }
if (config->nameservers.empty()) if (dns_config.nameservers.empty())
return false; // No point continuing. return base::nullopt; // No point continuing.
// Windows always tries a multi-label name "as is" before using suffixes. // Windows always tries a multi-label name "as is" before using suffixes.
config->ndots = 1; dns_config.ndots = 1;
if (!settings.append_to_multi_label_name.set) { if (!settings.append_to_multi_label_name.set) {
config->append_to_multi_label_name = false; dns_config.append_to_multi_label_name = false;
} else { } else {
config->append_to_multi_label_name = dns_config.append_to_multi_label_name =
(settings.append_to_multi_label_name.value != 0); (settings.append_to_multi_label_name.value != 0);
} }
if (settings.have_name_resolution_policy) { if (settings.have_name_resolution_policy) {
// TODO(szym): only set this to true if NRPT has DirectAccess rules. // TODO(szym): only set this to true if NRPT has DirectAccess rules.
config->use_local_ipv6 = true; dns_config.use_local_ipv6 = true;
} }
if (settings.have_name_resolution_policy || settings.have_proxy || uses_vpn) if (settings.have_name_resolution_policy || settings.have_proxy || uses_vpn)
config->unhandled_options = true; dns_config.unhandled_options = true;
ConfigureSuffixSearch(settings, config); ConfigureSuffixSearch(settings, dns_config);
return true; return dns_config;
} }
// Watches registry and HOSTS file for changes. Must live on a sequence which // Watches registry and HOSTS file for changes. Must live on a sequence which
...@@ -580,7 +624,7 @@ class DnsConfigServiceWin::Watcher ...@@ -580,7 +624,7 @@ class DnsConfigServiceWin::Watcher
: public NetworkChangeNotifier::IPAddressObserver, : public NetworkChangeNotifier::IPAddressObserver,
public DnsConfigService::Watcher { public DnsConfigService::Watcher {
public: public:
explicit Watcher(DnsConfigServiceWin* service) explicit Watcher(DnsConfigServiceWin& service)
: DnsConfigService::Watcher(service) {} : DnsConfigService::Watcher(service) {}
~Watcher() override { NetworkChangeNotifier::RemoveIPAddressObserver(this); } ~Watcher() override { NetworkChangeNotifier::RemoveIPAddressObserver(this); }
...@@ -648,25 +692,22 @@ class DnsConfigServiceWin::Watcher ...@@ -648,25 +692,22 @@ class DnsConfigServiceWin::Watcher
// Reads config from registry and IpHelper. All work performed in ThreadPool. // Reads config from registry and IpHelper. All work performed in ThreadPool.
class DnsConfigServiceWin::ConfigReader : public SerialWorker { class DnsConfigServiceWin::ConfigReader : public SerialWorker {
public: public:
explicit ConfigReader(DnsConfigServiceWin* service) explicit ConfigReader(DnsConfigServiceWin& service) : service_(&service) {}
: service_(service),
success_(false) {}
private: private:
~ConfigReader() override {} ~ConfigReader() override {}
void DoWork() override { void DoWork() override {
DnsSystemSettings settings = {}; base::Optional<DnsSystemSettings> settings = ReadSystemSettings();
success_ = false; if (settings.has_value())
if (ReadSystemSettings(&settings)) dns_config_ = ConvertSettingsToDnsConfig(settings.value());
success_ = ConvertSettingsToDnsConfig(settings, &dns_config_);
} }
void OnWorkFinished() override { void OnWorkFinished() override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!IsCancelled()); DCHECK(!IsCancelled());
if (success_) { if (dns_config_.has_value()) {
service_->OnConfigRead(dns_config_); service_->OnConfigRead(std::move(dns_config_).value());
} else { } else {
LOG(WARNING) << "Failed to read DnsConfig."; LOG(WARNING) << "Failed to read DnsConfig.";
// Try again in a while in case DnsConfigWatcher missed the signal. // Try again in a while in case DnsConfigWatcher missed the signal.
...@@ -678,25 +719,24 @@ class DnsConfigServiceWin::ConfigReader : public SerialWorker { ...@@ -678,25 +719,24 @@ class DnsConfigServiceWin::ConfigReader : public SerialWorker {
DnsConfigServiceWin* service_; DnsConfigServiceWin* service_;
// Written in DoWork(), read in OnWorkFinished(). No locking required. // Written in DoWork(), read in OnWorkFinished(). No locking required.
DnsConfig dns_config_; base::Optional<DnsConfig> dns_config_;
bool success_;
}; };
// Extension of DnsConfigService::HostsReader that fills in localhost and local // Extension of DnsConfigService::HostsReader that fills in localhost and local
// computer name if necessary. // computer name if necessary.
class DnsConfigServiceWin::HostsReader : public DnsConfigService::HostsReader { class DnsConfigServiceWin::HostsReader : public DnsConfigService::HostsReader {
public: public:
explicit HostsReader(DnsConfigServiceWin* service) explicit HostsReader(DnsConfigServiceWin& service)
: DnsConfigService::HostsReader(service, GetHostsPath().value()) {} : DnsConfigService::HostsReader(GetHostsPath().value(), service) {}
HostsReader(const HostsReader&) = delete; HostsReader(const HostsReader&) = delete;
HostsReader& operator=(const HostsReader&) = delete; HostsReader& operator=(const HostsReader&) = delete;
protected: protected:
bool AddAdditionalHostsTo(DnsHosts& dns_hosts) override { bool AddAdditionalHostsTo(DnsHosts& in_out_dns_hosts) override {
base::ScopedBlockingCall scoped_blocking_call( base::ScopedBlockingCall scoped_blocking_call(
FROM_HERE, base::BlockingType::MAY_BLOCK); FROM_HERE, base::BlockingType::MAY_BLOCK);
return AddLocalhostEntries(&dns_hosts); return AddLocalhostEntriesTo(in_out_dns_hosts);
} }
private: private:
...@@ -727,11 +767,11 @@ void DnsConfigServiceWin::ReadHostsNow() { ...@@ -727,11 +767,11 @@ void DnsConfigServiceWin::ReadHostsNow() {
bool DnsConfigServiceWin::StartWatching() { bool DnsConfigServiceWin::StartWatching() {
if (!config_reader_) if (!config_reader_)
config_reader_ = base::MakeRefCounted<ConfigReader>(this); config_reader_ = base::MakeRefCounted<ConfigReader>(*this);
if (!hosts_reader_) if (!hosts_reader_)
hosts_reader_ = base::MakeRefCounted<HostsReader>(this); hosts_reader_ = base::MakeRefCounted<HostsReader>(*this);
// TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139 // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139
watcher_.reset(new Watcher(this)); watcher_.reset(new Watcher(*this));
return watcher_->Watch(); return watcher_->Watch();
} }
......
...@@ -39,17 +39,15 @@ namespace net { ...@@ -39,17 +39,15 @@ namespace net {
namespace internal { namespace internal {
// Converts a UTF-16 domain name to ASCII, possibly using punycode. // Converts a UTF-16 domain name to ASCII, possibly using punycode.
// Returns true if the conversion succeeds and output is not empty. In case of // Returns empty string on failure.
// failure, |domain| might become dirty. std::string NET_EXPORT_PRIVATE ParseDomainASCII(base::WStringPiece widestr);
bool NET_EXPORT_PRIVATE ParseDomainASCII(base::WStringPiece widestr,
std::string* domain);
// Parses |value| as search list (comma-delimited list of domain names) from // Parses |value| as search list (comma-delimited list of domain names) from
// a registry key and stores it in |out|. Returns true on success. Empty // a registry key and stores it in |out|. Returns empty vector on failure. Empty
// entries (e.g., "chromium.org,,org") terminate the list. Non-ascii hostnames // entries (e.g., "chromium.org,,org") terminate the list. Non-ascii hostnames
// are converted to punycode. // are converted to punycode.
bool NET_EXPORT_PRIVATE ParseSearchList(const std::wstring& value, std::vector<std::string> NET_EXPORT_PRIVATE
std::vector<std::string>* out); ParseSearchList(base::WStringPiece value);
// All relevant settings read from registry and IP Helper. This isolates our // All relevant settings read from registry and IP Helper. This isolates our
// logic from system calls and is exposed for unit tests. Keep it an aggregate // logic from system calls and is exposed for unit tests. Keep it an aggregate
...@@ -76,6 +74,9 @@ struct NET_EXPORT_PRIVATE DnsSystemSettings { ...@@ -76,6 +74,9 @@ struct NET_EXPORT_PRIVATE DnsSystemSettings {
DnsSystemSettings(); DnsSystemSettings();
~DnsSystemSettings(); ~DnsSystemSettings();
DnsSystemSettings(DnsSystemSettings&&);
DnsSystemSettings& operator=(DnsSystemSettings&&);
// Filled in by GetAdapterAddresses. Note that the alternative // Filled in by GetAdapterAddresses. Note that the alternative
// GetNetworkParams does not include IPv6 addresses. // GetNetworkParams does not include IPv6 addresses.
std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> addresses; std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> addresses;
...@@ -114,11 +115,10 @@ struct NET_EXPORT_PRIVATE DnsSystemSettings { ...@@ -114,11 +115,10 @@ struct NET_EXPORT_PRIVATE DnsSystemSettings {
bool have_proxy = false; bool have_proxy = false;
}; };
// Fills in |dns_config| from |settings|. Exposed for tests. Returns false if a // Fills in |dns_config| from |settings|. Exposed for tests. Returns nullopt if
// valid config could not be determined. // a valid config could not be determined.
bool NET_EXPORT_PRIVATE base::Optional<DnsConfig> NET_EXPORT_PRIVATE
ConvertSettingsToDnsConfig(const DnsSystemSettings& settings, ConvertSettingsToDnsConfig(const DnsSystemSettings& settings);
DnsConfig* dns_config);
// Service for reading and watching Windows system DNS settings. This object is // Service for reading and watching Windows system DNS settings. This object is
// not thread-safe and methods may perform blocking I/O so methods must be // not thread-safe and methods may perform blocking I/O so methods must be
......
...@@ -4,11 +4,16 @@ ...@@ -4,11 +4,16 @@
#include "net/dns/dns_config_service_win.h" #include "net/dns/dns_config_service_win.h"
#include <string>
#include <vector>
#include "base/check.h" #include "base/check.h"
#include "base/memory/free_deleter.h" #include "base/memory/free_deleter.h"
#include "base/optional.h"
#include "net/base/ip_address.h" #include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h" #include "net/base/ip_endpoint.h"
#include "net/dns/public/dns_protocol.h" #include "net/dns/public/dns_protocol.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace net { namespace net {
...@@ -18,33 +23,22 @@ namespace { ...@@ -18,33 +23,22 @@ namespace {
TEST(DnsConfigServiceWinTest, ParseSearchList) { TEST(DnsConfigServiceWinTest, ParseSearchList) {
const struct TestCase { const struct TestCase {
const wchar_t* input; const wchar_t* input;
const char* output[4]; // NULL-terminated, empty if expected false std::vector<std::string> expected;
} cases[] = { } cases[] = {
{L"chromium.org", {"chromium.org", nullptr}}, {L"chromium.org", {"chromium.org"}},
{L"chromium.org,org", {"chromium.org", "org", nullptr}}, {L"chromium.org,org", {"chromium.org", "org"}},
// Empty suffixes terminate the list // Empty suffixes terminate the list
{L"crbug.com,com,,org", {"crbug.com", "com", nullptr}}, {L"crbug.com,com,,org", {"crbug.com", "com"}},
// IDN are converted to punycode // IDN are converted to punycode
{L"\u017c\xf3\u0142ta.pi\u0119\u015b\u0107.pl,pl", {L"\u017c\xf3\u0142ta.pi\u0119\u015b\u0107.pl,pl",
{"xn--ta-4ja03asj.xn--pi-wla5e0q.pl", "pl", nullptr}}, {"xn--ta-4ja03asj.xn--pi-wla5e0q.pl", "pl"}},
// Empty search list is invalid // Empty search list is invalid
{L"", {nullptr}}, {L"", {}},
{L",,", {nullptr}}, {L",,", {}},
}; };
for (const auto& t : cases) { for (const auto& t : cases) {
std::vector<std::string> actual_output, expected_output; EXPECT_EQ(internal::ParseSearchList(t.input), t.expected);
actual_output.push_back("UNSET");
for (const char* const* output = t.output; *output; ++output) {
expected_output.push_back(*output);
}
bool result = internal::ParseSearchList(t.input, &actual_output);
if (!expected_output.empty()) {
EXPECT_TRUE(result);
EXPECT_EQ(expected_output, actual_output);
} else {
EXPECT_FALSE(result) << "Unexpected parse success on " << t.input;
}
} }
} }
...@@ -183,14 +177,13 @@ TEST(DnsConfigServiceWinTest, ConvertAdapterAddresses) { ...@@ -183,14 +177,13 @@ TEST(DnsConfigServiceWinTest, ConvertAdapterAddresses) {
expected_nameservers.push_back(IPEndPoint(ip, port)); expected_nameservers.push_back(IPEndPoint(ip, port));
} }
DnsConfig config; base::Optional<DnsConfig> config =
bool success = internal::ConvertSettingsToDnsConfig(settings, &config); internal::ConvertSettingsToDnsConfig(settings);
bool expected_success = !expected_nameservers.empty(); bool expected_success = !expected_nameservers.empty();
EXPECT_EQ(expected_success, success); EXPECT_EQ(expected_success, config.has_value());
EXPECT_EQ(expected_nameservers, config.nameservers); if (config.has_value()) {
if (success) { EXPECT_EQ(expected_nameservers, config->nameservers);
ASSERT_EQ(1u, config.search.size()); EXPECT_THAT(config->search, testing::ElementsAre(t.expected_suffix));
EXPECT_EQ(t.expected_suffix, config.search[0]);
} }
} }
} }
...@@ -211,7 +204,7 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) { ...@@ -211,7 +204,7 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
internal::DnsSystemSettings::DevolutionSetting dnscache_devolution; internal::DnsSystemSettings::DevolutionSetting dnscache_devolution;
internal::DnsSystemSettings::DevolutionSetting tcpip_devolution; internal::DnsSystemSettings::DevolutionSetting tcpip_devolution;
} input_settings; } input_settings;
std::string expected_search[5]; std::vector<std::string> expected_search;
} cases[] = { } cases[] = {
{ {
// Policy SearchList override. // Policy SearchList override.
...@@ -389,13 +382,10 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) { ...@@ -389,13 +382,10 @@ TEST(DnsConfigServiceWinTest, ConvertSuffixSearch) {
settings.dnscache_devolution = t.input_settings.dnscache_devolution; settings.dnscache_devolution = t.input_settings.dnscache_devolution;
settings.tcpip_devolution = t.input_settings.tcpip_devolution; settings.tcpip_devolution = t.input_settings.tcpip_devolution;
DnsConfig config; EXPECT_THAT(
EXPECT_TRUE(internal::ConvertSettingsToDnsConfig(settings, &config)); internal::ConvertSettingsToDnsConfig(settings),
std::vector<std::string> expected_search; testing::Optional(testing::Field(
for (size_t j = 0; !t.expected_search[j].empty(); ++j) { &DnsConfig::search, testing::ElementsAreArray(t.expected_search))));
expected_search.push_back(t.expected_search[j]);
}
EXPECT_EQ(expected_search, config.search);
} }
} }
...@@ -416,9 +406,10 @@ TEST(DnsConfigServiceWinTest, AppendToMultiLabelName) { ...@@ -416,9 +406,10 @@ TEST(DnsConfigServiceWinTest, AppendToMultiLabelName) {
internal::DnsSystemSettings settings; internal::DnsSystemSettings settings;
settings.addresses = CreateAdapterAddresses(infos); settings.addresses = CreateAdapterAddresses(infos);
settings.append_to_multi_label_name = t.input; settings.append_to_multi_label_name = t.input;
DnsConfig config; EXPECT_THAT(
EXPECT_TRUE(internal::ConvertSettingsToDnsConfig(settings, &config)); internal::ConvertSettingsToDnsConfig(settings),
EXPECT_EQ(t.expected_output, config.append_to_multi_label_name); testing::Optional(testing::Field(&DnsConfig::append_to_multi_label_name,
testing::Eq(t.expected_output))));
} }
} }
...@@ -441,10 +432,11 @@ TEST(DnsConfigServiceWinTest, HaveNRPT) { ...@@ -441,10 +432,11 @@ TEST(DnsConfigServiceWinTest, HaveNRPT) {
internal::DnsSystemSettings settings; internal::DnsSystemSettings settings;
settings.addresses = CreateAdapterAddresses(infos); settings.addresses = CreateAdapterAddresses(infos);
settings.have_name_resolution_policy = t.have_nrpt; settings.have_name_resolution_policy = t.have_nrpt;
DnsConfig config; base::Optional<DnsConfig> config =
EXPECT_TRUE(internal::ConvertSettingsToDnsConfig(settings, &config)); internal::ConvertSettingsToDnsConfig(settings);
EXPECT_EQ(t.unhandled_options, config.unhandled_options); ASSERT_TRUE(config.has_value());
EXPECT_EQ(t.have_nrpt, config.use_local_ipv6); EXPECT_EQ(t.unhandled_options, config->unhandled_options);
EXPECT_EQ(t.have_nrpt, config->use_local_ipv6);
} }
} }
...@@ -467,9 +459,10 @@ TEST(DnsConfigServiceWinTest, HaveProxy) { ...@@ -467,9 +459,10 @@ TEST(DnsConfigServiceWinTest, HaveProxy) {
internal::DnsSystemSettings settings; internal::DnsSystemSettings settings;
settings.addresses = CreateAdapterAddresses(infos); settings.addresses = CreateAdapterAddresses(infos);
settings.have_proxy = t.have_proxy; settings.have_proxy = t.have_proxy;
DnsConfig config; EXPECT_THAT(
EXPECT_TRUE(internal::ConvertSettingsToDnsConfig(settings, &config)); internal::ConvertSettingsToDnsConfig(settings),
EXPECT_EQ(t.unhandled_options, config.unhandled_options); testing::Optional(testing::Field(&DnsConfig::unhandled_options,
testing::Eq(t.unhandled_options))));
} }
} }
...@@ -483,9 +476,9 @@ TEST(DnsConfigServiceWinTest, UsesVpn) { ...@@ -483,9 +476,9 @@ TEST(DnsConfigServiceWinTest, UsesVpn) {
internal::DnsSystemSettings settings; internal::DnsSystemSettings settings;
settings.addresses = CreateAdapterAddresses(infos); settings.addresses = CreateAdapterAddresses(infos);
DnsConfig config; EXPECT_THAT(internal::ConvertSettingsToDnsConfig(settings),
EXPECT_TRUE(internal::ConvertSettingsToDnsConfig(settings, &config)); testing::Optional(testing::Field(&DnsConfig::unhandled_options,
EXPECT_TRUE(config.unhandled_options); testing::IsTrue())));
} }
} // namespace } // namespace
......
...@@ -78,9 +78,7 @@ bool DnsConfigWatcher::Watch( ...@@ -78,9 +78,7 @@ bool DnsConfigWatcher::Watch(
} }
// static // static
bool DnsConfigWatcher::CheckDnsConfig(bool* out_unhandled_options) { bool DnsConfigWatcher::CheckDnsConfig(bool& out_unhandled_options) {
DCHECK(out_unhandled_options);
if (!GetDnsInfoApi().dns_configuration_copy) if (!GetDnsInfoApi().dns_configuration_copy)
return false; return false;
std::unique_ptr<dns_config_t, DnsConfigTDeleter> dns_config( std::unique_ptr<dns_config_t, DnsConfigTDeleter> dns_config(
...@@ -100,7 +98,7 @@ bool DnsConfigWatcher::CheckDnsConfig(bool* out_unhandled_options) { ...@@ -100,7 +98,7 @@ bool DnsConfigWatcher::CheckDnsConfig(bool* out_unhandled_options) {
++num_resolvers; ++num_resolvers;
} }
*out_unhandled_options = num_resolvers > 1; out_unhandled_options = num_resolvers > 1;
return true; return true;
} }
......
...@@ -17,7 +17,7 @@ class DnsConfigWatcher { ...@@ -17,7 +17,7 @@ class DnsConfigWatcher {
bool Watch(const base::RepeatingCallback<void(bool succeeded)>& callback); bool Watch(const base::RepeatingCallback<void(bool succeeded)>& callback);
// Returns false iff a valid config could not be determined. // Returns false iff a valid config could not be determined.
static bool CheckDnsConfig(bool* out_unhandled_options); static bool CheckDnsConfig(bool& out_unhandled_options);
private: private:
NotifyWatcherMac watcher_; NotifyWatcherMac watcher_;
......
...@@ -18,9 +18,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ...@@ -18,9 +18,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
base::StringPiece16 widestr( base::StringPiece16 widestr(
reinterpret_cast<const base::StringPiece16::value_type*>(data), size / 2); reinterpret_cast<const base::StringPiece16::value_type*>(data), size / 2);
std::string result; std::string result = net::internal::ParseDomainASCII(widestr);
if (net::internal::ParseDomainASCII(widestr, &result)) if (!result.empty())
// Call base::ToLowerASCII to get some additional code coverage signal. // Call base::ToLowerASCII to get some additional code coverage signal.
result = base::ToLowerASCII(result); result = base::ToLowerASCII(result);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment