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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
67 const unsigned kCacheEntryTTLSeconds = 60; | 67 const unsigned kCacheEntryTTLSeconds = 60; |
68 | 68 |
69 // Default TTL for unsuccessful resolutions with ProcTask. | 69 // Default TTL for unsuccessful resolutions with ProcTask. |
70 const unsigned kNegativeCacheEntryTTLSeconds = 0; | 70 const unsigned kNegativeCacheEntryTTLSeconds = 0; |
71 | 71 |
72 // Minimum TTL for successful resolutions with DnsTask. | 72 // Minimum TTL for successful resolutions with DnsTask. |
73 const unsigned kMinimumTTLSeconds = kCacheEntryTTLSeconds; | 73 const unsigned kMinimumTTLSeconds = kCacheEntryTTLSeconds; |
74 | 74 |
75 const char kLocalhost[] = "localhost."; | 75 const char kLocalhost[] = "localhost."; |
76 | 76 |
77 // Time between IPv6 probes, i.e. for how long results of each IPv6 probe are | |
78 // cached. | |
79 const int kIpv6ProbePeriodMs = 1000; | |
pauljensen
2015/05/13 13:00:22
kIpv6->kIPv6 like kIPv6Address
Sergey Ulanov
2015/05/13 18:15:58
Done, though IMO this is not right. In CamelCase n
| |
80 | |
77 // We use a separate histogram name for each platform to facilitate the | 81 // We use a separate histogram name for each platform to facilitate the |
78 // display of error codes by their symbolic name (since each platform has | 82 // display of error codes by their symbolic name (since each platform has |
79 // different mappings). | 83 // different mappings). |
80 const char kOSErrorsForGetAddrinfoHistogramName[] = | 84 const char kOSErrorsForGetAddrinfoHistogramName[] = |
81 #if defined(OS_WIN) | 85 #if defined(OS_WIN) |
82 "Net.OSErrorsForGetAddrinfo_Win"; | 86 "Net.OSErrorsForGetAddrinfo_Win"; |
83 #elif defined(OS_MACOSX) | 87 #elif defined(OS_MACOSX) |
84 "Net.OSErrorsForGetAddrinfo_Mac"; | 88 "Net.OSErrorsForGetAddrinfo_Mac"; |
85 #elif defined(OS_LINUX) | 89 #elif defined(OS_LINUX) |
86 "Net.OSErrorsForGetAddrinfo_Linux"; | 90 "Net.OSErrorsForGetAddrinfo_Linux"; |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
379 dict->SetString("priority", RequestPriorityToString(priority)); | 383 dict->SetString("priority", RequestPriorityToString(priority)); |
380 return dict; | 384 return dict; |
381 } | 385 } |
382 | 386 |
383 // Creates NetLog parameters for the DNS_CONFIG_CHANGED event. | 387 // Creates NetLog parameters for the DNS_CONFIG_CHANGED event. |
384 base::Value* NetLogDnsConfigCallback(const DnsConfig* config, | 388 base::Value* NetLogDnsConfigCallback(const DnsConfig* config, |
385 NetLogCaptureMode /* capture_mode */) { | 389 NetLogCaptureMode /* capture_mode */) { |
386 return config->ToValue(); | 390 return config->ToValue(); |
387 } | 391 } |
388 | 392 |
393 base::Value* NetLogIpv6AvailableCallback(bool ipv6_available, | |
394 bool cached, | |
395 NetLogCaptureMode /* capture_mode */) { | |
396 base::DictionaryValue* dict = new base::DictionaryValue(); | |
397 dict->SetBoolean("ipv6_available", ipv6_available); | |
398 dict->SetBoolean("cached", cached); | |
399 return dict; | |
400 } | |
401 | |
389 // The logging routines are defined here because some requests are resolved | 402 // The logging routines are defined here because some requests are resolved |
390 // without a Request object. | 403 // without a Request object. |
391 | 404 |
392 // Logs when a request has just been started. | 405 // Logs when a request has just been started. |
393 void LogStartRequest(const BoundNetLog& source_net_log, | 406 void LogStartRequest(const BoundNetLog& source_net_log, |
394 const HostResolver::RequestInfo& info) { | 407 const HostResolver::RequestInfo& info) { |
395 source_net_log.BeginEvent( | 408 source_net_log.BeginEvent( |
396 NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, | 409 NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, |
397 base::Bind(&NetLogRequestInfoCallback, &info)); | 410 base::Bind(&NetLogRequestInfoCallback, &info)); |
398 } | 411 } |
(...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1808 | 1821 |
1809 HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log) | 1822 HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log) |
1810 : max_queued_jobs_(0), | 1823 : max_queued_jobs_(0), |
1811 proc_params_(NULL, options.max_retry_attempts), | 1824 proc_params_(NULL, options.max_retry_attempts), |
1812 net_log_(net_log), | 1825 net_log_(net_log), |
1813 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), | 1826 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), |
1814 received_dns_config_(false), | 1827 received_dns_config_(false), |
1815 num_dns_failures_(0), | 1828 num_dns_failures_(0), |
1816 probe_ipv6_support_(true), | 1829 probe_ipv6_support_(true), |
1817 use_local_ipv6_(false), | 1830 use_local_ipv6_(false), |
1831 last_ipv6_probe_result_(false), | |
pauljensen
2015/05/13 13:00:22
nit: Even though this initial value should never b
Sergey Ulanov
2015/05/13 18:15:59
Done.
| |
1818 resolved_known_ipv6_hostname_(false), | 1832 resolved_known_ipv6_hostname_(false), |
1819 additional_resolver_flags_(0), | 1833 additional_resolver_flags_(0), |
1820 fallback_to_proctask_(true), | 1834 fallback_to_proctask_(true), |
1821 weak_ptr_factory_(this), | 1835 weak_ptr_factory_(this), |
1822 probe_weak_ptr_factory_(this) { | 1836 probe_weak_ptr_factory_(this) { |
1823 if (options.enable_caching) | 1837 if (options.enable_caching) |
1824 cache_ = HostCache::CreateDefaultCache(); | 1838 cache_ = HostCache::CreateDefaultCache(); |
1825 | 1839 |
1826 PrioritizedDispatcher::Limits job_limits = options.GetDispatcherLimits(); | 1840 PrioritizedDispatcher::Limits job_limits = options.GetDispatcherLimits(); |
1827 dispatcher_.reset(new PrioritizedDispatcher(job_limits)); | 1841 dispatcher_.reset(new PrioritizedDispatcher(job_limits)); |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2160 if (result) { | 2174 if (result) { |
2161 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; | 2175 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; |
2162 } else { | 2176 } else { |
2163 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; | 2177 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; |
2164 } | 2178 } |
2165 } | 2179 } |
2166 | 2180 |
2167 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( | 2181 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( |
2168 const RequestInfo& info, | 2182 const RequestInfo& info, |
2169 const IPAddressNumber* ip_number, | 2183 const IPAddressNumber* ip_number, |
2170 const BoundNetLog& net_log) const { | 2184 const BoundNetLog& net_log) { |
2171 HostResolverFlags effective_flags = | 2185 HostResolverFlags effective_flags = |
2172 info.host_resolver_flags() | additional_resolver_flags_; | 2186 info.host_resolver_flags() | additional_resolver_flags_; |
2173 AddressFamily effective_address_family = info.address_family(); | 2187 AddressFamily effective_address_family = info.address_family(); |
2174 | 2188 |
2175 if (info.address_family() == ADDRESS_FAMILY_UNSPECIFIED) { | 2189 if (info.address_family() == ADDRESS_FAMILY_UNSPECIFIED) { |
2176 if (probe_ipv6_support_ && !use_local_ipv6_ && | 2190 if (probe_ipv6_support_ && !use_local_ipv6_ && |
2177 // When resolving IPv4 literals, there's no need to probe for IPv6. | 2191 // When resolving IPv4 literals, there's no need to probe for IPv6. |
2178 // When resolving IPv6 literals, there's no benefit to artificially | 2192 // When resolving IPv6 literals, there's no benefit to artificially |
2179 // limiting our resolution based on a probe. Prior logic ensures | 2193 // limiting our resolution based on a probe. Prior logic ensures |
2180 // that this query is UNSPECIFIED (see info.address_family() | 2194 // that this query is UNSPECIFIED (see info.address_family() |
2181 // check above) and that |default_address_family_| is UNSPECIFIED | 2195 // check above) and that |default_address_family_| is UNSPECIFIED |
2182 // (|prove_ipv6_support_| is false if |default_address_family_| is | 2196 // (|prove_ipv6_support_| is false if |default_address_family_| is |
2183 // set) so the code requesting the resolution should be amenable to | 2197 // set) so the code requesting the resolution should be amenable to |
2184 // receiving a IPv6 resolution. | 2198 // receiving a IPv6 resolution. |
2185 ip_number == nullptr) { | 2199 ip_number == nullptr) { |
2186 // Google DNS address. | 2200 bool ipv6_available = IsIpv6Reachable(net_log); |
2187 const uint8 kIPv6Address[] = | 2201 if (!ipv6_available) { |
pauljensen
2015/05/13 13:00:22
Can we combine these two lines into "if (!IsIpv6Re
Sergey Ulanov
2015/05/13 18:15:58
Done.
| |
2188 { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, | |
2189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 }; | |
2190 IPAddressNumber address(kIPv6Address, | |
2191 kIPv6Address + arraysize(kIPv6Address)); | |
2192 bool rv6 = IsGloballyReachable(address, net_log); | |
2193 net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK, | |
2194 NetLog::BoolCallback("ipv6_available", rv6)); | |
2195 if (!rv6) { | |
2196 effective_address_family = ADDRESS_FAMILY_IPV4; | 2202 effective_address_family = ADDRESS_FAMILY_IPV4; |
2197 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; | 2203 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; |
2198 } | 2204 } |
2199 } else { | 2205 } else { |
2200 effective_address_family = default_address_family_; | 2206 effective_address_family = default_address_family_; |
2201 } | 2207 } |
2202 } | 2208 } |
2203 | 2209 |
2204 std::string hostname = info.hostname(); | 2210 std::string hostname = info.hostname(); |
2205 // Redirect .localhost queries to "localhost." to make sure that they | 2211 // Redirect .localhost queries to "localhost." to make sure that they |
2206 // are never sent out on the network, per RFC 6761. | 2212 // are never sent out on the network, per RFC 6761. |
2207 if (IsLocalhostTLD(info.hostname())) | 2213 if (IsLocalhostTLD(info.hostname())) |
2208 hostname = kLocalhost; | 2214 hostname = kLocalhost; |
2209 | 2215 |
2210 return Key(hostname, effective_address_family, effective_flags); | 2216 return Key(hostname, effective_address_family, effective_flags); |
2211 } | 2217 } |
2212 | 2218 |
2219 bool HostResolverImpl::IsIpv6Reachable(const BoundNetLog& net_log) { | |
2220 base::TimeTicks now = base::TimeTicks::Now(); | |
2221 bool cached = true; | |
2222 if ((now - last_ipv6_probe_time_).InMilliseconds() > kIpv6ProbePeriodMs) { | |
2223 // Google DNS address. | |
2224 const uint8 kIPv6Address[] = | |
2225 { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, | |
2226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 }; | |
pauljensen
2015/05/13 13:00:22
Can we either move kIPv6Address up to the beginnin
Sergey Ulanov
2015/05/13 18:15:58
Done.
| |
2227 IPAddressNumber address(kIPv6Address, | |
2228 kIPv6Address + arraysize(kIPv6Address)); | |
2229 last_ipv6_probe_result_ = IsGloballyReachable(address, net_log); | |
2230 last_ipv6_probe_time_ = now; | |
2231 cached = false; | |
2232 } | |
2233 net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK, | |
2234 base::Bind(&NetLogIpv6AvailableCallback, | |
2235 last_ipv6_probe_result_, cached)); | |
2236 return last_ipv6_probe_result_; | |
2237 } | |
2238 | |
2213 void HostResolverImpl::AbortAllInProgressJobs() { | 2239 void HostResolverImpl::AbortAllInProgressJobs() { |
2214 // In Abort, a Request callback could spawn new Jobs with matching keys, so | 2240 // In Abort, a Request callback could spawn new Jobs with matching keys, so |
2215 // first collect and remove all running jobs from |jobs_|. | 2241 // first collect and remove all running jobs from |jobs_|. |
2216 ScopedVector<Job> jobs_to_abort; | 2242 ScopedVector<Job> jobs_to_abort; |
2217 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) { | 2243 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) { |
2218 Job* job = it->second; | 2244 Job* job = it->second; |
2219 if (job->is_running()) { | 2245 if (job->is_running()) { |
2220 jobs_to_abort.push_back(job); | 2246 jobs_to_abort.push_back(job); |
2221 jobs_.erase(it++); | 2247 jobs_.erase(it++); |
2222 } else { | 2248 } else { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2272 for (JobMap::iterator it = jobs_.begin(); self.get() && it != jobs_.end();) { | 2298 for (JobMap::iterator it = jobs_.begin(); self.get() && it != jobs_.end();) { |
2273 Job* job = it->second; | 2299 Job* job = it->second; |
2274 ++it; | 2300 ++it; |
2275 // This could remove |job| from |jobs_|, but iterator will remain valid. | 2301 // This could remove |job| from |jobs_|, but iterator will remain valid. |
2276 job->ServeFromHosts(); | 2302 job->ServeFromHosts(); |
2277 } | 2303 } |
2278 } | 2304 } |
2279 | 2305 |
2280 void HostResolverImpl::OnIPAddressChanged() { | 2306 void HostResolverImpl::OnIPAddressChanged() { |
2281 resolved_known_ipv6_hostname_ = false; | 2307 resolved_known_ipv6_hostname_ = false; |
2308 last_ipv6_probe_time_ = base::TimeTicks(); | |
2282 // Abandon all ProbeJobs. | 2309 // Abandon all ProbeJobs. |
2283 probe_weak_ptr_factory_.InvalidateWeakPtrs(); | 2310 probe_weak_ptr_factory_.InvalidateWeakPtrs(); |
2284 if (cache_.get()) | 2311 if (cache_.get()) |
2285 cache_->clear(); | 2312 cache_->clear(); |
2286 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 2313 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
2287 new LoopbackProbeJob(probe_weak_ptr_factory_.GetWeakPtr()); | 2314 new LoopbackProbeJob(probe_weak_ptr_factory_.GetWeakPtr()); |
2288 #endif | 2315 #endif |
2289 AbortAllInProgressJobs(); | 2316 AbortAllInProgressJobs(); |
2290 // |this| may be deleted inside AbortAllInProgressJobs(). | 2317 // |this| may be deleted inside AbortAllInProgressJobs(). |
2291 } | 2318 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2392 dns_client_->SetConfig(dns_config); | 2419 dns_client_->SetConfig(dns_config); |
2393 num_dns_failures_ = 0; | 2420 num_dns_failures_ = 0; |
2394 if (dns_client_->GetConfig()) | 2421 if (dns_client_->GetConfig()) |
2395 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); | 2422 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); |
2396 } | 2423 } |
2397 | 2424 |
2398 AbortDnsTasks(); | 2425 AbortDnsTasks(); |
2399 } | 2426 } |
2400 | 2427 |
2401 } // namespace net | 2428 } // namespace net |
OLD | NEW |