diff options
author | agayev@chromium.org <agayev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-04 21:50:40 +0000 |
---|---|---|
committer | agayev@chromium.org <agayev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-04 21:50:40 +0000 |
commit | 95a214cd9711f435d3c964df768d394163e5c353 (patch) | |
tree | 000931469e217e37f27a93342f30408350367127 | |
parent | 8e42ba22706ce8ca0fd374351f4221a26ebd5e0a (diff) | |
download | chromium_src-95a214cd9711f435d3c964df768d394163e5c353.zip chromium_src-95a214cd9711f435d3c964df768d394163e5c353.tar.gz chromium_src-95a214cd9711f435d3c964df768d394163e5c353.tar.bz2 |
HostResolver: don't interpret NULL callback argument as a request to do synchronous resolution.
BUG=90547,60149
TEST=net_unittests
Review URL: http://codereview.chromium.org/7492059
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95509 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/base/host_resolver.cc | 1 | ||||
-rw-r--r-- | net/base/host_resolver.h | 24 | ||||
-rw-r--r-- | net/base/host_resolver_impl.cc | 179 | ||||
-rw-r--r-- | net/base/host_resolver_impl.h | 44 | ||||
-rw-r--r-- | net/base/host_resolver_impl_unittest.cc | 24 | ||||
-rw-r--r-- | net/base/mapped_host_resolver.cc | 10 | ||||
-rw-r--r-- | net/base/mapped_host_resolver.h | 13 | ||||
-rw-r--r-- | net/base/mock_host_resolver.cc | 6 | ||||
-rw-r--r-- | net/base/mock_host_resolver.h | 11 | ||||
-rw-r--r-- | net/base/net_error_list.h | 3 | ||||
-rw-r--r-- | net/base/single_request_host_resolver.cc | 2 | ||||
-rw-r--r-- | net/base/single_request_host_resolver_unittest.cc | 15 | ||||
-rw-r--r-- | net/dns/async_host_resolver.cc | 117 | ||||
-rw-r--r-- | net/dns/async_host_resolver.h | 3 | ||||
-rw-r--r-- | net/dns/async_host_resolver_unittest.cc | 11 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 21 | ||||
-rw-r--r-- | net/proxy/sync_host_resolver_bridge_unittest.cc | 7 | ||||
-rw-r--r-- | net/socket/socks_client_socket_unittest.cc | 17 | ||||
-rw-r--r-- | net/spdy/spdy_session_pool.cc | 9 |
19 files changed, 319 insertions, 198 deletions
diff --git a/net/base/host_resolver.cc b/net/base/host_resolver.cc index bf1c11a..01dfd41 100644 --- a/net/base/host_resolver.cc +++ b/net/base/host_resolver.cc @@ -11,7 +11,6 @@ HostResolver::RequestInfo::RequestInfo(const HostPortPair& host_port_pair) address_family_(ADDRESS_FAMILY_UNSPECIFIED), host_resolver_flags_(0), allow_cached_response_(true), - only_use_cached_response_(false), is_speculative_(false), priority_(MEDIUM) { } diff --git a/net/base/host_resolver.h b/net/base/host_resolver.h index 53a86da..d2b6a35 100644 --- a/net/base/host_resolver.h +++ b/net/base/host_resolver.h @@ -65,9 +65,6 @@ class NET_API HostResolver { bool allow_cached_response() const { return allow_cached_response_; } void set_allow_cached_response(bool b) { allow_cached_response_ = b; } - bool only_use_cached_response() const { return only_use_cached_response_; } - void set_only_use_cached_response(bool b) { only_use_cached_response_ = b; } - bool is_speculative() const { return is_speculative_; } void set_is_speculative(bool b) { is_speculative_ = b; } @@ -90,9 +87,6 @@ class NET_API HostResolver { // Whether it is ok to return a result from the host cache. bool allow_cached_response_; - // Whether the response will only use the cache. - bool only_use_cached_response_; - // Whether this request was started by the DNS prefetcher. bool is_speculative_; @@ -146,18 +140,16 @@ class NET_API HostResolver { // Resolves the given hostname (or IP address literal), filling out the // |addresses| object upon success. The |info.port| parameter will be set as // the sin(6)_port field of the sockaddr_in{6} struct. Returns OK if - // successful or an error code upon failure. + // successful or an error code upon failure. Returns + // ERR_NAME_NOT_RESOLVED if hostname is invalid, or if it is an + // incompatible IP literal (e.g. IPv6 is disabled and it is an IPv6 + // literal). // // If the operation cannnot be completed synchronously, ERR_IO_PENDING will // be returned and the real result code will be passed to the completion // callback. Otherwise the result code is returned immediately from this // call. // - // When |callback| is null, there are two possibilities: either an IP - // address literal is being resolved or lookup should be performed from - // cache only, meaning info.only_use_cached_response() should be true; in - // both cases operation should complete synchronously. - // // If |out_req| is non-NULL, then |*out_req| will be filled with a handle to // the async request. This handle is not valid after the request has // completed. @@ -169,6 +161,14 @@ class NET_API HostResolver { RequestHandle* out_req, const BoundNetLog& net_log) = 0; + // Resolves the given hostname (or IP address literal) out of cache + // only. This is guaranteed to complete synchronously. This acts like + // |Resolve()| if the hostname is IP literal or cached value exists. + // Otherwise, ERR_DNS_CACHE_MISS is returned. + virtual int ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& net_log) = 0; + // Cancels the specified request. |req| is the handle returned by Resolve(). // After a request is cancelled, its completion callback will not be called. virtual void CancelRequest(RequestHandle req) = 0; diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc index b317ca0..6697507 100644 --- a/net/base/host_resolver_impl.cc +++ b/net/base/host_resolver_impl.cc @@ -222,8 +222,6 @@ class RequestInfoParameters : public NetLog::EventParameters { dict->SetInteger("address_family", static_cast<int>(info_.address_family())); dict->SetBoolean("allow_cached_response", info_.allow_cached_response()); - dict->SetBoolean("only_use_cached_response", - info_.only_use_cached_response()); dict->SetBoolean("is_speculative", info_.is_speculative()); dict->SetInteger("priority", info_.priority()); @@ -1135,6 +1133,8 @@ int HostResolverImpl::Resolve(const RequestInfo& info, CompletionCallback* callback, RequestHandle* out_req, const BoundNetLog& source_net_log) { + DCHECK(addresses); + DCHECK(callback); DCHECK(CalledOnValidThread()); // Choose a unique ID number for observers to see. @@ -1147,82 +1147,17 @@ int HostResolverImpl::Resolve(const RequestInfo& info, // Update the net log and notify registered observers. OnStartRequest(source_net_log, request_net_log, request_id, info); - // The result of |getaddrinfo| for empty hosts is inconsistent across systems. - // On Windows it gives the default interface's address, whereas on Linux it - // gives an error. We will make it fail on all platforms for consistency. - if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) { - OnFinishRequest(source_net_log, - request_net_log, - request_id, - info, - ERR_NAME_NOT_RESOLVED, - 0); - return ERR_NAME_NOT_RESOLVED; - } - // Build a key that identifies the request in the cache and in the // outstanding jobs map. Key key = GetEffectiveKeyForRequest(info); - // Check for IP literal. - IPAddressNumber ip_number; - if (ParseIPLiteralToNumber(info.hostname(), &ip_number)) { - DCHECK_EQ(key.host_resolver_flags & - ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY | - HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6), - 0) << " Unhandled flag"; - bool ipv6_disabled = default_address_family_ == ADDRESS_FAMILY_IPV4 && - !ipv6_probe_monitoring_; - int net_error = OK; - if (ip_number.size() == 16 && ipv6_disabled) { - net_error = ERR_NAME_NOT_RESOLVED; - } else { - *addresses = AddressList::CreateFromIPAddressWithCname( - ip_number, info.port(), - (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)); - } - // Update the net log and notify registered observers. + int rv = ResolveHelper(request_id, key, info, addresses, + source_net_log, request_net_log); + if (rv != ERR_DNS_CACHE_MISS) { OnFinishRequest(source_net_log, request_net_log, request_id, info, - net_error, 0 /* os_error (unknown since from cache) */); - return net_error; - } - - // Sanity check -- it shouldn't be the case that allow_cached_response is - // false while only_use_cached_response is true. - DCHECK(info.allow_cached_response() || !info.only_use_cached_response()); - - // If callback is NULL, we must be doing cache-only lookup. - DCHECK(callback || info.only_use_cached_response()); - - // If we have an unexpired cache entry, use it. - if (info.allow_cached_response() && cache_.get()) { - const HostCache::Entry* cache_entry = cache_->Lookup( - key, base::TimeTicks::Now()); - if (cache_entry) { - request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); - int net_error = cache_entry->error; - if (net_error == OK) { - *addresses = CreateAddressListUsingPort( - cache_entry->addrlist, info.port()); - } - - // Update the net log and notify registered observers. - OnFinishRequest(source_net_log, request_net_log, request_id, info, - net_error, - 0 /* os_error (unknown since from cache) */); - - return net_error; - } - } - - if (info.only_use_cached_response()) { // Not allowed to do a real lookup. - OnFinishRequest(source_net_log, - request_net_log, - request_id, - info, - ERR_NAME_NOT_RESOLVED, - 0); - return ERR_NAME_NOT_RESOLVED; + rv, + 0 /* os_error (unknown since from cache) */); + return rv; } // Create a handle for this request, and pass it back to the user if they @@ -1254,6 +1189,54 @@ int HostResolverImpl::Resolve(const RequestInfo& info, return ERR_IO_PENDING; } +int HostResolverImpl::ResolveHelper(int request_id, + const Key& key, + const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& request_net_log, + const BoundNetLog& source_net_log) { + // The result of |getaddrinfo| for empty hosts is inconsistent across systems. + // On Windows it gives the default interface's address, whereas on Linux it + // gives an error. We will make it fail on all platforms for consistency. + if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) + return ERR_NAME_NOT_RESOLVED; + + int net_error = ERR_UNEXPECTED; + if (ResolveAsIP(key, info, &net_error, addresses)) + return net_error; + net_error = ERR_DNS_CACHE_MISS; + ServeFromCache(key, info, request_net_log, &net_error, addresses); + return net_error; +} + +int HostResolverImpl::ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& source_net_log) { + DCHECK(CalledOnValidThread()); + DCHECK(addresses); + + // Choose a unique ID number for observers to see. + int request_id = next_request_id_++; + + // Make a log item for the request. + BoundNetLog request_net_log = BoundNetLog::Make(net_log_, + NetLog::SOURCE_HOST_RESOLVER_IMPL_REQUEST); + + // Update the net log and notify registered observers. + OnStartRequest(source_net_log, request_net_log, request_id, info); + + // Build a key that identifies the request in the cache and in the + // outstanding jobs map. + Key key = GetEffectiveKeyForRequest(info); + + int rv = ResolveHelper(request_id, key, info, addresses, request_net_log, + source_net_log); + OnFinishRequest(source_net_log, request_net_log, request_id, info, + rv, + 0 /* os_error (unknown since from cache) */); + return rv; +} + // See OnJobComplete(Job*) for why it is important not to clean out // cancelled requests from Job::requests_. void HostResolverImpl::CancelRequest(RequestHandle req_handle) { @@ -1313,6 +1296,56 @@ HostResolverImpl* HostResolverImpl::GetAsHostResolverImpl() { return this; } + +bool HostResolverImpl::ResolveAsIP(const Key& key, + const RequestInfo& info, + int* net_error, + AddressList* addresses) { + DCHECK(addresses); + DCHECK(net_error); + IPAddressNumber ip_number; + if (!ParseIPLiteralToNumber(key.hostname, &ip_number)) + return false; + + DCHECK_EQ(key.host_resolver_flags & + ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY | + HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6), + 0) << " Unhandled flag"; + bool ipv6_disabled = default_address_family_ == ADDRESS_FAMILY_IPV4 && + !ipv6_probe_monitoring_; + *net_error = OK; + if (ip_number.size() == 16 && ipv6_disabled) { + *net_error = ERR_NAME_NOT_RESOLVED; + } else { + *addresses = AddressList::CreateFromIPAddressWithCname( + ip_number, info.port(), + (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)); + } + return true; +} + +bool HostResolverImpl::ServeFromCache(const Key& key, + const RequestInfo& info, + const BoundNetLog& request_net_log, + int* net_error, + AddressList* addresses) { + DCHECK(addresses); + DCHECK(net_error); + if (!info.allow_cached_response() || !cache_.get()) + return false; + + const HostCache::Entry* cache_entry = cache_->Lookup( + key, base::TimeTicks::Now()); + if (!cache_entry) + return false; + + request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); + *net_error = cache_entry->error; + if (*net_error == OK) + *addresses = CreateAddressListUsingPort(cache_entry->addrlist, info.port()); + return true; +} + void HostResolverImpl::AddOutstandingJob(Job* job) { scoped_refptr<Job>& found_job = jobs_[job->key()]; DCHECK(!found_job); diff --git a/net/base/host_resolver_impl.h b/net/base/host_resolver_impl.h index a6f5220..4fe298d 100644 --- a/net/base/host_resolver_impl.h +++ b/net/base/host_resolver_impl.h @@ -137,16 +137,19 @@ class NET_API HostResolverImpl AddressList* addresses, CompletionCallback* callback, RequestHandle* out_req, - const BoundNetLog& source_net_log); - virtual void CancelRequest(RequestHandle req); - virtual void AddObserver(HostResolver::Observer* observer); - virtual void RemoveObserver(HostResolver::Observer* observer); + const BoundNetLog& source_net_log) OVERRIDE; + virtual int ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& source_net_log) OVERRIDE; + virtual void CancelRequest(RequestHandle req) OVERRIDE; + virtual void AddObserver(HostResolver::Observer* observer) OVERRIDE; + virtual void RemoveObserver(HostResolver::Observer* observer) OVERRIDE; // Set address family, and disable IPv6 probe support. - virtual void SetDefaultAddressFamily(AddressFamily address_family); - virtual AddressFamily GetDefaultAddressFamily() const; + virtual void SetDefaultAddressFamily(AddressFamily address_family) OVERRIDE; + virtual AddressFamily GetDefaultAddressFamily() const OVERRIDE; - virtual HostResolverImpl* GetAsHostResolverImpl(); + virtual HostResolverImpl* GetAsHostResolverImpl() OVERRIDE; private: // Allow tests to access our innards for testing purposes. @@ -164,6 +167,33 @@ class NET_API HostResolverImpl typedef std::map<Key, scoped_refptr<Job> > JobMap; typedef std::vector<HostResolver::Observer*> ObserversList; + // Helper used by |Resolve()| and |ResolveFromCache()|. Performs IP + // literal and cache lookup, returns OK if successfull, + // ERR_NAME_NOT_RESOLVED if either hostname is invalid or IP literal is + // incompatible, ERR_DNS_CACHE_MISS if entry was not found in cache. + int ResolveHelper(int request_id, + const Key& key, + const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& request_net_log, + const BoundNetLog& source_net_log); + + // Tries to resolve |key| as an IP, returns true and sets |net_error| if + // succeeds, returns false otherwise. + bool ResolveAsIP(const Key& key, + const RequestInfo& info, + int* net_error, + AddressList* addresses); + + // If |key| is not found in cache returns false, otherwise returns + // true, sets |net_error| to the cached error code and fills |addresses| + // if it is a positive entry. + bool ServeFromCache(const Key& key, + const RequestInfo& info, + const BoundNetLog& request_net_log, + int* net_error, + AddressList* addresses); + // Returns the HostResolverProc to use for this instance. HostResolverProc* effective_resolver_proc() const { return resolver_proc_ ? diff --git a/net/base/host_resolver_impl_unittest.cc b/net/base/host_resolver_impl_unittest.cc index e01f328..0123adb 100644 --- a/net/base/host_resolver_impl_unittest.cc +++ b/net/base/host_resolver_impl_unittest.cc @@ -479,8 +479,10 @@ TEST_F(HostResolverImplTest, NumericIPv4Address) { CreateHostResolverImpl(resolver_proc)); AddressList addrlist; const int kPortnum = 5555; + TestCompletionCallback callback; HostResolver::RequestInfo info(HostPortPair("127.1.2.3", kPortnum)); - int err = host_resolver->Resolve(info, &addrlist, NULL, NULL, BoundNetLog()); + int err = host_resolver->Resolve(info, &addrlist, &callback, NULL, + BoundNetLog()); EXPECT_EQ(OK, err); const struct addrinfo* ainfo = addrlist.head(); @@ -504,8 +506,10 @@ TEST_F(HostResolverImplTest, NumericIPv6Address) { CreateHostResolverImpl(resolver_proc)); AddressList addrlist; const int kPortnum = 5555; + TestCompletionCallback callback; HostResolver::RequestInfo info(HostPortPair("2001:db8::1", kPortnum)); - int err = host_resolver->Resolve(info, &addrlist, NULL, NULL, BoundNetLog()); + int err = host_resolver->Resolve(info, &addrlist, &callback, NULL, + BoundNetLog()); EXPECT_EQ(OK, err); const struct addrinfo* ainfo = addrlist.head(); @@ -534,8 +538,9 @@ TEST_F(HostResolverImplTest, EmptyHost) { CreateHostResolverImpl(resolver_proc)); AddressList addrlist; const int kPortnum = 5555; + TestCompletionCallback callback; HostResolver::RequestInfo info(HostPortPair("", kPortnum)); - int err = host_resolver->Resolve(info, &addrlist, NULL, NULL, + int err = host_resolver->Resolve(info, &addrlist, &callback, NULL, BoundNetLog()); EXPECT_EQ(ERR_NAME_NOT_RESOLVED, err); } @@ -550,8 +555,10 @@ TEST_F(HostResolverImplTest, LongHost) { AddressList addrlist; const int kPortnum = 5555; std::string hostname(4097, 'a'); + TestCompletionCallback callback; HostResolver::RequestInfo info(HostPortPair(hostname, kPortnum)); - int err = host_resolver->Resolve(info, &addrlist, NULL, NULL, BoundNetLog()); + int err = host_resolver->Resolve(info, &addrlist, &callback, NULL, + BoundNetLog()); EXPECT_EQ(ERR_NAME_NOT_RESOLVED, err); } @@ -1632,13 +1639,11 @@ TEST_F(HostResolverImplTest, DisallowNonCachedResponses) { // First hit will miss the cache. HostResolver::RequestInfo info(HostPortPair("just.testing", kPortnum)); - info.set_only_use_cached_response(true); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); - int err = host_resolver->Resolve(info, &addrlist, NULL, NULL, log.bound()); - EXPECT_EQ(ERR_NAME_NOT_RESOLVED, err); + int err = host_resolver->ResolveFromCache(info, &addrlist, log.bound()); + EXPECT_EQ(ERR_DNS_CACHE_MISS, err); // This time, we fetch normally. - info.set_only_use_cached_response(false); TestCompletionCallback callback; err = host_resolver->Resolve(info, &addrlist, &callback, NULL, log.bound()); EXPECT_EQ(ERR_IO_PENDING, err); @@ -1646,8 +1651,7 @@ TEST_F(HostResolverImplTest, DisallowNonCachedResponses) { EXPECT_EQ(OK, err); // Now we should be able to fetch from the cache. - info.set_only_use_cached_response(true); - err = host_resolver->Resolve(info, &addrlist, NULL, NULL, log.bound()); + err = host_resolver->ResolveFromCache(info, &addrlist, log.bound()); EXPECT_EQ(OK, err); const struct addrinfo* ainfo = addrlist.head(); diff --git a/net/base/mapped_host_resolver.cc b/net/base/mapped_host_resolver.cc index 0e596f7..86912ff 100644 --- a/net/base/mapped_host_resolver.cc +++ b/net/base/mapped_host_resolver.cc @@ -7,6 +7,7 @@ #include "base/string_tokenizer.h" #include "base/string_util.h" #include "net/base/host_port_pair.h" +#include "net/base/net_errors.h" #include "net/base/net_util.h" namespace net { @@ -23,6 +24,8 @@ int MappedHostResolver::Resolve(const RequestInfo& info, CompletionCallback* callback, RequestHandle* out_req, const BoundNetLog& net_log) { + DCHECK(addresses); + DCHECK(callback); // Modify the request before forwarding it to |impl_|. RequestInfo modified_info = info; HostPortPair host_port(info.host_port_pair()); @@ -31,6 +34,13 @@ int MappedHostResolver::Resolve(const RequestInfo& info, return impl_->Resolve(modified_info, addresses, callback, out_req, net_log); } +int MappedHostResolver::ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& net_log) { + NOTIMPLEMENTED(); + return ERR_UNEXPECTED; +} + void MappedHostResolver::CancelRequest(RequestHandle req) { impl_->CancelRequest(req); } diff --git a/net/base/mapped_host_resolver.h b/net/base/mapped_host_resolver.h index 343c5e1..a589fa3 100644 --- a/net/base/mapped_host_resolver.h +++ b/net/base/mapped_host_resolver.h @@ -48,11 +48,14 @@ class NET_API MappedHostResolver : public HostResolver { AddressList* addresses, CompletionCallback* callback, RequestHandle* out_req, - const BoundNetLog& net_log); - virtual void CancelRequest(RequestHandle req); - virtual void AddObserver(Observer* observer); - virtual void RemoveObserver(Observer* observer); - virtual HostResolverImpl* GetAsHostResolverImpl(); + const BoundNetLog& net_log) OVERRIDE; + virtual int ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& net_log) OVERRIDE; + virtual void CancelRequest(RequestHandle req) OVERRIDE; + virtual void AddObserver(Observer* observer) OVERRIDE; + virtual void RemoveObserver(Observer* observer) OVERRIDE; + virtual HostResolverImpl* GetAsHostResolverImpl() OVERRIDE; private: scoped_ptr<HostResolver> impl_; diff --git a/net/base/mock_host_resolver.cc b/net/base/mock_host_resolver.cc index f822bde..6b2aa4c5 100644 --- a/net/base/mock_host_resolver.cc +++ b/net/base/mock_host_resolver.cc @@ -112,6 +112,12 @@ int MockHostResolverBase::Resolve(const RequestInfo& info, return impl_->Resolve(info, addresses, callback, out_req, net_log); } +int MockHostResolverBase::ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& net_log) { + return impl_->ResolveFromCache(info, addresses, net_log); +} + void MockHostResolverBase::CancelRequest(RequestHandle req) { impl_->CancelRequest(req); } diff --git a/net/base/mock_host_resolver.h b/net/base/mock_host_resolver.h index acf06cb..2fcf892 100644 --- a/net/base/mock_host_resolver.h +++ b/net/base/mock_host_resolver.h @@ -63,10 +63,13 @@ class MockHostResolverBase : public HostResolver { AddressList* addresses, CompletionCallback* callback, RequestHandle* out_req, - const BoundNetLog& net_log); - virtual void CancelRequest(RequestHandle req); - virtual void AddObserver(Observer* observer); - virtual void RemoveObserver(Observer* observer); + const BoundNetLog& net_log) OVERRIDE; + virtual int ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& net_log) OVERRIDE; + virtual void CancelRequest(RequestHandle req) OVERRIDE; + virtual void AddObserver(Observer* observer) OVERRIDE; + virtual void RemoveObserver(Observer* observer) OVERRIDE; protected: MockHostResolverBase(bool use_caching); diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h index 3297d69..d1f5261 100644 --- a/net/base/net_error_list.h +++ b/net/base/net_error_list.h @@ -595,3 +595,6 @@ NET_ERROR(DNS_SERVER_FAILED, -802) // DNS transaction timed out. NET_ERROR(DNS_TIMED_OUT, -803) + +// The entry was not found in cache, for cache-only lookups. +NET_ERROR(DNS_CACHE_MISS, -804) diff --git a/net/base/single_request_host_resolver.cc b/net/base/single_request_host_resolver.cc index d3f7758..ced4801 100644 --- a/net/base/single_request_host_resolver.cc +++ b/net/base/single_request_host_resolver.cc @@ -27,6 +27,8 @@ int SingleRequestHostResolver::Resolve(const HostResolver::RequestInfo& info, AddressList* addresses, CompletionCallback* callback, const BoundNetLog& net_log) { + DCHECK(addresses); + DCHECK(callback); DCHECK(!cur_request_callback_) << "resolver already in use"; HostResolver::RequestHandle request = NULL; diff --git a/net/base/single_request_host_resolver_unittest.cc b/net/base/single_request_host_resolver_unittest.cc index 7a3a3a6..abf8348 100644 --- a/net/base/single_request_host_resolver_unittest.cc +++ b/net/base/single_request_host_resolver_unittest.cc @@ -32,7 +32,7 @@ class HangingHostResolver : public HostResolver { AddressList* addresses, CompletionCallback* callback, RequestHandle* out_req, - const BoundNetLog& net_log) { + const BoundNetLog& net_log) OVERRIDE { EXPECT_FALSE(has_outstanding_request()); outstanding_request_ = reinterpret_cast<RequestHandle>(0x1234); *out_req = outstanding_request_; @@ -42,17 +42,24 @@ class HangingHostResolver : public HostResolver { return ERR_IO_PENDING; } - virtual void CancelRequest(RequestHandle req) { + virtual int ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& net_log) OVERRIDE { + NOTIMPLEMENTED(); + return ERR_UNEXPECTED; + } + + virtual void CancelRequest(RequestHandle req) OVERRIDE { EXPECT_TRUE(has_outstanding_request()); EXPECT_EQ(req, outstanding_request_); outstanding_request_ = NULL; } - virtual void AddObserver(Observer* observer) { + virtual void AddObserver(Observer* observer) OVERRIDE { FAIL(); } - virtual void RemoveObserver(Observer* observer) { + virtual void RemoveObserver(Observer* observer) OVERRIDE { FAIL(); } diff --git a/net/dns/async_host_resolver.cc b/net/dns/async_host_resolver.cc index 757a00f..27d307e 100644 --- a/net/dns/async_host_resolver.cc +++ b/net/dns/async_host_resolver.cc @@ -37,8 +37,6 @@ class RequestParameters : public NetLog::EventParameters { dict->SetInteger("address_family", static_cast<int>(info_.address_family())); dict->SetBoolean("allow_cached_response", info_.allow_cached_response()); - dict->SetBoolean("only_use_cached_response", - info_.only_use_cached_response()); dict->SetBoolean("is_speculative", info_.is_speculative()); dict->SetInteger("priority", info_.priority()); @@ -114,7 +112,7 @@ class AsyncHostResolver::Request { int id() const { return id_; } int result() const { return result_; } const Key& key() const { - DCHECK(IsValidKey()); + DCHECK(IsValid()); return key_; } const HostResolver::RequestInfo& info() const { return info_; } @@ -122,63 +120,24 @@ class AsyncHostResolver::Request { const BoundNetLog& source_net_log() const { return source_net_log_; } const BoundNetLog& request_net_log() const { return request_net_log_; } - bool ResolveSynchronously() { - bool resolve_succeeded = true; + bool ResolveAsIp() { IPAddressNumber ip_number; - if (info_.hostname().empty()) - result_ = ERR_NAME_NOT_RESOLVED; - else if (ParseIPLiteralToNumber(info_.hostname(), &ip_number)) - result_ = ServeAsIp(ip_number); - else if (!IsValidKey()) + if (!ParseIPLiteralToNumber(info_.hostname(), &ip_number)) + return false; + + if (ip_number.size() != kIPv4AddressSize) { result_ = ERR_NAME_NOT_RESOLVED; - else if (ServeFromCache()) + } else { + *addresses_ = AddressList::CreateFromIPAddressWithCname( + ip_number, + info_.port(), + info_.host_resolver_flags() & HOST_RESOLVER_CANONNAME); result_ = OK; - else if (info_.only_use_cached_response()) - result_ = ERR_NAME_NOT_RESOLVED; - else - resolve_succeeded = false; - return resolve_succeeded; - } - - // Called when a request completes synchronously; we do not have an - // AddressList argument, since in case of a successful synchronous - // completion, ResolveSynchronously would set the |addresses_| and in - // case of an unsuccessful synchronous completion, we do not touch - // |addresses_|. - void OnSyncComplete(int result) { - callback_ = NULL; - resolver_->OnFinish(this, result); - } - - // Called when a request completes asynchronously. - void OnAsyncComplete(int result, const AddressList& addresses) { - if (result == OK) - *addresses_ = CreateAddressListUsingPort(addresses, info_.port()); - DCHECK(callback_); - CompletionCallback* callback = callback_; - callback_ = NULL; - resolver_->OnFinish(this, result); - callback->Run(result); - } - - private: - bool IsValidKey() const { return !key_.first.empty(); } - - int ServeAsIp(const IPAddressNumber& ip_number) { - if (ip_number.size() != kIPv4AddressSize) - return ERR_NAME_NOT_RESOLVED; - *addresses_ = AddressList::CreateFromIPAddressWithCname( - ip_number, - info_.port(), - info_.host_resolver_flags() & HOST_RESOLVER_CANONNAME); - return OK; + } + return true; } bool ServeFromCache() { - // Sanity check -- it shouldn't be the case that allow_cached_response is - // false while only_use_cached_response is true. - DCHECK(info_.allow_cached_response() || !info_.only_use_cached_response()); - HostCache* cache = resolver_->cache_.get(); if (!cache || !info_.allow_cached_response()) return false; @@ -191,6 +150,7 @@ class AsyncHostResolver::Request { request_net_log_.AddEvent( NetLog::TYPE_ASYNC_HOST_RESOLVER_CACHE_HIT, NULL); DCHECK_EQ(OK, cache_entry->error); + result_ = cache_entry->error; *addresses_ = CreateAddressListUsingPort(cache_entry->addrlist, info_.port()); return true; @@ -198,6 +158,33 @@ class AsyncHostResolver::Request { return false; } + // Called when a request completes synchronously; we do not have an + // AddressList argument, since in case of a successful synchronous + // completion, either ResolveAsIp or ServerFromCache would set the + // |addresses_| and in case of an unsuccessful synchronous completion, we + // do not touch |addresses_|. + void OnSyncComplete(int result) { + callback_ = NULL; + resolver_->OnFinish(this, result); + } + + // Called when a request completes asynchronously. + void OnAsyncComplete(int result, const AddressList& addresses) { + if (result == OK) + *addresses_ = CreateAddressListUsingPort(addresses, info_.port()); + DCHECK(callback_); + CompletionCallback* callback = callback_; + callback_ = NULL; + resolver_->OnFinish(this, result); + callback->Run(result); + } + + // Returns true if request has a validly formed hostname. + bool IsValid() const { + return !info_.hostname().empty() && !key_.first.empty(); + } + + private: AsyncHostResolver* resolver_; BoundNetLog source_net_log_; BoundNetLog request_net_log_; @@ -246,11 +233,15 @@ int AsyncHostResolver::Resolve(const RequestInfo& info, CompletionCallback* callback, RequestHandle* out_req, const BoundNetLog& source_net_log) { + DCHECK(addresses); + DCHECK(callback); scoped_ptr<Request> request( CreateNewRequest(info, callback, addresses, source_net_log)); int rv = ERR_UNEXPECTED; - if (request->ResolveSynchronously()) + if (!request->IsValid()) + rv = ERR_NAME_NOT_RESOLVED; + else if (request->ResolveAsIp() || request->ServeFromCache()) rv = request->result(); else if (AttachToRequestList(request.get())) rv = ERR_IO_PENDING; @@ -269,6 +260,22 @@ int AsyncHostResolver::Resolve(const RequestInfo& info, return rv; } +int AsyncHostResolver::ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& source_net_log) { + scoped_ptr<Request> request( + CreateNewRequest(info, NULL, addresses, source_net_log)); + int rv = ERR_UNEXPECTED; + if (!request->IsValid()) + rv = ERR_NAME_NOT_RESOLVED; + else if (request->ResolveAsIp() || request->ServeFromCache()) + rv = request->result(); + else + rv = ERR_DNS_CACHE_MISS; + request->OnSyncComplete(rv); + return rv; +} + void AsyncHostResolver::OnStart(Request* request) { DCHECK(request); diff --git a/net/dns/async_host_resolver.h b/net/dns/async_host_resolver.h index dfc4de5..ddefbaf 100644 --- a/net/dns/async_host_resolver.h +++ b/net/dns/async_host_resolver.h @@ -44,6 +44,9 @@ class NET_API AsyncHostResolver CompletionCallback* callback, RequestHandle* out_req, const BoundNetLog& source_net_log) OVERRIDE; + virtual int ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& source_net_log) OVERRIDE; virtual void CancelRequest(RequestHandle req_handle) OVERRIDE; virtual void AddObserver(HostResolver::Observer* observer) OVERRIDE; virtual void RemoveObserver(HostResolver::Observer* observer) OVERRIDE; diff --git a/net/dns/async_host_resolver_unittest.cc b/net/dns/async_host_resolver_unittest.cc index 9d6f2b7..2f34ec8 100644 --- a/net/dns/async_host_resolver_unittest.cc +++ b/net/dns/async_host_resolver_unittest.cc @@ -179,13 +179,10 @@ TEST_F(AsyncHostResolverTest, IPv6LiteralLookup) { } TEST_F(AsyncHostResolverTest, CachedLookup) { - info0_.set_only_use_cached_response(true); - int rv = resolver_->Resolve(info0_, &addrlist0_, NULL, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); + int rv = resolver_->ResolveFromCache(info0_, &addrlist0_, BoundNetLog()); + EXPECT_EQ(ERR_DNS_CACHE_MISS, rv); // Cache the result of |info0_| lookup. - info0_.set_only_use_cached_response(false); rv = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -195,9 +192,7 @@ TEST_F(AsyncHostResolverTest, CachedLookup) { // Now lookup |info0_| from cache only, store results in |addrlist1_|, // should succeed synchronously. - info0_.set_only_use_cached_response(true); - rv = resolver_->Resolve(info0_, &addrlist1_, NULL, NULL, - BoundNetLog()); + rv = resolver_->ResolveFromCache(info0_, &addrlist1_, BoundNetLog()); EXPECT_EQ(OK, rv); VerifyAddressList(ip_addresses0_, kPortNum, addrlist1_); } diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 9679667..1a2825e 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -8861,26 +8861,29 @@ class OneTimeCachingHostResolver : public net::HostResolver { AddressList* addresses, CompletionCallback* callback, RequestHandle* out_req, - const BoundNetLog& net_log) { - int rv = host_resolver_.Resolve( + const BoundNetLog& net_log) OVERRIDE { + return host_resolver_.Resolve( info, addresses, callback, out_req, net_log); - if (rv == OK && info.only_use_cached_response() && - info.host_port_pair().Equals(host_port_)) { - // Discard cache. + } + + virtual int ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& net_log) OVERRIDE { + int rv = host_resolver_.ResolveFromCache(info, addresses, net_log); + if (rv == OK && info.host_port_pair().Equals(host_port_)) host_resolver_.Reset(NULL); - } return rv; } - virtual void CancelRequest(RequestHandle req) { + virtual void CancelRequest(RequestHandle req) OVERRIDE { host_resolver_.CancelRequest(req); } - virtual void AddObserver(Observer* observer) { + virtual void AddObserver(Observer* observer) OVERRIDE { return host_resolver_.AddObserver(observer); } - virtual void RemoveObserver(Observer* observer) { + virtual void RemoveObserver(Observer* observer) OVERRIDE{ return host_resolver_.RemoveObserver(observer); } diff --git a/net/proxy/sync_host_resolver_bridge_unittest.cc b/net/proxy/sync_host_resolver_bridge_unittest.cc index 1459a1e..75f7f16 100644 --- a/net/proxy/sync_host_resolver_bridge_unittest.cc +++ b/net/proxy/sync_host_resolver_bridge_unittest.cc @@ -47,6 +47,13 @@ class BlockableHostResolver : public HostResolver { return ERR_IO_PENDING; } + virtual int ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& net_log) OVERRIDE { + NOTIMPLEMENTED(); + return ERR_UNEXPECTED; + } + virtual void CancelRequest(RequestHandle req) OVERRIDE { EXPECT_EQ(reinterpret_cast<RequestHandle*>(1), req); was_request_cancelled_ = true; diff --git a/net/socket/socks_client_socket_unittest.cc b/net/socket/socks_client_socket_unittest.cc index 6cc7418..437d657 100644 --- a/net/socket/socks_client_socket_unittest.cc +++ b/net/socket/socks_client_socket_unittest.cc @@ -89,21 +89,30 @@ class HangingHostResolver : public HostResolver { AddressList* addresses, CompletionCallback* callback, RequestHandle* out_req, - const BoundNetLog& net_log) { + const BoundNetLog& net_log) OVERRIDE { + DCHECK(addresses); + DCHECK(callback); EXPECT_FALSE(HasOutstandingRequest()); outstanding_request_ = reinterpret_cast<RequestHandle>(1); *out_req = outstanding_request_; return ERR_IO_PENDING; } - virtual void CancelRequest(RequestHandle req) { + virtual int ResolveFromCache(const RequestInfo& info, + AddressList* addresses, + const BoundNetLog& net_log) OVERRIDE { + NOTIMPLEMENTED(); + return ERR_UNEXPECTED; + } + + virtual void CancelRequest(RequestHandle req) OVERRIDE { EXPECT_TRUE(HasOutstandingRequest()); EXPECT_EQ(outstanding_request_, req); outstanding_request_ = NULL; } - virtual void AddObserver(Observer* observer) {} - virtual void RemoveObserver(Observer* observer) {} + virtual void AddObserver(Observer* observer) OVERRIDE {} + virtual void RemoveObserver(Observer* observer) OVERRIDE {} bool HasOutstandingRequest() { return outstanding_request_ != NULL; diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc index c0a5194..d90a1d5 100644 --- a/net/spdy/spdy_session_pool.cc +++ b/net/spdy/spdy_session_pool.cc @@ -342,12 +342,9 @@ void SpdySessionPool::RemoveSessionList( bool SpdySessionPool::LookupAddresses(const HostPortProxyPair& pair, AddressList* addresses) const { net::HostResolver::RequestInfo resolve_info(pair.first); - resolve_info.set_only_use_cached_response(true); - int rv = resolver_->Resolve(resolve_info, - addresses, - NULL, - NULL, - net::BoundNetLog()); + int rv = resolver_->ResolveFromCache(resolve_info, + addresses, + net::BoundNetLog()); DCHECK_NE(ERR_IO_PENDING, rv); return rv == OK; } |