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

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

Issue 10873018: [net] Move DnsConfigService to NetworkChangeNotifier. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add comment Created 8 years, 3 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/files/file_path_watcher.h"
15 #include "base/file_path.h"
16 #include "base/logging.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/synchronization/lock.h"
19 #include "base/threading/non_thread_safe.h"
20 #include "base/win/object_watcher.h"
21 #include "base/win/registry.h"
22 #include "net/base/net_util.h"
23 #include "net/base/network_change_notifier.h"
24 #include "net/dns/dns_config_service_win.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 && key_.Valid()) {
57 watcher_.StopWatching();
58 key_.StopWatching();
59 key_.Close();
60 }
61 if (!callback_.is_null())
62 callback_.Run(succeeded);
63 }
64
65 private:
66 CallbackType callback_;
67 base::win::RegKey key_;
68 base::win::ObjectWatcher watcher_;
69
70 DISALLOW_COPY_AND_ASSIGN(RegistryWatcher);
71 };
72
73 } // namespace
74
75 // Watches registry for changes. Setting up watches requires IO loop.
76 class DnsConfigWatcher::Core {
77 public:
78 Core() {}
79 ~Core() {}
80
81 bool Watch() {
82 RegistryWatcher::CallbackType callback =
83 base::Bind(&Core::OnRegistryChanged, base::Unretained(this));
84
85 bool success = true;
86
87 // The Tcpip key must be present.
88 if (!tcpip_watcher_.Watch(kTcpipPath, callback)) {
89 LOG(ERROR) << "DNS registry watch failed to start.";
90 success = false;
91 }
92
93 // Watch for IPv6 nameservers.
94 tcpip6_watcher_.Watch(kTcpip6Path, callback);
95
96 // DNS suffix search list and devolution can be configured via group
97 // policy which sets this registry key. If the key is missing, the policy
98 // does not apply, and the DNS client uses Tcpip and Dnscache settings.
99 // If a policy is installed, DnsConfigService will need to be restarted.
100 // BUG=99509
101
102 dnscache_watcher_.Watch(kDnscachePath, callback);
103 policy_watcher_.Watch(kPolicyPath, callback);
104
105 if (!hosts_watcher_.Watch(GetHostsPath(),
106 base::Bind(&Core::OnHostsChanged,
107 base::Unretained(this)))) {
108 LOG(ERROR) << "DNS hosts watch failed to start.";
109 success = false;
110 }
111 return success;
112 }
113
114 private:
115 void OnRegistryChanged(bool succeeded) {
116 if (succeeded) {
117 NetworkChangeNotifier::NotifyObserversOfDNSChange(
118 NetworkChangeNotifier::CHANGE_DNS_SETTINGS);
119 } else {
120 LOG(ERROR) << "DNS config watch failed.";
121 NetworkChangeNotifier::NotifyObserversOfDNSChange(
122 NetworkChangeNotifier::CHANGE_DNS_WATCH_FAILED);
123 }
124 }
125
126 void OnHostsChanged(const FilePath& path, bool error) {
127 if (!error) {
128 NetworkChangeNotifier::NotifyObserversOfDNSChange(
129 NetworkChangeNotifier::CHANGE_DNS_HOSTS);
130 } else {
131 LOG(ERROR) << "DNS hosts watch failed.";
132 NetworkChangeNotifier::NotifyObserversOfDNSChange(
133 NetworkChangeNotifier::CHANGE_DNS_WATCH_FAILED);
134 }
135 }
136
137 RegistryWatcher tcpip_watcher_;
138 RegistryWatcher tcpip6_watcher_;
139 RegistryWatcher dnscache_watcher_;
140 RegistryWatcher policy_watcher_;
141 base::files::FilePathWatcher hosts_watcher_;
142
143 DISALLOW_COPY_AND_ASSIGN(Core);
144 };
145
146 DnsConfigWatcher::DnsConfigWatcher() {}
147
148 DnsConfigWatcher::~DnsConfigWatcher() {}
149
150 void DnsConfigWatcher::Init() {
151 core_.reset(new Core());
152 if (core_->Watch()) {
153 NetworkChangeNotifier::NotifyObserversOfDNSChange(
154 NetworkChangeNotifier::CHANGE_DNS_WATCH_STARTED);
155 }
156 // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139
157 }
158
159 void DnsConfigWatcher::CleanUp() {
160 core_.reset();
161 }
162
163 } // namespace internal
164 } // namespace net
165
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