Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: net/dns/host_resolver_impl.cc

Issue 1177933002: Resolve RFC 6761 localhost names to loopback (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: style tweaks, simplification Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 // If the family was restricted to IPv4 due to a detected lack of IPv6
2168 // support, resolve with no restrictions. (See SystemHostResolverCall
2169 // for rationale.)
2170 bool no_ipv6 = key.address_family == ADDRESS_FAMILY_IPV4 &&
2171 !(key.host_resolver_flags &
2172 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6);
2173
2174 for (const auto& address : resolved_addresses) {
2175 if (address.GetFamily() == ADDRESS_FAMILY_IPV6) {
2176 if (!no_ipv6)
2177 addresses->push_back(address);
2178 } else if (key.address_family != ADDRESS_FAMILY_IPV6) {
Ryan Sleevi 2015/06/12 01:00:04 I don't understand this clause - could you elabora
estark 2015/06/12 05:59:46 This is the logic I intended to write: If the add
2179 addresses->push_back(address);
2180 }
2181 }
2182
2183 return true;
2184 }
2185
2162 void HostResolverImpl::CacheResult(const Key& key, 2186 void HostResolverImpl::CacheResult(const Key& key,
2163 const HostCache::Entry& entry, 2187 const HostCache::Entry& entry,
2164 base::TimeDelta ttl) { 2188 base::TimeDelta ttl) {
2165 if (cache_.get()) 2189 if (cache_.get())
2166 cache_->Set(key, entry, base::TimeTicks::Now(), ttl); 2190 cache_->Set(key, entry, base::TimeTicks::Now(), ttl);
2167 } 2191 }
2168 2192
2169 void HostResolverImpl::RemoveJob(Job* job) { 2193 void HostResolverImpl::RemoveJob(Job* job) {
2170 DCHECK(job); 2194 DCHECK(job);
2171 JobMap::iterator it = jobs_.find(job->key()); 2195 JobMap::iterator it = jobs_.find(job->key());
(...skipping 26 matching lines...) Expand all
2198 // check above) so the code requesting the resolution should be amenable 2222 // check above) so the code requesting the resolution should be amenable
2199 // to receiving a IPv6 resolution. 2223 // to receiving a IPv6 resolution.
2200 ip_number == nullptr) { 2224 ip_number == nullptr) {
2201 if (!IsIPv6Reachable(net_log)) { 2225 if (!IsIPv6Reachable(net_log)) {
2202 effective_address_family = ADDRESS_FAMILY_IPV4; 2226 effective_address_family = ADDRESS_FAMILY_IPV4;
2203 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; 2227 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
2204 } 2228 }
2205 } 2229 }
2206 } 2230 }
2207 2231
2208 std::string hostname = info.hostname(); 2232 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 } 2233 }
2216 2234
2217 bool HostResolverImpl::IsIPv6Reachable(const BoundNetLog& net_log) { 2235 bool HostResolverImpl::IsIPv6Reachable(const BoundNetLog& net_log) {
2218 base::TimeTicks now = base::TimeTicks::Now(); 2236 base::TimeTicks now = base::TimeTicks::Now();
2219 bool cached = true; 2237 bool cached = true;
2220 if ((now - last_ipv6_probe_time_).InMilliseconds() > kIPv6ProbePeriodMs) { 2238 if ((now - last_ipv6_probe_time_).InMilliseconds() > kIPv6ProbePeriodMs) {
2221 IPAddressNumber address(kIPv6ProbeAddress, 2239 IPAddressNumber address(kIPv6ProbeAddress,
2222 kIPv6ProbeAddress + arraysize(kIPv6ProbeAddress)); 2240 kIPv6ProbeAddress + arraysize(kIPv6ProbeAddress));
2223 last_ipv6_probe_result_ = IsGloballyReachable(address, net_log); 2241 last_ipv6_probe_result_ = IsGloballyReachable(address, net_log);
2224 last_ipv6_probe_time_ = now; 2242 last_ipv6_probe_time_ = now;
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
2412 dns_client_->SetConfig(dns_config); 2430 dns_client_->SetConfig(dns_config);
2413 num_dns_failures_ = 0; 2431 num_dns_failures_ = 0;
2414 if (dns_client_->GetConfig()) 2432 if (dns_client_->GetConfig())
2415 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); 2433 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true);
2416 } 2434 }
2417 2435
2418 AbortDnsTasks(); 2436 AbortDnsTasks();
2419 } 2437 }
2420 2438
2421 } // namespace net 2439 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698