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 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 if (total_count_ == 0) | 487 if (total_count_ == 0) |
488 DCHECK_EQ(MINIMUM_PRIORITY, highest_priority_); | 488 DCHECK_EQ(MINIMUM_PRIORITY, highest_priority_); |
489 } | 489 } |
490 | 490 |
491 private: | 491 private: |
492 RequestPriority highest_priority_; | 492 RequestPriority highest_priority_; |
493 size_t total_count_; | 493 size_t total_count_; |
494 size_t counts_[NUM_PRIORITIES]; | 494 size_t counts_[NUM_PRIORITIES]; |
495 }; | 495 }; |
496 | 496 |
| 497 void MakeNotStale(HostCache::EntryStaleness* stale_info) { |
| 498 if (!stale_info) |
| 499 return; |
| 500 stale_info->expired_by = base::TimeDelta::FromSeconds(-1); |
| 501 stale_info->network_changes = 0; |
| 502 stale_info->stale_hits = 0; |
| 503 } |
| 504 |
497 } // namespace | 505 } // namespace |
498 | 506 |
499 //----------------------------------------------------------------------------- | 507 //----------------------------------------------------------------------------- |
500 | 508 |
501 bool ResolveLocalHostname(base::StringPiece host, | 509 bool ResolveLocalHostname(base::StringPiece host, |
502 uint16_t port, | 510 uint16_t port, |
503 AddressList* address_list) { | 511 AddressList* address_list) { |
504 address_list->clear(); | 512 address_list->clear(); |
505 | 513 |
506 bool is_local6; | 514 bool is_local6; |
(...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1916 | 1924 |
1917 IPAddress ip_address; | 1925 IPAddress ip_address; |
1918 IPAddress* ip_address_ptr = nullptr; | 1926 IPAddress* ip_address_ptr = nullptr; |
1919 if (ip_address.AssignFromIPLiteral(info.hostname())) | 1927 if (ip_address.AssignFromIPLiteral(info.hostname())) |
1920 ip_address_ptr = &ip_address; | 1928 ip_address_ptr = &ip_address; |
1921 | 1929 |
1922 // Build a key that identifies the request in the cache and in the | 1930 // Build a key that identifies the request in the cache and in the |
1923 // outstanding jobs map. | 1931 // outstanding jobs map. |
1924 Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log); | 1932 Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log); |
1925 | 1933 |
1926 int rv = ResolveHelper(key, info, ip_address_ptr, addresses, source_net_log); | 1934 int rv = ResolveHelper(key, info, ip_address_ptr, addresses, false, nullptr, |
| 1935 source_net_log); |
1927 if (rv != ERR_DNS_CACHE_MISS) { | 1936 if (rv != ERR_DNS_CACHE_MISS) { |
1928 LogFinishRequest(source_net_log, info, rv); | 1937 LogFinishRequest(source_net_log, info, rv); |
1929 RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta()); | 1938 RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta()); |
1930 return rv; | 1939 return rv; |
1931 } | 1940 } |
1932 | 1941 |
1933 // Next we need to attach our request to a "job". This job is responsible for | 1942 // Next we need to attach our request to a "job". This job is responsible for |
1934 // calling "getaddrinfo(hostname)" on a worker thread. | 1943 // calling "getaddrinfo(hostname)" on a worker thread. |
1935 | 1944 |
1936 JobMap::iterator jobit = jobs_.find(key); | 1945 JobMap::iterator jobit = jobs_.find(key); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2025 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; | 2034 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; |
2026 } else { | 2035 } else { |
2027 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; | 2036 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; |
2028 } | 2037 } |
2029 } | 2038 } |
2030 | 2039 |
2031 int HostResolverImpl::ResolveHelper(const Key& key, | 2040 int HostResolverImpl::ResolveHelper(const Key& key, |
2032 const RequestInfo& info, | 2041 const RequestInfo& info, |
2033 const IPAddress* ip_address, | 2042 const IPAddress* ip_address, |
2034 AddressList* addresses, | 2043 AddressList* addresses, |
| 2044 bool allow_stale, |
| 2045 HostCache::EntryStaleness* stale_info, |
2035 const BoundNetLog& source_net_log) { | 2046 const BoundNetLog& source_net_log) { |
| 2047 DCHECK(allow_stale == !!stale_info); |
2036 // The result of |getaddrinfo| for empty hosts is inconsistent across systems. | 2048 // The result of |getaddrinfo| for empty hosts is inconsistent across systems. |
2037 // On Windows it gives the default interface's address, whereas on Linux it | 2049 // On Windows it gives the default interface's address, whereas on Linux it |
2038 // gives an error. We will make it fail on all platforms for consistency. | 2050 // gives an error. We will make it fail on all platforms for consistency. |
2039 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) | 2051 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) { |
| 2052 MakeNotStale(stale_info); |
2040 return ERR_NAME_NOT_RESOLVED; | 2053 return ERR_NAME_NOT_RESOLVED; |
| 2054 } |
2041 | 2055 |
2042 int net_error = ERR_UNEXPECTED; | 2056 int net_error = ERR_UNEXPECTED; |
2043 if (ResolveAsIP(key, info, ip_address, &net_error, addresses)) | 2057 if (ResolveAsIP(key, info, ip_address, &net_error, addresses)) { |
| 2058 MakeNotStale(stale_info); |
2044 return net_error; | 2059 return net_error; |
2045 if (ServeFromCache(key, info, &net_error, addresses)) { | 2060 } |
| 2061 if (ServeFromCache(key, info, &net_error, addresses, allow_stale, |
| 2062 stale_info)) { |
2046 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT); | 2063 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT); |
| 2064 // |ServeFromCache()| will set |*stale_info| as needed. |
2047 return net_error; | 2065 return net_error; |
2048 } | 2066 } |
2049 // TODO(szym): Do not do this if nsswitch.conf instructs not to. | 2067 // TODO(szym): Do not do this if nsswitch.conf instructs not to. |
2050 // http://crbug.com/117655 | 2068 // http://crbug.com/117655 |
2051 if (ServeFromHosts(key, info, addresses)) { | 2069 if (ServeFromHosts(key, info, addresses)) { |
2052 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT); | 2070 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT); |
| 2071 MakeNotStale(stale_info); |
2053 return OK; | 2072 return OK; |
2054 } | 2073 } |
2055 | 2074 |
2056 if (ServeLocalhost(key, info, addresses)) | 2075 if (ServeLocalhost(key, info, addresses)) { |
| 2076 MakeNotStale(stale_info); |
2057 return OK; | 2077 return OK; |
| 2078 } |
2058 | 2079 |
2059 return ERR_DNS_CACHE_MISS; | 2080 return ERR_DNS_CACHE_MISS; |
2060 } | 2081 } |
2061 | 2082 |
2062 int HostResolverImpl::ResolveFromCache(const RequestInfo& info, | 2083 int HostResolverImpl::ResolveFromCache(const RequestInfo& info, |
2063 AddressList* addresses, | 2084 AddressList* addresses, |
2064 const BoundNetLog& source_net_log) { | 2085 const BoundNetLog& source_net_log) { |
2065 DCHECK(CalledOnValidThread()); | 2086 DCHECK(CalledOnValidThread()); |
2066 DCHECK(addresses); | 2087 DCHECK(addresses); |
2067 | 2088 |
2068 // Update the net log and notify registered observers. | 2089 // Update the net log and notify registered observers. |
2069 LogStartRequest(source_net_log, info); | 2090 LogStartRequest(source_net_log, info); |
2070 | 2091 |
2071 IPAddress ip_address; | 2092 IPAddress ip_address; |
2072 IPAddress* ip_address_ptr = nullptr; | 2093 IPAddress* ip_address_ptr = nullptr; |
2073 if (ip_address.AssignFromIPLiteral(info.hostname())) | 2094 if (ip_address.AssignFromIPLiteral(info.hostname())) |
2074 ip_address_ptr = &ip_address; | 2095 ip_address_ptr = &ip_address; |
2075 | 2096 |
2076 Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log); | 2097 Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log); |
2077 | 2098 |
2078 int rv = ResolveHelper(key, info, ip_address_ptr, addresses, source_net_log); | 2099 int rv = ResolveHelper(key, info, ip_address_ptr, addresses, false, nullptr, |
| 2100 source_net_log); |
2079 LogFinishRequest(source_net_log, info, rv); | 2101 LogFinishRequest(source_net_log, info, rv); |
2080 return rv; | 2102 return rv; |
2081 } | 2103 } |
2082 | 2104 |
2083 void HostResolverImpl::ChangeRequestPriority(RequestHandle req_handle, | 2105 void HostResolverImpl::ChangeRequestPriority(RequestHandle req_handle, |
2084 RequestPriority priority) { | 2106 RequestPriority priority) { |
2085 DCHECK(CalledOnValidThread()); | 2107 DCHECK(CalledOnValidThread()); |
2086 Request* req = reinterpret_cast<Request*>(req_handle); | 2108 Request* req = reinterpret_cast<Request*>(req_handle); |
2087 DCHECK(req); | 2109 DCHECK(req); |
2088 Job* job = req->job(); | 2110 Job* job = req->job(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2121 | 2143 |
2122 // Check if async DNS is enabled, but we currently have no configuration | 2144 // Check if async DNS is enabled, but we currently have no configuration |
2123 // for it. | 2145 // for it. |
2124 const DnsConfig* dns_config = dns_client_->GetConfig(); | 2146 const DnsConfig* dns_config = dns_client_->GetConfig(); |
2125 if (dns_config == NULL) | 2147 if (dns_config == NULL) |
2126 return base::WrapUnique(new base::DictionaryValue()); | 2148 return base::WrapUnique(new base::DictionaryValue()); |
2127 | 2149 |
2128 return dns_config->ToValue(); | 2150 return dns_config->ToValue(); |
2129 } | 2151 } |
2130 | 2152 |
| 2153 int HostResolverImpl::ResolveStaleFromCache( |
| 2154 const RequestInfo& info, |
| 2155 AddressList* addresses, |
| 2156 HostCache::EntryStaleness* stale_info, |
| 2157 const BoundNetLog& source_net_log) { |
| 2158 DCHECK(CalledOnValidThread()); |
| 2159 DCHECK(addresses); |
| 2160 DCHECK(stale_info); |
| 2161 |
| 2162 // Update the net log and notify registered observers. |
| 2163 LogStartRequest(source_net_log, info); |
| 2164 |
| 2165 IPAddress ip_address; |
| 2166 IPAddress* ip_address_ptr = nullptr; |
| 2167 if (ip_address.AssignFromIPLiteral(info.hostname())) |
| 2168 ip_address_ptr = &ip_address; |
| 2169 |
| 2170 Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log); |
| 2171 |
| 2172 int rv = ResolveHelper(key, info, ip_address_ptr, addresses, true, stale_info, |
| 2173 source_net_log); |
| 2174 LogFinishRequest(source_net_log, info, rv); |
| 2175 return rv; |
| 2176 } |
| 2177 |
2131 bool HostResolverImpl::ResolveAsIP(const Key& key, | 2178 bool HostResolverImpl::ResolveAsIP(const Key& key, |
2132 const RequestInfo& info, | 2179 const RequestInfo& info, |
2133 const IPAddress* ip_address, | 2180 const IPAddress* ip_address, |
2134 int* net_error, | 2181 int* net_error, |
2135 AddressList* addresses) { | 2182 AddressList* addresses) { |
2136 DCHECK(addresses); | 2183 DCHECK(addresses); |
2137 DCHECK(net_error); | 2184 DCHECK(net_error); |
2138 if (ip_address == nullptr) | 2185 if (ip_address == nullptr) |
2139 return false; | 2186 return false; |
2140 | 2187 |
2141 *net_error = OK; | 2188 *net_error = OK; |
2142 AddressFamily family = GetAddressFamily(*ip_address); | 2189 AddressFamily family = GetAddressFamily(*ip_address); |
2143 if (key.address_family != ADDRESS_FAMILY_UNSPECIFIED && | 2190 if (key.address_family != ADDRESS_FAMILY_UNSPECIFIED && |
2144 key.address_family != family) { | 2191 key.address_family != family) { |
2145 // Don't return IPv6 addresses for IPv4 queries, and vice versa. | 2192 // Don't return IPv6 addresses for IPv4 queries, and vice versa. |
2146 *net_error = ERR_NAME_NOT_RESOLVED; | 2193 *net_error = ERR_NAME_NOT_RESOLVED; |
2147 } else { | 2194 } else { |
2148 *addresses = AddressList::CreateFromIPAddress(*ip_address, info.port()); | 2195 *addresses = AddressList::CreateFromIPAddress(*ip_address, info.port()); |
2149 if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME) | 2196 if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME) |
2150 addresses->SetDefaultCanonicalName(); | 2197 addresses->SetDefaultCanonicalName(); |
2151 } | 2198 } |
2152 return true; | 2199 return true; |
2153 } | 2200 } |
2154 | 2201 |
2155 bool HostResolverImpl::ServeFromCache(const Key& key, | 2202 bool HostResolverImpl::ServeFromCache(const Key& key, |
2156 const RequestInfo& info, | 2203 const RequestInfo& info, |
2157 int* net_error, | 2204 int* net_error, |
2158 AddressList* addresses) { | 2205 AddressList* addresses, |
| 2206 bool allow_stale, |
| 2207 HostCache::EntryStaleness* stale_info) { |
2159 DCHECK(addresses); | 2208 DCHECK(addresses); |
2160 DCHECK(net_error); | 2209 DCHECK(net_error); |
| 2210 DCHECK(allow_stale == !!stale_info); |
2161 if (!info.allow_cached_response() || !cache_.get()) | 2211 if (!info.allow_cached_response() || !cache_.get()) |
2162 return false; | 2212 return false; |
2163 | 2213 |
2164 const HostCache::Entry* cache_entry = cache_->Lookup( | 2214 const HostCache::Entry* cache_entry; |
2165 key, base::TimeTicks::Now()); | 2215 if (allow_stale) |
| 2216 cache_entry = cache_->LookupStale(key, base::TimeTicks::Now(), stale_info); |
| 2217 else |
| 2218 cache_entry = cache_->Lookup(key, base::TimeTicks::Now()); |
2166 if (!cache_entry) | 2219 if (!cache_entry) |
2167 return false; | 2220 return false; |
2168 | 2221 |
2169 *net_error = cache_entry->error(); | 2222 *net_error = cache_entry->error(); |
2170 if (*net_error == OK) { | 2223 if (*net_error == OK) { |
2171 if (cache_entry->has_ttl()) | 2224 if (cache_entry->has_ttl()) |
2172 RecordTTL(cache_entry->ttl()); | 2225 RecordTTL(cache_entry->ttl()); |
2173 *addresses = EnsurePortOnAddressList(cache_entry->addresses(), info.port()); | 2226 *addresses = EnsurePortOnAddressList(cache_entry->addresses(), info.port()); |
2174 } | 2227 } |
2175 return true; | 2228 return true; |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2504 dns_client_->SetConfig(dns_config); | 2557 dns_client_->SetConfig(dns_config); |
2505 num_dns_failures_ = 0; | 2558 num_dns_failures_ = 0; |
2506 if (dns_client_->GetConfig()) | 2559 if (dns_client_->GetConfig()) |
2507 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); | 2560 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); |
2508 } | 2561 } |
2509 | 2562 |
2510 AbortDnsTasks(); | 2563 AbortDnsTasks(); |
2511 } | 2564 } |
2512 | 2565 |
2513 } // namespace net | 2566 } // namespace net |
OLD | NEW |