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

Side by Side Diff: net/dns/dns_config_watcher_win.cc

Issue 10377092: [net/dns] Isolate DnsConfigWatcher from DnsConfigService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added sanity DCHECK. Created 8 years, 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/dns/dns_config_watcher_posix.cc ('k') | net/dns/dns_test_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/dns/dns_config_watcher.h"
6
7 #include <winsock2.h>
8
9 #include <string>
10
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/compiler_specific.h"
14 #include "base/file_path.h"
15 #include "base/logging.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/synchronization/lock.h"
18 #include "base/threading/non_thread_safe.h"
19 #include "base/win/object_watcher.h"
20 #include "base/win/registry.h"
21 #include "net/base/net_util.h"
22 #include "net/base/network_change_notifier.h"
23 #include "net/dns/dns_config_service_win.h"
24 #include "net/dns/file_path_watcher_wrapper.h"
25
26 namespace net {
27 namespace internal {
28
29 namespace {
30
31 // Watches a single registry key for changes.
32 class RegistryWatcher : public base::win::ObjectWatcher::Delegate,
33 public base::NonThreadSafe {
34 public:
35 typedef base::Callback<void(bool succeeded)> CallbackType;
36 RegistryWatcher() {}
37
38 bool Watch(const wchar_t* key, const CallbackType& callback) {
39 DCHECK(CalledOnValidThread());
40 DCHECK(!callback.is_null());
41 DCHECK(callback_.is_null());
42 callback_ = callback;
43 if (key_.Open(HKEY_LOCAL_MACHINE, key, KEY_NOTIFY) != ERROR_SUCCESS)
44 return false;
45 if (key_.StartWatching() != ERROR_SUCCESS)
46 return false;
47 if (!watcher_.StartWatching(key_.watch_event(), this))
48 return false;
49 return true;
50 }
51
52 virtual void OnObjectSignaled(HANDLE object) OVERRIDE {
53 DCHECK(CalledOnValidThread());
54 bool succeeded = (key_.StartWatching() == ERROR_SUCCESS) &&
55 watcher_.StartWatching(key_.watch_event(), this);
56 if (!succeeded) {
57 if (key_.Valid()) {
58 watcher_.StopWatching();
59 key_.StopWatching();
60 key_.Close();
61 }
62 }
63 if (!callback_.is_null())
64 callback_.Run(succeeded);
65 }
66
67 private:
68 CallbackType callback_;
69 base::win::RegKey key_;
70 base::win::ObjectWatcher watcher_;
71
72 DISALLOW_COPY_AND_ASSIGN(RegistryWatcher);
73 };
74
75 } // namespace
76
77 // Watches registry for changes. Setting up watches requires IO loop.
78 class DnsConfigWatcher::Core {
79 public:
80 Core() {}
81 ~Core() {}
82
83 bool Watch() {
84 RegistryWatcher::CallbackType callback =
85 base::Bind(&Core::OnRegistryChanged, base::Unretained(this));
86
87 bool success = true;
88
89 // The Tcpip key must be present.
90 if (!tcpip_watcher_.Watch(kTcpipPath, callback)) {
91 LOG(ERROR) << "DNS registry watch failed to start.";
92 success = false;
93 }
94
95 // Watch for IPv6 nameservers.
96 tcpip6_watcher_.Watch(kTcpip6Path, callback);
97
98 // DNS suffix search list and devolution can be configured via group
99 // policy which sets this registry key. If the key is missing, the policy
100 // does not apply, and the DNS client uses Tcpip and Dnscache settings.
101 // If a policy is installed, DnsConfigService will need to be restarted.
102 // BUG=99509
103
104 dnscache_watcher_.Watch(kDnscachePath, callback);
105 policy_watcher_.Watch(kPolicyPath, callback);
106
107 if (!hosts_watcher_.Watch(GetHostsPath(),
108 base::Bind(&Core::OnHostsChanged,
109 base::Unretained(this)))) {
110 LOG(ERROR) << "DNS hosts watch failed to start.";
111 success = false;
112 }
113 return success;
114 }
115
116 private:
117 void OnRegistryChanged(bool succeeded) {
118 if (succeeded) {
119 NetworkChangeNotifier::NotifyObserversOfDNSChange(
120 NetworkChangeNotifier::CHANGE_DNS_SETTINGS);
121 } else {
122 LOG(ERROR) << "DNS config watch failed.";
123 NetworkChangeNotifier::NotifyObserversOfDNSChange(
124 NetworkChangeNotifier::CHANGE_DNS_WATCH_FAILED);
125 }
126 }
127
128 void OnHostsChanged(bool succeeded) {
129 if (succeeded) {
130 NetworkChangeNotifier::NotifyObserversOfDNSChange(
131 NetworkChangeNotifier::CHANGE_DNS_HOSTS);
132 } else {
133 LOG(ERROR) << "DNS hosts watch failed.";
134 NetworkChangeNotifier::NotifyObserversOfDNSChange(
135 NetworkChangeNotifier::CHANGE_DNS_WATCH_FAILED);
136 }
137 }
138
139 RegistryWatcher tcpip_watcher_;
140 RegistryWatcher tcpip6_watcher_;
141 RegistryWatcher dnscache_watcher_;
142 RegistryWatcher policy_watcher_;
143 FilePathWatcherWrapper hosts_watcher_;
144
145 DISALLOW_COPY_AND_ASSIGN(Core);
146 };
147
148 DnsConfigWatcher::DnsConfigWatcher() {}
149
150 DnsConfigWatcher::~DnsConfigWatcher() {}
151
152 void DnsConfigWatcher::Init() {
153 core_.reset(new Core());
154 if (core_->Watch()) {
155 NetworkChangeNotifier::NotifyObserversOfDNSChange(
156 NetworkChangeNotifier::CHANGE_DNS_WATCH_STARTED);
157 }
158 // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139
159 }
160
161 void DnsConfigWatcher::CleanUp() {
162 core_.reset();
163 }
164
165 } // namespace internal
166 } // namespace net
167
OLDNEW
« no previous file with comments | « net/dns/dns_config_watcher_posix.cc ('k') | net/dns/dns_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698