Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(542)

Unified Diff: net/dns/dns_config_service_posix.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/dns/dns_config_service_posix.h ('k') | net/dns/dns_config_service_posix_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/dns/dns_config_service_posix.cc
diff --git a/net/dns/dns_config_service_posix.cc b/net/dns/dns_config_service_posix.cc
deleted file mode 100644
index 135f3fd68767a064c58a15652d8e549f7336d5da..0000000000000000000000000000000000000000
--- a/net/dns/dns_config_service_posix.cc
+++ /dev/null
@@ -1,505 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/dns/dns_config_service_posix.h"
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/files/file_path.h"
-#include "base/files/file_path_watcher.h"
-#include "base/lazy_instance.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/metrics/histogram.h"
-#include "base/time/time.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_util.h"
-#include "net/dns/dns_hosts.h"
-#include "net/dns/dns_protocol.h"
-#include "net/dns/notify_watcher_mac.h"
-#include "net/dns/serial_worker.h"
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-#include "net/dns/dns_config_watcher_mac.h"
-#endif
-
-#if defined(OS_ANDROID)
-#include <sys/system_properties.h>
-#include "net/base/network_change_notifier.h"
-#endif
-
-namespace net {
-
-namespace internal {
-
-namespace {
-
-#if !defined(OS_ANDROID)
-const base::FilePath::CharType* kFilePathHosts =
- FILE_PATH_LITERAL("/etc/hosts");
-#else
-const base::FilePath::CharType* kFilePathHosts =
- FILE_PATH_LITERAL("/system/etc/hosts");
-#endif
-
-#if defined(OS_IOS)
-
-// There is no public API to watch the DNS configuration on iOS.
-class DnsConfigWatcher {
- public:
- typedef base::Callback<void(bool succeeded)> CallbackType;
-
- bool Watch(const CallbackType& callback) {
- return false;
- }
-};
-
-#elif defined(OS_ANDROID)
-// On Android, assume DNS config may have changed on every network change.
-class DnsConfigWatcher : public NetworkChangeNotifier::NetworkChangeObserver {
- public:
- DnsConfigWatcher() {
- NetworkChangeNotifier::AddNetworkChangeObserver(this);
- }
-
- ~DnsConfigWatcher() override {
- NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
- }
-
- bool Watch(const base::Callback<void(bool succeeded)>& callback) {
- callback_ = callback;
- return true;
- }
-
- void OnNetworkChanged(NetworkChangeNotifier::ConnectionType type) override {
- if (!callback_.is_null() && type != NetworkChangeNotifier::CONNECTION_NONE)
- callback_.Run(true);
- }
-
- private:
- base::Callback<void(bool succeeded)> callback_;
-};
-#elif !defined(OS_MACOSX)
-// DnsConfigWatcher for OS_MACOSX is in dns_config_watcher_mac.{hh,cc}.
-
-#ifndef _PATH_RESCONF // Normally defined in <resolv.h>
-#define _PATH_RESCONF "/etc/resolv.conf"
-#endif
-
-static const base::FilePath::CharType* kFilePathConfig =
- FILE_PATH_LITERAL(_PATH_RESCONF);
-
-class DnsConfigWatcher {
- public:
- typedef base::Callback<void(bool succeeded)> CallbackType;
-
- bool Watch(const CallbackType& callback) {
- callback_ = callback;
- return watcher_.Watch(base::FilePath(kFilePathConfig), false,
- base::Bind(&DnsConfigWatcher::OnCallback,
- base::Unretained(this)));
- }
-
- private:
- void OnCallback(const base::FilePath& path, bool error) {
- callback_.Run(!error);
- }
-
- base::FilePathWatcher watcher_;
- CallbackType callback_;
-};
-#endif
-
-#if !defined(OS_ANDROID)
-ConfigParsePosixResult ReadDnsConfig(DnsConfig* config) {
- ConfigParsePosixResult result;
- config->unhandled_options = false;
-#if defined(OS_OPENBSD)
- // Note: res_ninit in glibc always returns 0 and sets RES_INIT.
- // res_init behaves the same way.
- memset(&_res, 0, sizeof(_res));
- if (res_init() == 0) {
- result = ConvertResStateToDnsConfig(_res, config);
- } else {
- result = CONFIG_PARSE_POSIX_RES_INIT_FAILED;
- }
-#else // all other OS_POSIX
- struct __res_state res;
- memset(&res, 0, sizeof(res));
- if (res_ninit(&res) == 0) {
- result = ConvertResStateToDnsConfig(res, config);
- } else {
- result = CONFIG_PARSE_POSIX_RES_INIT_FAILED;
- }
- // Prefer res_ndestroy where available.
-#if defined(OS_MACOSX) || defined(OS_FREEBSD)
- res_ndestroy(&res);
-#else
- res_nclose(&res);
-#endif
-#endif
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- ConfigParsePosixResult error = DnsConfigWatcher::CheckDnsConfig();
- switch (error) {
- case CONFIG_PARSE_POSIX_OK:
- break;
- case CONFIG_PARSE_POSIX_UNHANDLED_OPTIONS:
- LOG(WARNING) << "dns_config has unhandled options!";
- config->unhandled_options = true;
- default:
- return error;
- }
-#endif // defined(OS_MACOSX) && !defined(OS_IOS)
- // Override timeout value to match default setting on Windows.
- config->timeout = base::TimeDelta::FromSeconds(kDnsTimeoutSeconds);
- return result;
-}
-#else // defined(OS_ANDROID)
-// Theoretically, this is bad. __system_property_get is not a supported API
-// (but it's currently visible to anyone using Bionic), and the properties
-// are implementation details that may disappear in future Android releases.
-// Practically, libcutils provides property_get, which is a public API, and the
-// DNS code (and its clients) are already robust against failing to get the DNS
-// config for whatever reason, so the properties can disappear and the world
-// won't end.
-// TODO(ttuttle): Depend on libcutils, then switch this (and other uses of
-// __system_property_get) to property_get.
-ConfigParsePosixResult ReadDnsConfig(DnsConfig* dns_config) {
- std::string dns1_string, dns2_string;
- char property_value[PROP_VALUE_MAX];
- __system_property_get("net.dns1", property_value);
- dns1_string = property_value;
- __system_property_get("net.dns2", property_value);
- dns2_string = property_value;
- if (dns1_string.length() == 0 && dns2_string.length() == 0)
- return CONFIG_PARSE_POSIX_NO_NAMESERVERS;
-
- IPAddressNumber dns1_number, dns2_number;
- bool parsed1 = ParseIPLiteralToNumber(dns1_string, &dns1_number);
- bool parsed2 = ParseIPLiteralToNumber(dns2_string, &dns2_number);
- if (!parsed1 && !parsed2)
- return CONFIG_PARSE_POSIX_BAD_ADDRESS;
-
- if (parsed1) {
- IPEndPoint dns1(dns1_number, dns_protocol::kDefaultPort);
- dns_config->nameservers.push_back(dns1);
- }
- if (parsed2) {
- IPEndPoint dns2(dns2_number, dns_protocol::kDefaultPort);
- dns_config->nameservers.push_back(dns2);
- }
-
- return CONFIG_PARSE_POSIX_OK;
-}
-#endif
-
-} // namespace
-
-class DnsConfigServicePosix::Watcher {
- public:
- explicit Watcher(DnsConfigServicePosix* service)
- : service_(service),
- weak_factory_(this) {}
- ~Watcher() {}
-
- bool Watch() {
- bool success = true;
- if (!config_watcher_.Watch(base::Bind(&Watcher::OnConfigChanged,
- base::Unretained(this)))) {
- LOG(ERROR) << "DNS config watch failed to start.";
- success = false;
- UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus",
- DNS_CONFIG_WATCH_FAILED_TO_START_CONFIG,
- DNS_CONFIG_WATCH_MAX);
- }
- if (!hosts_watcher_.Watch(base::FilePath(kFilePathHosts), false,
- base::Bind(&Watcher::OnHostsChanged,
- base::Unretained(this)))) {
- LOG(ERROR) << "DNS hosts watch failed to start.";
- success = false;
- UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus",
- DNS_CONFIG_WATCH_FAILED_TO_START_HOSTS,
- DNS_CONFIG_WATCH_MAX);
- }
- return success;
- }
-
- private:
- void OnConfigChanged(bool succeeded) {
- // Ignore transient flutter of resolv.conf by delaying the signal a bit.
- const base::TimeDelta kDelay = base::TimeDelta::FromMilliseconds(50);
- base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&Watcher::OnConfigChangedDelayed,
- weak_factory_.GetWeakPtr(),
- succeeded),
- kDelay);
- }
- void OnConfigChangedDelayed(bool succeeded) {
- service_->OnConfigChanged(succeeded);
- }
- void OnHostsChanged(const base::FilePath& path, bool error) {
- service_->OnHostsChanged(!error);
- }
-
- DnsConfigServicePosix* service_;
- DnsConfigWatcher config_watcher_;
- base::FilePathWatcher hosts_watcher_;
-
- base::WeakPtrFactory<Watcher> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(Watcher);
-};
-
-// A SerialWorker that uses libresolv to initialize res_state and converts
-// it to DnsConfig (except on Android, where it reads system properties
-// net.dns1 and net.dns2; see #if around ReadDnsConfig above.)
-class DnsConfigServicePosix::ConfigReader : public SerialWorker {
- public:
- explicit ConfigReader(DnsConfigServicePosix* service)
- : service_(service), success_(false) {}
-
- void DoWork() override {
- base::TimeTicks start_time = base::TimeTicks::Now();
- ConfigParsePosixResult result = ReadDnsConfig(&dns_config_);
- switch (result) {
- case CONFIG_PARSE_POSIX_MISSING_OPTIONS:
- case CONFIG_PARSE_POSIX_UNHANDLED_OPTIONS:
- DCHECK(dns_config_.unhandled_options);
- // Fall through.
- case CONFIG_PARSE_POSIX_OK:
- success_ = true;
- break;
- default:
- success_ = false;
- break;
- }
- UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ConfigParsePosix",
- result, CONFIG_PARSE_POSIX_MAX);
- UMA_HISTOGRAM_BOOLEAN("AsyncDNS.ConfigParseResult", success_);
- UMA_HISTOGRAM_TIMES("AsyncDNS.ConfigParseDuration",
- base::TimeTicks::Now() - start_time);
- }
-
- void OnWorkFinished() override {
- DCHECK(!IsCancelled());
- if (success_) {
- service_->OnConfigRead(dns_config_);
- } else {
- LOG(WARNING) << "Failed to read DnsConfig.";
- }
- }
-
- private:
- ~ConfigReader() override {}
-
- DnsConfigServicePosix* service_;
- // Written in DoWork, read in OnWorkFinished, no locking necessary.
- DnsConfig dns_config_;
- bool success_;
-
- DISALLOW_COPY_AND_ASSIGN(ConfigReader);
-};
-
-// A SerialWorker that reads the HOSTS file and runs Callback.
-class DnsConfigServicePosix::HostsReader : public SerialWorker {
- public:
- explicit HostsReader(DnsConfigServicePosix* service)
- : service_(service), path_(kFilePathHosts), success_(false) {}
-
- private:
- ~HostsReader() override {}
-
- void DoWork() override {
- base::TimeTicks start_time = base::TimeTicks::Now();
- success_ = ParseHostsFile(path_, &hosts_);
- UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HostParseResult", success_);
- UMA_HISTOGRAM_TIMES("AsyncDNS.HostsParseDuration",
- base::TimeTicks::Now() - start_time);
- }
-
- void OnWorkFinished() override {
- if (success_) {
- service_->OnHostsRead(hosts_);
- } else {
- LOG(WARNING) << "Failed to read DnsHosts.";
- }
- }
-
- DnsConfigServicePosix* service_;
- const base::FilePath path_;
- // Written in DoWork, read in OnWorkFinished, no locking necessary.
- DnsHosts hosts_;
- bool success_;
-
- DISALLOW_COPY_AND_ASSIGN(HostsReader);
-};
-
-DnsConfigServicePosix::DnsConfigServicePosix()
- : config_reader_(new ConfigReader(this)),
- hosts_reader_(new HostsReader(this)) {}
-
-DnsConfigServicePosix::~DnsConfigServicePosix() {
- config_reader_->Cancel();
- hosts_reader_->Cancel();
-}
-
-void DnsConfigServicePosix::ReadNow() {
- config_reader_->WorkNow();
- hosts_reader_->WorkNow();
-}
-
-bool DnsConfigServicePosix::StartWatching() {
- // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139
- watcher_.reset(new Watcher(this));
- UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", DNS_CONFIG_WATCH_STARTED,
- DNS_CONFIG_WATCH_MAX);
- return watcher_->Watch();
-}
-
-void DnsConfigServicePosix::OnConfigChanged(bool succeeded) {
- InvalidateConfig();
- if (succeeded) {
- config_reader_->WorkNow();
- } else {
- LOG(ERROR) << "DNS config watch failed.";
- set_watch_failed(true);
- UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus",
- DNS_CONFIG_WATCH_FAILED_CONFIG,
- DNS_CONFIG_WATCH_MAX);
- }
-}
-
-void DnsConfigServicePosix::OnHostsChanged(bool succeeded) {
- InvalidateHosts();
- if (succeeded) {
- hosts_reader_->WorkNow();
- } else {
- LOG(ERROR) << "DNS hosts watch failed.";
- set_watch_failed(true);
- UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus",
- DNS_CONFIG_WATCH_FAILED_HOSTS,
- DNS_CONFIG_WATCH_MAX);
- }
-}
-
-#if !defined(OS_ANDROID)
-ConfigParsePosixResult ConvertResStateToDnsConfig(const struct __res_state& res,
- DnsConfig* dns_config) {
- CHECK(dns_config != NULL);
- if (!(res.options & RES_INIT))
- return CONFIG_PARSE_POSIX_RES_INIT_UNSET;
-
- dns_config->nameservers.clear();
-
-#if defined(OS_MACOSX) || defined(OS_FREEBSD)
- union res_sockaddr_union addresses[MAXNS];
- int nscount = res_getservers(const_cast<res_state>(&res), addresses, MAXNS);
- DCHECK_GE(nscount, 0);
- DCHECK_LE(nscount, MAXNS);
- for (int i = 0; i < nscount; ++i) {
- IPEndPoint ipe;
- if (!ipe.FromSockAddr(
- reinterpret_cast<const struct sockaddr*>(&addresses[i]),
- sizeof addresses[i])) {
- return CONFIG_PARSE_POSIX_BAD_ADDRESS;
- }
- dns_config->nameservers.push_back(ipe);
- }
-#elif defined(OS_LINUX)
- static_assert(arraysize(res.nsaddr_list) >= MAXNS &&
- arraysize(res._u._ext.nsaddrs) >= MAXNS,
- "incompatible libresolv res_state");
- DCHECK_LE(res.nscount, MAXNS);
- // Initially, glibc stores IPv6 in |_ext.nsaddrs| and IPv4 in |nsaddr_list|.
- // In res_send.c:res_nsend, it merges |nsaddr_list| into |nsaddrs|,
- // but we have to combine the two arrays ourselves.
- for (int i = 0; i < res.nscount; ++i) {
- IPEndPoint ipe;
- const struct sockaddr* addr = NULL;
- size_t addr_len = 0;
- if (res.nsaddr_list[i].sin_family) { // The indicator used by res_nsend.
- addr = reinterpret_cast<const struct sockaddr*>(&res.nsaddr_list[i]);
- addr_len = sizeof res.nsaddr_list[i];
- } else if (res._u._ext.nsaddrs[i] != NULL) {
- addr = reinterpret_cast<const struct sockaddr*>(res._u._ext.nsaddrs[i]);
- addr_len = sizeof *res._u._ext.nsaddrs[i];
- } else {
- return CONFIG_PARSE_POSIX_BAD_EXT_STRUCT;
- }
- if (!ipe.FromSockAddr(addr, addr_len))
- return CONFIG_PARSE_POSIX_BAD_ADDRESS;
- dns_config->nameservers.push_back(ipe);
- }
-#else // !(defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_FREEBSD))
- DCHECK_LE(res.nscount, MAXNS);
- for (int i = 0; i < res.nscount; ++i) {
- IPEndPoint ipe;
- if (!ipe.FromSockAddr(
- reinterpret_cast<const struct sockaddr*>(&res.nsaddr_list[i]),
- sizeof res.nsaddr_list[i])) {
- return CONFIG_PARSE_POSIX_BAD_ADDRESS;
- }
- dns_config->nameservers.push_back(ipe);
- }
-#endif
-
- dns_config->search.clear();
- for (int i = 0; (i < MAXDNSRCH) && res.dnsrch[i]; ++i) {
- dns_config->search.push_back(std::string(res.dnsrch[i]));
- }
-
- dns_config->ndots = res.ndots;
- dns_config->timeout = base::TimeDelta::FromSeconds(res.retrans);
- dns_config->attempts = res.retry;
-#if defined(RES_ROTATE)
- dns_config->rotate = res.options & RES_ROTATE;
-#endif
-#if defined(RES_USE_EDNS0)
- dns_config->edns0 = res.options & RES_USE_EDNS0;
-#endif
-#if !defined(RES_USE_DNSSEC)
- // Some versions of libresolv don't have support for the DO bit. In this
- // case, we proceed without it.
- static const int RES_USE_DNSSEC = 0;
-#endif
-
- // The current implementation assumes these options are set. They normally
- // cannot be overwritten by /etc/resolv.conf
- unsigned kRequiredOptions = RES_RECURSE | RES_DEFNAMES | RES_DNSRCH;
- if ((res.options & kRequiredOptions) != kRequiredOptions) {
- dns_config->unhandled_options = true;
- return CONFIG_PARSE_POSIX_MISSING_OPTIONS;
- }
-
- unsigned kUnhandledOptions = RES_USEVC | RES_IGNTC | RES_USE_DNSSEC;
- if (res.options & kUnhandledOptions) {
- dns_config->unhandled_options = true;
- return CONFIG_PARSE_POSIX_UNHANDLED_OPTIONS;
- }
-
- if (dns_config->nameservers.empty())
- return CONFIG_PARSE_POSIX_NO_NAMESERVERS;
-
- // 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
- const IPAddressNumber kEmptyAddress(kIPv4AddressSize);
- for (unsigned i = 0; i < dns_config->nameservers.size(); ++i) {
- if (dns_config->nameservers[i].address() == kEmptyAddress)
- return CONFIG_PARSE_POSIX_NULL_ADDRESS;
- }
- return CONFIG_PARSE_POSIX_OK;
-}
-#endif // !defined(OS_ANDROID)
-
-} // namespace internal
-
-// static
-scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() {
- return scoped_ptr<DnsConfigService>(new internal::DnsConfigServicePosix());
-}
-
-} // namespace net
« no previous file with comments | « net/dns/dns_config_service_posix.h ('k') | net/dns/dns_config_service_posix_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698