summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/android/network_change_notifier_android.cc36
-rw-r--r--net/android/network_change_notifier_android.h3
-rw-r--r--net/dns/dns_config_service_posix.cc97
-rw-r--r--net/dns/dns_config_service_posix.h4
-rw-r--r--net/dns/dns_config_service_posix_unittest.cc4
-rw-r--r--net/dns/dns_config_watcher_mac.cc2
-rw-r--r--net/dns/dns_config_watcher_mac.h2
7 files changed, 127 insertions, 21 deletions
diff --git a/net/android/network_change_notifier_android.cc b/net/android/network_change_notifier_android.cc
index d4e1a5c..e0f5244 100644
--- a/net/android/network_change_notifier_android.cc
+++ b/net/android/network_change_notifier_android.cc
@@ -59,8 +59,39 @@
#include "net/android/network_change_notifier_android.h"
+#include "base/threading/thread.h"
+#include "net/dns/dns_config_service.h"
+
namespace net {
+// Thread on which we can run DnsConfigService, which requires a TYPE_IO
+// message loop to monitor /system/etc/hosts.
+class NetworkChangeNotifierAndroid::DnsConfigServiceThread
+ : public base::Thread {
+ public:
+ DnsConfigServiceThread() : base::Thread("DnsConfigService") {}
+
+ virtual ~DnsConfigServiceThread() {
+ Stop();
+ }
+
+ virtual void Init() OVERRIDE {
+ dns_config_service_ = DnsConfigService::CreateSystemService();
+ dns_config_service_->WatchConfig(
+ base::Bind(&NetworkChangeNotifier::SetDnsConfig));
+ }
+
+ virtual void CleanUp() OVERRIDE {
+ dns_config_service_.reset();
+ }
+
+ private:
+ scoped_ptr<DnsConfigService> dns_config_service_;
+
+ DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceThread);
+};
+
+
NetworkChangeNotifierAndroid::~NetworkChangeNotifierAndroid() {
delegate_->RemoveObserver(this);
}
@@ -83,8 +114,11 @@ bool NetworkChangeNotifierAndroid::Register(JNIEnv* env) {
NetworkChangeNotifierAndroid::NetworkChangeNotifierAndroid(
NetworkChangeNotifierDelegateAndroid* delegate)
: NetworkChangeNotifier(NetworkChangeCalculatorParamsAndroid()),
- delegate_(delegate) {
+ delegate_(delegate),
+ dns_config_service_thread_(new DnsConfigServiceThread()) {
delegate_->AddObserver(this);
+ dns_config_service_thread_->StartWithOptions(
+ base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
}
// static
diff --git a/net/android/network_change_notifier_android.h b/net/android/network_change_notifier_android.h
index f167cfc..e82b852 100644
--- a/net/android/network_change_notifier_android.h
+++ b/net/android/network_change_notifier_android.h
@@ -56,12 +56,15 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierAndroid
friend class NetworkChangeNotifierAndroidTest;
friend class NetworkChangeNotifierFactoryAndroid;
+ class DnsConfigServiceThread;
+
explicit NetworkChangeNotifierAndroid(
NetworkChangeNotifierDelegateAndroid* delegate);
static NetworkChangeCalculatorParams NetworkChangeCalculatorParamsAndroid();
NetworkChangeNotifierDelegateAndroid* const delegate_;
+ scoped_ptr<DnsConfigServiceThread> dns_config_service_thread_;
DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierAndroid);
};
diff --git a/net/dns/dns_config_service_posix.cc b/net/dns/dns_config_service_posix.cc
index 8dcec23..0644d4d 100644
--- a/net/dns/dns_config_service_posix.cc
+++ b/net/dns/dns_config_service_posix.cc
@@ -25,15 +25,24 @@
#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)
@@ -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,6 +158,44 @@ 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
@@ -181,7 +255,8 @@ class DnsConfigServicePosix::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 +386,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 +486,7 @@ ConfigParsePosixResult ConvertResStateToDnsConfig(const struct __res_state& res,
}
return CONFIG_PARSE_POSIX_OK;
}
+#endif // !defined(OS_ANDROID)
} // namespace internal
@@ -418,20 +495,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
diff --git a/net/dns/dns_config_service_posix.h b/net/dns/dns_config_service_posix.h
index be19ab9..ef28154 100644
--- a/net/dns/dns_config_service_posix.h
+++ b/net/dns/dns_config_service_posix.h
@@ -5,9 +5,11 @@
#ifndef NET_DNS_DNS_CONFIG_SERVICE_POSIX_H_
#define NET_DNS_DNS_CONFIG_SERVICE_POSIX_H_
+#if !defined(OS_ANDROID)
#include <sys/types.h>
#include <netinet/in.h>
#include <resolv.h>
+#endif
#include "base/compiler_specific.h"
#include "net/base/net_export.h"
@@ -57,9 +59,11 @@ enum ConfigParsePosixResult {
CONFIG_PARSE_POSIX_MAX // Bounding values for enumeration.
};
+#if !defined(OS_ANDROID)
// Fills in |dns_config| from |res|.
ConfigParsePosixResult NET_EXPORT_PRIVATE ConvertResStateToDnsConfig(
const struct __res_state& res, DnsConfig* dns_config);
+#endif
} // namespace internal
diff --git a/net/dns/dns_config_service_posix_unittest.cc b/net/dns/dns_config_service_posix_unittest.cc
index 92e46ed..1bfbe08 100644
--- a/net/dns/dns_config_service_posix_unittest.cc
+++ b/net/dns/dns_config_service_posix_unittest.cc
@@ -9,6 +9,8 @@
#include "testing/gtest/include/gtest/gtest.h"
+#if !defined(OS_ANDROID)
+
namespace net {
namespace {
@@ -154,3 +156,5 @@ TEST(DnsConfigServicePosixTest, RejectEmptyNameserver) {
} // namespace
} // namespace net
+
+#endif // !OS_ANDROID
diff --git a/net/dns/dns_config_watcher_mac.cc b/net/dns/dns_config_watcher_mac.cc
index a92db0c..0139472 100644
--- a/net/dns/dns_config_watcher_mac.cc
+++ b/net/dns/dns_config_watcher_mac.cc
@@ -102,5 +102,5 @@ ConfigParsePosixResult DnsConfigWatcher::CheckDnsConfig() {
return CONFIG_PARSE_POSIX_OK;
}
-} // naespace internal
+} // namespace internal
} // namespace net
diff --git a/net/dns/dns_config_watcher_mac.h b/net/dns/dns_config_watcher_mac.h
index 0c3fc6a..d3e9924 100644
--- a/net/dns/dns_config_watcher_mac.h
+++ b/net/dns/dns_config_watcher_mac.h
@@ -22,5 +22,5 @@ class DnsConfigWatcher {
NotifyWatcherMac watcher_;
};
-} // naespace internal
+} // namespace internal
} // namespace net