| 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 <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 return true; | 83 return true; |
| 84 } | 84 } |
| 85 LONG result = key_.ReadValue(name, &out->value); | 85 LONG result = key_.ReadValue(name, &out->value); |
| 86 if (result == ERROR_SUCCESS) { | 86 if (result == ERROR_SUCCESS) { |
| 87 out->set = true; | 87 out->set = true; |
| 88 return true; | 88 return true; |
| 89 } | 89 } |
| 90 return (result == ERROR_FILE_NOT_FOUND); | 90 return (result == ERROR_FILE_NOT_FOUND); |
| 91 } | 91 } |
| 92 | 92 |
| 93 bool ReadDword(const wchar_t* name, | 93 bool ReadDword(const wchar_t* name, DnsSystemSettings::RegDword* out) const { |
| 94 DnsSystemSettings::RegDword* out) const { | |
| 95 DCHECK(CalledOnValidThread()); | 94 DCHECK(CalledOnValidThread()); |
| 96 out->set = false; | 95 out->set = false; |
| 97 if (!key_.Valid()) { | 96 if (!key_.Valid()) { |
| 98 // Assume that if the |key_| is invalid then the key is missing. | 97 // Assume that if the |key_| is invalid then the key is missing. |
| 99 return true; | 98 return true; |
| 100 } | 99 } |
| 101 LONG result = key_.ReadValueDW(name, &out->value); | 100 LONG result = key_.ReadValueDW(name, &out->value); |
| 102 if (result == ERROR_SUCCESS) { | 101 if (result == ERROR_SUCCESS) { |
| 103 out->set = true; | 102 out->set = true; |
| 104 return true; | 103 return true; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 } | 159 } |
| 161 | 160 |
| 162 bool ReadDevolutionSetting(const RegistryReader& reader, | 161 bool ReadDevolutionSetting(const RegistryReader& reader, |
| 163 DnsSystemSettings::DevolutionSetting* setting) { | 162 DnsSystemSettings::DevolutionSetting* setting) { |
| 164 return reader.ReadDword(L"UseDomainNameDevolution", &setting->enabled) && | 163 return reader.ReadDword(L"UseDomainNameDevolution", &setting->enabled) && |
| 165 reader.ReadDword(L"DomainNameDevolutionLevel", &setting->level); | 164 reader.ReadDword(L"DomainNameDevolutionLevel", &setting->level); |
| 166 } | 165 } |
| 167 | 166 |
| 168 // Reads DnsSystemSettings from IpHelper and registry. | 167 // Reads DnsSystemSettings from IpHelper and registry. |
| 169 ConfigParseWinResult ReadSystemSettings(DnsSystemSettings* settings) { | 168 ConfigParseWinResult ReadSystemSettings(DnsSystemSettings* settings) { |
| 170 settings->addresses = ReadIpHelper(GAA_FLAG_SKIP_ANYCAST | | 169 settings->addresses = |
| 171 GAA_FLAG_SKIP_UNICAST | | 170 ReadIpHelper(GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_UNICAST | |
| 172 GAA_FLAG_SKIP_MULTICAST | | 171 GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME); |
| 173 GAA_FLAG_SKIP_FRIENDLY_NAME); | |
| 174 if (!settings->addresses.get()) | 172 if (!settings->addresses.get()) |
| 175 return CONFIG_PARSE_WIN_READ_IPHELPER; | 173 return CONFIG_PARSE_WIN_READ_IPHELPER; |
| 176 | 174 |
| 177 RegistryReader tcpip_reader(kTcpipPath); | 175 RegistryReader tcpip_reader(kTcpipPath); |
| 178 RegistryReader tcpip6_reader(kTcpip6Path); | 176 RegistryReader tcpip6_reader(kTcpip6Path); |
| 179 RegistryReader dnscache_reader(kDnscachePath); | 177 RegistryReader dnscache_reader(kDnscachePath); |
| 180 RegistryReader policy_reader(kPolicyPath); | 178 RegistryReader policy_reader(kPolicyPath); |
| 181 RegistryReader primary_dns_suffix_reader(kPrimaryDnsSuffixPath); | 179 RegistryReader primary_dns_suffix_reader(kPrimaryDnsSuffixPath); |
| 182 | 180 |
| 183 if (!policy_reader.ReadString(L"SearchList", | 181 if (!policy_reader.ReadString(L"SearchList", &settings->policy_search_list)) { |
| 184 &settings->policy_search_list)) { | |
| 185 return CONFIG_PARSE_WIN_READ_POLICY_SEARCHLIST; | 182 return CONFIG_PARSE_WIN_READ_POLICY_SEARCHLIST; |
| 186 } | 183 } |
| 187 | 184 |
| 188 if (!tcpip_reader.ReadString(L"SearchList", &settings->tcpip_search_list)) | 185 if (!tcpip_reader.ReadString(L"SearchList", &settings->tcpip_search_list)) |
| 189 return CONFIG_PARSE_WIN_READ_TCPIP_SEARCHLIST; | 186 return CONFIG_PARSE_WIN_READ_TCPIP_SEARCHLIST; |
| 190 | 187 |
| 191 if (!tcpip_reader.ReadString(L"Domain", &settings->tcpip_domain)) | 188 if (!tcpip_reader.ReadString(L"Domain", &settings->tcpip_domain)) |
| 192 return CONFIG_PARSE_WIN_READ_DOMAIN; | 189 return CONFIG_PARSE_WIN_READ_DOMAIN; |
| 193 | 190 |
| 194 if (!ReadDevolutionSetting(policy_reader, &settings->policy_devolution)) | 191 if (!ReadDevolutionSetting(policy_reader, &settings->policy_devolution)) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 212 | 209 |
| 213 base::win::RegistryKeyIterator nrpt_rules(HKEY_LOCAL_MACHINE, kNRPTPath); | 210 base::win::RegistryKeyIterator nrpt_rules(HKEY_LOCAL_MACHINE, kNRPTPath); |
| 214 settings->have_name_resolution_policy = (nrpt_rules.SubkeyCount() > 0); | 211 settings->have_name_resolution_policy = (nrpt_rules.SubkeyCount() > 0); |
| 215 | 212 |
| 216 return CONFIG_PARSE_WIN_OK; | 213 return CONFIG_PARSE_WIN_OK; |
| 217 } | 214 } |
| 218 | 215 |
| 219 // Default address of "localhost" and local computer name can be overridden | 216 // Default address of "localhost" and local computer name can be overridden |
| 220 // by the HOSTS file, but if it's not there, then we need to fill it in. | 217 // by the HOSTS file, but if it's not there, then we need to fill it in. |
| 221 HostsParseWinResult AddLocalhostEntries(DnsHosts* hosts) { | 218 HostsParseWinResult AddLocalhostEntries(DnsHosts* hosts) { |
| 222 const unsigned char kIPv4Localhost[] = { 127, 0, 0, 1 }; | 219 const unsigned char kIPv4Localhost[] = {127, 0, 0, 1}; |
| 223 const unsigned char kIPv6Localhost[] = { 0, 0, 0, 0, 0, 0, 0, 0, | 220 const unsigned char kIPv6Localhost[] = {0, 0, 0, 0, 0, 0, 0, 0, |
| 224 0, 0, 0, 0, 0, 0, 0, 1 }; | 221 0, 0, 0, 0, 0, 0, 0, 1}; |
| 225 IPAddressNumber loopback_ipv4(kIPv4Localhost, | 222 IPAddressNumber loopback_ipv4(kIPv4Localhost, |
| 226 kIPv4Localhost + arraysize(kIPv4Localhost)); | 223 kIPv4Localhost + arraysize(kIPv4Localhost)); |
| 227 IPAddressNumber loopback_ipv6(kIPv6Localhost, | 224 IPAddressNumber loopback_ipv6(kIPv6Localhost, |
| 228 kIPv6Localhost + arraysize(kIPv6Localhost)); | 225 kIPv6Localhost + arraysize(kIPv6Localhost)); |
| 229 | 226 |
| 230 // This does not override any pre-existing entries from the HOSTS file. | 227 // This does not override any pre-existing entries from the HOSTS file. |
| 231 hosts->insert(std::make_pair(DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4), | 228 hosts->insert(std::make_pair(DnsHostsKey("localhost", ADDRESS_FAMILY_IPV4), |
| 232 loopback_ipv4)); | 229 loopback_ipv4)); |
| 233 hosts->insert(std::make_pair(DnsHostsKey("localhost", ADDRESS_FAMILY_IPV6), | 230 hosts->insert(std::make_pair(DnsHostsKey("localhost", ADDRESS_FAMILY_IPV6), |
| 234 loopback_ipv6)); | 231 loopback_ipv6)); |
| 235 | 232 |
| 236 WCHAR buffer[MAX_PATH]; | 233 WCHAR buffer[MAX_PATH]; |
| 237 DWORD size = MAX_PATH; | 234 DWORD size = MAX_PATH; |
| 238 std::string localname; | 235 std::string localname; |
| 239 if (!GetComputerNameExW(ComputerNameDnsHostname, buffer, &size) || | 236 if (!GetComputerNameExW(ComputerNameDnsHostname, buffer, &size) || |
| 240 !ParseDomainASCII(buffer, &localname)) { | 237 !ParseDomainASCII(buffer, &localname)) { |
| 241 return HOSTS_PARSE_WIN_COMPUTER_NAME_FAILED; | 238 return HOSTS_PARSE_WIN_COMPUTER_NAME_FAILED; |
| 242 } | 239 } |
| 243 StringToLowerASCII(&localname); | 240 StringToLowerASCII(&localname); |
| 244 | 241 |
| 245 bool have_ipv4 = | 242 bool have_ipv4 = |
| 246 hosts->count(DnsHostsKey(localname, ADDRESS_FAMILY_IPV4)) > 0; | 243 hosts->count(DnsHostsKey(localname, ADDRESS_FAMILY_IPV4)) > 0; |
| 247 bool have_ipv6 = | 244 bool have_ipv6 = |
| 248 hosts->count(DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)) > 0; | 245 hosts->count(DnsHostsKey(localname, ADDRESS_FAMILY_IPV6)) > 0; |
| 249 | 246 |
| 250 if (have_ipv4 && have_ipv6) | 247 if (have_ipv4 && have_ipv6) |
| 251 return HOSTS_PARSE_WIN_OK; | 248 return HOSTS_PARSE_WIN_OK; |
| 252 | 249 |
| 253 scoped_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> addresses = | 250 scoped_ptr<IP_ADAPTER_ADDRESSES, base::FreeDeleter> addresses = |
| 254 ReadIpHelper(GAA_FLAG_SKIP_ANYCAST | | 251 ReadIpHelper(GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER | |
| 255 GAA_FLAG_SKIP_DNS_SERVER | | 252 GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME); |
| 256 GAA_FLAG_SKIP_MULTICAST | | |
| 257 GAA_FLAG_SKIP_FRIENDLY_NAME); | |
| 258 if (!addresses.get()) | 253 if (!addresses.get()) |
| 259 return HOSTS_PARSE_WIN_IPHELPER_FAILED; | 254 return HOSTS_PARSE_WIN_IPHELPER_FAILED; |
| 260 | 255 |
| 261 // The order of adapters is the network binding order, so stick to the | 256 // The order of adapters is the network binding order, so stick to the |
| 262 // first good adapter for each family. | 257 // first good adapter for each family. |
| 263 for (const IP_ADAPTER_ADDRESSES* adapter = addresses.get(); | 258 for (const IP_ADAPTER_ADDRESSES* adapter = addresses.get(); |
| 264 adapter != NULL && (!have_ipv4 || !have_ipv6); | 259 adapter != NULL && (!have_ipv4 || !have_ipv6); |
| 265 adapter = adapter->Next) { | 260 adapter = adapter->Next) { |
| 266 if (adapter->OperStatus != IfOperStatusUp) | 261 if (adapter->OperStatus != IfOperStatusUp) |
| 267 continue; | 262 continue; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 if (key_.StartWatching() != ERROR_SUCCESS) | 301 if (key_.StartWatching() != ERROR_SUCCESS) |
| 307 return false; | 302 return false; |
| 308 if (!watcher_.StartWatching(key_.watch_event(), this)) | 303 if (!watcher_.StartWatching(key_.watch_event(), this)) |
| 309 return false; | 304 return false; |
| 310 return true; | 305 return true; |
| 311 } | 306 } |
| 312 | 307 |
| 313 virtual void OnObjectSignaled(HANDLE object) OVERRIDE { | 308 virtual void OnObjectSignaled(HANDLE object) OVERRIDE { |
| 314 DCHECK(CalledOnValidThread()); | 309 DCHECK(CalledOnValidThread()); |
| 315 bool succeeded = (key_.StartWatching() == ERROR_SUCCESS) && | 310 bool succeeded = (key_.StartWatching() == ERROR_SUCCESS) && |
| 316 watcher_.StartWatching(key_.watch_event(), this); | 311 watcher_.StartWatching(key_.watch_event(), this); |
| 317 if (!succeeded && key_.Valid()) { | 312 if (!succeeded && key_.Valid()) { |
| 318 watcher_.StopWatching(); | 313 watcher_.StopWatching(); |
| 319 key_.StopWatching(); | 314 key_.StopWatching(); |
| 320 key_.Close(); | 315 key_.Close(); |
| 321 } | 316 } |
| 322 if (!callback_.is_null()) | 317 if (!callback_.is_null()) |
| 323 callback_.Run(succeeded); | 318 callback_.Run(succeeded); |
| 324 } | 319 } |
| 325 | 320 |
| 326 private: | 321 private: |
| 327 CallbackType callback_; | 322 CallbackType callback_; |
| 328 base::win::RegKey key_; | 323 base::win::RegKey key_; |
| 329 base::win::ObjectWatcher watcher_; | 324 base::win::ObjectWatcher watcher_; |
| 330 | 325 |
| 331 DISALLOW_COPY_AND_ASSIGN(RegistryWatcher); | 326 DISALLOW_COPY_AND_ASSIGN(RegistryWatcher); |
| 332 }; | 327 }; |
| 333 | 328 |
| 334 // Returns true iff |address| is DNS address from IPv6 stateless discovery, | 329 // Returns true iff |address| is DNS address from IPv6 stateless discovery, |
| 335 // i.e., matches fec0:0:0:ffff::{1,2,3}. | 330 // i.e., matches fec0:0:0:ffff::{1,2,3}. |
| 336 // http://tools.ietf.org/html/draft-ietf-ipngwg-dns-discovery | 331 // http://tools.ietf.org/html/draft-ietf-ipngwg-dns-discovery |
| 337 bool IsStatelessDiscoveryAddress(const IPAddressNumber& address) { | 332 bool IsStatelessDiscoveryAddress(const IPAddressNumber& address) { |
| 338 if (address.size() != kIPv6AddressSize) | 333 if (address.size() != kIPv6AddressSize) |
| 339 return false; | 334 return false; |
| 340 const uint8 kPrefix[] = { | 335 const uint8 kPrefix[] = { |
| 341 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | 336 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, |
| 342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 343 }; | 338 }; |
| 344 return std::equal(kPrefix, kPrefix + arraysize(kPrefix), | 339 return std::equal(kPrefix, kPrefix + arraysize(kPrefix), address.begin()) && |
| 345 address.begin()) && (address.back() < 4); | 340 (address.back() < 4); |
| 346 } | 341 } |
| 347 | 342 |
| 348 // Returns the path to the HOSTS file. | 343 // Returns the path to the HOSTS file. |
| 349 base::FilePath GetHostsPath() { | 344 base::FilePath GetHostsPath() { |
| 350 TCHAR buffer[MAX_PATH]; | 345 TCHAR buffer[MAX_PATH]; |
| 351 UINT rc = GetSystemDirectory(buffer, MAX_PATH); | 346 UINT rc = GetSystemDirectory(buffer, MAX_PATH); |
| 352 DCHECK(0 < rc && rc < MAX_PATH); | 347 DCHECK(0 < rc && rc < MAX_PATH); |
| 353 return base::FilePath(buffer).Append( | 348 return base::FilePath(buffer) |
| 354 FILE_PATH_LITERAL("drivers\\etc\\hosts")); | 349 .Append(FILE_PATH_LITERAL("drivers\\etc\\hosts")); |
| 355 } | 350 } |
| 356 | 351 |
| 357 void ConfigureSuffixSearch(const DnsSystemSettings& settings, | 352 void ConfigureSuffixSearch(const DnsSystemSettings& settings, |
| 358 DnsConfig* config) { | 353 DnsConfig* config) { |
| 359 // SearchList takes precedence, so check it first. | 354 // SearchList takes precedence, so check it first. |
| 360 if (settings.policy_search_list.set) { | 355 if (settings.policy_search_list.set) { |
| 361 std::vector<std::string> search; | 356 std::vector<std::string> search; |
| 362 if (ParseSearchList(settings.policy_search_list.value, &search)) { | 357 if (ParseSearchList(settings.policy_search_list.value, &search)) { |
| 363 config->search.swap(search); | 358 config->search.swap(search); |
| 364 return; | 359 return; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 // devolution setting. | 417 // devolution setting. |
| 423 // | 418 // |
| 424 // If the level is explicitly set below 2, devolution is disabled. | 419 // If the level is explicitly set below 2, devolution is disabled. |
| 425 if (!devolution.level.set || devolution.level.value < 2) | 420 if (!devolution.level.set || devolution.level.value < 2) |
| 426 return; // Devolution disabled. | 421 return; // Devolution disabled. |
| 427 | 422 |
| 428 // Devolve the primary suffix. This naive logic matches the observed | 423 // Devolve the primary suffix. This naive logic matches the observed |
| 429 // behavior (see also ParseSearchList). If a suffix is not valid, it will be | 424 // behavior (see also ParseSearchList). If a suffix is not valid, it will be |
| 430 // discarded when the fully-qualified name is converted to DNS format. | 425 // discarded when the fully-qualified name is converted to DNS format. |
| 431 | 426 |
| 432 unsigned num_dots = std::count(primary_suffix.begin(), | 427 unsigned num_dots = |
| 433 primary_suffix.end(), '.'); | 428 std::count(primary_suffix.begin(), primary_suffix.end(), '.'); |
| 434 | 429 |
| 435 for (size_t offset = 0; num_dots >= devolution.level.value; --num_dots) { | 430 for (size_t offset = 0; num_dots >= devolution.level.value; --num_dots) { |
| 436 offset = primary_suffix.find('.', offset + 1); | 431 offset = primary_suffix.find('.', offset + 1); |
| 437 config->search.push_back(primary_suffix.substr(offset + 1)); | 432 config->search.push_back(primary_suffix.substr(offset + 1)); |
| 438 } | 433 } |
| 439 } | 434 } |
| 440 | 435 |
| 441 } // namespace | 436 } // namespace |
| 442 | 437 |
| 443 bool ParseSearchList(const base::string16& value, | 438 bool ParseSearchList(const base::string16& value, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 ConfigureSuffixSearch(settings, config); | 535 ConfigureSuffixSearch(settings, config); |
| 541 return result; | 536 return result; |
| 542 } | 537 } |
| 543 | 538 |
| 544 // Watches registry and HOSTS file for changes. Must live on a thread which | 539 // Watches registry and HOSTS file for changes. Must live on a thread which |
| 545 // allows IO. | 540 // allows IO. |
| 546 class DnsConfigServiceWin::Watcher | 541 class DnsConfigServiceWin::Watcher |
| 547 : public NetworkChangeNotifier::IPAddressObserver { | 542 : public NetworkChangeNotifier::IPAddressObserver { |
| 548 public: | 543 public: |
| 549 explicit Watcher(DnsConfigServiceWin* service) : service_(service) {} | 544 explicit Watcher(DnsConfigServiceWin* service) : service_(service) {} |
| 550 ~Watcher() { | 545 ~Watcher() { NetworkChangeNotifier::RemoveIPAddressObserver(this); } |
| 551 NetworkChangeNotifier::RemoveIPAddressObserver(this); | |
| 552 } | |
| 553 | 546 |
| 554 bool Watch() { | 547 bool Watch() { |
| 555 RegistryWatcher::CallbackType callback = | 548 RegistryWatcher::CallbackType callback = base::Bind( |
| 556 base::Bind(&DnsConfigServiceWin::OnConfigChanged, | 549 &DnsConfigServiceWin::OnConfigChanged, base::Unretained(service_)); |
| 557 base::Unretained(service_)); | |
| 558 | 550 |
| 559 bool success = true; | 551 bool success = true; |
| 560 | 552 |
| 561 // The Tcpip key must be present. | 553 // The Tcpip key must be present. |
| 562 if (!tcpip_watcher_.Watch(kTcpipPath, callback)) { | 554 if (!tcpip_watcher_.Watch(kTcpipPath, callback)) { |
| 563 LOG(ERROR) << "DNS registry watch failed to start."; | 555 LOG(ERROR) << "DNS registry watch failed to start."; |
| 564 success = false; | 556 success = false; |
| 565 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", | 557 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", |
| 566 DNS_CONFIG_WATCH_FAILED_TO_START_CONFIG, | 558 DNS_CONFIG_WATCH_FAILED_TO_START_CONFIG, |
| 567 DNS_CONFIG_WATCH_MAX); | 559 DNS_CONFIG_WATCH_MAX); |
| 568 } | 560 } |
| 569 | 561 |
| 570 // Watch for IPv6 nameservers. | 562 // Watch for IPv6 nameservers. |
| 571 tcpip6_watcher_.Watch(kTcpip6Path, callback); | 563 tcpip6_watcher_.Watch(kTcpip6Path, callback); |
| 572 | 564 |
| 573 // DNS suffix search list and devolution can be configured via group | 565 // DNS suffix search list and devolution can be configured via group |
| 574 // policy which sets this registry key. If the key is missing, the policy | 566 // policy which sets this registry key. If the key is missing, the policy |
| 575 // does not apply, and the DNS client uses Tcpip and Dnscache settings. | 567 // does not apply, and the DNS client uses Tcpip and Dnscache settings. |
| 576 // If a policy is installed, DnsConfigService will need to be restarted. | 568 // If a policy is installed, DnsConfigService will need to be restarted. |
| 577 // BUG=99509 | 569 // BUG=99509 |
| 578 | 570 |
| 579 dnscache_watcher_.Watch(kDnscachePath, callback); | 571 dnscache_watcher_.Watch(kDnscachePath, callback); |
| 580 policy_watcher_.Watch(kPolicyPath, callback); | 572 policy_watcher_.Watch(kPolicyPath, callback); |
| 581 | 573 |
| 582 if (!hosts_watcher_.Watch(GetHostsPath(), false, | 574 if (!hosts_watcher_.Watch( |
| 583 base::Bind(&Watcher::OnHostsChanged, | 575 GetHostsPath(), |
| 584 base::Unretained(this)))) { | 576 false, |
| 577 base::Bind(&Watcher::OnHostsChanged, base::Unretained(this)))) { |
| 585 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", | 578 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", |
| 586 DNS_CONFIG_WATCH_FAILED_TO_START_HOSTS, | 579 DNS_CONFIG_WATCH_FAILED_TO_START_HOSTS, |
| 587 DNS_CONFIG_WATCH_MAX); | 580 DNS_CONFIG_WATCH_MAX); |
| 588 LOG(ERROR) << "DNS hosts watch failed to start."; | 581 LOG(ERROR) << "DNS hosts watch failed to start."; |
| 589 success = false; | 582 success = false; |
| 590 } else { | 583 } else { |
| 591 // Also need to observe changes to local non-loopback IP for DnsHosts. | 584 // Also need to observe changes to local non-loopback IP for DnsHosts. |
| 592 NetworkChangeNotifier::AddIPAddressObserver(this); | 585 NetworkChangeNotifier::AddIPAddressObserver(this); |
| 593 } | 586 } |
| 594 return success; | 587 return success; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 615 RegistryWatcher policy_watcher_; | 608 RegistryWatcher policy_watcher_; |
| 616 base::FilePathWatcher hosts_watcher_; | 609 base::FilePathWatcher hosts_watcher_; |
| 617 | 610 |
| 618 DISALLOW_COPY_AND_ASSIGN(Watcher); | 611 DISALLOW_COPY_AND_ASSIGN(Watcher); |
| 619 }; | 612 }; |
| 620 | 613 |
| 621 // Reads config from registry and IpHelper. All work performed on WorkerPool. | 614 // Reads config from registry and IpHelper. All work performed on WorkerPool. |
| 622 class DnsConfigServiceWin::ConfigReader : public SerialWorker { | 615 class DnsConfigServiceWin::ConfigReader : public SerialWorker { |
| 623 public: | 616 public: |
| 624 explicit ConfigReader(DnsConfigServiceWin* service) | 617 explicit ConfigReader(DnsConfigServiceWin* service) |
| 625 : service_(service), | 618 : service_(service), success_(false) {} |
| 626 success_(false) {} | |
| 627 | 619 |
| 628 private: | 620 private: |
| 629 virtual ~ConfigReader() {} | 621 virtual ~ConfigReader() {} |
| 630 | 622 |
| 631 virtual void DoWork() OVERRIDE { | 623 virtual void DoWork() OVERRIDE { |
| 632 // Should be called on WorkerPool. | 624 // Should be called on WorkerPool. |
| 633 base::TimeTicks start_time = base::TimeTicks::Now(); | 625 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 634 DnsSystemSettings settings = {}; | 626 DnsSystemSettings settings = {}; |
| 635 ConfigParseWinResult result = ReadSystemSettings(&settings); | 627 ConfigParseWinResult result = ReadSystemSettings(&settings); |
| 636 if (result == CONFIG_PARSE_WIN_OK) | 628 if (result == CONFIG_PARSE_WIN_OK) |
| 637 result = ConvertSettingsToDnsConfig(settings, &dns_config_); | 629 result = ConvertSettingsToDnsConfig(settings, &dns_config_); |
| 638 success_ = (result == CONFIG_PARSE_WIN_OK || | 630 success_ = (result == CONFIG_PARSE_WIN_OK || |
| 639 result == CONFIG_PARSE_WIN_UNHANDLED_OPTIONS); | 631 result == CONFIG_PARSE_WIN_UNHANDLED_OPTIONS); |
| 640 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ConfigParseWin", | 632 UMA_HISTOGRAM_ENUMERATION( |
| 641 result, CONFIG_PARSE_WIN_MAX); | 633 "AsyncDNS.ConfigParseWin", result, CONFIG_PARSE_WIN_MAX); |
| 642 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.ConfigParseResult", success_); | 634 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.ConfigParseResult", success_); |
| 643 UMA_HISTOGRAM_TIMES("AsyncDNS.ConfigParseDuration", | 635 UMA_HISTOGRAM_TIMES("AsyncDNS.ConfigParseDuration", |
| 644 base::TimeTicks::Now() - start_time); | 636 base::TimeTicks::Now() - start_time); |
| 645 } | 637 } |
| 646 | 638 |
| 647 virtual void OnWorkFinished() OVERRIDE { | 639 virtual void OnWorkFinished() OVERRIDE { |
| 648 DCHECK(loop()->BelongsToCurrentThread()); | 640 DCHECK(loop()->BelongsToCurrentThread()); |
| 649 DCHECK(!IsCancelled()); | 641 DCHECK(!IsCancelled()); |
| 650 if (success_) { | 642 if (success_) { |
| 651 service_->OnConfigRead(dns_config_); | 643 service_->OnConfigRead(dns_config_); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 663 // Written in DoWork(), read in OnWorkFinished(). No locking required. | 655 // Written in DoWork(), read in OnWorkFinished(). No locking required. |
| 664 DnsConfig dns_config_; | 656 DnsConfig dns_config_; |
| 665 bool success_; | 657 bool success_; |
| 666 }; | 658 }; |
| 667 | 659 |
| 668 // Reads hosts from HOSTS file and fills in localhost and local computer name if | 660 // Reads hosts from HOSTS file and fills in localhost and local computer name if |
| 669 // necessary. All work performed on WorkerPool. | 661 // necessary. All work performed on WorkerPool. |
| 670 class DnsConfigServiceWin::HostsReader : public SerialWorker { | 662 class DnsConfigServiceWin::HostsReader : public SerialWorker { |
| 671 public: | 663 public: |
| 672 explicit HostsReader(DnsConfigServiceWin* service) | 664 explicit HostsReader(DnsConfigServiceWin* service) |
| 673 : path_(GetHostsPath()), | 665 : path_(GetHostsPath()), service_(service), success_(false) {} |
| 674 service_(service), | |
| 675 success_(false) { | |
| 676 } | |
| 677 | 666 |
| 678 private: | 667 private: |
| 679 virtual ~HostsReader() {} | 668 virtual ~HostsReader() {} |
| 680 | 669 |
| 681 virtual void DoWork() OVERRIDE { | 670 virtual void DoWork() OVERRIDE { |
| 682 base::TimeTicks start_time = base::TimeTicks::Now(); | 671 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 683 HostsParseWinResult result = HOSTS_PARSE_WIN_UNREADABLE_HOSTS_FILE; | 672 HostsParseWinResult result = HOSTS_PARSE_WIN_UNREADABLE_HOSTS_FILE; |
| 684 if (ParseHostsFile(path_, &hosts_)) | 673 if (ParseHostsFile(path_, &hosts_)) |
| 685 result = AddLocalhostEntries(&hosts_); | 674 result = AddLocalhostEntries(&hosts_); |
| 686 success_ = (result == HOSTS_PARSE_WIN_OK); | 675 success_ = (result == HOSTS_PARSE_WIN_OK); |
| 687 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.HostsParseWin", | 676 UMA_HISTOGRAM_ENUMERATION( |
| 688 result, HOSTS_PARSE_WIN_MAX); | 677 "AsyncDNS.HostsParseWin", result, HOSTS_PARSE_WIN_MAX); |
| 689 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HostParseResult", success_); | 678 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HostParseResult", success_); |
| 690 UMA_HISTOGRAM_TIMES("AsyncDNS.HostsParseDuration", | 679 UMA_HISTOGRAM_TIMES("AsyncDNS.HostsParseDuration", |
| 691 base::TimeTicks::Now() - start_time); | 680 base::TimeTicks::Now() - start_time); |
| 692 } | 681 } |
| 693 | 682 |
| 694 virtual void OnWorkFinished() OVERRIDE { | 683 virtual void OnWorkFinished() OVERRIDE { |
| 695 DCHECK(loop()->BelongsToCurrentThread()); | 684 DCHECK(loop()->BelongsToCurrentThread()); |
| 696 if (success_) { | 685 if (success_) { |
| 697 service_->OnHostsRead(hosts_); | 686 service_->OnHostsRead(hosts_); |
| 698 } else { | 687 } else { |
| 699 LOG(WARNING) << "Failed to read DnsHosts."; | 688 LOG(WARNING) << "Failed to read DnsHosts."; |
| 700 } | 689 } |
| 701 } | 690 } |
| 702 | 691 |
| 703 const base::FilePath path_; | 692 const base::FilePath path_; |
| 704 DnsConfigServiceWin* service_; | 693 DnsConfigServiceWin* service_; |
| 705 // Written in DoWork, read in OnWorkFinished, no locking necessary. | 694 // Written in DoWork, read in OnWorkFinished, no locking necessary. |
| 706 DnsHosts hosts_; | 695 DnsHosts hosts_; |
| 707 bool success_; | 696 bool success_; |
| 708 | 697 |
| 709 DISALLOW_COPY_AND_ASSIGN(HostsReader); | 698 DISALLOW_COPY_AND_ASSIGN(HostsReader); |
| 710 }; | 699 }; |
| 711 | 700 |
| 712 DnsConfigServiceWin::DnsConfigServiceWin() | 701 DnsConfigServiceWin::DnsConfigServiceWin() |
| 713 : config_reader_(new ConfigReader(this)), | 702 : config_reader_(new ConfigReader(this)), |
| 714 hosts_reader_(new HostsReader(this)) {} | 703 hosts_reader_(new HostsReader(this)) { |
| 704 } |
| 715 | 705 |
| 716 DnsConfigServiceWin::~DnsConfigServiceWin() { | 706 DnsConfigServiceWin::~DnsConfigServiceWin() { |
| 717 config_reader_->Cancel(); | 707 config_reader_->Cancel(); |
| 718 hosts_reader_->Cancel(); | 708 hosts_reader_->Cancel(); |
| 719 } | 709 } |
| 720 | 710 |
| 721 void DnsConfigServiceWin::ReadNow() { | 711 void DnsConfigServiceWin::ReadNow() { |
| 722 config_reader_->WorkNow(); | 712 config_reader_->WorkNow(); |
| 723 hosts_reader_->WorkNow(); | 713 hosts_reader_->WorkNow(); |
| 724 } | 714 } |
| 725 | 715 |
| 726 bool DnsConfigServiceWin::StartWatching() { | 716 bool DnsConfigServiceWin::StartWatching() { |
| 727 // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139 | 717 // TODO(szym): re-start watcher if that makes sense. http://crbug.com/116139 |
| 728 watcher_.reset(new Watcher(this)); | 718 watcher_.reset(new Watcher(this)); |
| 729 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.WatchStatus", DNS_CONFIG_WATCH_STARTED, | 719 UMA_HISTOGRAM_ENUMERATION( |
| 730 DNS_CONFIG_WATCH_MAX); | 720 "AsyncDNS.WatchStatus", DNS_CONFIG_WATCH_STARTED, DNS_CONFIG_WATCH_MAX); |
| 731 return watcher_->Watch(); | 721 return watcher_->Watch(); |
| 732 } | 722 } |
| 733 | 723 |
| 734 void DnsConfigServiceWin::OnConfigChanged(bool succeeded) { | 724 void DnsConfigServiceWin::OnConfigChanged(bool succeeded) { |
| 735 InvalidateConfig(); | 725 InvalidateConfig(); |
| 736 if (succeeded) { | 726 if (succeeded) { |
| 737 config_reader_->WorkNow(); | 727 config_reader_->WorkNow(); |
| 738 } else { | 728 } else { |
| 739 LOG(ERROR) << "DNS config watch failed."; | 729 LOG(ERROR) << "DNS config watch failed."; |
| 740 set_watch_failed(true); | 730 set_watch_failed(true); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 758 } | 748 } |
| 759 | 749 |
| 760 } // namespace internal | 750 } // namespace internal |
| 761 | 751 |
| 762 // static | 752 // static |
| 763 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { | 753 scoped_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { |
| 764 return scoped_ptr<DnsConfigService>(new internal::DnsConfigServiceWin()); | 754 return scoped_ptr<DnsConfigService>(new internal::DnsConfigServiceWin()); |
| 765 } | 755 } |
| 766 | 756 |
| 767 } // namespace net | 757 } // namespace net |
| OLD | NEW |