Chromium Code Reviews| 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/host_resolver_impl.h" | 5 #include "net/dns/host_resolver_impl.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <Winsock2.h> | 8 #include <Winsock2.h> |
| 9 #elif defined(OS_POSIX) | 9 #elif defined(OS_POSIX) |
| 10 #include <netdb.h> | 10 #include <netdb.h> |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 const size_t kSuffixLenTrimmed = kSuffixLen - 1; | 224 const size_t kSuffixLenTrimmed = kSuffixLen - 1; |
| 225 if (hostname.back() == '.') { | 225 if (hostname.back() == '.') { |
| 226 return hostname.size() > kSuffixLen && | 226 return hostname.size() > kSuffixLen && |
| 227 !hostname.compare(hostname.size() - kSuffixLen, kSuffixLen, kSuffix); | 227 !hostname.compare(hostname.size() - kSuffixLen, kSuffixLen, kSuffix); |
| 228 } | 228 } |
| 229 return hostname.size() > kSuffixLenTrimmed && | 229 return hostname.size() > kSuffixLenTrimmed && |
| 230 !hostname.compare(hostname.size() - kSuffixLenTrimmed, kSuffixLenTrimmed, | 230 !hostname.compare(hostname.size() - kSuffixLenTrimmed, kSuffixLenTrimmed, |
| 231 kSuffix, kSuffixLenTrimmed); | 231 kSuffix, kSuffixLenTrimmed); |
| 232 } | 232 } |
| 233 | 233 |
| 234 // Attempts to connect a UDP socket to |dest|:53. | |
| 235 bool IsGloballyReachable(const IPAddress& dest, | |
| 236 const NetLogWithSource& net_log) { | |
| 237 // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed. | |
| 238 tracked_objects::ScopedTracker tracking_profile_1( | |
| 239 FROM_HERE_WITH_EXPLICIT_FUNCTION("455942 IsGloballyReachable")); | |
| 240 | |
| 241 std::unique_ptr<DatagramClientSocket> socket( | |
| 242 ClientSocketFactory::GetDefaultFactory()->CreateDatagramClientSocket( | |
| 243 DatagramSocket::DEFAULT_BIND, RandIntCallback(), net_log.net_log(), | |
| 244 net_log.source())); | |
| 245 int rv = socket->Connect(IPEndPoint(dest, 53)); | |
| 246 if (rv != OK) | |
| 247 return false; | |
| 248 IPEndPoint endpoint; | |
| 249 rv = socket->GetLocalAddress(&endpoint); | |
| 250 if (rv != OK) | |
| 251 return false; | |
| 252 DCHECK_EQ(ADDRESS_FAMILY_IPV6, endpoint.GetFamily()); | |
| 253 const IPAddress& address = endpoint.address(); | |
| 254 | |
| 255 bool is_link_local = | |
| 256 (address.bytes()[0] == 0xFE) && ((address.bytes()[1] & 0xC0) == 0x80); | |
| 257 if (is_link_local) | |
| 258 return false; | |
| 259 | |
| 260 const uint8_t kTeredoPrefix[] = {0x20, 0x01, 0, 0}; | |
| 261 if (IPAddressStartsWith(address, kTeredoPrefix)) | |
| 262 return false; | |
| 263 | |
| 264 return true; | |
| 265 } | |
| 266 | |
| 267 // Provide a common macro to simplify code and readability. We must use a | 234 // Provide a common macro to simplify code and readability. We must use a |
| 268 // macro as the underlying HISTOGRAM macro creates static variables. | 235 // macro as the underlying HISTOGRAM macro creates static variables. |
| 269 #define DNS_HISTOGRAM(name, time) UMA_HISTOGRAM_CUSTOM_TIMES(name, time, \ | 236 #define DNS_HISTOGRAM(name, time) UMA_HISTOGRAM_CUSTOM_TIMES(name, time, \ |
| 270 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromHours(1), 100) | 237 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromHours(1), 100) |
| 271 | 238 |
| 272 // A macro to simplify code and readability. | 239 // A macro to simplify code and readability. |
| 273 #define DNS_HISTOGRAM_BY_PRIORITY(basename, priority, time) \ | 240 #define DNS_HISTOGRAM_BY_PRIORITY(basename, priority, time) \ |
| 274 do { \ | 241 do { \ |
| 275 switch (priority) { \ | 242 switch (priority) { \ |
| 276 case HIGHEST: DNS_HISTOGRAM(basename "_HIGHEST", time); break; \ | 243 case HIGHEST: DNS_HISTOGRAM(basename "_HIGHEST", time); break; \ |
| (...skipping 1796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2073 HostResolverImpl::HostResolverImpl( | 2040 HostResolverImpl::HostResolverImpl( |
| 2074 const Options& options, | 2041 const Options& options, |
| 2075 NetLog* net_log, | 2042 NetLog* net_log, |
| 2076 scoped_refptr<base::TaskRunner> worker_task_runner) | 2043 scoped_refptr<base::TaskRunner> worker_task_runner) |
| 2077 : max_queued_jobs_(0), | 2044 : max_queued_jobs_(0), |
| 2078 proc_params_(NULL, options.max_retry_attempts), | 2045 proc_params_(NULL, options.max_retry_attempts), |
| 2079 net_log_(net_log), | 2046 net_log_(net_log), |
| 2080 received_dns_config_(false), | 2047 received_dns_config_(false), |
| 2081 num_dns_failures_(0), | 2048 num_dns_failures_(0), |
| 2082 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), | 2049 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), |
| 2050 assume_ipv6_failure_on_wifi_(false), | |
| 2083 use_local_ipv6_(false), | 2051 use_local_ipv6_(false), |
| 2084 last_ipv6_probe_result_(true), | 2052 last_ipv6_probe_result_(true), |
| 2085 resolved_known_ipv6_hostname_(false), | 2053 resolved_known_ipv6_hostname_(false), |
| 2086 additional_resolver_flags_(0), | 2054 additional_resolver_flags_(0), |
| 2087 fallback_to_proctask_(true), | 2055 fallback_to_proctask_(true), |
| 2088 worker_task_runner_(std::move(worker_task_runner)), | 2056 worker_task_runner_(std::move(worker_task_runner)), |
| 2089 persist_initialized_(false), | 2057 persist_initialized_(false), |
| 2090 weak_ptr_factory_(this), | 2058 weak_ptr_factory_(this), |
| 2091 probe_weak_ptr_factory_(this) { | 2059 probe_weak_ptr_factory_(this) { |
| 2092 if (options.enable_caching) | 2060 if (options.enable_caching) |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2257 | 2225 |
| 2258 void HostResolverImpl::SetDefaultAddressFamily(AddressFamily address_family) { | 2226 void HostResolverImpl::SetDefaultAddressFamily(AddressFamily address_family) { |
| 2259 DCHECK(CalledOnValidThread()); | 2227 DCHECK(CalledOnValidThread()); |
| 2260 default_address_family_ = address_family; | 2228 default_address_family_ = address_family; |
| 2261 } | 2229 } |
| 2262 | 2230 |
| 2263 AddressFamily HostResolverImpl::GetDefaultAddressFamily() const { | 2231 AddressFamily HostResolverImpl::GetDefaultAddressFamily() const { |
| 2264 return default_address_family_; | 2232 return default_address_family_; |
| 2265 } | 2233 } |
| 2266 | 2234 |
| 2235 void HostResolverImpl::SetNoIPv6OnWifi() { | |
| 2236 DCHECK(CalledOnValidThread()); | |
| 2237 assume_ipv6_failure_on_wifi_ = true; | |
| 2238 } | |
| 2239 | |
| 2240 bool HostResolverImpl::GetNoIPv6OnWifi() { | |
| 2241 return assume_ipv6_failure_on_wifi_; | |
| 2242 } | |
| 2243 | |
| 2267 bool HostResolverImpl::ResolveAsIP(const Key& key, | 2244 bool HostResolverImpl::ResolveAsIP(const Key& key, |
| 2268 const RequestInfo& info, | 2245 const RequestInfo& info, |
| 2269 const IPAddress* ip_address, | 2246 const IPAddress* ip_address, |
| 2270 int* net_error, | 2247 int* net_error, |
| 2271 AddressList* addresses) { | 2248 AddressList* addresses) { |
| 2272 DCHECK(addresses); | 2249 DCHECK(addresses); |
| 2273 DCHECK(net_error); | 2250 DCHECK(net_error); |
| 2274 if (ip_address == nullptr) | 2251 if (ip_address == nullptr) |
| 2275 return false; | 2252 return false; |
| 2276 | 2253 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2435 // to receiving a IPv6 resolution. | 2412 // to receiving a IPv6 resolution. |
| 2436 !use_local_ipv6_ && ip_address == nullptr && !IsIPv6Reachable(net_log)) { | 2413 !use_local_ipv6_ && ip_address == nullptr && !IsIPv6Reachable(net_log)) { |
| 2437 effective_address_family = ADDRESS_FAMILY_IPV4; | 2414 effective_address_family = ADDRESS_FAMILY_IPV4; |
| 2438 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; | 2415 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; |
| 2439 } | 2416 } |
| 2440 | 2417 |
| 2441 return Key(info.hostname(), effective_address_family, effective_flags); | 2418 return Key(info.hostname(), effective_address_family, effective_flags); |
| 2442 } | 2419 } |
| 2443 | 2420 |
| 2444 bool HostResolverImpl::IsIPv6Reachable(const NetLogWithSource& net_log) { | 2421 bool HostResolverImpl::IsIPv6Reachable(const NetLogWithSource& net_log) { |
| 2422 // Don't bother checking if we're on wifi and we're assuming that IPv6 doesn't | |
|
pauljensen
2017/04/13 17:17:01
nit (and on next line): wifi->WiFi
pauljensen
2017/04/13 17:17:01
nit: I'm not sure which style-guide recommends it,
mgersh
2017/04/13 19:07:20
Done.
mgersh
2017/04/13 19:07:20
Done.
| |
| 2423 // work on wifi. | |
| 2424 if (assume_ipv6_failure_on_wifi_ && | |
| 2425 NetworkChangeNotifier::GetConnectionType() == | |
| 2426 NetworkChangeNotifier::CONNECTION_WIFI) { | |
| 2427 return false; | |
| 2428 } | |
| 2429 | |
| 2445 // Cache the result for kIPv6ProbePeriodMs (measured from after | 2430 // Cache the result for kIPv6ProbePeriodMs (measured from after |
| 2446 // IsGloballyReachable() completes). | 2431 // IsGloballyReachable() completes). |
| 2447 bool cached = true; | 2432 bool cached = true; |
| 2448 if ((base::TimeTicks::Now() - last_ipv6_probe_time_).InMilliseconds() > | 2433 if ((base::TimeTicks::Now() - last_ipv6_probe_time_).InMilliseconds() > |
| 2449 kIPv6ProbePeriodMs) { | 2434 kIPv6ProbePeriodMs) { |
| 2450 last_ipv6_probe_result_ = | 2435 last_ipv6_probe_result_ = |
| 2451 IsGloballyReachable(IPAddress(kIPv6ProbeAddress), net_log); | 2436 IsGloballyReachable(IPAddress(kIPv6ProbeAddress), net_log); |
| 2452 last_ipv6_probe_time_ = base::TimeTicks::Now(); | 2437 last_ipv6_probe_time_ = base::TimeTicks::Now(); |
| 2453 cached = false; | 2438 cached = false; |
| 2454 } | 2439 } |
| 2455 net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK, | 2440 net_log.AddEvent(NetLogEventType::HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK, |
| 2456 base::Bind(&NetLogIPv6AvailableCallback, | 2441 base::Bind(&NetLogIPv6AvailableCallback, |
| 2457 last_ipv6_probe_result_, cached)); | 2442 last_ipv6_probe_result_, cached)); |
| 2458 return last_ipv6_probe_result_; | 2443 return last_ipv6_probe_result_; |
| 2459 } | 2444 } |
| 2460 | 2445 |
| 2446 bool HostResolverImpl::IsGloballyReachable(const IPAddress& dest, | |
| 2447 const NetLogWithSource& net_log) { | |
| 2448 // TODO(eroman): Remove ScopedTracker below once crbug.com/455942 is fixed. | |
| 2449 tracked_objects::ScopedTracker tracking_profile_1( | |
| 2450 FROM_HERE_WITH_EXPLICIT_FUNCTION("455942 IsGloballyReachable")); | |
| 2451 | |
| 2452 std::unique_ptr<DatagramClientSocket> socket( | |
| 2453 ClientSocketFactory::GetDefaultFactory()->CreateDatagramClientSocket( | |
| 2454 DatagramSocket::DEFAULT_BIND, RandIntCallback(), net_log.net_log(), | |
| 2455 net_log.source())); | |
| 2456 int rv = socket->Connect(IPEndPoint(dest, 53)); | |
| 2457 if (rv != OK) | |
| 2458 return false; | |
| 2459 IPEndPoint endpoint; | |
| 2460 rv = socket->GetLocalAddress(&endpoint); | |
| 2461 if (rv != OK) | |
| 2462 return false; | |
| 2463 DCHECK_EQ(ADDRESS_FAMILY_IPV6, endpoint.GetFamily()); | |
| 2464 const IPAddress& address = endpoint.address(); | |
| 2465 | |
| 2466 bool is_link_local = | |
| 2467 (address.bytes()[0] == 0xFE) && ((address.bytes()[1] & 0xC0) == 0x80); | |
| 2468 if (is_link_local) | |
| 2469 return false; | |
| 2470 | |
| 2471 const uint8_t kTeredoPrefix[] = {0x20, 0x01, 0, 0}; | |
| 2472 if (IPAddressStartsWith(address, kTeredoPrefix)) | |
| 2473 return false; | |
| 2474 | |
| 2475 return true; | |
| 2476 } | |
| 2477 | |
| 2461 void HostResolverImpl::RunLoopbackProbeJob() { | 2478 void HostResolverImpl::RunLoopbackProbeJob() { |
| 2462 new LoopbackProbeJob(weak_ptr_factory_.GetWeakPtr(), | 2479 new LoopbackProbeJob(weak_ptr_factory_.GetWeakPtr(), |
| 2463 worker_task_runner_.get()); | 2480 worker_task_runner_.get()); |
| 2464 } | 2481 } |
| 2465 | 2482 |
| 2466 void HostResolverImpl::AbortAllInProgressJobs() { | 2483 void HostResolverImpl::AbortAllInProgressJobs() { |
| 2467 // In Abort, a Request callback could spawn new Jobs with matching keys, so | 2484 // In Abort, a Request callback could spawn new Jobs with matching keys, so |
| 2468 // first collect and remove all running jobs from |jobs_|. | 2485 // first collect and remove all running jobs from |jobs_|. |
| 2469 std::vector<std::unique_ptr<Job>> jobs_to_abort; | 2486 std::vector<std::unique_ptr<Job>> jobs_to_abort; |
| 2470 for (auto it = jobs_.begin(); it != jobs_.end();) { | 2487 for (auto it = jobs_.begin(); it != jobs_.end();) { |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2718 if (job_) | 2735 if (job_) |
| 2719 job_->CancelRequest(this); | 2736 job_->CancelRequest(this); |
| 2720 } | 2737 } |
| 2721 | 2738 |
| 2722 void HostResolverImpl::RequestImpl::ChangeRequestPriority( | 2739 void HostResolverImpl::RequestImpl::ChangeRequestPriority( |
| 2723 RequestPriority priority) { | 2740 RequestPriority priority) { |
| 2724 job_->ChangeRequestPriority(this, priority); | 2741 job_->ChangeRequestPriority(this, priority); |
| 2725 } | 2742 } |
| 2726 | 2743 |
| 2727 } // namespace net | 2744 } // namespace net |
| OLD | NEW |