diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/android/network_change_notifier_android.cc | 36 | ||||
-rw-r--r-- | net/android/network_change_notifier_android.h | 3 | ||||
-rw-r--r-- | net/dns/dns_config_service_posix.cc | 97 | ||||
-rw-r--r-- | net/dns/dns_config_service_posix.h | 4 | ||||
-rw-r--r-- | net/dns/dns_config_service_posix_unittest.cc | 4 | ||||
-rw-r--r-- | net/dns/dns_config_watcher_mac.cc | 2 | ||||
-rw-r--r-- | net/dns/dns_config_watcher_mac.h | 2 |
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 |