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

Unified Diff: net/dns/dns_config_service_win.cc

Issue 10873018: [net] Move DnsConfigService to NetworkChangeNotifier. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more fixes for mac Created 8 years, 4 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
Index: net/dns/dns_config_service_win.cc
diff --git a/net/dns/dns_config_service_win.cc b/net/dns/dns_config_service_win.cc
index 54ef1c0d397fe2316df94e987235c34b89116698..01f9be50225fd237b9483146b44d16385d708bd3 100644
--- a/net/dns/dns_config_service_win.cc
+++ b/net/dns/dns_config_service_win.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/files/file_path_watcher.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
@@ -21,11 +22,11 @@
#include "base/threading/thread_restrictions.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
+#include "base/win/object_watcher.h"
#include "base/win/registry.h"
#include "base/win/windows_version.h"
#include "googleurl/src/url_canon.h"
#include "net/base/net_util.h"
-#include "net/base/network_change_notifier.h"
#include "net/dns/dns_hosts.h"
#include "net/dns/dns_protocol.h"
#include "net/dns/serial_worker.h"
@@ -272,6 +273,48 @@ HostsParseWinResult AddLocalhostEntries(DnsHosts* hosts) {
return HOSTS_PARSE_WIN_OK;
}
+// Watches a single registry key for changes.
+class RegistryWatcher : public base::win::ObjectWatcher::Delegate,
+ public base::NonThreadSafe {
+ public:
+ typedef base::Callback<void(bool succeeded)> CallbackType;
+ RegistryWatcher() {}
+
+ bool Watch(const wchar_t* key, const CallbackType& callback) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(!callback.is_null());
+ DCHECK(callback_.is_null());
+ callback_ = callback;
+ if (key_.Open(HKEY_LOCAL_MACHINE, key, KEY_NOTIFY) != ERROR_SUCCESS)
+ return false;
+ if (key_.StartWatching() != ERROR_SUCCESS)
+ return false;
+ if (!watcher_.StartWatching(key_.watch_event(), this))
+ return false;
+ return true;
+ }
+
+ virtual void OnObjectSignaled(HANDLE object) OVERRIDE {
+ DCHECK(CalledOnValidThread());
+ bool succeeded = (key_.StartWatching() == ERROR_SUCCESS) &&
+ watcher_.StartWatching(key_.watch_event(), this);
+ if (!succeeded && key_.Valid()) {
+ watcher_.StopWatching();
+ key_.StopWatching();
+ key_.Close();
+ }
+ if (!callback_.is_null())
+ callback_.Run(succeeded);
+ }
+
+ private:
+ CallbackType callback_;
+ base::win::RegKey key_;
+ base::win::ObjectWatcher watcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(RegistryWatcher);
+};
+
} // namespace
FilePath GetHostsPath() {
@@ -450,6 +493,63 @@ ConfigParseWinResult ConvertSettingsToDnsConfig(
return CONFIG_PARSE_WIN_OK;
}
+// Watches registry and HOSTS file for changes. Setting up watches requires
+// IO loop.
+class DnsConfigServiceWin::Watcher {
pauljensen 2012/08/27 21:44:10 Why is DnsConfigServiceWin::Watcher a separate cla
szym 2012/08/27 21:49:20 The primary reason is that this is a direct copy f
+ public:
+ explicit Watcher(DnsConfigServiceWin* service) : service_(service) {}
+ ~Watcher() {}
+
+ bool Watch() {
+ RegistryWatcher::CallbackType callback =
+ base::Bind(&DnsConfigServiceWin::OnConfigChanged,
+ base::Unretained(service_));
+
+ bool success = true;
+
+ // The Tcpip key must be present.
+ if (!tcpip_watcher_.Watch(kTcpipPath, callback)) {
+ LOG(ERROR) << "DNS registry watch failed to start.";
+ success = false;
+ }
+
+ // Watch for IPv6 nameservers.
+ tcpip6_watcher_.Watch(kTcpip6Path, callback);
+
+ // DNS suffix search list and devolution can be configured via group
+ // policy which sets this registry key. If the key is missing, the policy
+ // does not apply, and the DNS client uses Tcpip and Dnscache settings.
+ // If a policy is installed, DnsConfigService will need to be restarted.
+ // BUG=99509
+
+ dnscache_watcher_.Watch(kDnscachePath, callback);
+ policy_watcher_.Watch(kPolicyPath, callback);
+
+ if (!hosts_watcher_.Watch(GetHostsPath(),
+ base::Bind(&Watcher::OnHostsChanged,
+ base::Unretained(this)))) {
+ LOG(ERROR) << "DNS hosts watch failed to start.";
+ success = false;
+ }
+ return success;
+ }
+
+ private:
+ void OnHostsChanged(const FilePath& path, bool error) {
+ service_->OnHostsChanged(!error);
+ }
+
+ DnsConfigServiceWin* service_;
+
+ RegistryWatcher tcpip_watcher_;
+ RegistryWatcher tcpip6_watcher_;
+ RegistryWatcher dnscache_watcher_;
+ RegistryWatcher policy_watcher_;
+ base::files::FilePathWatcher hosts_watcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(Watcher);
+};
+
// Reads config from registry and IpHelper. All work performed on WorkerPool.
class DnsConfigServiceWin::ConfigReader : public SerialWorker {
public:
@@ -541,7 +641,8 @@ class DnsConfigServiceWin::HostsReader : public SerialWorker {
};
DnsConfigServiceWin::DnsConfigServiceWin()
- : config_reader_(new ConfigReader(this)),
+ : watcher_(new Watcher(this)),
+ config_reader_(new ConfigReader(this)),
hosts_reader_(new HostsReader(this)) {}
DnsConfigServiceWin::~DnsConfigServiceWin() {
@@ -550,37 +651,46 @@ DnsConfigServiceWin::~DnsConfigServiceWin() {
NetworkChangeNotifier::RemoveIPAddressObserver(this);
}
-void DnsConfigServiceWin::Watch(const CallbackType& callback) {
- DnsConfigService::Watch(callback);
+void DnsConfigServiceWin::ReadNow() {
+ config_reader_->WorkNow();
+ hosts_reader_->WorkNow();
+}
+
+bool DnsConfigServiceWin::StartWatching() {
// Also need to observe changes to local non-loopback IP for DnsHosts.
NetworkChangeNotifier::AddIPAddressObserver(this);
+ // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139
+ return watcher_->Watch();
}
-void DnsConfigServiceWin::OnDNSChanged(unsigned detail) {
- if (detail & NetworkChangeNotifier::CHANGE_DNS_WATCH_FAILED) {
- InvalidateConfig();
- InvalidateHosts();
- // We don't trust a config that we cannot watch in the future.
- config_reader_->Cancel();
- hosts_reader_->Cancel();
- return;
- }
- if (detail & NetworkChangeNotifier::CHANGE_DNS_WATCH_STARTED)
- detail = ~0; // Assume everything changed.
- if (detail & NetworkChangeNotifier::CHANGE_DNS_SETTINGS) {
- InvalidateConfig();
+void DnsConfigServiceWin::OnIPAddressChanged() {
+ // Need to update non-loopback IP of local host.
+ OnHostsChanged(true);
+}
+
+void DnsConfigServiceWin::OnConfigChanged(bool succeeded) {
+ InvalidateConfig();
+ if (succeeded) {
config_reader_->WorkNow();
- }
- if (detail & NetworkChangeNotifier::CHANGE_DNS_HOSTS) {
- InvalidateHosts();
- hosts_reader_->WorkNow();
+ } else {
+ LOG(ERROR) << "DNS config watch failed.";
+ // Don't trust the result if the watcher failed.
+ // Note: The SerialWorker will need to be re-constructed to accept new jobs.
+ config_reader_->Cancel();
}
}
-void DnsConfigServiceWin::OnIPAddressChanged() {
- // Need to update non-loopback IP of local host.
- if (NetworkChangeNotifier::IsWatchingDNS())
- OnDNSChanged(NetworkChangeNotifier::CHANGE_DNS_HOSTS);
+void DnsConfigServiceWin::OnHostsChanged(bool succeeded) {
+ InvalidateHosts();
+ if (succeeded) {
+ hosts_reader_->WorkNow();
+ } else {
+ LOG(ERROR) << "DNS hosts watch failed.";
+ // Don't trust the result if the watcher failed.
+ // Note: The SerialWorker will need to be re-constructed to accept new jobs.
+ hosts_reader_->Cancel();
+ NetworkChangeNotifier::RemoveIPAddressObserver(this);
+ }
}
} // namespace internal

Powered by Google App Engine
This is Rietveld 408576698