summaryrefslogtreecommitdiffstats
path: root/net/base/async_host_resolver.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/base/async_host_resolver.cc')
-rw-r--r--net/base/async_host_resolver.cc427
1 files changed, 0 insertions, 427 deletions
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