| Index: net/dns/async_host_resolver.cc
|
| diff --git a/net/dns/async_host_resolver.cc b/net/dns/async_host_resolver.cc
|
| index 1666e04ce2eb3cd15ad9f6bef7c8c4df98720188..ff93c3e52f794bc09719bbda2179e43a8f96ba97 100644
|
| --- a/net/dns/async_host_resolver.cc
|
| +++ b/net/dns/async_host_resolver.cc
|
| @@ -8,12 +8,16 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/logging.h"
|
| +#include "base/message_loop.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/dns/dns_protocol.h"
|
| +#include "net/dns/dns_response.h"
|
| +#include "net/dns/dns_session.h"
|
| #include "net/socket/client_socket_factory.h"
|
|
|
| namespace net {
|
| @@ -22,7 +26,7 @@ namespace {
|
|
|
| // TODO(agayev): fix this when IPv6 support is added.
|
| uint16 QueryTypeFromAddressFamily(AddressFamily address_family) {
|
| - return kDNS_A;
|
| + return dns_protocol::kTypeA;
|
| }
|
|
|
| class RequestParameters : public NetLog::EventParameters {
|
| @@ -56,17 +60,22 @@ class RequestParameters : public NetLog::EventParameters {
|
| 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;
|
| + size_t max_dns_requests = max_concurrent_resolves;
|
| + if (max_dns_requests == 0)
|
| + max_dns_requests = 20;
|
| + size_t max_pending_requests = max_dns_requests * 100;
|
| + DnsConfig config;
|
| + config.nameservers.push_back(IPEndPoint(dns_ip, 53));
|
| + DnsSession* session = new DnsSession(
|
| + config,
|
| + ClientSocketFactory::GetDefaultFactory(),
|
| + base::Bind(&base::RandInt),
|
| + net_log);
|
| HostResolver* resolver = new AsyncHostResolver(
|
| - IPEndPoint(dns_ip, 53),
|
| - max_transactions,
|
| + max_dns_requests,
|
| max_pending_requests,
|
| - base::Bind(&base::RandInt),
|
| HostCache::CreateDefaultCache(),
|
| - NULL,
|
| + DnsClient::CreateClient(session),
|
| net_log);
|
| return resolver;
|
| }
|
| @@ -193,19 +202,15 @@ class AsyncHostResolver::Request {
|
| };
|
|
|
| //-----------------------------------------------------------------------------
|
| -AsyncHostResolver::AsyncHostResolver(const IPEndPoint& dns_server,
|
| - size_t max_transactions,
|
| +AsyncHostResolver::AsyncHostResolver(size_t max_dns_requests,
|
| size_t max_pending_requests,
|
| - const RandIntCallback& rand_int_cb,
|
| HostCache* cache,
|
| - ClientSocketFactory* factory,
|
| + DnsClient* client,
|
| NetLog* net_log)
|
| - : max_transactions_(max_transactions),
|
| + : max_dns_requests_(max_dns_requests),
|
| max_pending_requests_(max_pending_requests),
|
| - dns_server_(dns_server),
|
| - rand_int_cb_(rand_int_cb),
|
| cache_(cache),
|
| - factory_(factory),
|
| + client_(client),
|
| net_log_(net_log) {
|
| }
|
|
|
| @@ -215,8 +220,8 @@ AsyncHostResolver::~AsyncHostResolver() {
|
| it != requestlist_map_.end(); ++it)
|
| STLDeleteElements(&it->second);
|
|
|
| - // Destroy transactions.
|
| - STLDeleteElements(&transactions_);
|
| + // Destroy DNS requests.
|
| + STLDeleteElements(&dns_requests_);
|
|
|
| // Destroy pending requests.
|
| for (size_t i = 0; i < arraysize(pending_requests_); ++i)
|
| @@ -240,8 +245,8 @@ int AsyncHostResolver::Resolve(const RequestInfo& info,
|
| rv = request->result();
|
| else if (AttachToRequestList(request.get()))
|
| rv = ERR_IO_PENDING;
|
| - else if (transactions_.size() < max_transactions_)
|
| - rv = StartNewTransactionFor(request.get());
|
| + else if (dns_requests_.size() < max_dns_requests_)
|
| + rv = StartNewDnsRequestFor(request.get());
|
| else
|
| rv = Enqueue(request.get());
|
|
|
| @@ -327,39 +332,56 @@ HostCache* AsyncHostResolver::GetHostCache() {
|
| return cache_.get();
|
| }
|
|
|
| -void AsyncHostResolver::OnTransactionComplete(
|
| +void AsyncHostResolver::OnDnsRequestComplete(
|
| + DnsClient::Request* dns_req,
|
| 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());
|
| + const DnsResponse* response) {
|
| + DCHECK(std::find(dns_requests_.begin(), dns_requests_.end(), dns_req)
|
| + != dns_requests_.end());
|
|
|
| - // If by the time requests that caused |transaction| are cancelled, we do
|
| + // If by the time requests that caused |dns_req| are cancelled, we do
|
| // not have a port number to associate with the result, therefore, we
|
| // assume the most common port, otherwise we use the port number of the
|
| // first request.
|
| - RequestList& requests = requestlist_map_[transaction->key()];
|
| + KeyRequestListMap::iterator rit = requestlist_map_.find(
|
| + std::make_pair(dns_req->qname(), dns_req->qtype()));
|
| + DCHECK(rit != requestlist_map_.end());
|
| + RequestList& requests = rit->second;
|
| int port = requests.empty() ? 80 : requests.front()->info().port();
|
|
|
| - // Run callback of every request that was depending on this transaction,
|
| + // Extract AddressList out of DnsResponse.
|
| + AddressList addr_list;
|
| + if (result == OK) {
|
| + IPAddressList ip_addresses;
|
| + DnsRecordParser parser = response->Parser();
|
| + DnsResourceRecord record;
|
| + // TODO(szym): Add stricter checking of names, aliases and address lengths.
|
| + while (parser.ParseRecord(&record)) {
|
| + if (record.type == dns_req->qtype() &&
|
| + (record.rdata.size() == kIPv4AddressSize ||
|
| + record.rdata.size() == kIPv6AddressSize)) {
|
| + ip_addresses.push_back(IPAddressNumber(record.rdata.begin(),
|
| + record.rdata.end()));
|
| + }
|
| + }
|
| + if (!ip_addresses.empty())
|
| + addr_list = AddressList::CreateFromIPAddressList(ip_addresses, port);
|
| + else
|
| + result = ERR_NAME_NOT_RESOLVED;
|
| + }
|
| +
|
| + // Run callback of every request that was depending on this DNS request,
|
| // also notify observers.
|
| - AddressList addrlist;
|
| - if (result == OK)
|
| - addrlist = AddressList::CreateFromIPAddressList(ip_addresses, port);
|
| - for (RequestList::iterator it = requests.begin(); it != requests.end();
|
| - ++it)
|
| - (*it)->OnAsyncComplete(result, addrlist);
|
| -
|
| - // It is possible that the requests that caused |transaction| to be
|
| - // created are cancelled by the time |transaction| completes. In that
|
| + for (RequestList::iterator it = requests.begin(); it != requests.end(); ++it)
|
| + (*it)->OnAsyncComplete(result, addr_list);
|
| +
|
| + // It is possible that the requests that caused |dns_req| to be
|
| + // created are cancelled by the time |dns_req| completes. In that
|
| // case |requests| would be empty. We are knowingly throwing away the
|
| // result of a DNS resolution in that case, because (a) if there are no
|
| // requests, we do not have info to obtain a key from, (b) DnsTransaction
|
| // does not have info(), adding one into it just temporarily doesn't make
|
| - // sense, since HostCache will be replaced with RR cache soon, (c)
|
| - // recreating info from DnsTransaction::Key adds a lot of temporary
|
| - // code/functions (like converting back from qtype to AddressFamily.)
|
| + // sense, since HostCache will be replaced with RR cache soon.
|
| // Also, we only cache positive results. All of this will change when RR
|
| // cache is added.
|
| if (result == OK && cache_.get() && !requests.empty()) {
|
| @@ -367,16 +389,16 @@ void AsyncHostResolver::OnTransactionComplete(
|
| HostResolver::RequestInfo info = request->info();
|
| HostCache::Key key(
|
| info.hostname(), info.address_family(), info.host_resolver_flags());
|
| - cache_->Set(key, result, addrlist, base::TimeTicks::Now());
|
| + cache_->Set(key, result, addr_list, base::TimeTicks::Now());
|
| }
|
|
|
| // Cleanup requests.
|
| STLDeleteElements(&requests);
|
| - requestlist_map_.erase(transaction->key());
|
| + requestlist_map_.erase(rit);
|
|
|
| - // Cleanup transaction and start a new one if there are pending requests.
|
| - delete transaction;
|
| - transactions_.remove(transaction);
|
| + // Cleanup |dns_req| and start a new one if there are pending requests.
|
| + delete dns_req;
|
| + dns_requests_.remove(dns_req);
|
| ProcessPending();
|
| }
|
|
|
| @@ -399,25 +421,22 @@ bool AsyncHostResolver::AttachToRequestList(Request* request) {
|
| return true;
|
| }
|
|
|
| -int AsyncHostResolver::StartNewTransactionFor(Request* request) {
|
| +int AsyncHostResolver::StartNewDnsRequestFor(Request* request) {
|
| DCHECK(requestlist_map_.find(request->key()) == requestlist_map_.end());
|
| - DCHECK(transactions_.size() < max_transactions_);
|
| + DCHECK(dns_requests_.size() < max_dns_requests_);
|
|
|
| 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_,
|
| + DnsClient::Request* dns_req = client_->CreateRequest(
|
| 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();
|
| + base::Bind(&AsyncHostResolver::OnDnsRequestComplete,
|
| + base::Unretained(this)),
|
| + request->request_net_log());
|
| + dns_requests_.push_back(dns_req);
|
| + return dns_req->Start();
|
| }
|
|
|
| int AsyncHostResolver::Enqueue(Request* request) {
|
| @@ -490,7 +509,7 @@ void AsyncHostResolver::ProcessPending() {
|
| }
|
| }
|
| }
|
| - StartNewTransactionFor(request);
|
| + StartNewDnsRequestFor(request);
|
| }
|
|
|
| } // namespace net
|
|
|