diff options
Diffstat (limited to 'chromium/net/dns/dns_config_service_posix.cc')
-rw-r--r-- | chromium/net/dns/dns_config_service_posix.cc | 106 |
1 files changed, 84 insertions, 22 deletions
diff --git a/chromium/net/dns/dns_config_service_posix.cc b/chromium/net/dns/dns_config_service_posix.cc index b352d3269c0..2c298ddedbb 100644 --- a/chromium/net/dns/dns_config_service_posix.cc +++ b/chromium/net/dns/dns_config_service_posix.cc @@ -25,19 +25,28 @@ #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 { -#if !defined(OS_ANDROID) 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 plublic API to watch the DNS configuration on iOS. +// There is no public API to watch the DNS configuration on iOS. class DnsConfigWatcher { public: typedef base::Callback<void(bool succeeded)> CallbackType; @@ -47,6 +56,32 @@ class DnsConfigWatcher { } }; +#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); + } + + virtual ~DnsConfigWatcher() { + NetworkChangeNotifier::RemoveNetworkChangeObserver(this); + } + + bool Watch(const base::Callback<void(bool succeeded)>& callback) { + callback_ = callback; + return true; + } + + virtual 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}. @@ -78,6 +113,7 @@ class DnsConfigWatcher { }; #endif +#if !defined(OS_ANDROID) ConfigParsePosixResult ReadDnsConfig(DnsConfig* config) { ConfigParsePosixResult result; config->unhandled_options = false; @@ -122,14 +158,52 @@ ConfigParsePosixResult ReadDnsConfig(DnsConfig* config) { 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) - : weak_factory_(this), - service_(service) {} + : service_(service), + weak_factory_(this) {} ~Watcher() {} bool Watch() { @@ -172,16 +246,18 @@ class DnsConfigServicePosix::Watcher { service_->OnHostsChanged(!error); } - base::WeakPtrFactory<Watcher> weak_factory_; 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. +// 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) @@ -311,6 +387,7 @@ void DnsConfigServicePosix::OnHostsChanged(bool succeeded) { } } +#if !defined(OS_ANDROID) ConfigParsePosixResult ConvertResStateToDnsConfig(const struct __res_state& res, DnsConfig* dns_config) { CHECK(dns_config != NULL); @@ -410,6 +487,7 @@ ConfigParsePosixResult ConvertResStateToDnsConfig(const struct __res_state& res, } return CONFIG_PARSE_POSIX_OK; } +#endif // !defined(OS_ANDROID) } // namespace internal @@ -418,20 +496,4 @@ scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { return scoped_ptr<DnsConfigService>(new internal::DnsConfigServicePosix()); } -#else // defined(OS_ANDROID) -// Android NDK provides only a stub <resolv.h> header. -class StubDnsConfigService : public DnsConfigService { - public: - StubDnsConfigService() {} - virtual ~StubDnsConfigService() {} - private: - virtual void ReadNow() OVERRIDE {} - virtual bool StartWatching() OVERRIDE { return false; } -}; -// static -scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { - return scoped_ptr<DnsConfigService>(new StubDnsConfigService()); -} -#endif - } // namespace net |