| 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 | 67 |
| 68 // Default TTL for successful resolutions with ProcTask. | 68 // Default TTL for successful resolutions with ProcTask. |
| 69 const unsigned kCacheEntryTTLSeconds = 60; | 69 const unsigned kCacheEntryTTLSeconds = 60; |
| 70 | 70 |
| 71 // Default TTL for unsuccessful resolutions with ProcTask. | 71 // Default TTL for unsuccessful resolutions with ProcTask. |
| 72 const unsigned kNegativeCacheEntryTTLSeconds = 0; | 72 const unsigned kNegativeCacheEntryTTLSeconds = 0; |
| 73 | 73 |
| 74 // Minimum TTL for successful resolutions with DnsTask. | 74 // Minimum TTL for successful resolutions with DnsTask. |
| 75 const unsigned kMinimumTTLSeconds = kCacheEntryTTLSeconds; | 75 const unsigned kMinimumTTLSeconds = kCacheEntryTTLSeconds; |
| 76 | 76 |
| 77 const char kLocalhost[] = "localhost."; | |
| 78 | |
| 79 // Time between IPv6 probes, i.e. for how long results of each IPv6 probe are | 77 // Time between IPv6 probes, i.e. for how long results of each IPv6 probe are |
| 80 // cached. | 78 // cached. |
| 81 const int kIPv6ProbePeriodMs = 1000; | 79 const int kIPv6ProbePeriodMs = 1000; |
| 82 | 80 |
| 83 // Google DNS address used for IPv6 probes. | 81 // Google DNS address used for IPv6 probes. |
| 84 const uint8_t kIPv6ProbeAddress[] = | 82 const uint8_t kIPv6ProbeAddress[] = |
| 85 { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, | 83 { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, |
| 86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 }; | 84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 }; |
| 87 | 85 |
| 88 // We use a separate histogram name for each platform to facilitate the | 86 // We use a separate histogram name for each platform to facilitate the |
| (...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1311 // The dispatcher could have started |this| in the above call to Add, which | 1309 // The dispatcher could have started |this| in the above call to Add, which |
| 1312 // could have called Schedule again. In that case |handle| will be null, | 1310 // could have called Schedule again. In that case |handle| will be null, |
| 1313 // but |handle_| may have been set by the other nested call to Schedule. | 1311 // but |handle_| may have been set by the other nested call to Schedule. |
| 1314 if (!handle.is_null()) { | 1312 if (!handle.is_null()) { |
| 1315 DCHECK(handle_.is_null()); | 1313 DCHECK(handle_.is_null()); |
| 1316 handle_ = handle; | 1314 handle_ = handle; |
| 1317 } | 1315 } |
| 1318 } | 1316 } |
| 1319 | 1317 |
| 1320 void AddRequest(scoped_ptr<Request> req) { | 1318 void AddRequest(scoped_ptr<Request> req) { |
| 1321 // .localhost queries are redirected to "localhost." to make sure | 1319 DCHECK_EQ(key_.hostname, req->info().hostname()); |
| 1322 // that they are never sent out on the network, per RFC 6761. | |
| 1323 if (IsLocalhostTLD(req->info().hostname())) { | |
| 1324 DCHECK_EQ(key_.hostname, kLocalhost); | |
| 1325 } else { | |
| 1326 DCHECK_EQ(key_.hostname, req->info().hostname()); | |
| 1327 } | |
| 1328 | 1320 |
| 1329 req->set_job(this); | 1321 req->set_job(this); |
| 1330 priority_tracker_.Add(req->priority()); | 1322 priority_tracker_.Add(req->priority()); |
| 1331 | 1323 |
| 1332 req->source_net_log().AddEvent( | 1324 req->source_net_log().AddEvent( |
| 1333 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, | 1325 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, |
| 1334 net_log_.source().ToEventParametersCallback()); | 1326 net_log_.source().ToEventParametersCallback()); |
| 1335 | 1327 |
| 1336 net_log_.AddEvent( | 1328 net_log_.AddEvent( |
| 1337 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_ATTACH, | 1329 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_ATTACH, |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1990 if (ServeFromCache(key, info, &net_error, addresses)) { | 1982 if (ServeFromCache(key, info, &net_error, addresses)) { |
| 1991 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT); | 1983 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT); |
| 1992 return net_error; | 1984 return net_error; |
| 1993 } | 1985 } |
| 1994 // TODO(szym): Do not do this if nsswitch.conf instructs not to. | 1986 // TODO(szym): Do not do this if nsswitch.conf instructs not to. |
| 1995 // http://crbug.com/117655 | 1987 // http://crbug.com/117655 |
| 1996 if (ServeFromHosts(key, info, addresses)) { | 1988 if (ServeFromHosts(key, info, addresses)) { |
| 1997 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT); | 1989 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT); |
| 1998 return OK; | 1990 return OK; |
| 1999 } | 1991 } |
| 1992 |
| 1993 if (ServeLocalhost(key, info, addresses)) |
| 1994 return OK; |
| 1995 |
| 2000 return ERR_DNS_CACHE_MISS; | 1996 return ERR_DNS_CACHE_MISS; |
| 2001 } | 1997 } |
| 2002 | 1998 |
| 2003 int HostResolverImpl::ResolveFromCache(const RequestInfo& info, | 1999 int HostResolverImpl::ResolveFromCache(const RequestInfo& info, |
| 2004 AddressList* addresses, | 2000 AddressList* addresses, |
| 2005 const BoundNetLog& source_net_log) { | 2001 const BoundNetLog& source_net_log) { |
| 2006 DCHECK(CalledOnValidThread()); | 2002 DCHECK(CalledOnValidThread()); |
| 2007 DCHECK(addresses); | 2003 DCHECK(addresses); |
| 2008 | 2004 |
| 2009 // Update the net log and notify registered observers. | 2005 // Update the net log and notify registered observers. |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2152 IsAllIPv4Loopback(*addresses)) { | 2148 IsAllIPv4Loopback(*addresses)) { |
| 2153 Key new_key(key); | 2149 Key new_key(key); |
| 2154 new_key.address_family = ADDRESS_FAMILY_UNSPECIFIED; | 2150 new_key.address_family = ADDRESS_FAMILY_UNSPECIFIED; |
| 2155 new_key.host_resolver_flags &= | 2151 new_key.host_resolver_flags &= |
| 2156 ~HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; | 2152 ~HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; |
| 2157 return ServeFromHosts(new_key, info, addresses); | 2153 return ServeFromHosts(new_key, info, addresses); |
| 2158 } | 2154 } |
| 2159 return !addresses->empty(); | 2155 return !addresses->empty(); |
| 2160 } | 2156 } |
| 2161 | 2157 |
| 2158 bool HostResolverImpl::ServeLocalhost(const Key& key, |
| 2159 const RequestInfo& info, |
| 2160 AddressList* addresses) { |
| 2161 AddressList resolved_addresses; |
| 2162 if (!ResolveLocalHostname(key.hostname, info.port(), &resolved_addresses)) |
| 2163 return false; |
| 2164 |
| 2165 addresses->clear(); |
| 2166 |
| 2167 for (const auto& address : resolved_addresses) { |
| 2168 // Include the address if: |
| 2169 // - caller didn't specify an address family, or |
| 2170 // - caller specifically asked for the address family of this address, or |
| 2171 // - this is an IPv6 address and caller specifically asked for IPv4 due |
| 2172 // to lack of detected IPv6 support. (See SystemHostResolverCall for |
| 2173 // rationale). |
| 2174 if (key.address_family == ADDRESS_FAMILY_UNSPECIFIED || |
| 2175 key.address_family == address.GetFamily() || |
| 2176 (address.GetFamily() == ADDRESS_FAMILY_IPV6 && |
| 2177 key.address_family == ADDRESS_FAMILY_IPV4 && |
| 2178 (key.host_resolver_flags & |
| 2179 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6))) { |
| 2180 addresses->push_back(address); |
| 2181 } |
| 2182 } |
| 2183 |
| 2184 return true; |
| 2185 } |
| 2186 |
| 2162 void HostResolverImpl::CacheResult(const Key& key, | 2187 void HostResolverImpl::CacheResult(const Key& key, |
| 2163 const HostCache::Entry& entry, | 2188 const HostCache::Entry& entry, |
| 2164 base::TimeDelta ttl) { | 2189 base::TimeDelta ttl) { |
| 2165 if (cache_.get()) | 2190 if (cache_.get()) |
| 2166 cache_->Set(key, entry, base::TimeTicks::Now(), ttl); | 2191 cache_->Set(key, entry, base::TimeTicks::Now(), ttl); |
| 2167 } | 2192 } |
| 2168 | 2193 |
| 2169 void HostResolverImpl::RemoveJob(Job* job) { | 2194 void HostResolverImpl::RemoveJob(Job* job) { |
| 2170 DCHECK(job); | 2195 DCHECK(job); |
| 2171 JobMap::iterator it = jobs_.find(job->key()); | 2196 JobMap::iterator it = jobs_.find(job->key()); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2198 // check above) so the code requesting the resolution should be amenable | 2223 // check above) so the code requesting the resolution should be amenable |
| 2199 // to receiving a IPv6 resolution. | 2224 // to receiving a IPv6 resolution. |
| 2200 ip_number == nullptr) { | 2225 ip_number == nullptr) { |
| 2201 if (!IsIPv6Reachable(net_log)) { | 2226 if (!IsIPv6Reachable(net_log)) { |
| 2202 effective_address_family = ADDRESS_FAMILY_IPV4; | 2227 effective_address_family = ADDRESS_FAMILY_IPV4; |
| 2203 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; | 2228 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; |
| 2204 } | 2229 } |
| 2205 } | 2230 } |
| 2206 } | 2231 } |
| 2207 | 2232 |
| 2208 std::string hostname = info.hostname(); | 2233 return Key(info.hostname(), effective_address_family, effective_flags); |
| 2209 // Redirect .localhost queries to "localhost." to make sure that they | |
| 2210 // are never sent out on the network, per RFC 6761. | |
| 2211 if (IsLocalhostTLD(info.hostname())) | |
| 2212 hostname = kLocalhost; | |
| 2213 | |
| 2214 return Key(hostname, effective_address_family, effective_flags); | |
| 2215 } | 2234 } |
| 2216 | 2235 |
| 2217 bool HostResolverImpl::IsIPv6Reachable(const BoundNetLog& net_log) { | 2236 bool HostResolverImpl::IsIPv6Reachable(const BoundNetLog& net_log) { |
| 2218 base::TimeTicks now = base::TimeTicks::Now(); | 2237 base::TimeTicks now = base::TimeTicks::Now(); |
| 2219 bool cached = true; | 2238 bool cached = true; |
| 2220 if ((now - last_ipv6_probe_time_).InMilliseconds() > kIPv6ProbePeriodMs) { | 2239 if ((now - last_ipv6_probe_time_).InMilliseconds() > kIPv6ProbePeriodMs) { |
| 2221 IPAddressNumber address(kIPv6ProbeAddress, | 2240 IPAddressNumber address(kIPv6ProbeAddress, |
| 2222 kIPv6ProbeAddress + arraysize(kIPv6ProbeAddress)); | 2241 kIPv6ProbeAddress + arraysize(kIPv6ProbeAddress)); |
| 2223 last_ipv6_probe_result_ = IsGloballyReachable(address, net_log); | 2242 last_ipv6_probe_result_ = IsGloballyReachable(address, net_log); |
| 2224 last_ipv6_probe_time_ = now; | 2243 last_ipv6_probe_time_ = now; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2412 dns_client_->SetConfig(dns_config); | 2431 dns_client_->SetConfig(dns_config); |
| 2413 num_dns_failures_ = 0; | 2432 num_dns_failures_ = 0; |
| 2414 if (dns_client_->GetConfig()) | 2433 if (dns_client_->GetConfig()) |
| 2415 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); | 2434 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); |
| 2416 } | 2435 } |
| 2417 | 2436 |
| 2418 AbortDnsTasks(); | 2437 AbortDnsTasks(); |
| 2419 } | 2438 } |
| 2420 | 2439 |
| 2421 } // namespace net | 2440 } // namespace net |
| OLD | NEW |