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

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

Issue 9721002: [net/dns] Removes locking from DnsConfigServiceWin and adds local computer name. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 9 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
« no previous file with comments | « net/dns/dns_config_service_win.h ('k') | net/dns/dns_hosts.h » ('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_win.h" 5 #include "net/dns/dns_config_service_win.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/file_path.h" 13 #include "base/file_path.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
16 #include "base/string_split.h" 16 #include "base/string_split.h"
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 #include "base/synchronization/lock.h" 18 #include "base/synchronization/lock.h"
19 #include "base/threading/non_thread_safe.h"
19 #include "base/threading/thread_restrictions.h" 20 #include "base/threading/thread_restrictions.h"
20 #include "base/utf_string_conversions.h" 21 #include "base/utf_string_conversions.h"
21 #include "base/win/object_watcher.h" 22 #include "base/win/object_watcher.h"
22 #include "base/win/registry.h" 23 #include "base/win/registry.h"
23 #include "base/win/windows_version.h" 24 #include "base/win/windows_version.h"
24 #include "googleurl/src/url_canon.h" 25 #include "googleurl/src/url_canon.h"
25 #include "net/base/net_util.h" 26 #include "net/base/net_util.h"
26 #include "net/dns/dns_protocol.h" 27 #include "net/dns/dns_protocol.h"
27 #include "net/dns/file_path_watcher_wrapper.h" 28 #include "net/dns/file_path_watcher_wrapper.h"
28 #include "net/dns/serial_worker.h" 29 #include "net/dns/serial_worker.h"
29 30
30 #pragma comment(lib, "iphlpapi.lib") 31 #pragma comment(lib, "iphlpapi.lib")
31 32
32 namespace net { 33 namespace net {
33 34
34 namespace internal { 35 namespace internal {
35 36
36 namespace { 37 namespace {
37 38
38 // Watches a single registry key for changes. Thread-safe. 39 // Registry key paths.
39 class RegistryWatcher : public base::win::ObjectWatcher::Delegate { 40 const wchar_t* const kTcpipPath =
41 L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
42 const wchar_t* const kTcpip6Path =
43 L"SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters";
44 const wchar_t* const kDnscachePath =
45 L"SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters";
46 const wchar_t* const kPolicyPath =
47 L"SOFTWARE\\Policies\\Microsoft\\Windows NT\\DNSClient";
48
49 // Convenience for reading values using RegKey.
50 class RegistryReader : public base::NonThreadSafe {
40 public: 51 public:
41 typedef base::Callback<void(bool succeeded)> CallbackType; 52 explicit RegistryReader(const wchar_t* key) {
42 RegistryWatcher() {} 53 // Ignoring the result. |key_.Valid()| will catch failures.
43 54 key_.Open(HKEY_LOCAL_MACHINE, key, KEY_QUERY_VALUE);
44 bool Watch(const wchar_t* key, const CallbackType& callback) {
45 base::AutoLock lock(lock_);
46 DCHECK(!callback.is_null());
47 CancelLocked();
48 if (key_.Open(HKEY_LOCAL_MACHINE, key,
49 KEY_NOTIFY | KEY_QUERY_VALUE) != ERROR_SUCCESS)
50 return false;
51 if (key_.StartWatching() != ERROR_SUCCESS)
52 return false;
53 if (!watcher_.StartWatching(key_.watch_event(), this))
54 return false;
55 callback_ = callback;
56 return true;
57 }
58
59 void Cancel() {
60 base::AutoLock lock(lock_);
61 CancelLocked();
62 }
63
64 virtual void OnObjectSignaled(HANDLE object) OVERRIDE {
65 base::AutoLock lock(lock_);
66 bool succeeded = (key_.StartWatching() == ERROR_SUCCESS) &&
67 watcher_.StartWatching(key_.watch_event(), this);
68 if (!callback_.is_null())
69 callback_.Run(succeeded);
70 } 55 }
71 56
72 bool ReadString(const wchar_t* name, 57 bool ReadString(const wchar_t* name,
73 DnsSystemSettings::RegString* out) const { 58 DnsSystemSettings::RegString* out) const {
74 base::AutoLock lock(lock_); 59 DCHECK(CalledOnValidThread());
75 out->set = false; 60 out->set = false;
76 if (!key_.Valid()) { 61 if (!key_.Valid()) {
77 // Assume that if the |key_| is invalid then the key is missing. 62 // Assume that if the |key_| is invalid then the key is missing.
78 return true; 63 return true;
79 } 64 }
80 LONG result = key_.ReadValue(name, &out->value); 65 LONG result = key_.ReadValue(name, &out->value);
81 if (result == ERROR_SUCCESS) { 66 if (result == ERROR_SUCCESS) {
82 out->set = true; 67 out->set = true;
83 return true; 68 return true;
84 } 69 }
85 return (result == ERROR_FILE_NOT_FOUND); 70 return (result == ERROR_FILE_NOT_FOUND);
86 } 71 }
87 72
88 bool ReadDword(const wchar_t* name, 73 bool ReadDword(const wchar_t* name,
89 DnsSystemSettings::RegDword* out) const { 74 DnsSystemSettings::RegDword* out) const {
90 base::AutoLock lock(lock_); 75 DCHECK(CalledOnValidThread());
91 out->set = false; 76 out->set = false;
92 if (!key_.Valid()) { 77 if (!key_.Valid()) {
93 // Assume that if the |key_| is invalid then the key is missing. 78 // Assume that if the |key_| is invalid then the key is missing.
94 return true; 79 return true;
95 } 80 }
96 LONG result = key_.ReadValueDW(name, &out->value); 81 LONG result = key_.ReadValueDW(name, &out->value);
97 if (result == ERROR_SUCCESS) { 82 if (result == ERROR_SUCCESS) {
98 out->set = true; 83 out->set = true;
99 return true; 84 return true;
100 } 85 }
101 return (result == ERROR_FILE_NOT_FOUND); 86 return (result == ERROR_FILE_NOT_FOUND);
102 } 87 }
103 88
104 private: 89 private:
105 void CancelLocked() { 90 base::win::RegKey key_;
106 lock_.AssertAcquired(); 91
92 DISALLOW_COPY_AND_ASSIGN(RegistryReader);
93 };
94
95
96 // Watches a single registry key for changes.
97 class RegistryWatcher : public base::win::ObjectWatcher::Delegate,
98 public base::NonThreadSafe {
99 public:
100 typedef base::Callback<void(bool succeeded)> CallbackType;
101 RegistryWatcher() {}
102
103 bool Watch(const wchar_t* key, const CallbackType& callback) {
104 DCHECK(CalledOnValidThread());
105 DCHECK(!callback.is_null());
106 Cancel();
107 if (key_.Open(HKEY_LOCAL_MACHINE, key, KEY_NOTIFY) != ERROR_SUCCESS)
108 return false;
109 if (key_.StartWatching() != ERROR_SUCCESS)
110 return false;
111 if (!watcher_.StartWatching(key_.watch_event(), this))
112 return false;
113 callback_ = callback;
114 return true;
115 }
116
117 void Cancel() {
118 DCHECK(CalledOnValidThread());
107 callback_.Reset(); 119 callback_.Reset();
108 if (key_.Valid()) { 120 if (key_.Valid()) {
109 watcher_.StopWatching(); 121 watcher_.StopWatching();
110 key_.StopWatching(); 122 key_.StopWatching();
111 } 123 }
112 } 124 }
113 125
114 mutable base::Lock lock_; 126 virtual void OnObjectSignaled(HANDLE object) OVERRIDE {
127 DCHECK(CalledOnValidThread());
128 bool succeeded = (key_.StartWatching() == ERROR_SUCCESS) &&
129 watcher_.StartWatching(key_.watch_event(), this);
mmenke 2012/03/19 15:18:01 nit: Think this should be indented one more space
130 if (!callback_.is_null())
131 callback_.Run(succeeded);
132 }
133
134 private:
115 CallbackType callback_; 135 CallbackType callback_;
116 base::win::RegKey key_; 136 base::win::RegKey key_;
117 base::win::ObjectWatcher watcher_; 137 base::win::ObjectWatcher watcher_;
118 138
119 DISALLOW_COPY_AND_ASSIGN(RegistryWatcher); 139 DISALLOW_COPY_AND_ASSIGN(RegistryWatcher);
120 }; 140 };
121 141
122 // Converts a string16 domain name to ASCII, possibly using punycode. 142 // Converts a string16 domain name to ASCII, possibly using punycode.
123 // Returns true if the conversion succeeds and output is not empty. In case of 143 // Returns true if the conversion succeeds and output is not empty. In case of
124 // failure, |domain| might become dirty. 144 // failure, |domain| might become dirty.
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 : service_(service), 336 : service_(service),
317 success_(false) {} 337 success_(false) {}
318 338
319 bool Watch() { 339 bool Watch() {
320 DCHECK(loop()->BelongsToCurrentThread()); 340 DCHECK(loop()->BelongsToCurrentThread());
321 341
322 RegistryWatcher::CallbackType callback = 342 RegistryWatcher::CallbackType callback =
323 base::Bind(&ConfigReader::OnChange, base::Unretained(this)); 343 base::Bind(&ConfigReader::OnChange, base::Unretained(this));
324 344
325 // The Tcpip key must be present. 345 // The Tcpip key must be present.
326 if (!tcpip_watcher_.Watch( 346 if (!tcpip_watcher_.Watch(kTcpipPath, callback))
327 L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
328 callback))
329 return false; 347 return false;
330 348
331 // Watch for IPv6 nameservers. 349 // Watch for IPv6 nameservers.
332 tcpip6_watcher_.Watch( 350 tcpip6_watcher_.Watch(kTcpip6Path, callback);
333 L"SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters",
334 callback);
335 351
336 // DNS suffix search list and devolution can be configured via group 352 // DNS suffix search list and devolution can be configured via group
337 // policy which sets this registry key. If the key is missing, the policy 353 // policy which sets this registry key. If the key is missing, the policy
338 // does not apply, and the DNS client uses Tcpip and Dnscache settings. 354 // does not apply, and the DNS client uses Tcpip and Dnscache settings.
339 // If a policy is installed, DnsConfigService will need to be restarted. 355 // If a policy is installed, DnsConfigService will need to be restarted.
340 // BUG=99509 356 // BUG=99509
341 357
342 dnscache_watcher_.Watch( 358 dnscache_watcher_.Watch(kDnscachePath, callback);
343 L"SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters", 359 policy_watcher_.Watch(kPolicyPath, callback);
344 callback);
345
346 policy_watcher_.Watch(
347 L"SOFTWARE\\Policies\\Microsoft\\Windows NT\\DNSClient",
348 callback);
349 360
350 WorkNow(); 361 WorkNow();
351 return true; 362 return true;
352 } 363 }
353 364
354 void Cancel() { 365 void Cancel() {
355 DCHECK(loop()->BelongsToCurrentThread()); 366 DCHECK(loop()->BelongsToCurrentThread());
356 SerialWorker::Cancel(); 367 SerialWorker::Cancel();
357 policy_watcher_.Cancel(); 368 policy_watcher_.Cancel();
358 dnscache_watcher_.Cancel(); 369 dnscache_watcher_.Cancel();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 (tries < 3) && (rv == ERROR_BUFFER_OVERFLOW); 402 (tries < 3) && (rv == ERROR_BUFFER_OVERFLOW);
392 tries++) { 403 tries++) {
393 settings->addresses.reset( 404 settings->addresses.reset(
394 reinterpret_cast<PIP_ADAPTER_ADDRESSES>(malloc(len))); 405 reinterpret_cast<PIP_ADAPTER_ADDRESSES>(malloc(len)));
395 rv = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, 406 rv = GetAdaptersAddresses(AF_UNSPEC, flags, NULL,
396 settings->addresses.get(), &len); 407 settings->addresses.get(), &len);
397 } 408 }
398 return (rv == NO_ERROR); 409 return (rv == NO_ERROR);
399 } 410 }
400 411
401 bool ReadDevolutionSetting(const RegistryWatcher& watcher, 412 bool ReadDevolutionSetting(const RegistryReader& reader,
402 DnsSystemSettings::DevolutionSetting& setting) { 413 DnsSystemSettings::DevolutionSetting& setting) {
403 return watcher.ReadDword(L"UseDomainNameDevolution", &setting.enabled) && 414 return reader.ReadDword(L"UseDomainNameDevolution", &setting.enabled) &&
404 watcher.ReadDword(L"DomainNameDevolutionLevel", &setting.level); 415 reader.ReadDword(L"DomainNameDevolutionLevel", &setting.level);
405 } 416 }
406 417
407 virtual void DoWork() OVERRIDE { 418 virtual void DoWork() OVERRIDE {
408 // Should be called on WorkerPool. 419 // Should be called on WorkerPool.
409 success_ = false; 420 success_ = false;
410 421
411 DnsSystemSettings settings; 422 DnsSystemSettings settings;
412 memset(&settings, 0, sizeof(settings)); 423 memset(&settings, 0, sizeof(settings));
413 if (!ReadIpHelper(&settings)) 424 if (!ReadIpHelper(&settings))
414 return; // no point reading the rest 425 return; // no point reading the rest
415 426
416 if (!policy_watcher_.ReadString(L"SearchList", 427 RegistryReader tcpip_reader(kTcpipPath);
417 &settings.policy_search_list)) 428 RegistryReader tcpip6_reader(kTcpip6Path);
429 RegistryReader dnscache_reader(kDnscachePath);
430 RegistryReader policy_reader(kPolicyPath);
431
432 if (!policy_reader.ReadString(L"SearchList",
433 &settings.policy_search_list))
418 return; 434 return;
419 435
420 if (!tcpip_watcher_.ReadString(L"SearchList", &settings.tcpip_search_list)) 436 if (!tcpip_reader.ReadString(L"SearchList", &settings.tcpip_search_list))
421 return; 437 return;
422 438
423 if (!tcpip_watcher_.ReadString(L"Domain", &settings.tcpip_domain)) 439 if (!tcpip_reader.ReadString(L"Domain", &settings.tcpip_domain))
424 return; 440 return;
425 441
426 if (!ReadDevolutionSetting(policy_watcher_, settings.policy_devolution)) 442 if (!ReadDevolutionSetting(policy_reader, settings.policy_devolution))
427 return; 443 return;
428 444
429 if (!ReadDevolutionSetting(dnscache_watcher_, 445 if (!ReadDevolutionSetting(dnscache_reader,
430 settings.dnscache_devolution)) 446 settings.dnscache_devolution))
431 return; 447 return;
432 448
433 if (!ReadDevolutionSetting(tcpip_watcher_, settings.tcpip_devolution)) 449 if (!ReadDevolutionSetting(tcpip_reader, settings.tcpip_devolution))
434 return; 450 return;
435 451
436 if (!policy_watcher_.ReadDword(L"AppendToMultiLabelName", 452 if (!policy_reader.ReadDword(L"AppendToMultiLabelName",
437 &settings.append_to_multi_label_name)) 453 &settings.append_to_multi_label_name))
438 return; 454 return;
439 455
440 success_ = ConvertSettingsToDnsConfig(settings, &dns_config_); 456 success_ = ConvertSettingsToDnsConfig(settings, &dns_config_);
441 } 457 }
442 458
443 virtual void OnWorkFinished() OVERRIDE { 459 virtual void OnWorkFinished() OVERRIDE {
444 DCHECK(loop()->BelongsToCurrentThread()); 460 DCHECK(loop()->BelongsToCurrentThread());
445 DCHECK(!IsCancelled()); 461 DCHECK(!IsCancelled());
446 if (success_) { 462 if (success_) {
447 service_->OnConfigRead(dns_config_); 463 service_->OnConfigRead(dns_config_);
448 } else { 464 } else {
449 LOG(WARNING) << "Failed to read config."; 465 LOG(WARNING) << "Failed to read config.";
450 } 466 }
451 } 467 }
452 468
453 DnsConfigServiceWin* service_; 469 DnsConfigServiceWin* service_;
454 // Written in DoRead(), read in OnReadFinished(). No locking required. 470 // Written in DoRead(), read in OnReadFinished(). No locking required.
455 DnsConfig dns_config_; 471 DnsConfig dns_config_;
456 bool success_; 472 bool success_;
457 473
458 RegistryWatcher tcpip_watcher_; 474 RegistryWatcher tcpip_watcher_;
459 RegistryWatcher tcpip6_watcher_; 475 RegistryWatcher tcpip6_watcher_;
460 RegistryWatcher dnscache_watcher_; 476 RegistryWatcher dnscache_watcher_;
461 RegistryWatcher policy_watcher_; 477 RegistryWatcher policy_watcher_;
462 }; 478 };
463 479
480
481 // An extension for DnsHostsReader which also reads local name from
482 // GetComputerNameEx and watches registry for changes to local name.
483 class DnsConfigServiceWin::HostsReader : public base::NonThreadSafe {
484 public:
485 explicit HostsReader(DnsConfigServiceWin* service) : service_(service) {
486 TCHAR buffer[MAX_PATH];
487 UINT rc = GetSystemDirectory(buffer, MAX_PATH);
488 DCHECK(0 < rc && rc < MAX_PATH);
489 FilePath hosts_path = FilePath(buffer).
490 Append(FILE_PATH_LITERAL("drivers\\etc\\hosts"));
491 hosts_reader_ = new DnsHostsReader(
492 hosts_path,
493 base::Bind(&HostsReader::OnHostsRead, base::Unretained(this)));
494 }
495
496 bool Watch() {
497 DCHECK(CalledOnValidThread());
498 if (!hosts_watcher_.Watch(hosts_reader_->path(),
499 base::Bind(&HostsReader::OnHostsChanged,
500 base::Unretained(this)))) {
501 return false;
502 }
503 if (!registry_watcher_.Watch(kTcpipPath,
504 base::Bind(&HostsReader::OnNameChanged,
505 base::Unretained(this)))) {
mmenke 2012/03/19 15:18:01 nit: Indent this to the open paren, if it fits, s
506 return false;
507 }
508
509 hosts_reader_->WorkNow();
510 return true;
511 }
512
513 ~HostsReader() {
514 hosts_reader_->Cancel();
515 }
516
517 private:
518 void OnHostsChanged(bool succeeded) {
519 DCHECK(CalledOnValidThread());
520 service_->InvalidateHosts();
521 if (succeeded)
522 hosts_reader_->WorkNow();
523 else
524 LOG(ERROR) << "Failed to watch DNS hosts";
525 }
526
527 void OnHostsRead(const DnsHosts& hosts) {
528 DCHECK(CalledOnValidThread());
529 hosts_ = hosts;
530 UpdateService();
531 }
532
533 void OnNameChanged(bool succeeded) {
534 DCHECK(CalledOnValidThread());
535 if (!succeeded) {
536 LOG(ERROR) << "Failed to watch local computer name";
537 service_->InvalidateHosts();
538 return;
539 }
540 WCHAR buffer[MAX_PATH];
541 DWORD size = MAX_PATH;
542 std::string localname;
543 if (!GetComputerNameExW(ComputerNameDnsHostname, buffer, &size) ||
544 !ParseDomainASCII(buffer, &localname)) {
545 service_->InvalidateHosts();
546 LOG(ERROR) << "Failed to read local computer name";
547 return;
548 }
549
550 if (localname != localname_) {
551 localname_ = localname;
552 UpdateService();
mmenke 2012/03/19 15:18:01 What if the last call to OnHostsChanged failed? S
553 }
554 }
555
556 void UpdateService() {
557 DCHECK(CalledOnValidThread());
558 DnsHosts complete_hosts = hosts_;
559
560 const unsigned char kIPv4Localhost[] = { 127, 0, 0, 1 };
561 const unsigned char kIPv6Localhost[] = { 0, 0, 0, 0, 0, 0, 0, 0,
562 0, 0, 0, 0, 0, 0, 0, 1 };
563
564 complete_hosts[DnsHostsKey(localname_, ADDRESS_FAMILY_IPV4)] =
565 IPAddressNumber(kIPv4Localhost,
566 kIPv4Localhost + arraysize(kIPv4Localhost));
567 complete_hosts[DnsHostsKey(localname_, ADDRESS_FAMILY_IPV6)] =
568 IPAddressNumber(kIPv6Localhost,
569 kIPv6Localhost + arraysize(kIPv6Localhost));
570 service_->OnHostsRead(complete_hosts);
571 }
572
573 DnsConfigServiceWin* service_;
574 FilePathWatcherWrapper hosts_watcher_;
575 RegistryWatcher registry_watcher_;
576 scoped_refptr<DnsHostsReader> hosts_reader_;
577
578 // Contents of the HOSTS file.
579 DnsHosts hosts_;
580 // Local computer name in ASCII.
581 std::string localname_;
582
583 DISALLOW_COPY_AND_ASSIGN(HostsReader);
584 };
585
586
464 DnsConfigServiceWin::DnsConfigServiceWin() 587 DnsConfigServiceWin::DnsConfigServiceWin()
465 : config_reader_(new ConfigReader(this)), 588 : config_reader_(new ConfigReader(this)),
466 hosts_watcher_(new FilePathWatcherWrapper()) {} 589 hosts_reader_(new HostsReader(this)) {}
467 590
468 DnsConfigServiceWin::~DnsConfigServiceWin() { 591 DnsConfigServiceWin::~DnsConfigServiceWin() {
469 DCHECK(CalledOnValidThread()); 592 DCHECK(CalledOnValidThread());
470 config_reader_->Cancel(); 593 config_reader_->Cancel();
471 if (hosts_reader_)
472 hosts_reader_->Cancel();
473 } 594 }
474 595
475 void DnsConfigServiceWin::Watch(const CallbackType& callback) { 596 void DnsConfigServiceWin::Watch(const CallbackType& callback) {
476 DCHECK(CalledOnValidThread()); 597 DCHECK(CalledOnValidThread());
477 DCHECK(!callback.is_null()); 598 DCHECK(!callback.is_null());
478 set_callback(callback); 599 set_callback(callback);
479 600
480 // This is done only once per lifetime so open the keys and file watcher 601 // This is done only once per lifetime so open the keys and file watcher
481 // handles on this thread. 602 // handles on this thread.
482 // TODO(szym): Should/can this be avoided? http://crbug.com/114223 603 // TODO(szym): Should/can this be avoided? http://crbug.com/114223
483 base::ThreadRestrictions::ScopedAllowIO allow_io; 604 base::ThreadRestrictions::ScopedAllowIO allow_io;
484 605
485 if (!config_reader_->Watch()) { 606 if (!config_reader_->Watch()) {
486 LOG(ERROR) << "Failed to start watching DNS config"; 607 LOG(ERROR) << "Failed to start watching DNS config";
487 InvalidateConfig(); 608 InvalidateConfig();
488 } 609 }
489 610
490 TCHAR buffer[MAX_PATH]; 611 if (!hosts_reader_->Watch()) {
491 UINT rc = GetSystemDirectory(buffer, MAX_PATH); 612 LOG(ERROR) << "Failed to start watching HOSTS";
492 DCHECK(0 < rc && rc < MAX_PATH); 613 InvalidateHosts();
493 FilePath hosts_path = FilePath(buffer).
494 Append(FILE_PATH_LITERAL("drivers\\etc\\hosts"));
495 hosts_reader_ = new DnsHostsReader(
496 hosts_path,
497 base::Bind(&DnsConfigServiceWin::OnHostsRead, base::Unretained(this)));
498 if (hosts_watcher_->Watch(hosts_path,
499 base::Bind(&DnsConfigServiceWin::OnHostsChanged,
500 base::Unretained(this)))) {
501 OnHostsChanged(true);
502 } else {
503 OnHostsChanged(false);
504 } 614 }
505 } 615 }
506 616
507 void DnsConfigServiceWin::OnHostsChanged(bool succeeded) {
508 InvalidateHosts();
509 if (succeeded)
510 hosts_reader_->WorkNow();
511 else
512 LOG(ERROR) << "Failed to watch DNS hosts";
513 }
514 617
mmenke 2012/03/19 15:18:01 nit: Remove extra blank line.
515 } // namespace internal 618 } // namespace internal
516 619
517 // static 620 // static
518 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { 621 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() {
519 return scoped_ptr<DnsConfigService>(new internal::DnsConfigServiceWin()); 622 return scoped_ptr<DnsConfigService>(new internal::DnsConfigServiceWin());
520 } 623 }
521 624
522 } // namespace net 625 } // namespace net
523 626
OLDNEW
« no previous file with comments | « net/dns/dns_config_service_win.h ('k') | net/dns/dns_hosts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698