diff options
author | agayev@chromium.org <agayev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-20 20:16:26 +0000 |
---|---|---|
committer | agayev@chromium.org <agayev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-20 20:16:26 +0000 |
commit | de093d1f62f204fc02d8f693bc88fd99f1d74171 (patch) | |
tree | b3a6ffa4fac912743c102c067d8f3c5e747e199a | |
parent | 5728fef191336ccbfbc910fc851cbe814862b6e6 (diff) | |
download | chromium_src-de093d1f62f204fc02d8f693bc88fd99f1d74171.zip chromium_src-de093d1f62f204fc02d8f693bc88fd99f1d74171.tar.gz chromium_src-de093d1f62f204fc02d8f693bc88fd99f1d74171.tar.bz2 |
Revert 93237 - Implement AsyncHostResolver, an asynchronous HostResolver.
BUG=60149
TEST=net_unittests --gtest_filter="AsyncHostResolverTest*"
Review URL: http://codereview.chromium.org/7342046
TBR=agayev@chromium.org
Review URL: http://codereview.chromium.org/7466010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@93240 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/io_thread.cc | 19 | ||||
-rw-r--r-- | chrome/browser/net/passive_log_collector.cc | 29 | ||||
-rw-r--r-- | chrome/browser/net/passive_log_collector.h | 16 | ||||
-rw-r--r-- | chrome/browser/resources/net_internals/sourceentry.js | 1 | ||||
-rw-r--r-- | net/base/async_host_resolver.cc | 427 | ||||
-rw-r--r-- | net/base/async_host_resolver.h | 156 | ||||
-rw-r--r-- | net/base/async_host_resolver_unittest.cc | 574 | ||||
-rw-r--r-- | net/base/dns_test_util.cc | 35 | ||||
-rw-r--r-- | net/base/dns_test_util.h | 181 | ||||
-rw-r--r-- | net/base/dns_transaction_unittest.cc | 211 | ||||
-rw-r--r-- | net/base/host_resolver.h | 6 | ||||
-rw-r--r-- | net/base/host_resolver_impl_unittest.cc | 94 | ||||
-rw-r--r-- | net/base/net_log_event_type_list.h | 40 | ||||
-rw-r--r-- | net/base/net_log_source_type_list.h | 3 | ||||
-rw-r--r-- | net/net.gyp | 3 |
15 files changed, 212 insertions, 1583 deletions
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 35070e19..11d8827 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -34,7 +34,6 @@ #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/in_process_webkit/indexed_db_key_utility_client.h" #include "content/common/url_fetcher.h" -#include "net/base/async_host_resolver.h" #include "net/base/cert_verifier.h" #include "net/base/cookie_monster.h" #include "net/base/dnsrr_resolver.h" @@ -161,24 +160,8 @@ net::HostResolver* CreateGlobalHostResolver(net::NetLog* net_log) { } } - net::HostResolver* global_host_resolver = NULL; - if (command_line.HasSwitch(switches::kDnsServer)) { - std::string dns_ip_string = - command_line.GetSwitchValueASCII(switches::kDnsServer); - net::IPAddressNumber dns_ip_number; - if (net::ParseIPLiteralToNumber(dns_ip_string, &dns_ip_number)) { - global_host_resolver = - net::CreateAsyncHostResolver(parallelism, dns_ip_number, net_log); - } else { - LOG(ERROR) << "Invalid IP address specified for --dns-server: " - << dns_ip_string; - } - } - - if (!global_host_resolver) { - global_host_resolver = + net::HostResolver* global_host_resolver = net::CreateSystemHostResolver(parallelism, retry_attempts, net_log); - } // Determine if we should disable IPv6 support. if (!command_line.HasSwitch(switches::kEnableIPv6)) { diff --git a/chrome/browser/net/passive_log_collector.cc b/chrome/browser/net/passive_log_collector.cc index ca321dd..6e522a7 100644 --- a/chrome/browser/net/passive_log_collector.cc +++ b/chrome/browser/net/passive_log_collector.cc @@ -78,8 +78,6 @@ PassiveLogCollector::PassiveLogCollector() trackers_[net::NetLog::SOURCE_EXPONENTIAL_BACKOFF_THROTTLING] = &exponential_backoff_throttling_tracker_; trackers_[net::NetLog::SOURCE_DNS_TRANSACTION] = &dns_transaction_tracker_; - trackers_[net::NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST] = - &async_host_resolver_request_tracker_; // Make sure our mapping is up-to-date. for (size_t i = 0; i < arraysize(trackers_); ++i) DCHECK(trackers_[i]) << "Unhandled SourceType: " << i; @@ -697,30 +695,3 @@ PassiveLogCollector::DnsTransactionTracker::DoAddEntry( } return ACTION_NONE; } - -//---------------------------------------------------------------------------- -// AsyncHostResolverRequestTracker -//---------------------------------------------------------------------------- - -const size_t -PassiveLogCollector::AsyncHostResolverRequestTracker::kMaxNumSources = 100; - -const size_t -PassiveLogCollector::AsyncHostResolverRequestTracker::kMaxGraveyardSize = 15; - -PassiveLogCollector:: - AsyncHostResolverRequestTracker::AsyncHostResolverRequestTracker() - : SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) { -} - -PassiveLogCollector::SourceTracker::Action -PassiveLogCollector::AsyncHostResolverRequestTracker::DoAddEntry( - const ChromeNetLog::Entry& entry, - SourceInfo* out_info) { - AddEntryToSourceInfo(entry, out_info); - if (entry.type == net::NetLog::TYPE_ASYNC_HOST_RESOLVER_REQUEST && - entry.phase == net::NetLog::PHASE_END) { - return ACTION_MOVE_TO_GRAVEYARD; - } - return ACTION_NONE; -} diff --git a/chrome/browser/net/passive_log_collector.h b/chrome/browser/net/passive_log_collector.h index 28598b2..56c60c7 100644 --- a/chrome/browser/net/passive_log_collector.h +++ b/chrome/browser/net/passive_log_collector.h @@ -369,21 +369,6 @@ class PassiveLogCollector : public ChromeNetLog::ThreadSafeObserver { DISALLOW_COPY_AND_ASSIGN(DnsTransactionTracker); }; - // Tracks the log entries for the last seen SOURCE_ASYNC_HOST_RESOLVER_REQUEST - class AsyncHostResolverRequestTracker : public SourceTracker { - public: - static const size_t kMaxNumSources; - static const size_t kMaxGraveyardSize; - - AsyncHostResolverRequestTracker(); - - private: - virtual Action DoAddEntry(const ChromeNetLog::Entry& entry, - SourceInfo* out_info); - - DISALLOW_COPY_AND_ASSIGN(AsyncHostResolverRequestTracker); - }; - PassiveLogCollector(); virtual ~PassiveLogCollector(); @@ -425,7 +410,6 @@ class PassiveLogCollector : public ChromeNetLog::ThreadSafeObserver { HttpStreamJobTracker http_stream_job_tracker_; ExponentialBackoffThrottlingTracker exponential_backoff_throttling_tracker_; DnsTransactionTracker dns_transaction_tracker_; - AsyncHostResolverRequestTracker async_host_resolver_request_tracker_; // This array maps each NetLog::SourceType to one of the tracker instances // defined above. Use of this array avoid duplicating the list of trackers diff --git a/chrome/browser/resources/net_internals/sourceentry.js b/chrome/browser/resources/net_internals/sourceentry.js index 1a901ca..3cb5fd0 100644 --- a/chrome/browser/resources/net_internals/sourceentry.js +++ b/chrome/browser/resources/net_internals/sourceentry.js @@ -321,7 +321,6 @@ SourceEntry.prototype.getDescription = function() { description = connectJobSourceEntry.getDescription(); } break; - case LogSourceType.ASYNC_HOST_RESOLVER_REQUEST: case LogSourceType.DNS_TRANSACTION: description = e.params.hostname; break; diff --git a/net/base/async_host_resolver.cc b/net/base/async_host_resolver.cc deleted file mode 100644 index 8aa9818..0000000 --- a/net/base/async_host_resolver.cc +++ /dev/null @@ -1,427 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/async_host_resolver.h" - -#include <algorithm> - -#include "base/bind.h" -#include "base/logging.h" -#include "base/rand_util.h" -#include "base/stl_util.h" -#include "base/values.h" -#include "net/base/address_list.h" -#include "net/base/dns_util.h" -#include "net/base/net_errors.h" -#include "net/socket/client_socket_factory.h" - -namespace net { - -namespace { - -// TODO(agayev): fix this when IPv6 support is added. -uint16 QueryTypeFromAddressFamily(AddressFamily address_family) { - return kDNS_A; -} - -int ResolveAsIp(const HostResolver::RequestInfo& info, - const IPAddressNumber& ip_number, - AddressList* addresses) { - 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; -} - -class RequestParameters : public NetLog::EventParameters { - public: - RequestParameters(const HostResolver::RequestInfo& info, - const NetLog::Source& source) - : info_(info), source_(source) {} - - virtual Value* ToValue() const { - DictionaryValue* dict = new DictionaryValue(); - dict->SetString("hostname", info_.host_port_pair().ToString()); - 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()); - - if (source_.is_valid()) - dict->Set("source_dependency", source_.ToValue()); - - return dict; - } - - private: - const HostResolver::RequestInfo info_; - const NetLog::Source source_; -}; - -} // namespace - -HostResolver* CreateAsyncHostResolver(size_t max_concurrent_resolves, - const IPAddressNumber& dns_ip, - NetLog* net_log) { - size_t max_transactions = max_concurrent_resolves; - if (max_transactions == 0) - max_transactions = 20; - size_t max_pending_requests = max_transactions * 100; - HostResolver* resolver = new AsyncHostResolver( - IPEndPoint(dns_ip, 53), - max_transactions, - max_pending_requests, - base::Bind(&base::RandInt), - NULL, - net_log); - return resolver; -} - -//----------------------------------------------------------------------------- -class AsyncHostResolver::Request { - public: - Request(const BoundNetLog& source_net_log, - const BoundNetLog& request_net_log, - int id, - const HostResolver::RequestInfo& info, - const Key& key, - CompletionCallback* callback, - AddressList* addresses) - : source_net_log_(source_net_log), - request_net_log_(request_net_log), - id_(id), - info_(info), - key_(key), - callback_(callback), - addresses_(addresses) { - DCHECK(addresses_); - } - - int id() const { return id_; } - const HostResolver::RequestInfo& info() const { return info_; } - const Key& key() const { return key_; } - RequestPriority priority() const { return info_.priority(); } - const BoundNetLog& source_net_log() const { return source_net_log_; } - const BoundNetLog& request_net_log() const { return request_net_log_; } - const AddressList* addresses() const { return addresses_; } - - void OnComplete(int result, const IPAddressList& ip_addresses) { - DCHECK(callback_); - if (result == OK) - *addresses_ = - AddressList::CreateFromIPAddressList(ip_addresses, info_.port()); - callback_->Run(result); - } - - private: - BoundNetLog source_net_log_; - BoundNetLog request_net_log_; - const int id_; - const HostResolver::RequestInfo info_; - const Key key_; - CompletionCallback* callback_; - AddressList* addresses_; -}; - -//----------------------------------------------------------------------------- -AsyncHostResolver::AsyncHostResolver(const IPEndPoint& dns_server, - size_t max_transactions, - size_t max_pending_requests, - const RandIntCallback& rand_int_cb, - ClientSocketFactory* factory, - NetLog* net_log) - : max_transactions_(max_transactions), - max_pending_requests_(max_pending_requests), - dns_server_(dns_server), - rand_int_cb_(rand_int_cb), - factory_(factory), - next_request_id_(0), - net_log_(net_log) { -} - -AsyncHostResolver::~AsyncHostResolver() { - for (KeyRequestListMap::iterator it = requestlist_map_.begin(); - it != requestlist_map_.end(); ++it) - STLDeleteElements(&it->second); - STLDeleteElements(&transactions_); -} - -int AsyncHostResolver::Resolve(const RequestInfo& info, - AddressList* addresses, - CompletionCallback* callback, - RequestHandle* out_req, - const BoundNetLog& source_net_log) { - DCHECK(addresses); - - IPAddressNumber ip_number; - std::string dns_name; - int rv = ERR_UNEXPECTED; - if (info.hostname().empty()) - rv = ERR_NAME_NOT_RESOLVED; - else if (ParseIPLiteralToNumber(info.hostname(), &ip_number)) - rv = ResolveAsIp(info, ip_number, addresses); - else if (!DNSDomainFromDot(info.hostname(), &dns_name)) - rv = ERR_NAME_NOT_RESOLVED; - else if (info.only_use_cached_response()) // TODO(agayev): support caching - rv = ERR_NAME_NOT_RESOLVED; - - Request* request = CreateNewRequest( - info, dns_name, callback, addresses, source_net_log); - - OnStart(request); - if (rv != ERR_UNEXPECTED) { - OnFinish(request, rv); - delete request; - return rv; - } - - if (out_req) - *out_req = reinterpret_cast<RequestHandle>(request); - - if (AttachToRequestList(request)) - return ERR_IO_PENDING; - if (transactions_.size() < max_transactions_) - return StartNewTransactionFor(request); - return Enqueue(request); -} - -void AsyncHostResolver::OnStart(Request* request) { - DCHECK(request); - - request->source_net_log().BeginEvent( - NetLog::TYPE_ASYNC_HOST_RESOLVER, - make_scoped_refptr(new NetLogSourceParameter( - "source_dependency", request->request_net_log().source()))); - - request->request_net_log().BeginEvent( - NetLog::TYPE_ASYNC_HOST_RESOLVER_REQUEST, - make_scoped_refptr(new RequestParameters( - request->info(), request->source_net_log().source()))); - - FOR_EACH_OBSERVER( - HostResolver::Observer, observers_, - OnStartResolution(request->id(), request->info())); -} - -void AsyncHostResolver::OnFinish(Request* request, int result) { - DCHECK(request); - bool was_resolved = result == OK; - - FOR_EACH_OBSERVER( - HostResolver::Observer, observers_, - OnFinishResolutionWithStatus( - request->id(), was_resolved, request->info())); - - request->request_net_log().EndEventWithNetErrorCode( - NetLog::TYPE_ASYNC_HOST_RESOLVER_REQUEST, result); - request->source_net_log().EndEvent( - NetLog::TYPE_ASYNC_HOST_RESOLVER, NULL); -} - -void AsyncHostResolver::OnCancel(Request* request) { - DCHECK(request); - - FOR_EACH_OBSERVER( - HostResolver::Observer, observers_, - OnCancelResolution(request->id(), request->info())); - - request->request_net_log().AddEvent( - NetLog::TYPE_CANCELLED, NULL); - request->request_net_log().EndEvent( - NetLog::TYPE_ASYNC_HOST_RESOLVER_REQUEST, NULL); - request->source_net_log().EndEvent( - NetLog::TYPE_ASYNC_HOST_RESOLVER, NULL); -} - -void AsyncHostResolver::CancelRequest(RequestHandle req_handle) { - scoped_ptr<Request> request(reinterpret_cast<Request*>(req_handle)); - DCHECK(request.get()); - - KeyRequestListMap::iterator it = requestlist_map_.find(request->key()); - if (it != requestlist_map_.end()) - it->second.remove(request.get()); - else - pending_requests_[request->priority()].remove(request.get()); - - OnCancel(request.get()); -} - -void AsyncHostResolver::AddObserver(HostResolver::Observer* observer) { - observers_.AddObserver(observer); -} - -void AsyncHostResolver::RemoveObserver(HostResolver::Observer* observer) { - observers_.RemoveObserver(observer); -} - -void AsyncHostResolver::SetDefaultAddressFamily( - AddressFamily address_family) { - NOTIMPLEMENTED(); -} - -AddressFamily AsyncHostResolver::GetDefaultAddressFamily() const { - return ADDRESS_FAMILY_IPV4; -} - -HostResolverImpl* AsyncHostResolver::GetAsHostResolverImpl() { - return NULL; -} - -void AsyncHostResolver::OnTransactionComplete( - int result, - const DnsTransaction* transaction, - const IPAddressList& ip_addresses) { - - DCHECK(std::find(transactions_.begin(), transactions_.end(), transaction) - != transactions_.end()); - DCHECK(requestlist_map_.find(transaction->key()) != requestlist_map_.end()); - - // Run callback of every request that was depending on this transaction, - // also notify observers. - RequestList& requests = requestlist_map_[transaction->key()]; - for (RequestList::iterator it = requests.begin(); it != requests.end(); - ++it) { - Request* request = *it; - OnFinish(request, result); - request->OnComplete(result, ip_addresses); - } - - // Cleanup requests. - STLDeleteElements(&requests); - requestlist_map_.erase(transaction->key()); - - // Cleanup transaction and start a new one if there are pending requests. - delete transaction; - transactions_.remove(transaction); - ProcessPending(); -} - -AsyncHostResolver::Request* AsyncHostResolver::CreateNewRequest( - const RequestInfo& info, - const std::string& dns_name, - CompletionCallback* callback, - AddressList* addresses, - const BoundNetLog& source_net_log) { - - uint16 query_type = QueryTypeFromAddressFamily(info.address_family()); - Key key(dns_name, query_type); - - BoundNetLog request_net_log = BoundNetLog::Make(net_log_, - NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST); - - int id = next_request_id_++; - Request* request = new Request( - source_net_log, request_net_log, id, info, key, callback, addresses); - return request; -} - -bool AsyncHostResolver::AttachToRequestList(Request* request) { - KeyRequestListMap::iterator it = requestlist_map_.find(request->key()); - if (it == requestlist_map_.end()) - return false; - it->second.push_back(request); - return true; -} - -int AsyncHostResolver::StartNewTransactionFor(Request* request) { - DCHECK(requestlist_map_.find(request->key()) == requestlist_map_.end()); - DCHECK(transactions_.size() < max_transactions_); - - request->request_net_log().AddEvent( - NetLog::TYPE_ASYNC_HOST_RESOLVER_CREATE_DNS_TRANSACTION, NULL); - - requestlist_map_[request->key()].push_back(request); - DnsTransaction* transaction = new DnsTransaction( - dns_server_, - request->key().first, - request->key().second, - rand_int_cb_, - factory_, - request->request_net_log(), - net_log_); - transaction->SetDelegate(this); - transactions_.push_back(transaction); - return transaction->Start(); -} - -int AsyncHostResolver::Enqueue(Request* request) { - scoped_ptr<Request> evicted_request(Insert(request)); - if (evicted_request != NULL) { - int rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; - if (evicted_request.get() == request) - return rv; - evicted_request->OnComplete(rv, IPAddressList()); - } - return ERR_IO_PENDING; -} - -AsyncHostResolver::Request* AsyncHostResolver::Insert(Request* request) { - pending_requests_[request->priority()].push_back(request); - if (GetNumPending() > max_pending_requests_) { - Request* req = RemoveLowest(); - DCHECK(req); - return req; - } - return NULL; -} - -size_t AsyncHostResolver::GetNumPending() { - size_t num_pending = 0; - for (size_t i = 0; i < arraysize(pending_requests_); ++i) - num_pending += pending_requests_[i].size(); - return num_pending; -} - -AsyncHostResolver::Request* AsyncHostResolver::RemoveLowest() { - for (int i = static_cast<int>(arraysize(pending_requests_)) - 1; - i >= 0; --i) { - RequestList& requests = pending_requests_[i]; - if (!requests.empty()) { - Request* request = requests.front(); - requests.pop_front(); - return request; - } - } - return NULL; -} - -AsyncHostResolver::Request* AsyncHostResolver::RemoveHighest() { - for (size_t i = 0; i < arraysize(pending_requests_) - 1; ++i) { - RequestList& requests = pending_requests_[i]; - if (!requests.empty()) { - Request* request = requests.front(); - requests.pop_front(); - return request; - } - } - return NULL; -} - -void AsyncHostResolver::ProcessPending() { - Request* request = RemoveHighest(); - if (!request) - return; - for (size_t i = 0; i < arraysize(pending_requests_); ++i) { - RequestList& requests = pending_requests_[i]; - RequestList::iterator it = requests.begin(); - while (it != requests.end()) { - if (request->key() == (*it)->key()) { - requestlist_map_[request->key()].push_back(*it); - it = requests.erase(it); - } else { - ++it; - } - } - } - StartNewTransactionFor(request); -} - -} // namespace net diff --git a/net/base/async_host_resolver.h b/net/base/async_host_resolver.h deleted file mode 100644 index 42ba997..0000000 --- a/net/base/async_host_resolver.h +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_BASE_ASYNC_HOST_RESOLVER_H_ -#define NET_BASE_ASYNC_HOST_RESOLVER_H_ -#pragma once - -#include <list> -#include <map> -#include <vector> - -#include "base/observer_list.h" -#include "base/threading/non_thread_safe.h" -#include "net/base/address_family.h" -#include "net/base/dns_transaction.h" -#include "net/base/host_resolver.h" -#include "net/base/ip_endpoint.h" -#include "net/base/net_log.h" -#include "net/base/rand_callback.h" - -namespace net { - -class AddressesList; -class ClientSocketFactory; - -class NET_API AsyncHostResolver : public HostResolver, - public DnsTransaction::Delegate, - public base::NonThreadSafe { - public: - AsyncHostResolver(const IPEndPoint& dns_server, - size_t max_transactions, - size_t max_pending_requests_, - const RandIntCallback& rand_int, - ClientSocketFactory* factory, - NetLog* net_log); - virtual ~AsyncHostResolver(); - - // HostResolver interface - virtual int Resolve(const RequestInfo& info, - AddressList* addresses, - CompletionCallback* callback, - RequestHandle* out_req, - 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; - virtual void SetDefaultAddressFamily(AddressFamily address_family) OVERRIDE; - virtual AddressFamily GetDefaultAddressFamily() const OVERRIDE; - virtual HostResolverImpl* GetAsHostResolverImpl() OVERRIDE; - - // DnsTransaction::Delegate interface - virtual void OnTransactionComplete( - int result, - const DnsTransaction* transaction, - const IPAddressList& ip_addresses) OVERRIDE; - - private: - FRIEND_TEST_ALL_PREFIXES(AsyncHostResolverTest, QueuedLookup); - FRIEND_TEST_ALL_PREFIXES(AsyncHostResolverTest, CancelPendingLookup); - FRIEND_TEST_ALL_PREFIXES(AsyncHostResolverTest, - ResolverDestructionCancelsLookups); - FRIEND_TEST_ALL_PREFIXES(AsyncHostResolverTest, - OverflowQueueWithLowPriorityLookup); - FRIEND_TEST_ALL_PREFIXES(AsyncHostResolverTest, - OverflowQueueWithHighPriorityLookup); - - class Request; - - typedef DnsTransaction::Key Key; - typedef std::list<Request*> RequestList; - typedef std::list<const DnsTransaction*> TransactionList; - typedef std::map<Key, RequestList> KeyRequestListMap; - - // Create a new request for the incoming Resolve() call. - Request* CreateNewRequest(const RequestInfo& info, - const std::string& dns_name, - CompletionCallback* callback, - AddressList* addresses, - const BoundNetLog& source_net_log); - - // Called when a request has just been started. - void OnStart(Request* request); - - // Called when a request has just completed (before its callback is run). - void OnFinish(Request* request, int result); - - // Called when a request has been cancelled. - void OnCancel(Request* request); - - // If there is an in-progress transaction for Request->key(), this will - // attach |request| to the respective list. - bool AttachToRequestList(Request* request); - - // Will start a new transaction for |request|, will insert a new key in - // |requestlist_map_| and append |request| to the respective list. - int StartNewTransactionFor(Request* request); - - // Will enqueue |request| in |pending_requests_|. - int Enqueue(Request* request); - - // A helper used by Enqueue to insert |request| into |pending_requests_|. - Request* Insert(Request* request); - - // Returns the number of pending requests. - size_t GetNumPending(); - - // Removes and returns a pointer to the lowest/highest priority request - // from |pending_requests_|. - Request* RemoveLowest(); - Request* RemoveHighest(); - - // Once a transaction has completed, called to start a new transaction if - // there are pending requests. - void ProcessPending(); - - // Maximum number of concurrent transactions. - size_t max_transactions_; - - // List of current transactions. - TransactionList transactions_; - - // A map from Key to a list of requests waiting for the Key to resolve. - KeyRequestListMap requestlist_map_; - - // Maximum number of pending requests. - size_t max_pending_requests_; - - // Queues based on priority for putting pending requests. - RequestList pending_requests_[NUM_PRIORITIES]; - - // DNS server to which queries will be setn. - IPEndPoint dns_server_; - - // Callback to be passed to DnsTransaction for generating DNS query ids. - RandIntCallback rand_int_cb_; - - // Also passed to DnsTransaction; it's a dependency injection to aid - // testing, outside of unit tests, its value is always NULL. - ClientSocketFactory* factory_; - - // The observers to notify when a request starts/ends. - ObserverList<HostResolver::Observer> observers_; - - // Monotonically increasing ID number to assign to the next request. - // Observers are the only consumers of this ID number. - int next_request_id_; - - NetLog* net_log_; - - DISALLOW_COPY_AND_ASSIGN(AsyncHostResolver); -}; - -} // namespace net - -#endif // NET_BASE_ASYNC_HOST_RESOLVER_H_ diff --git a/net/base/async_host_resolver_unittest.cc b/net/base/async_host_resolver_unittest.cc deleted file mode 100644 index 9ca6676..0000000 --- a/net/base/async_host_resolver_unittest.cc +++ /dev/null @@ -1,574 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/base/async_host_resolver.h" - -#include "base/bind.h" -#include "base/scoped_ptr.h" -#include "net/base/dns_test_util.h" -#include "net/base/net_log.h" -#include "net/base/rand_callback.h" -#include "net/base/sys_addrinfo.h" -#include "net/socket/socket_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { - -namespace { - -void VerifyAddressList(const std::vector<const char*>& ip_addresses, - int port, - const AddressList& addrlist) { - ASSERT_LT(0u, ip_addresses.size()); - ASSERT_NE(static_cast<addrinfo*>(NULL), addrlist.head()); - - IPAddressNumber ip_number; - const struct addrinfo* ainfo = addrlist.head(); - for (std::vector<const char*>::const_iterator i = ip_addresses.begin(); - i != ip_addresses.end(); ++i, ainfo = ainfo->ai_next) { - ASSERT_NE(static_cast<addrinfo*>(NULL), ainfo); - EXPECT_EQ(sizeof(struct sockaddr_in), ainfo->ai_addrlen); - - const struct sockaddr* sa = ainfo->ai_addr; - const struct sockaddr_in* sa_in = (const struct sockaddr_in*) sa; - EXPECT_EQ(htons(port), sa_in->sin_port); - EXPECT_STREQ(*i, NetAddressToString(sa, ainfo->ai_addrlen).c_str()); - } - ASSERT_EQ(static_cast<addrinfo*>(NULL), ainfo); -} - -} // namespace - -static const int kPortNum = 80; -static const size_t kMaxTransactions = 2; -static const size_t kMaxPendingRequests = 1; -static int transaction_ids[] = {0, 1, 2, 3}; - -// The following fixture sets up an environment for four different lookups -// with their data defined in dns_test_util.h. All tests make use of these -// predefined variables instead of each defining their own, to avoid -// boilerplate code in every test. Assuming every coming query is for a -// distinct hostname, as |kMaxTransactions| is set to 2 and -// |kMaxPendingRequests| is set to 1, first two queries start immediately -// and the next one is sent to pending queue; as a result, the next query -// should either fail itself or cause the pending query to fail depending -// on its priority. -class AsyncHostResolverTest : public testing::Test { - public: - AsyncHostResolverTest() - : info0_(HostPortPair(kT0HostName, kPortNum)), - info1_(HostPortPair(kT1HostName, kPortNum)), - info2_(HostPortPair(kT2HostName, kPortNum)), - info3_(HostPortPair(kT3HostName, kPortNum)), - ip_addresses0_(kT0IpAddresses, - kT0IpAddresses + arraysize(kT0IpAddresses)), - ip_addresses1_(kT1IpAddresses, - kT1IpAddresses + arraysize(kT1IpAddresses)), - ip_addresses2_(kT2IpAddresses, - kT2IpAddresses + arraysize(kT2IpAddresses)), - ip_addresses3_(kT3IpAddresses, - kT3IpAddresses + arraysize(kT3IpAddresses)), - test_prng_(std::deque<int>( - transaction_ids, transaction_ids + arraysize(transaction_ids))) { - - rand_int_cb_ = base::Bind(&TestPrng::GetNext, - base::Unretained(&test_prng_)); - // AF_INET only for now. - info0_.set_address_family(ADDRESS_FAMILY_IPV4); - info1_.set_address_family(ADDRESS_FAMILY_IPV4); - info2_.set_address_family(ADDRESS_FAMILY_IPV4); - info3_.set_address_family(ADDRESS_FAMILY_IPV4); - - // Setup socket read/writes for transaction 0. - writes0_.push_back( - MockWrite(true, reinterpret_cast<const char*>(kT0QueryDatagram), - arraysize(kT0QueryDatagram))); - reads0_.push_back( - MockRead(true, reinterpret_cast<const char*>(kT0ResponseDatagram), - arraysize(kT0ResponseDatagram))); - data0_.reset(new StaticSocketDataProvider(&reads0_[0], reads0_.size(), - &writes0_[0], writes0_.size())); - - // Setup socket read/writes for transaction 1. - writes1_.push_back( - MockWrite(true, reinterpret_cast<const char*>(kT1QueryDatagram), - arraysize(kT1QueryDatagram))); - reads1_.push_back( - MockRead(true, reinterpret_cast<const char*>(kT1ResponseDatagram), - arraysize(kT1ResponseDatagram))); - data1_.reset(new StaticSocketDataProvider(&reads1_[0], reads1_.size(), - &writes1_[0], writes1_.size())); - - // Setup socket read/writes for transaction 2. - writes2_.push_back( - MockWrite(true, reinterpret_cast<const char*>(kT2QueryDatagram), - arraysize(kT2QueryDatagram))); - reads2_.push_back( - MockRead(true, reinterpret_cast<const char*>(kT2ResponseDatagram), - arraysize(kT2ResponseDatagram))); - data2_.reset(new StaticSocketDataProvider(&reads2_[0], reads2_.size(), - &writes2_[0], writes2_.size())); - - // Setup socket read/writes for transaction 3. - writes3_.push_back( - MockWrite(true, reinterpret_cast<const char*>(kT3QueryDatagram), - arraysize(kT3QueryDatagram))); - reads3_.push_back( - MockRead(true, reinterpret_cast<const char*>(kT3ResponseDatagram), - arraysize(kT3ResponseDatagram))); - data3_.reset(new StaticSocketDataProvider(&reads3_[0], reads3_.size(), - &writes3_[0], writes3_.size())); - - factory_.AddSocketDataProvider(data0_.get()); - factory_.AddSocketDataProvider(data1_.get()); - factory_.AddSocketDataProvider(data2_.get()); - factory_.AddSocketDataProvider(data3_.get()); - - IPEndPoint dns_server; - bool rv0 = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server); - DCHECK(rv0); - - resolver_.reset( - new AsyncHostResolver( - dns_server, kMaxTransactions, kMaxPendingRequests, rand_int_cb_, - &factory_, NULL)); - } - - protected: - AddressList addrlist0_, addrlist1_, addrlist2_, addrlist3_; - HostResolver::RequestInfo info0_, info1_, info2_, info3_; - std::vector<MockWrite> writes0_, writes1_, writes2_, writes3_; - std::vector<MockRead> reads0_, reads1_, reads2_, reads3_; - scoped_ptr<StaticSocketDataProvider> data0_, data1_, data2_, data3_; - std::vector<const char*> ip_addresses0_, ip_addresses1_, - ip_addresses2_, ip_addresses3_; - MockClientSocketFactory factory_; - TestPrng test_prng_; - RandIntCallback rand_int_cb_; - scoped_ptr<HostResolver> resolver_; - TestCompletionCallback callback0_, callback1_, callback2_, callback3_; -}; - -TEST_F(AsyncHostResolverTest, EmptyHostLookup) { - info0_.set_host_port_pair(HostPortPair("", kPortNum)); - int rv = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); -} - -TEST_F(AsyncHostResolverTest, IPv4LiteralLookup) { - const char* kIPLiteral = "192.168.1.2"; - info0_.set_host_port_pair(HostPortPair(kIPLiteral, kPortNum)); - info0_.set_host_resolver_flags(HOST_RESOLVER_CANONNAME); - int rv = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - EXPECT_EQ(OK, rv); - std::vector<const char*> ip_addresses(1, kIPLiteral); - VerifyAddressList(ip_addresses, kPortNum, addrlist0_); - EXPECT_STREQ(kIPLiteral, addrlist0_.head()->ai_canonname); -} - -TEST_F(AsyncHostResolverTest, IPv6LiteralLookup) { - info0_.set_host_port_pair(HostPortPair("2001:db8:0::42", kPortNum)); - int rv = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - // When support for IPv6 is added, this should succeed. - EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); -} - -TEST_F(AsyncHostResolverTest, CachedOnlyLookup) { - info0_.set_only_use_cached_response(true); - int rv = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - // When caching is added, this should succeed. - EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); -} - -TEST_F(AsyncHostResolverTest, InvalidHostNameLookup) { - const std::string kHostName1(64, 'a'); - info0_.set_host_port_pair(HostPortPair(kHostName1, kPortNum)); - int rv = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); - - const std::string kHostName2(4097, 'b'); - info0_.set_host_port_pair(HostPortPair(kHostName2, kPortNum)); - rv = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); -} - -TEST_F(AsyncHostResolverTest, Lookup) { - int rv = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv); - rv = callback0_.WaitForResult(); - EXPECT_EQ(OK, rv); - VerifyAddressList(ip_addresses0_, kPortNum, addrlist0_); -} - -TEST_F(AsyncHostResolverTest, ConcurrentLookup) { - int rv0 = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - int rv1 = resolver_->Resolve(info1_, &addrlist1_, &callback1_, NULL, - BoundNetLog()); - int rv2 = resolver_->Resolve(info2_, &addrlist2_, &callback2_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv0); - EXPECT_EQ(ERR_IO_PENDING, rv1); - EXPECT_EQ(ERR_IO_PENDING, rv2); - - rv0 = callback0_.WaitForResult(); - EXPECT_EQ(OK, rv0); - VerifyAddressList(ip_addresses0_, kPortNum, addrlist0_); - - rv1 = callback1_.WaitForResult(); - EXPECT_EQ(OK, rv1); - VerifyAddressList(ip_addresses1_, kPortNum, addrlist1_); - - rv2 = callback2_.WaitForResult(); - EXPECT_EQ(OK, rv2); - VerifyAddressList(ip_addresses2_, kPortNum, addrlist2_); - - EXPECT_EQ(3u, factory_.udp_client_sockets().size()); -} - -TEST_F(AsyncHostResolverTest, SameHostLookupsConsumeSingleTransaction) { - // We pass the info0_ to all requests. - int rv0 = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - int rv1 = resolver_->Resolve(info0_, &addrlist1_, &callback1_, NULL, - BoundNetLog()); - int rv2 = resolver_->Resolve(info0_, &addrlist2_, &callback2_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv0); - EXPECT_EQ(ERR_IO_PENDING, rv1); - EXPECT_EQ(ERR_IO_PENDING, rv2); - - rv0 = callback0_.WaitForResult(); - EXPECT_EQ(OK, rv0); - VerifyAddressList(ip_addresses0_, kPortNum, addrlist0_); - - rv1 = callback1_.WaitForResult(); - EXPECT_EQ(OK, rv1); - VerifyAddressList(ip_addresses0_, kPortNum, addrlist1_); - - rv2 = callback2_.WaitForResult(); - EXPECT_EQ(OK, rv2); - VerifyAddressList(ip_addresses0_, kPortNum, addrlist2_); - - // Although we have three lookups, a single UDP socket was used. - EXPECT_EQ(1u, factory_.udp_client_sockets().size()); -} - -TEST_F(AsyncHostResolverTest, CancelLookup) { - HostResolver::RequestHandle req0 = NULL, req2 = NULL; - int rv0 = resolver_->Resolve(info0_, &addrlist0_, &callback0_, &req0, - BoundNetLog()); - int rv1 = resolver_->Resolve(info1_, &addrlist1_, &callback1_, NULL, - BoundNetLog()); - int rv2 = resolver_->Resolve(info2_, &addrlist2_, &callback2_, &req2, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv0); - EXPECT_EQ(ERR_IO_PENDING, rv1); - EXPECT_EQ(ERR_IO_PENDING, rv2); - - resolver_->CancelRequest(req0); - resolver_->CancelRequest(req2); - - MessageLoop::current()->RunAllPending(); - - EXPECT_FALSE(callback0_.have_result()); - EXPECT_FALSE(callback2_.have_result()); - - rv1 = callback1_.WaitForResult(); - EXPECT_EQ(OK, rv1); - VerifyAddressList(ip_addresses1_, kPortNum, addrlist1_); -} - -// Tests the following scenario: start two resolutions for the same host, -// cancel one of them, make sure that the other one completes. -TEST_F(AsyncHostResolverTest, CancelSameHostLookup) { - HostResolver::RequestHandle req0 = NULL; - - // Pass the info0_ to both requests. - int rv0 = resolver_->Resolve(info0_, &addrlist0_, &callback0_, &req0, - BoundNetLog()); - int rv1 = resolver_->Resolve(info0_, &addrlist1_, &callback1_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv0); - EXPECT_EQ(ERR_IO_PENDING, rv1); - - resolver_->CancelRequest(req0); - MessageLoop::current()->RunAllPending(); - EXPECT_FALSE(callback0_.have_result()); - - rv1 = callback1_.WaitForResult(); - EXPECT_EQ(OK, rv1); - VerifyAddressList(ip_addresses0_, kPortNum, addrlist1_); - - EXPECT_EQ(1u, factory_.udp_client_sockets().size()); -} - -// Test that a queued lookup completes. -TEST_F(AsyncHostResolverTest, QueuedLookup) { - // kMaxTransactions is 2, thus the following requests consume all - // available transactions. - int rv0 = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - int rv1 = resolver_->Resolve(info1_, &addrlist1_, &callback1_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv0); - EXPECT_EQ(ERR_IO_PENDING, rv1); - - // The following request will end up in queue. - int rv2 = resolver_->Resolve(info2_, &addrlist2_, &callback2_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv2); - EXPECT_EQ(1u, - static_cast<AsyncHostResolver*>(resolver_.get())->GetNumPending()); - - // Make sure all requests complete. - rv0 = callback0_.WaitForResult(); - EXPECT_EQ(OK, rv0); - VerifyAddressList(ip_addresses0_, kPortNum, addrlist0_); - - rv1 = callback1_.WaitForResult(); - EXPECT_EQ(OK, rv1); - VerifyAddressList(ip_addresses1_, kPortNum, addrlist1_); - - rv2 = callback2_.WaitForResult(); - EXPECT_EQ(OK, rv2); - VerifyAddressList(ip_addresses2_, kPortNum, addrlist2_); -} - -// Test that cancelling a queued lookup works. -TEST_F(AsyncHostResolverTest, CancelPendingLookup) { - // kMaxTransactions is 2, thus the following requests consume all - // available transactions. - int rv0 = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - int rv1 = resolver_->Resolve(info1_, &addrlist1_, &callback1_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv0); - EXPECT_EQ(ERR_IO_PENDING, rv1); - - // The following request will end up in queue. - HostResolver::RequestHandle req2 = NULL; - int rv2 = resolver_->Resolve(info2_, &addrlist2_, &callback2_, &req2, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv2); - EXPECT_EQ(1u, - static_cast<AsyncHostResolver*>(resolver_.get())->GetNumPending()); - - resolver_->CancelRequest(req2); - - // Make sure first two requests complete while the cancelled one doesn't. - MessageLoop::current()->RunAllPending(); - EXPECT_FALSE(callback2_.have_result()); - - rv0 = callback0_.WaitForResult(); - EXPECT_EQ(OK, rv0); - VerifyAddressList(ip_addresses0_, kPortNum, addrlist0_); - - rv1 = callback1_.WaitForResult(); - EXPECT_EQ(OK, rv1); - VerifyAddressList(ip_addresses1_, kPortNum, addrlist1_); -} - -TEST_F(AsyncHostResolverTest, ResolverDestructionCancelsLookups) { - int rv0 = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - int rv1 = resolver_->Resolve(info1_, &addrlist1_, &callback1_, NULL, - BoundNetLog()); - // This one is queued. - int rv2 = resolver_->Resolve(info2_, &addrlist2_, &callback2_, NULL, - BoundNetLog()); - EXPECT_EQ(1u, - static_cast<AsyncHostResolver*>(resolver_.get())->GetNumPending()); - - EXPECT_EQ(ERR_IO_PENDING, rv0); - EXPECT_EQ(ERR_IO_PENDING, rv1); - EXPECT_EQ(ERR_IO_PENDING, rv2); - - resolver_.reset(); - - MessageLoop::current()->RunAllPending(); - - EXPECT_FALSE(callback0_.have_result()); - EXPECT_FALSE(callback1_.have_result()); - EXPECT_FALSE(callback2_.have_result()); -} - -// Test that when the number of pending lookups is at max, a new lookup -// with a priority lower than all of those in the queue fails. -TEST_F(AsyncHostResolverTest, OverflowQueueWithLowPriorityLookup) { - int rv0 = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - int rv1 = resolver_->Resolve(info1_, &addrlist1_, &callback1_, NULL, - BoundNetLog()); - // This one is queued and fills up the queue since its size is 1. - int rv2 = resolver_->Resolve(info2_, &addrlist2_, &callback2_, NULL, - BoundNetLog()); - EXPECT_EQ(1u, - static_cast<AsyncHostResolver*>(resolver_.get())->GetNumPending()); - - EXPECT_EQ(ERR_IO_PENDING, rv0); - EXPECT_EQ(ERR_IO_PENDING, rv1); - EXPECT_EQ(ERR_IO_PENDING, rv2); - - // This one fails. - info3_.set_priority(LOWEST); - int rv3 = resolver_->Resolve(info3_, &addrlist3_, &callback3_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, rv3); - - MessageLoop::current()->RunAllPending(); - EXPECT_FALSE(callback3_.have_result()); -} - -// Test that when the number of pending lookups is at max, a new lookup -// with a priority higher than any of those in the queue succeeds and -// causes the lowest priority lookup in the queue to fail. -TEST_F(AsyncHostResolverTest, OverflowQueueWithHighPriorityLookup) { - int rv0 = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - int rv1 = resolver_->Resolve(info1_, &addrlist1_, &callback1_, NULL, - BoundNetLog()); - - // Next lookup is queued. Since this will be ejected from the queue and - // will not consume a socket from our factory, we are not passing it - // predefined members. - HostResolver::RequestInfo info(HostPortPair("cnn.com", 80)); - info.set_address_family(ADDRESS_FAMILY_IPV4); - AddressList addrlist_fail; - TestCompletionCallback callback_fail; - int rv_fail = resolver_->Resolve(info, &addrlist_fail, &callback_fail, NULL, - BoundNetLog()); - EXPECT_EQ(1u, - static_cast<AsyncHostResolver*>(resolver_.get())->GetNumPending()); - - EXPECT_EQ(ERR_IO_PENDING, rv0); - EXPECT_EQ(ERR_IO_PENDING, rv1); - EXPECT_EQ(ERR_IO_PENDING, rv_fail); - - // Lookup 2 causes the above to fail, but itself should succeed. - info2_.set_priority(HIGHEST); - int rv2 = resolver_->Resolve(info2_, &addrlist2_, &callback2_, NULL, - BoundNetLog()); - - rv0 = callback0_.WaitForResult(); - EXPECT_EQ(OK, rv0); - VerifyAddressList(ip_addresses0_, kPortNum, addrlist0_); - - rv1 = callback1_.WaitForResult(); - EXPECT_EQ(OK, rv1); - VerifyAddressList(ip_addresses1_, kPortNum, addrlist1_); - - rv_fail = callback_fail.WaitForResult(); - EXPECT_EQ(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, rv_fail); - EXPECT_EQ(static_cast<addrinfo*>(NULL), addrlist_fail.head()); - - rv2 = callback2_.WaitForResult(); - EXPECT_EQ(OK, rv2); - VerifyAddressList(ip_addresses2_, kPortNum, addrlist2_); -} - -// Test that registering, unregistering, and notifying of observers of -// resolution start, completion and cancellation (both due to CancelRequest -// and resolver destruction) work. -TEST_F(AsyncHostResolverTest, Observers) { - TestHostResolverObserver observer; - resolver_->AddObserver(&observer); - - int rv0 = resolver_->Resolve(info0_, &addrlist0_, &callback0_, NULL, - BoundNetLog()); - int rv1 = resolver_->Resolve(info1_, &addrlist1_, &callback1_, NULL, - BoundNetLog()); - // We will cancel this one. - HostResolver::RequestHandle req2 = NULL; - int rv2 = resolver_->Resolve(info2_, &addrlist2_, &callback2_, &req2, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv0); - EXPECT_EQ(ERR_IO_PENDING, rv1); - EXPECT_EQ(ERR_IO_PENDING, rv2); - - // Cancel lookup 2. - resolver_->CancelRequest(req2); - - // Lookup 0 and 1 should succeed. - rv0 = callback0_.WaitForResult(); - EXPECT_EQ(OK, rv0); - VerifyAddressList(ip_addresses0_, kPortNum, addrlist0_); - - rv1 = callback1_.WaitForResult(); - EXPECT_EQ(OK, rv1); - VerifyAddressList(ip_addresses1_, kPortNum, addrlist1_); - - // Next lookup should not have finished. - MessageLoop::current()->RunAllPending(); - EXPECT_FALSE(callback2_.have_result()); - - // Verify observer calls. - EXPECT_EQ(3u, observer.start_log.size()); - EXPECT_EQ(2u, observer.finish_log.size()); - EXPECT_EQ(1u, observer.cancel_log.size()); - - // Lookup 0 started and finished. - EXPECT_TRUE(observer.start_log[0] == - TestHostResolverObserver::StartOrCancelEntry(0, info0_)); - EXPECT_TRUE(observer.finish_log[0] == - TestHostResolverObserver::FinishEntry(0, true, info0_)); - - // Ditto for lookup 1. - EXPECT_TRUE(observer.start_log[1] == - TestHostResolverObserver::StartOrCancelEntry(1, info1_)); - EXPECT_TRUE(observer.finish_log[1] == - TestHostResolverObserver::FinishEntry(1, true, info1_)); - - // Lookup 2 was cancelled, hence, failed to finish. - EXPECT_TRUE(observer.start_log[2] == - TestHostResolverObserver::StartOrCancelEntry(2, info2_)); - EXPECT_TRUE(observer.cancel_log[0] == - TestHostResolverObserver::StartOrCancelEntry(2, info2_)); - - // Unregister observer. - resolver_->RemoveObserver(&observer); - - // We will do lookup 2 again but will not be cancel it this time. - rv2 = resolver_->Resolve(info2_, &addrlist2_, &callback2_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv2); - - // Run lookup 2 to completion. - rv2 = callback2_.WaitForResult(); - EXPECT_EQ(OK, rv2); - VerifyAddressList(ip_addresses2_, kPortNum, addrlist2_); - - // Observer log should stay the same. - EXPECT_EQ(3u, observer.start_log.size()); - EXPECT_EQ(2u, observer.finish_log.size()); - EXPECT_EQ(1u, observer.cancel_log.size()); - - // Re-register observer. - resolver_->AddObserver(&observer); - - // Start lookup 3. - int rv3 = resolver_->Resolve(info3_, &addrlist3_, &callback3_, NULL, - BoundNetLog()); - EXPECT_EQ(ERR_IO_PENDING, rv3); - - // Destroy the resolver and make sure that observer was notified of just - // the resolution start. - resolver_.reset(); - - EXPECT_EQ(4u, observer.start_log.size()); // Was incremented by 1. - EXPECT_EQ(2u, observer.finish_log.size()); - EXPECT_EQ(1u, observer.cancel_log.size()); - - EXPECT_TRUE(observer.start_log[3] == - TestHostResolverObserver::StartOrCancelEntry(4, info3_)); -} - -} // namespace net diff --git a/net/base/dns_test_util.cc b/net/base/dns_test_util.cc index d7f6803..f448b6f 100644 --- a/net/base/dns_test_util.cc +++ b/net/base/dns_test_util.cc @@ -22,41 +22,6 @@ int TestPrng::GetNext(int min, int max) { return rv; } -bool operator==(const HostResolver::RequestInfo& a, - const HostResolver::RequestInfo& b) { - return a.hostname() == b.hostname() && - a.port() == b.port() && - a.allow_cached_response() == b.allow_cached_response() && - a.priority() == b.priority() && - a.is_speculative() == b.is_speculative() && - a.referrer() == b.referrer(); -} - -TestHostResolverObserver::TestHostResolverObserver() { -} - -TestHostResolverObserver::~TestHostResolverObserver() { -} - -void TestHostResolverObserver::OnStartResolution( - int id, - const HostResolver::RequestInfo& info) { - start_log.push_back(StartOrCancelEntry(id, info)); -} - -void TestHostResolverObserver::OnFinishResolutionWithStatus( - int id, - bool was_resolved, - const HostResolver::RequestInfo& info) { - finish_log.push_back(FinishEntry(id, was_resolved, info)); -} - -void TestHostResolverObserver::OnCancelResolution( - int id, - const HostResolver::RequestInfo& info) { - cancel_log.push_back(StartOrCancelEntry(id, info)); -} - bool ConvertStringsToIPAddressList( const char* const ip_strings[], size_t size, IPAddressList* address_list) { DCHECK(address_list); diff --git a/net/base/dns_test_util.h b/net/base/dns_test_util.h index 04d8652..96ce38a 100644 --- a/net/base/dns_test_util.h +++ b/net/base/dns_test_util.h @@ -12,7 +12,6 @@ #include "base/logging.h" #include "net/base/dns_transaction.h" #include "net/base/dns_util.h" -#include "net/base/host_resolver.h" #include "net/base/ip_endpoint.h" #include "net/base/net_util.h" @@ -35,62 +34,6 @@ class TestPrng { DISALLOW_COPY_AND_ASSIGN(TestPrng); }; -bool operator==(const HostResolver::RequestInfo& a, - const HostResolver::RequestInfo& b); - -// Observer that just makes note of how it was called. The test code can then -// inspect to make sure it was called with the right parameters. Used by -// HostResolverImpl and AsyncHostResolver unit tests. -class TestHostResolverObserver : public HostResolver::Observer { - public: - TestHostResolverObserver(); - virtual ~TestHostResolverObserver(); - - // HostResolver::Observer methods: - virtual void OnStartResolution(int id, const HostResolver::RequestInfo& info); - virtual void OnFinishResolutionWithStatus( - int id, - bool was_resolved, - const HostResolver::RequestInfo& info); - virtual void OnCancelResolution( - int id, - const HostResolver::RequestInfo& info); - - // Tuple (id, info). - struct StartOrCancelEntry { - StartOrCancelEntry(int id, const HostResolver::RequestInfo& info) - : id(id), info(info) {} - - bool operator==(const StartOrCancelEntry& other) const { - return id == other.id && info == other.info; - } - - int id; - HostResolver::RequestInfo info; - }; - - // Tuple (id, was_resolved, info). - struct FinishEntry { - FinishEntry(int id, bool was_resolved, - const HostResolver::RequestInfo& info) - : id(id), was_resolved(was_resolved), info(info) {} - - bool operator==(const FinishEntry& other) const { - return id == other.id && - was_resolved == other.was_resolved && - info == other.info; - } - - int id; - bool was_resolved; - HostResolver::RequestInfo info; - }; - - std::vector<StartOrCancelEntry> start_log; - std::vector<FinishEntry> finish_log; - std::vector<StartOrCancelEntry> cancel_log; -}; - // A utility function for tests that given an array of IP literals, // converts it to an IPAddressList. bool ConvertStringsToIPAddressList( @@ -104,26 +47,29 @@ static const char kDnsIp[] = "192.168.1.1"; static const uint16 kDnsPort = 53; //----------------------------------------------------------------------------- -// Query/response set for www.google.com, ID is fixed to 0. -static const char kT0HostName[] = "www.google.com"; -static const uint16 kT0Qtype = kDNS_A; -static const char kT0DnsName[] = { +// Query/response set for www.google.com, ID is fixed to 1. + +static const uint16 kT1Qtype = kDNS_A; + +static const char kT1DnsName[] = { 0x03, 'w', 'w', 'w', 0x06, 'g', 'o', 'o', 'g', 'l', 'e', 0x03, 'c', 'o', 'm', 0x00 }; -static const uint8 kT0QueryDatagram[] = { + +static const uint8 kT1QueryDatagram[] = { // query for www.google.com, type A. - 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01 }; -static const uint8 kT0ResponseDatagram[] = { + +static const uint8 kT1ResponseDatagram[] = { // response contains one CNAME for www.l.google.com and the following // IP addresses: 74.125.226.{179,180,176,177,178} - 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x06, + 0x00, 0x01, 0x81, 0x80, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, @@ -141,34 +87,37 @@ static const uint8 kT0ResponseDatagram[] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb2 }; -static const char* const kT0IpAddresses[] = { + +static const char* const kT1IpAddresses[] = { "74.125.226.179", "74.125.226.180", "74.125.226.176", "74.125.226.177", "74.125.226.178" }; //----------------------------------------------------------------------------- -// Query/response set for codereview.chromium.org, ID is fixed to 1. -static const char kT1HostName[] = "codereview.chromium.org"; -static const uint16 kT1Qtype = kDNS_A; -static const char kT1DnsName[] = { +// Query/response set for codereview.chromium.org, ID is fixed to 2. +static const uint16 kT2Qtype = kDNS_A; + +static const char kT2DnsName[] = { 0x12, 'c', 'o', 'd', 'e', 'r', 'e', 'v', 'i', 'e', 'w', 0x10, 'c', 'h', 'r', 'o', 'm', 'i', 'u', 'm', 0x03, 'o', 'r', 'g', 0x00 }; -static const uint8 kT1QueryDatagram[] = { + +static const uint8 kT2QueryDatagram[] = { // query for codereview.chromium.org, type A. - 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x08, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01 }; -static const uint8 kT1ResponseDatagram[] = { + +static const uint8 kT2ResponseDatagram[] = { // response contains one CNAME for ghs.l.google.com and the following // IP address: 64.233.169.121 - 0x00, 0x01, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x08, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, @@ -180,92 +129,8 @@ static const uint8 kT1ResponseDatagram[] = { 0x35, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x0b, 0x00, 0x04, 0x40, 0xe9, 0xa9, 0x79 }; -static const char* const kT1IpAddresses[] = { - "64.233.169.121" -}; //----------------------------------------------------------------------------- -// Query/response set for www.ccs.neu.edu, ID is fixed to 2. -static const char kT2HostName[] = "www.ccs.neu.edu"; -static const uint16 kT2Qtype = kDNS_A; -static const char kT2DnsName[] = { - 0x03, 'w', 'w', 'w', - 0x03, 'c', 'c', 'c', - 0x03, 'n', 'e', 'u', - 0x03, 'e', 'd', 'u', - 0x00 -}; -static const uint8 kT2QueryDatagram[] = { - // query for www.ccs.neu.edu, type A. - 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, - 0x03, 0x63, 0x63, 0x73, 0x03, 0x6e, 0x65, 0x75, - 0x03, 0x65, 0x64, 0x75, 0x00, 0x00, 0x01, 0x00, - 0x01 -}; -static const uint8 kT2ResponseDatagram[] = { - // response contains one CNAME for vulcan.ccs.neu.edu and the following - // IP address: 129.10.116.81 - 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, - 0x03, 0x63, 0x63, 0x73, 0x03, 0x6e, 0x65, 0x75, - 0x03, 0x65, 0x64, 0x75, 0x00, 0x00, 0x01, 0x00, - 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, - 0x00, 0x01, 0x2c, 0x00, 0x09, 0x06, 0x76, 0x75, - 0x6c, 0x63, 0x61, 0x6e, 0xc0, 0x10, 0xc0, 0x2d, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x2c, - 0x00, 0x04, 0x81, 0x0a, 0x74, 0x51 -}; -static const char* const kT2IpAddresses[] = { - "129.10.116.81" -}; - -//----------------------------------------------------------------------------- -// Query/response set for www.google.az, ID is fixed to 3. -static const char kT3HostName[] = "www.google.az"; -static const uint16 kT3Qtype = kDNS_A; -static const char kT3DnsName[] = { - 0x03, 'w', 'w', 'w', - 0x06, 'g', 'o', 'o', 'g', 'l', 'e', - 0x02, 'a', 'z', - 0x00 -}; -static const uint8 kT3QueryDatagram[] = { - // query for www.google.az, type A. - 0x00, 0x03, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, - 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x02, - 0x61, 0x7a, 0x00, 0x00, 0x01, 0x00, 0x01 -}; -static const uint8 kT3ResponseDatagram[] = { - // response contains www.google.com as CNAME for www.google.az and - // www.l.google.com as CNAME for www.google.com and the following - // IP addresses: 74.125.226.{178,179,180,176,177} - 0x00, 0x03, 0x81, 0x80, 0x00, 0x01, 0x00, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77, - 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x02, - 0x61, 0x7a, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, - 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x50, - 0x99, 0x00, 0x10, 0x03, 0x77, 0x77, 0x77, 0x06, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, - 0x6f, 0x6d, 0x00, 0xc0, 0x2b, 0x00, 0x05, 0x00, - 0x01, 0x00, 0x01, 0x50, 0x99, 0x00, 0x08, 0x03, - 0x77, 0x77, 0x77, 0x01, 0x6c, 0xc0, 0x2f, 0xc0, - 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb2, 0xc0, - 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb3, 0xc0, - 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb4, 0xc0, - 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb0, 0xc0, - 0x47, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x04, 0x4a, 0x7d, 0xe2, 0xb1 -}; -static const char* const kT3IpAddresses[] = { - "74.125.226.178", "74.125.226.179", "74.125.226.180", - "74.125.226.176", "74.125.226.177" -}; } // namespace net diff --git a/net/base/dns_transaction_unittest.cc b/net/base/dns_transaction_unittest.cc index 2e557e9..6c532f2 100644 --- a/net/base/dns_transaction_unittest.cc +++ b/net/base/dns_transaction_unittest.cc @@ -53,48 +53,48 @@ class TestDelegate : public DnsTransaction::Delegate { TEST(DnsTransactionTest, NormalQueryResponseTest) { - MockWrite writes0[] = { - MockWrite(true, reinterpret_cast<const char*>(kT0QueryDatagram), - arraysize(kT0QueryDatagram)) + MockWrite writes1[] = { + MockWrite(true, reinterpret_cast<const char*>(kT1QueryDatagram), + arraysize(kT1QueryDatagram)) }; - MockRead reads0[] = { - MockRead(true, reinterpret_cast<const char*>(kT0ResponseDatagram), - arraysize(kT0ResponseDatagram)) + MockRead reads1[] = { + MockRead(true, reinterpret_cast<const char*>(kT1ResponseDatagram), + arraysize(kT1ResponseDatagram)) }; - StaticSocketDataProvider data(reads0, arraysize(reads0), - writes0, arraysize(writes0)); + StaticSocketDataProvider data(reads1, arraysize(reads1), + writes1, arraysize(writes1)); MockClientSocketFactory factory; factory.AddSocketDataProvider(&data); - TestPrng test_prng(std::deque<int>(1, 0)); + TestPrng test_prng(std::deque<int>(1, 1)); RandIntCallback rand_int_cb = base::Bind(&TestPrng::GetNext, base::Unretained(&test_prng)); - std::string t0_dns_name(kT0DnsName, arraysize(kT0DnsName)); + std::string t1_dns_name(kT1DnsName, arraysize(kT1DnsName)); IPEndPoint dns_server; - bool rv = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server); - ASSERT_TRUE(rv); + bool rv0 = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server); + ASSERT_TRUE(rv0); - DnsTransaction t(dns_server, t0_dns_name, kT1Qtype, rand_int_cb, &factory, + DnsTransaction t(dns_server, t1_dns_name, kT1Qtype, rand_int_cb, &factory, BoundNetLog(), NULL); TestDelegate delegate; t.SetDelegate(&delegate); IPAddressList expected_ip_addresses; - rv = ConvertStringsToIPAddressList(kT0IpAddresses, - arraysize(kT0IpAddresses), - &expected_ip_addresses); - ASSERT_TRUE(rv); + rv0 = ConvertStringsToIPAddressList(kT1IpAddresses, + arraysize(kT1IpAddresses), + &expected_ip_addresses); + ASSERT_TRUE(rv0); - int rv0 = t.Start(); - EXPECT_EQ(ERR_IO_PENDING, rv0); + int rv = t.Start(); + EXPECT_EQ(ERR_IO_PENDING, rv); MessageLoop::current()->Run(); - EXPECT_TRUE(DnsTransaction::Key(t0_dns_name, kT0Qtype) == t.key()); + EXPECT_TRUE(DnsTransaction::Key(t1_dns_name, kT1Qtype) == t.key()); EXPECT_EQ(OK, delegate.result()); EXPECT_EQ(&t, delegate.transaction()); EXPECT_TRUE(expected_ip_addresses == delegate.ip_addresses()); @@ -104,42 +104,42 @@ TEST(DnsTransactionTest, NormalQueryResponseTest) { } TEST(DnsTransactionTest, MismatchedQueryResponseTest) { - MockWrite writes0[] = { - MockWrite(true, reinterpret_cast<const char*>(kT0QueryDatagram), - arraysize(kT0QueryDatagram)) + MockWrite writes1[] = { + MockWrite(true, reinterpret_cast<const char*>(kT1QueryDatagram), + arraysize(kT1QueryDatagram)) }; - MockRead reads1[] = { - MockRead(true, reinterpret_cast<const char*>(kT1ResponseDatagram), - arraysize(kT1ResponseDatagram)) + MockRead reads2[] = { + MockRead(true, reinterpret_cast<const char*>(kT2ResponseDatagram), + arraysize(kT2ResponseDatagram)) }; - StaticSocketDataProvider data(reads1, arraysize(reads1), - writes0, arraysize(writes0)); + StaticSocketDataProvider data(reads2, arraysize(reads2), + writes1, arraysize(writes1)); MockClientSocketFactory factory; factory.AddSocketDataProvider(&data); - TestPrng test_prng(std::deque<int>(1, 0)); + TestPrng test_prng(std::deque<int>(1, 1)); RandIntCallback rand_int_cb = base::Bind(&TestPrng::GetNext, base::Unretained(&test_prng)); - std::string t0_dns_name(kT0DnsName, arraysize(kT0DnsName)); + std::string t1_dns_name(kT1DnsName, arraysize(kT1DnsName)); IPEndPoint dns_server; - bool rv = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server); - ASSERT_TRUE(rv); + bool rv0 = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server); + ASSERT_TRUE(rv0); - DnsTransaction t(dns_server, t0_dns_name, kT1Qtype, rand_int_cb, &factory, + DnsTransaction t(dns_server, t1_dns_name, kT1Qtype, rand_int_cb, &factory, BoundNetLog(), NULL); TestDelegate delegate; t.SetDelegate(&delegate); - int rv0 = t.Start(); - EXPECT_EQ(ERR_IO_PENDING, rv0); + int rv = t.Start(); + EXPECT_EQ(ERR_IO_PENDING, rv); MessageLoop::current()->Run(); - EXPECT_TRUE(DnsTransaction::Key(t0_dns_name, kT0Qtype) == t.key()); + EXPECT_TRUE(DnsTransaction::Key(t1_dns_name, kT1Qtype) == t.key()); EXPECT_EQ(ERR_DNS_MALFORMED_RESPONSE, delegate.result()); EXPECT_EQ(0u, delegate.ip_addresses().size()); EXPECT_EQ(&t, delegate.transaction()); @@ -150,35 +150,35 @@ TEST(DnsTransactionTest, MismatchedQueryResponseTest) { // Test that after the first timeout we do a fresh connection and if we get // a response on the new connection, we return it. TEST(DnsTransactionTest, FirstTimeoutTest) { - MockWrite writes0[] = { - MockWrite(true, reinterpret_cast<const char*>(kT0QueryDatagram), - arraysize(kT0QueryDatagram)) + MockWrite writes1[] = { + MockWrite(true, reinterpret_cast<const char*>(kT1QueryDatagram), + arraysize(kT1QueryDatagram)) }; - MockRead reads0[] = { - MockRead(true, reinterpret_cast<const char*>(kT0ResponseDatagram), - arraysize(kT0ResponseDatagram)) + MockRead reads1[] = { + MockRead(true, reinterpret_cast<const char*>(kT1ResponseDatagram), + arraysize(kT1ResponseDatagram)) }; - scoped_refptr<DelayedSocketData> socket0_data( - new DelayedSocketData(2, NULL, 0, writes0, arraysize(writes0))); scoped_refptr<DelayedSocketData> socket1_data( - new DelayedSocketData(0, reads0, arraysize(reads0), - writes0, arraysize(writes0))); + new DelayedSocketData(2, NULL, 0, writes1, arraysize(writes1))); + scoped_refptr<DelayedSocketData> socket2_data( + new DelayedSocketData(0, reads1, arraysize(reads1), + writes1, arraysize(writes1))); MockClientSocketFactory factory; - factory.AddSocketDataProvider(socket0_data.get()); factory.AddSocketDataProvider(socket1_data.get()); + factory.AddSocketDataProvider(socket2_data.get()); - TestPrng test_prng(std::deque<int>(2, 0)); + TestPrng test_prng(std::deque<int>(2, 1)); RandIntCallback rand_int_cb = base::Bind(&TestPrng::GetNext, base::Unretained(&test_prng)); - std::string t0_dns_name(kT0DnsName, arraysize(kT0DnsName)); + std::string t1_dns_name(kT1DnsName, arraysize(kT1DnsName)); IPEndPoint dns_server; - bool rv = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server); - ASSERT_TRUE(rv); + bool rv0 = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server); + ASSERT_TRUE(rv0); - DnsTransaction t(dns_server, t0_dns_name, kT1Qtype, rand_int_cb, &factory, + DnsTransaction t(dns_server, t1_dns_name, kT1Qtype, rand_int_cb, &factory, BoundNetLog(), NULL); TestDelegate delegate; @@ -189,26 +189,25 @@ TEST(DnsTransactionTest, FirstTimeoutTest) { kTimeoutsMs + arraysize(kTimeoutsMs))); IPAddressList expected_ip_addresses; - rv = ConvertStringsToIPAddressList(kT0IpAddresses, - arraysize(kT0IpAddresses), - &expected_ip_addresses); - ASSERT_TRUE(rv); - - int rv0 = t.Start(); - EXPECT_EQ(ERR_IO_PENDING, rv0); + rv0 = ConvertStringsToIPAddressList(kT1IpAddresses, + arraysize(kT1IpAddresses), + &expected_ip_addresses); + ASSERT_TRUE(rv0); + int rv = t.Start(); + EXPECT_EQ(ERR_IO_PENDING, rv); MessageLoop::current()->Run(); - EXPECT_TRUE(DnsTransaction::Key(t0_dns_name, kT0Qtype) == t.key()); + EXPECT_TRUE(DnsTransaction::Key(t1_dns_name, kT1Qtype) == t.key()); EXPECT_EQ(OK, delegate.result()); EXPECT_EQ(&t, delegate.transaction()); EXPECT_TRUE(expected_ip_addresses == delegate.ip_addresses()); - EXPECT_TRUE(socket0_data->at_read_eof()); - EXPECT_TRUE(socket0_data->at_write_eof()); EXPECT_TRUE(socket1_data->at_read_eof()); EXPECT_TRUE(socket1_data->at_write_eof()); + EXPECT_TRUE(socket2_data->at_read_eof()); + EXPECT_TRUE(socket2_data->at_write_eof()); EXPECT_EQ(2u, factory.udp_client_sockets().size()); } @@ -216,38 +215,38 @@ TEST(DnsTransactionTest, FirstTimeoutTest) { // the second timeout we do another fresh connection, and if we get a // response on the second connection, we return it. TEST(DnsTransactionTest, SecondTimeoutTest) { - MockWrite writes0[] = { - MockWrite(true, reinterpret_cast<const char*>(kT0QueryDatagram), - arraysize(kT0QueryDatagram)) + MockWrite writes1[] = { + MockWrite(true, reinterpret_cast<const char*>(kT1QueryDatagram), + arraysize(kT1QueryDatagram)) }; - MockRead reads0[] = { - MockRead(true, reinterpret_cast<const char*>(kT0ResponseDatagram), - arraysize(kT0ResponseDatagram)) + MockRead reads1[] = { + MockRead(true, reinterpret_cast<const char*>(kT1ResponseDatagram), + arraysize(kT1ResponseDatagram)) }; - scoped_refptr<DelayedSocketData> socket0_data( - new DelayedSocketData(2, NULL, 0, writes0, arraysize(writes0))); scoped_refptr<DelayedSocketData> socket1_data( - new DelayedSocketData(2, NULL, 0, writes0, arraysize(writes0))); + new DelayedSocketData(2, NULL, 0, writes1, arraysize(writes1))); scoped_refptr<DelayedSocketData> socket2_data( - new DelayedSocketData(0, reads0, arraysize(reads0), - writes0, arraysize(writes0))); + new DelayedSocketData(2, NULL, 0, writes1, arraysize(writes1))); + scoped_refptr<DelayedSocketData> socket3_data( + new DelayedSocketData(0, reads1, arraysize(reads1), + writes1, arraysize(writes1))); MockClientSocketFactory factory; - factory.AddSocketDataProvider(socket0_data.get()); factory.AddSocketDataProvider(socket1_data.get()); factory.AddSocketDataProvider(socket2_data.get()); + factory.AddSocketDataProvider(socket3_data.get()); - TestPrng test_prng(std::deque<int>(3, 0)); + TestPrng test_prng(std::deque<int>(3, 1)); RandIntCallback rand_int_cb = base::Bind(&TestPrng::GetNext, base::Unretained(&test_prng)); - std::string t0_dns_name(kT0DnsName, arraysize(kT0DnsName)); + std::string t1_dns_name(kT1DnsName, arraysize(kT1DnsName)); IPEndPoint dns_server; - bool rv = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server); - ASSERT_TRUE(rv); + bool rv0 = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server); + ASSERT_TRUE(rv0); - DnsTransaction t(dns_server, t0_dns_name, kT1Qtype, rand_int_cb, &factory, + DnsTransaction t(dns_server, t1_dns_name, kT1Qtype, rand_int_cb, &factory, BoundNetLog(), NULL); TestDelegate delegate; @@ -258,27 +257,27 @@ TEST(DnsTransactionTest, SecondTimeoutTest) { kTimeoutsMs + arraysize(kTimeoutsMs))); IPAddressList expected_ip_addresses; - rv = ConvertStringsToIPAddressList(kT0IpAddresses, - arraysize(kT0IpAddresses), - &expected_ip_addresses); - ASSERT_TRUE(rv); + rv0 = ConvertStringsToIPAddressList(kT1IpAddresses, + arraysize(kT1IpAddresses), + &expected_ip_addresses); + ASSERT_TRUE(rv0); - int rv0 = t.Start(); - EXPECT_EQ(ERR_IO_PENDING, rv0); + int rv = t.Start(); + EXPECT_EQ(ERR_IO_PENDING, rv); MessageLoop::current()->Run(); - EXPECT_TRUE(DnsTransaction::Key(t0_dns_name, kT1Qtype) == t.key()); + EXPECT_TRUE(DnsTransaction::Key(t1_dns_name, kT1Qtype) == t.key()); EXPECT_EQ(OK, delegate.result()); EXPECT_EQ(&t, delegate.transaction()); EXPECT_TRUE(expected_ip_addresses == delegate.ip_addresses()); - EXPECT_TRUE(socket0_data->at_read_eof()); - EXPECT_TRUE(socket0_data->at_write_eof()); EXPECT_TRUE(socket1_data->at_read_eof()); EXPECT_TRUE(socket1_data->at_write_eof()); EXPECT_TRUE(socket2_data->at_read_eof()); EXPECT_TRUE(socket2_data->at_write_eof()); + EXPECT_TRUE(socket3_data->at_read_eof()); + EXPECT_TRUE(socket3_data->at_write_eof()); EXPECT_EQ(3u, factory.udp_client_sockets().size()); } @@ -286,32 +285,32 @@ TEST(DnsTransactionTest, SecondTimeoutTest) { // the second timeout we do another fresh connection and after the third // timeout we give up and return a timeout error. TEST(DnsTransactionTest, ThirdTimeoutTest) { - MockWrite writes0[] = { - MockWrite(true, reinterpret_cast<const char*>(kT0QueryDatagram), - arraysize(kT0QueryDatagram)) + MockWrite writes1[] = { + MockWrite(true, reinterpret_cast<const char*>(kT1QueryDatagram), + arraysize(kT1QueryDatagram)) }; - scoped_refptr<DelayedSocketData> socket0_data( - new DelayedSocketData(2, NULL, 0, writes0, arraysize(writes0))); scoped_refptr<DelayedSocketData> socket1_data( - new DelayedSocketData(2, NULL, 0, writes0, arraysize(writes0))); + new DelayedSocketData(2, NULL, 0, writes1, arraysize(writes1))); scoped_refptr<DelayedSocketData> socket2_data( - new DelayedSocketData(2, NULL, 0, writes0, arraysize(writes0))); + new DelayedSocketData(2, NULL, 0, writes1, arraysize(writes1))); + scoped_refptr<DelayedSocketData> socket3_data( + new DelayedSocketData(2, NULL, 0, writes1, arraysize(writes1))); MockClientSocketFactory factory; - factory.AddSocketDataProvider(socket0_data.get()); factory.AddSocketDataProvider(socket1_data.get()); factory.AddSocketDataProvider(socket2_data.get()); + factory.AddSocketDataProvider(socket3_data.get()); - TestPrng test_prng(std::deque<int>(3, 0)); + TestPrng test_prng(std::deque<int>(3, 1)); RandIntCallback rand_int_cb = base::Bind(&TestPrng::GetNext, base::Unretained(&test_prng)); - std::string t0_dns_name(kT0DnsName, arraysize(kT0DnsName)); + std::string t1_dns_name(kT1DnsName, arraysize(kT1DnsName)); IPEndPoint dns_server; - bool rv = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server); - ASSERT_TRUE(rv); + bool rv0 = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server); + ASSERT_TRUE(rv0); - DnsTransaction t(dns_server, t0_dns_name, kT1Qtype, rand_int_cb, &factory, + DnsTransaction t(dns_server, t1_dns_name, kT1Qtype, rand_int_cb, &factory, BoundNetLog(), NULL); TestDelegate delegate; @@ -321,21 +320,21 @@ TEST(DnsTransactionTest, ThirdTimeoutTest) { std::vector<base::TimeDelta>(kTimeoutsMs, kTimeoutsMs + arraysize(kTimeoutsMs))); - int rv0 = t.Start(); - EXPECT_EQ(ERR_IO_PENDING, rv0); + int rv = t.Start(); + EXPECT_EQ(ERR_IO_PENDING, rv); MessageLoop::current()->Run(); - EXPECT_TRUE(DnsTransaction::Key(t0_dns_name, kT0Qtype) == t.key()); + EXPECT_TRUE(DnsTransaction::Key(t1_dns_name, kT1Qtype) == t.key()); EXPECT_EQ(ERR_DNS_TIMED_OUT, delegate.result()); EXPECT_EQ(&t, delegate.transaction()); - EXPECT_TRUE(socket0_data->at_read_eof()); - EXPECT_TRUE(socket0_data->at_write_eof()); EXPECT_TRUE(socket1_data->at_read_eof()); EXPECT_TRUE(socket1_data->at_write_eof()); EXPECT_TRUE(socket2_data->at_read_eof()); EXPECT_TRUE(socket2_data->at_write_eof()); + EXPECT_TRUE(socket3_data->at_read_eof()); + EXPECT_TRUE(socket3_data->at_write_eof()); EXPECT_EQ(3u, factory.udp_client_sockets().size()); } diff --git a/net/base/host_resolver.h b/net/base/host_resolver.h index 77977c1..d46fcc3 100644 --- a/net/base/host_resolver.h +++ b/net/base/host_resolver.h @@ -14,7 +14,6 @@ #include "net/base/completion_callback.h" #include "net/base/host_port_pair.h" #include "net/base/net_api.h" -#include "net/base/net_util.h" #include "net/base/request_priority.h" namespace net { @@ -210,11 +209,6 @@ NET_API HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves, size_t max_retry_attempts, NetLog* net_log); -// Creates a HostResolver implementation that sends actual DNS queries to -// the specified DNS server and parses response and returns results. -NET_API HostResolver* CreateAsyncHostResolver(size_t max_concurrent_resolves, - const IPAddressNumber& dns_ip, - NetLog* net_log); } // namespace net #endif // NET_BASE_HOST_RESOLVER_H_ diff --git a/net/base/host_resolver_impl_unittest.cc b/net/base/host_resolver_impl_unittest.cc index a833599..52b7f89 100644 --- a/net/base/host_resolver_impl_unittest.cc +++ b/net/base/host_resolver_impl_unittest.cc @@ -16,7 +16,6 @@ #include "base/time.h" #include "net/base/address_list.h" #include "net/base/completion_callback.h" -#include "net/base/dns_test_util.h" #include "net/base/mock_host_resolver.h" #include "net/base/net_errors.h" #include "net/base/net_log_unittest.h" @@ -980,6 +979,73 @@ TEST_F(HostResolverImplTest, BypassCache) { MessageLoop::current()->Run(); } +bool operator==(const HostResolver::RequestInfo& a, + const HostResolver::RequestInfo& b) { + return a.hostname() == b.hostname() && + a.port() == b.port() && + a.allow_cached_response() == b.allow_cached_response() && + a.priority() == b.priority() && + a.is_speculative() == b.is_speculative() && + a.referrer() == b.referrer(); +} + +// Observer that just makes note of how it was called. The test code can then +// inspect to make sure it was called with the right parameters. +class CapturingObserver : public HostResolver::Observer { + public: + // DnsResolutionObserver methods: + virtual void OnStartResolution(int id, + const HostResolver::RequestInfo& info) { + start_log.push_back(StartOrCancelEntry(id, info)); + } + + virtual void OnFinishResolutionWithStatus( + int id, + bool was_resolved, + const HostResolver::RequestInfo& info) { + finish_log.push_back(FinishEntry(id, was_resolved, info)); + } + + virtual void OnCancelResolution(int id, + const HostResolver::RequestInfo& info) { + cancel_log.push_back(StartOrCancelEntry(id, info)); + } + + // Tuple (id, info). + struct StartOrCancelEntry { + StartOrCancelEntry(int id, const HostResolver::RequestInfo& info) + : id(id), info(info) {} + + bool operator==(const StartOrCancelEntry& other) const { + return id == other.id && info == other.info; + } + + int id; + HostResolver::RequestInfo info; + }; + + // Tuple (id, was_resolved, info). + struct FinishEntry { + FinishEntry(int id, bool was_resolved, + const HostResolver::RequestInfo& info) + : id(id), was_resolved(was_resolved), info(info) {} + + bool operator==(const FinishEntry& other) const { + return id == other.id && + was_resolved == other.was_resolved && + info == other.info; + } + + int id; + bool was_resolved; + HostResolver::RequestInfo info; + }; + + std::vector<StartOrCancelEntry> start_log; + std::vector<FinishEntry> finish_log; + std::vector<StartOrCancelEntry> cancel_log; +}; + // Test that registering, unregistering, and notifying of observers works. // Does not test the cancellation notification since all resolves are // synchronous. @@ -987,7 +1053,7 @@ TEST_F(HostResolverImplTest, Observers) { scoped_ptr<HostResolver> host_resolver( CreateHostResolverImpl(NULL)); - TestHostResolverObserver observer; + CapturingObserver observer; host_resolver->AddObserver(&observer); @@ -1012,9 +1078,9 @@ TEST_F(HostResolverImplTest, Observers) { EXPECT_EQ(1U, observer.finish_log.size()); EXPECT_EQ(0U, observer.cancel_log.size()); EXPECT_TRUE(observer.start_log[0] == - TestHostResolverObserver::StartOrCancelEntry(0, info1)); + CapturingObserver::StartOrCancelEntry(0, info1)); EXPECT_TRUE(observer.finish_log[0] == - TestHostResolverObserver::FinishEntry(0, true, info1)); + CapturingObserver::FinishEntry(0, true, info1)); // Resolve "host1" again -- this time it will be served from cache, but it // should still notify of completion. @@ -1026,9 +1092,9 @@ TEST_F(HostResolverImplTest, Observers) { EXPECT_EQ(2U, observer.finish_log.size()); EXPECT_EQ(0U, observer.cancel_log.size()); EXPECT_TRUE(observer.start_log[1] == - TestHostResolverObserver::StartOrCancelEntry(1, info1)); + CapturingObserver::StartOrCancelEntry(1, info1)); EXPECT_TRUE(observer.finish_log[1] == - TestHostResolverObserver::FinishEntry(1, true, info1)); + CapturingObserver::FinishEntry(1, true, info1)); // Resolve "host2", setting referrer to "http://foobar.com" HostResolver::RequestInfo info2(HostPortPair("host2", 70)); @@ -1040,9 +1106,9 @@ TEST_F(HostResolverImplTest, Observers) { EXPECT_EQ(3U, observer.finish_log.size()); EXPECT_EQ(0U, observer.cancel_log.size()); EXPECT_TRUE(observer.start_log[2] == - TestHostResolverObserver::StartOrCancelEntry(2, info2)); + CapturingObserver::StartOrCancelEntry(2, info2)); EXPECT_TRUE(observer.finish_log[2] == - TestHostResolverObserver::FinishEntry(2, true, info2)); + CapturingObserver::FinishEntry(2, true, info2)); // Unregister the observer. host_resolver->RemoveObserver(&observer); @@ -1062,7 +1128,7 @@ TEST_F(HostResolverImplTest, Observers) { // (1) Delete the HostResolver while job is outstanding. // (2) Call HostResolver::CancelRequest() while a request is outstanding. TEST_F(HostResolverImplTest, CancellationObserver) { - TestHostResolverObserver observer; + CapturingObserver observer; { // Create a host resolver and attach an observer. scoped_ptr<HostResolver> host_resolver( @@ -1089,7 +1155,7 @@ TEST_F(HostResolverImplTest, CancellationObserver) { EXPECT_EQ(0U, observer.cancel_log.size()); EXPECT_TRUE(observer.start_log[0] == - TestHostResolverObserver::StartOrCancelEntry(0, info1)); + CapturingObserver::StartOrCancelEntry(0, info1)); // Cancel the request. host_resolver->CancelRequest(req); @@ -1099,7 +1165,7 @@ TEST_F(HostResolverImplTest, CancellationObserver) { EXPECT_EQ(1U, observer.cancel_log.size()); EXPECT_TRUE(observer.cancel_log[0] == - TestHostResolverObserver::StartOrCancelEntry(0, info1)); + CapturingObserver::StartOrCancelEntry(0, info1)); // Start an async request for (host2:60) HostResolver::RequestInfo info2(HostPortPair("host2", 60)); @@ -1113,7 +1179,7 @@ TEST_F(HostResolverImplTest, CancellationObserver) { EXPECT_EQ(1U, observer.cancel_log.size()); EXPECT_TRUE(observer.start_log[1] == - TestHostResolverObserver::StartOrCancelEntry(1, info2)); + CapturingObserver::StartOrCancelEntry(1, info2)); // Upon exiting this scope, HostResolver is destroyed, so all requests are // implicitly cancelled. @@ -1128,7 +1194,7 @@ TEST_F(HostResolverImplTest, CancellationObserver) { HostResolver::RequestInfo info(HostPortPair("host2", 60)); EXPECT_TRUE(observer.cancel_log[1] == - TestHostResolverObserver::StartOrCancelEntry(1, info)); + CapturingObserver::StartOrCancelEntry(1, info)); } // Test that IP address changes flush the cache. @@ -1298,7 +1364,7 @@ TEST_F(HostResolverImplTest, HigherPriorityRequestsStartedFirst) { new HostResolverImpl(resolver_proc, CreateDefaultCache(), kMaxJobs, kRetryAttempts, NULL)); - TestHostResolverObserver observer; + CapturingObserver observer; host_resolver->AddObserver(&observer); // Note that at this point the CapturingHostResolverProc is blocked, so any diff --git a/net/base/net_log_event_type_list.h b/net/base/net_log_event_type_list.h index 8e57c96..f0c2333 100644 --- a/net/base/net_log_event_type_list.h +++ b/net/base/net_log_event_type_list.h @@ -1077,8 +1077,8 @@ EVENT_TYPE(THROTTLING_GOT_CUSTOM_RETRY_AFTER) // // { // "net_error": <The net error code for the failure>, -// "ip_address_list": <The result of the resolution process, -// an IPAddressList> +// "ip_address_list": <The result of the resolution process -- list of IP +// addresses>, // } EVENT_TYPE(DNS_TRANSACTION) @@ -1093,39 +1093,3 @@ EVENT_TYPE(DNS_TRANSACTION) // attempt>, // } EVENT_TYPE(DNS_TRANSACTION_ATTEMPT_STARTED) - -// ------------------------------------------------------------------------ -// AsyncHostResolver -// ------------------------------------------------------------------------ - -// The start/end of waiting on a host resolve (DNS) request. -// The BEGIN phase contains the following parameters: -// -// { -// "source_dependency": <Source id of the request being waited on>, -// } -EVENT_TYPE(ASYNC_HOST_RESOLVER) - -// The start/end of a host resolve (DNS) request. -// -// The BEGIN phase contains the following parameters: -// -// { -// "hostname": <Hostname associated with the request>, -// "address_family": <Address family of the request>, -// "allow_cached_response": <Whether to allow cached response>, -// "only_use_cached_response": <Use cached results only>, -// "is_speculative": <Whether the lookup is speculative>, -// "priority": <Priority of the request>, -// "source_dependency": <Source id, if any, of what created the request>, -// } -// -// The END phase will contain this parameter: -// { -// "net_error": <The net error code integer>, -// } -EVENT_TYPE(ASYNC_HOST_RESOLVER_REQUEST) - -// This event is created when a new DnsTransaction is about to be created -// for a request. -EVENT_TYPE(ASYNC_HOST_RESOLVER_CREATE_DNS_TRANSACTION) diff --git a/net/base/net_log_source_type_list.h b/net/base/net_log_source_type_list.h index de80d14..2fcd534 100644 --- a/net/base/net_log_source_type_list.h +++ b/net/base/net_log_source_type_list.h @@ -21,6 +21,5 @@ SOURCE_TYPE(MEMORY_CACHE_ENTRY, 10) SOURCE_TYPE(HTTP_STREAM_JOB, 11) SOURCE_TYPE(EXPONENTIAL_BACKOFF_THROTTLING, 12) SOURCE_TYPE(DNS_TRANSACTION, 13) -SOURCE_TYPE(ASYNC_HOST_RESOLVER_REQUEST, 14) -SOURCE_TYPE(COUNT, 15) // Always keep this as the last entry. +SOURCE_TYPE(COUNT, 14) // Always keep this as the last entry. diff --git a/net/net.gyp b/net/net.gyp index 12cfe91..f83cc76 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -31,8 +31,6 @@ 'base/address_list_net_log_param.h', 'base/asn1_util.cc', 'base/asn1_util.h', - 'base/async_host_resolver.cc', - 'base/async_host_resolver.h', 'base/auth.cc', 'base/auth.h', 'base/backoff_entry.cc', @@ -874,7 +872,6 @@ ], 'sources': [ 'base/address_list_unittest.cc', - 'base/async_host_resolver_unittest.cc', 'base/backoff_entry_unittest.cc', 'base/cert_database_nss_unittest.cc', 'base/cert_verifier_unittest.cc', |