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

Side by Side Diff: net/dns/dns_config_service_posix.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_service_posix.h ('k') | net/dns/dns_config_service_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/dns/dns_config_service_posix.h" 5 #include "net/dns/dns_config_service_posix.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/files/file_path_watcher.h"
11 #include "base/file_path.h" 12 #include "base/file_path.h"
12 #include "base/file_util.h" 13 #include "base/file_util.h"
13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
14 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
15 #include "base/time.h" 16 #include "base/time.h"
16 #include "net/base/ip_endpoint.h" 17 #include "net/base/ip_endpoint.h"
17 #include "net/base/net_util.h" 18 #include "net/base/net_util.h"
18 #include "net/dns/dns_hosts.h" 19 #include "net/dns/dns_hosts.h"
19 #include "net/dns/dns_protocol.h" 20 #include "net/dns/dns_protocol.h"
21 #include "net/dns/notify_watcher_mac.h"
20 #include "net/dns/serial_worker.h" 22 #include "net/dns/serial_worker.h"
21 23
22 namespace net { 24 namespace net {
23 25
24 #if !defined(OS_ANDROID) 26 #if !defined(OS_ANDROID)
25 namespace internal { 27 namespace internal {
26 28
27 namespace { 29 namespace {
28 30
31 const FilePath::CharType* kFilePathHosts = FILE_PATH_LITERAL("/etc/hosts");
32
33 #if defined(OS_MACOSX)
34 // From 10.7.3 configd-395.10/dnsinfo/dnsinfo.h
35 static const char* kDnsNotifyKey =
36 "com.apple.system.SystemConfiguration.dns_configuration";
37
38 class ConfigWatcher {
39 public:
40 bool Watch(const base::Callback<void(bool succeeded)>& callback) {
41 return watcher_.Watch(kDnsNotifyKey, callback);
42 }
43
44 private:
45 NotifyWatcherMac watcher_;
46 };
47 #else
48
29 #ifndef _PATH_RESCONF // Normally defined in <resolv.h> 49 #ifndef _PATH_RESCONF // Normally defined in <resolv.h>
30 #define _PATH_RESCONF "/etc/resolv.conf" 50 #define _PATH_RESCONF "/etc/resolv.conf"
31 #endif 51 #endif
32 52
33 const FilePath::CharType* kFilePathHosts = FILE_PATH_LITERAL("/etc/hosts"); 53 static const FilePath::CharType* kFilePathConfig =
54 FILE_PATH_LITERAL(_PATH_RESCONF);
55
56 class ConfigWatcher {
57 public:
58 typedef base::Callback<void(bool succeeded)> CallbackType;
59
60 bool Watch(const CallbackType& callback) {
61 callback_ = callback;
62 return watcher_.Watch(FilePath(kFilePathConfig),
63 base::Bind(&ConfigWatcher::OnCallback,
64 base::Unretained(this)));
65 }
66
67 private:
68 void OnCallback(const FilePath& path, bool error) {
69 callback_.Run(!error);
70 }
71
72 base::files::FilePathWatcher watcher_;
73 CallbackType callback_;
74 };
75 #endif
34 76
35 ConfigParsePosixResult ReadDnsConfig(DnsConfig* config) { 77 ConfigParsePosixResult ReadDnsConfig(DnsConfig* config) {
36 ConfigParsePosixResult result; 78 ConfigParsePosixResult result;
37 #if defined(OS_OPENBSD) 79 #if defined(OS_OPENBSD)
38 // Note: res_ninit in glibc always returns 0 and sets RES_INIT. 80 // Note: res_ninit in glibc always returns 0 and sets RES_INIT.
39 // res_init behaves the same way. 81 // res_init behaves the same way.
40 memset(&_res, 0, sizeof(_res)); 82 memset(&_res, 0, sizeof(_res));
41 if (res_init() == 0) { 83 if (res_init() == 0) {
42 result = ConvertResStateToDnsConfig(_res, config); 84 result = ConvertResStateToDnsConfig(_res, config);
43 } else { 85 } else {
(...skipping 12 matching lines...) Expand all
56 res_ndestroy(&res); 98 res_ndestroy(&res);
57 #else 99 #else
58 res_nclose(&res); 100 res_nclose(&res);
59 #endif 101 #endif
60 #endif 102 #endif
61 // Override timeout value to match default setting on Windows. 103 // Override timeout value to match default setting on Windows.
62 config->timeout = base::TimeDelta::FromSeconds(kDnsTimeoutSeconds); 104 config->timeout = base::TimeDelta::FromSeconds(kDnsTimeoutSeconds);
63 return result; 105 return result;
64 } 106 }
65 107
108 } // namespace
109
110 class DnsConfigServicePosix::Watcher {
111 public:
112 explicit Watcher(DnsConfigServicePosix* service) : service_(service) {}
113 ~Watcher() {}
114
115 bool Watch() {
116 bool success = true;
117 if (!config_watcher_.Watch(
118 base::Bind(&DnsConfigServicePosix::OnConfigChanged,
119 base::Unretained(service_)))) {
120 LOG(ERROR) << "DNS config watch failed to start.";
121 success = false;
122 }
123 if (!hosts_watcher_.Watch(FilePath(kFilePathHosts),
124 base::Bind(&Watcher::OnHostsChanged,
125 base::Unretained(this)))) {
126 LOG(ERROR) << "DNS hosts watch failed to start.";
127 success = false;
128 }
129 return success;
130 }
131
132 private:
133 void OnHostsChanged(const FilePath& path, bool error) {
134 service_->OnHostsChanged(!error);
135 }
136
137 DnsConfigServicePosix* service_;
138 ConfigWatcher config_watcher_;
139 base::files::FilePathWatcher hosts_watcher_;
140
141 DISALLOW_COPY_AND_ASSIGN(Watcher);
142 };
143
66 // A SerialWorker that uses libresolv to initialize res_state and converts 144 // A SerialWorker that uses libresolv to initialize res_state and converts
67 // it to DnsConfig. 145 // it to DnsConfig.
68 class ConfigReader : public SerialWorker { 146 class DnsConfigServicePosix::ConfigReader : public SerialWorker {
69 public: 147 public:
70 typedef base::Callback<void(const DnsConfig& config)> CallbackType; 148 explicit ConfigReader(DnsConfigServicePosix* service)
71 explicit ConfigReader(const CallbackType& callback) 149 : service_(service), success_(false) {}
72 : callback_(callback), success_(false) {}
73 150
74 virtual void DoWork() OVERRIDE { 151 virtual void DoWork() OVERRIDE {
75 base::TimeTicks start_time = base::TimeTicks::Now(); 152 base::TimeTicks start_time = base::TimeTicks::Now();
76 ConfigParsePosixResult result = ReadDnsConfig(&dns_config_); 153 ConfigParsePosixResult result = ReadDnsConfig(&dns_config_);
77 success_ = (result == CONFIG_PARSE_POSIX_OK); 154 success_ = (result == CONFIG_PARSE_POSIX_OK);
78 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ConfigParsePosix", 155 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ConfigParsePosix",
79 result, CONFIG_PARSE_POSIX_MAX); 156 result, CONFIG_PARSE_POSIX_MAX);
80 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.ConfigParseResult", success_); 157 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.ConfigParseResult", success_);
81 UMA_HISTOGRAM_TIMES("AsyncDNS.ConfigParseDuration", 158 UMA_HISTOGRAM_TIMES("AsyncDNS.ConfigParseDuration",
82 base::TimeTicks::Now() - start_time); 159 base::TimeTicks::Now() - start_time);
83 } 160 }
84 161
85 virtual void OnWorkFinished() OVERRIDE { 162 virtual void OnWorkFinished() OVERRIDE {
86 DCHECK(!IsCancelled()); 163 DCHECK(!IsCancelled());
87 if (success_) { 164 if (success_) {
88 callback_.Run(dns_config_); 165 service_->OnConfigRead(dns_config_);
89 } else { 166 } else {
90 LOG(WARNING) << "Failed to read DnsConfig."; 167 LOG(WARNING) << "Failed to read DnsConfig.";
91 } 168 }
92 } 169 }
93 170
94 private: 171 private:
95 virtual ~ConfigReader() {} 172 virtual ~ConfigReader() {}
96 173
97 const CallbackType callback_; 174 DnsConfigServicePosix* service_;
98 // Written in DoWork, read in OnWorkFinished, no locking necessary. 175 // Written in DoWork, read in OnWorkFinished, no locking necessary.
99 DnsConfig dns_config_; 176 DnsConfig dns_config_;
100 bool success_; 177 bool success_;
101 178
102 DISALLOW_COPY_AND_ASSIGN(ConfigReader); 179 DISALLOW_COPY_AND_ASSIGN(ConfigReader);
103 }; 180 };
104 181
105 // A SerialWorker that reads the HOSTS file and runs Callback. 182 // A SerialWorker that reads the HOSTS file and runs Callback.
106 class HostsReader : public SerialWorker { 183 class DnsConfigServicePosix::HostsReader : public SerialWorker {
107 public: 184 public:
108 typedef base::Callback<void(const DnsHosts& hosts)> CallbackType; 185 explicit HostsReader(DnsConfigServicePosix* service)
109 explicit HostsReader(const CallbackType& callback) 186 : service_(service), path_(kFilePathHosts), success_(false) {}
110 : path_(kFilePathHosts), callback_(callback), success_(false) {}
111 187
112 private: 188 private:
113 virtual ~HostsReader() {} 189 virtual ~HostsReader() {}
114 190
115 virtual void DoWork() OVERRIDE { 191 virtual void DoWork() OVERRIDE {
116 base::TimeTicks start_time = base::TimeTicks::Now(); 192 base::TimeTicks start_time = base::TimeTicks::Now();
117 success_ = ParseHostsFile(path_, &hosts_); 193 success_ = ParseHostsFile(path_, &hosts_);
118 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HostParseResult", success_); 194 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HostParseResult", success_);
119 UMA_HISTOGRAM_TIMES("AsyncDNS.HostsParseDuration", 195 UMA_HISTOGRAM_TIMES("AsyncDNS.HostsParseDuration",
120 base::TimeTicks::Now() - start_time); 196 base::TimeTicks::Now() - start_time);
121 } 197 }
122 198
123 virtual void OnWorkFinished() OVERRIDE { 199 virtual void OnWorkFinished() OVERRIDE {
124 if (success_) { 200 if (success_) {
125 callback_.Run(hosts_); 201 service_->OnHostsRead(hosts_);
126 } else { 202 } else {
127 LOG(WARNING) << "Failed to read DnsHosts."; 203 LOG(WARNING) << "Failed to read DnsHosts.";
128 } 204 }
129 } 205 }
130 206
207 DnsConfigServicePosix* service_;
131 const FilePath path_; 208 const FilePath path_;
132 const CallbackType callback_; 209 const CallbackType callback_;
133 // Written in DoWork, read in OnWorkFinished, no locking necessary. 210 // Written in DoWork, read in OnWorkFinished, no locking necessary.
134 DnsHosts hosts_; 211 DnsHosts hosts_;
135 bool success_; 212 bool success_;
136 213
137 DISALLOW_COPY_AND_ASSIGN(HostsReader); 214 DISALLOW_COPY_AND_ASSIGN(HostsReader);
138 }; 215 };
139 216
140 } // namespace 217 DnsConfigServicePosix::DnsConfigServicePosix()
141 218 : watcher_(new Watcher(this)),
142 DnsConfigServicePosix::DnsConfigServicePosix() { 219 config_reader_(new ConfigReader(this)),
143 config_reader_ = new ConfigReader( 220 hosts_reader_(new HostsReader(this)) {}
144 base::Bind(&DnsConfigServicePosix::OnConfigRead,
145 base::Unretained(this)));
146 hosts_reader_ = new HostsReader(
147 base::Bind(&DnsConfigServicePosix::OnHostsRead,
148 base::Unretained(this)));
149 }
150 221
151 DnsConfigServicePosix::~DnsConfigServicePosix() { 222 DnsConfigServicePosix::~DnsConfigServicePosix() {
152 config_reader_->Cancel(); 223 config_reader_->Cancel();
153 hosts_reader_->Cancel(); 224 hosts_reader_->Cancel();
154 } 225 }
155 226
156 void DnsConfigServicePosix::OnDNSChanged(unsigned detail) { 227 void DnsConfigServicePosix::ReadNow() {
157 if (detail & NetworkChangeNotifier::CHANGE_DNS_WATCH_FAILED) { 228 config_reader_->WorkNow();
158 InvalidateConfig(); 229 hosts_reader_->WorkNow();
159 InvalidateHosts(); 230 }
160 // We don't trust a config that we cannot watch in the future. 231
161 config_reader_->Cancel(); 232 bool DnsConfigServicePosix::StartWatching() {
162 hosts_reader_->Cancel(); 233 // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139
163 return; 234 return watcher_->Watch();
164 } 235 }
165 if (detail & NetworkChangeNotifier::CHANGE_DNS_WATCH_STARTED) 236
166 detail = ~0; // Assume everything changed. 237 void DnsConfigServicePosix::OnConfigChanged(bool succeeded) {
167 if (detail & NetworkChangeNotifier::CHANGE_DNS_SETTINGS) { 238 InvalidateConfig();
168 InvalidateConfig(); 239 if (succeeded) {
169 config_reader_->WorkNow(); 240 config_reader_->WorkNow();
170 } 241 } else {
171 if (detail & NetworkChangeNotifier::CHANGE_DNS_HOSTS) { 242 LOG(ERROR) << "DNS config watch failed.";
172 InvalidateHosts(); 243 set_watch_failed(true);
173 hosts_reader_->WorkNow();
174 } 244 }
175 } 245 }
176 246
247 void DnsConfigServicePosix::OnHostsChanged(bool succeeded) {
248 InvalidateHosts();
249 if (succeeded) {
250 hosts_reader_->WorkNow();
251 } else {
252 LOG(ERROR) << "DNS hosts watch failed.";
253 set_watch_failed(true);
254 }
255 }
256
177 ConfigParsePosixResult ConvertResStateToDnsConfig(const struct __res_state& res, 257 ConfigParsePosixResult ConvertResStateToDnsConfig(const struct __res_state& res,
178 DnsConfig* dns_config) { 258 DnsConfig* dns_config) {
179 CHECK(dns_config != NULL); 259 CHECK(dns_config != NULL);
180 if (!(res.options & RES_INIT)) 260 if (!(res.options & RES_INIT))
181 return CONFIG_PARSE_POSIX_RES_INIT_UNSET; 261 return CONFIG_PARSE_POSIX_RES_INIT_UNSET;
182 262
183 dns_config->nameservers.clear(); 263 dns_config->nameservers.clear();
184 264
185 #if defined(OS_MACOSX) || defined(OS_FREEBSD) 265 #if defined(OS_MACOSX) || defined(OS_FREEBSD)
186 union res_sockaddr_union addresses[MAXNS]; 266 union res_sockaddr_union addresses[MAXNS];
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { 356 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() {
277 return scoped_ptr<DnsConfigService>(new internal::DnsConfigServicePosix()); 357 return scoped_ptr<DnsConfigService>(new internal::DnsConfigServicePosix());
278 } 358 }
279 359
280 #else // defined(OS_ANDROID) 360 #else // defined(OS_ANDROID)
281 // Android NDK provides only a stub <resolv.h> header. 361 // Android NDK provides only a stub <resolv.h> header.
282 class StubDnsConfigService : public DnsConfigService { 362 class StubDnsConfigService : public DnsConfigService {
283 public: 363 public:
284 StubDnsConfigService() {} 364 StubDnsConfigService() {}
285 virtual ~StubDnsConfigService() {} 365 virtual ~StubDnsConfigService() {}
286 virtual void OnDNSChanged(unsigned detail) OVERRIDE {} 366 private:
367 virtual void ReadNow() OVERRIDE {}
368 virtual bool StartWatching() OVERRIDE { return false; }
287 }; 369 };
288 // static 370 // static
289 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { 371 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() {
290 return scoped_ptr<DnsConfigService>(new StubDnsConfigService()); 372 return scoped_ptr<DnsConfigService>(new StubDnsConfigService());
291 } 373 }
292 #endif 374 #endif
293 375
294 } // namespace net 376 } // namespace net
OLDNEW
« no previous file with comments | « net/dns/dns_config_service_posix.h ('k') | net/dns/dns_config_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698