OLD | NEW |
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 <memory> | 8 #include <memory> |
9 #include <string> | 9 #include <string> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/callback.h" | 12 #include "base/callback.h" |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
15 #include "base/files/file_path_watcher.h" | 15 #include "base/files/file_path_watcher.h" |
16 #include "base/location.h" | 16 #include "base/location.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/macros.h" | 18 #include "base/macros.h" |
19 #include "base/memory/free_deleter.h" | 19 #include "base/memory/free_deleter.h" |
20 #include "base/metrics/histogram_macros.h" | 20 #include "base/metrics/histogram_macros.h" |
21 #include "base/single_thread_task_runner.h" | 21 #include "base/single_thread_task_runner.h" |
22 #include "base/strings/string_split.h" | 22 #include "base/strings/string_split.h" |
23 #include "base/strings/string_util.h" | 23 #include "base/strings/string_util.h" |
24 #include "base/strings/utf_string_conversions.h" | 24 #include "base/strings/utf_string_conversions.h" |
25 #include "base/synchronization/lock.h" | 25 #include "base/synchronization/lock.h" |
26 #include "base/threading/non_thread_safe.h" | 26 #include "base/threading/thread_checker.h" |
27 #include "base/threading/thread_restrictions.h" | 27 #include "base/threading/thread_restrictions.h" |
28 #include "base/threading/thread_task_runner_handle.h" | 28 #include "base/threading/thread_task_runner_handle.h" |
29 #include "base/time/time.h" | 29 #include "base/time/time.h" |
30 #include "base/win/registry.h" | 30 #include "base/win/registry.h" |
31 #include "base/win/scoped_handle.h" | 31 #include "base/win/scoped_handle.h" |
32 #include "net/base/ip_address.h" | 32 #include "net/base/ip_address.h" |
33 #include "net/base/network_change_notifier.h" | 33 #include "net/base/network_change_notifier.h" |
34 #include "net/dns/dns_hosts.h" | 34 #include "net/dns/dns_hosts.h" |
35 #include "net/dns/dns_protocol.h" | 35 #include "net/dns/dns_protocol.h" |
36 #include "net/dns/serial_worker.h" | 36 #include "net/dns/serial_worker.h" |
(...skipping 25 matching lines...) Expand all Loading... |
62 enum HostsParseWinResult { | 62 enum HostsParseWinResult { |
63 HOSTS_PARSE_WIN_OK = 0, | 63 HOSTS_PARSE_WIN_OK = 0, |
64 HOSTS_PARSE_WIN_UNREADABLE_HOSTS_FILE, | 64 HOSTS_PARSE_WIN_UNREADABLE_HOSTS_FILE, |
65 HOSTS_PARSE_WIN_COMPUTER_NAME_FAILED, | 65 HOSTS_PARSE_WIN_COMPUTER_NAME_FAILED, |
66 HOSTS_PARSE_WIN_IPHELPER_FAILED, | 66 HOSTS_PARSE_WIN_IPHELPER_FAILED, |
67 HOSTS_PARSE_WIN_BAD_ADDRESS, | 67 HOSTS_PARSE_WIN_BAD_ADDRESS, |
68 HOSTS_PARSE_WIN_MAX // Bounding values for enumeration. | 68 HOSTS_PARSE_WIN_MAX // Bounding values for enumeration. |
69 }; | 69 }; |
70 | 70 |
71 // Convenience for reading values using RegKey. | 71 // Convenience for reading values using RegKey. |
72 class RegistryReader : public base::NonThreadSafe { | 72 class RegistryReader { |
73 public: | 73 public: |
74 explicit RegistryReader(const wchar_t* key) { | 74 explicit RegistryReader(const wchar_t* key) { |
75 // Ignoring the result. |key_.Valid()| will catch failures. | 75 // Ignoring the result. |key_.Valid()| will catch failures. |
76 key_.Open(HKEY_LOCAL_MACHINE, key, KEY_QUERY_VALUE); | 76 key_.Open(HKEY_LOCAL_MACHINE, key, KEY_QUERY_VALUE); |
77 } | 77 } |
78 | 78 |
| 79 ~RegistryReader() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } |
| 80 |
79 bool ReadString(const wchar_t* name, | 81 bool ReadString(const wchar_t* name, |
80 DnsSystemSettings::RegString* out) const { | 82 DnsSystemSettings::RegString* out) const { |
81 DCHECK(CalledOnValidThread()); | 83 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
82 out->set = false; | 84 out->set = false; |
83 if (!key_.Valid()) { | 85 if (!key_.Valid()) { |
84 // Assume that if the |key_| is invalid then the key is missing. | 86 // Assume that if the |key_| is invalid then the key is missing. |
85 return true; | 87 return true; |
86 } | 88 } |
87 LONG result = key_.ReadValue(name, &out->value); | 89 LONG result = key_.ReadValue(name, &out->value); |
88 if (result == ERROR_SUCCESS) { | 90 if (result == ERROR_SUCCESS) { |
89 out->set = true; | 91 out->set = true; |
90 return true; | 92 return true; |
91 } | 93 } |
92 return (result == ERROR_FILE_NOT_FOUND); | 94 return (result == ERROR_FILE_NOT_FOUND); |
93 } | 95 } |
94 | 96 |
95 bool ReadDword(const wchar_t* name, | 97 bool ReadDword(const wchar_t* name, |
96 DnsSystemSettings::RegDword* out) const { | 98 DnsSystemSettings::RegDword* out) const { |
97 DCHECK(CalledOnValidThread()); | 99 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
98 out->set = false; | 100 out->set = false; |
99 if (!key_.Valid()) { | 101 if (!key_.Valid()) { |
100 // Assume that if the |key_| is invalid then the key is missing. | 102 // Assume that if the |key_| is invalid then the key is missing. |
101 return true; | 103 return true; |
102 } | 104 } |
103 LONG result = key_.ReadValueDW(name, &out->value); | 105 LONG result = key_.ReadValueDW(name, &out->value); |
104 if (result == ERROR_SUCCESS) { | 106 if (result == ERROR_SUCCESS) { |
105 out->set = true; | 107 out->set = true; |
106 return true; | 108 return true; |
107 } | 109 } |
108 return (result == ERROR_FILE_NOT_FOUND); | 110 return (result == ERROR_FILE_NOT_FOUND); |
109 } | 111 } |
110 | 112 |
111 private: | 113 private: |
112 base::win::RegKey key_; | 114 base::win::RegKey key_; |
113 | 115 |
| 116 THREAD_CHECKER(thread_checker_); |
| 117 |
114 DISALLOW_COPY_AND_ASSIGN(RegistryReader); | 118 DISALLOW_COPY_AND_ASSIGN(RegistryReader); |
115 }; | 119 }; |
116 | 120 |
117 // Wrapper for GetAdaptersAddresses. Returns NULL if failed. | 121 // Wrapper for GetAdaptersAddresses. Returns NULL if failed. |
118 std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> ReadIpHelper( | 122 std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> ReadIpHelper( |
119 ULONG flags) { | 123 ULONG flags) { |
120 base::ThreadRestrictions::AssertIOAllowed(); | 124 base::ThreadRestrictions::AssertIOAllowed(); |
121 | 125 |
122 std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> out; | 126 std::unique_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> out; |
123 ULONG len = 15000; // As recommended by MSDN for GetAdaptersAddresses. | 127 ULONG len = 15000; // As recommended by MSDN for GetAdaptersAddresses. |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 } else if (!have_ipv6 && (ipe.GetFamily() == ADDRESS_FAMILY_IPV6)) { | 284 } else if (!have_ipv6 && (ipe.GetFamily() == ADDRESS_FAMILY_IPV6)) { |
281 have_ipv6 = true; | 285 have_ipv6 = true; |
282 (*hosts)[DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)] = ipe.address(); | 286 (*hosts)[DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)] = ipe.address(); |
283 } | 287 } |
284 } | 288 } |
285 } | 289 } |
286 return HOSTS_PARSE_WIN_OK; | 290 return HOSTS_PARSE_WIN_OK; |
287 } | 291 } |
288 | 292 |
289 // Watches a single registry key for changes. | 293 // Watches a single registry key for changes. |
290 class RegistryWatcher : public base::NonThreadSafe { | 294 class RegistryWatcher { |
291 public: | 295 public: |
292 typedef base::Callback<void(bool succeeded)> CallbackType; | 296 typedef base::Callback<void(bool succeeded)> CallbackType; |
293 RegistryWatcher() {} | 297 RegistryWatcher() {} |
294 | 298 |
| 299 ~RegistryWatcher() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } |
| 300 |
295 bool Watch(const wchar_t* key, const CallbackType& callback) { | 301 bool Watch(const wchar_t* key, const CallbackType& callback) { |
296 DCHECK(CalledOnValidThread()); | 302 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
297 DCHECK(!callback.is_null()); | 303 DCHECK(!callback.is_null()); |
298 DCHECK(callback_.is_null()); | 304 DCHECK(callback_.is_null()); |
299 callback_ = callback; | 305 callback_ = callback; |
300 if (key_.Open(HKEY_LOCAL_MACHINE, key, KEY_NOTIFY) != ERROR_SUCCESS) | 306 if (key_.Open(HKEY_LOCAL_MACHINE, key, KEY_NOTIFY) != ERROR_SUCCESS) |
301 return false; | 307 return false; |
302 | 308 |
303 return key_.StartWatching(base::Bind(&RegistryWatcher::OnObjectSignaled, | 309 return key_.StartWatching(base::Bind(&RegistryWatcher::OnObjectSignaled, |
304 base::Unretained(this))); | 310 base::Unretained(this))); |
305 } | 311 } |
306 | 312 |
307 void OnObjectSignaled() { | 313 void OnObjectSignaled() { |
308 DCHECK(CalledOnValidThread()); | 314 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
309 DCHECK(!callback_.is_null()); | 315 DCHECK(!callback_.is_null()); |
310 if (key_.StartWatching(base::Bind(&RegistryWatcher::OnObjectSignaled, | 316 if (key_.StartWatching(base::Bind(&RegistryWatcher::OnObjectSignaled, |
311 base::Unretained(this)))) { | 317 base::Unretained(this)))) { |
312 callback_.Run(true); | 318 callback_.Run(true); |
313 } else { | 319 } else { |
314 key_.Close(); | 320 key_.Close(); |
315 callback_.Run(false); | 321 callback_.Run(false); |
316 } | 322 } |
317 } | 323 } |
318 | 324 |
319 private: | 325 private: |
320 CallbackType callback_; | 326 CallbackType callback_; |
321 base::win::RegKey key_; | 327 base::win::RegKey key_; |
322 | 328 |
| 329 THREAD_CHECKER(thread_checker_); |
| 330 |
323 DISALLOW_COPY_AND_ASSIGN(RegistryWatcher); | 331 DISALLOW_COPY_AND_ASSIGN(RegistryWatcher); |
324 }; | 332 }; |
325 | 333 |
326 // Returns true iff |address| is DNS address from IPv6 stateless discovery, | 334 // Returns true iff |address| is DNS address from IPv6 stateless discovery, |
327 // i.e., matches fec0:0:0:ffff::{1,2,3}. | 335 // i.e., matches fec0:0:0:ffff::{1,2,3}. |
328 // http://tools.ietf.org/html/draft-ietf-ipngwg-dns-discovery | 336 // http://tools.ietf.org/html/draft-ietf-ipngwg-dns-discovery |
329 bool IsStatelessDiscoveryAddress(const IPAddress& address) { | 337 bool IsStatelessDiscoveryAddress(const IPAddress& address) { |
330 if (!address.IsIPv6()) | 338 if (!address.IsIPv6()) |
331 return false; | 339 return false; |
332 const uint8_t kPrefix[] = {0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | 340 const uint8_t kPrefix[] = {0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 } | 772 } |
765 | 773 |
766 } // namespace internal | 774 } // namespace internal |
767 | 775 |
768 // static | 776 // static |
769 std::unique_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { | 777 std::unique_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { |
770 return std::unique_ptr<DnsConfigService>(new internal::DnsConfigServiceWin()); | 778 return std::unique_ptr<DnsConfigService>(new internal::DnsConfigServiceWin()); |
771 } | 779 } |
772 | 780 |
773 } // namespace net | 781 } // namespace net |
OLD | NEW |