summaryrefslogtreecommitdiffstats
path: root/chromium/net/dns/dns_config_service_posix.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/dns/dns_config_service_posix.cc')
-rw-r--r--chromium/net/dns/dns_config_service_posix.cc106
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