diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-14 23:32:29 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-14 23:32:29 +0000 |
commit | 708d0cce7d55778a3527c6c6ea60ebaac1d6ec10 (patch) | |
tree | 27f9736e21c5bb0f44f798ffd0629c157fbed0ed /net/base/host_resolver_impl.cc | |
parent | e833677d6b5a38936bcc2ce455dfe303ce8e0f8b (diff) | |
download | chromium_src-708d0cce7d55778a3527c6c6ea60ebaac1d6ec10.zip chromium_src-708d0cce7d55778a3527c6c6ea60ebaac1d6ec10.tar.gz chromium_src-708d0cce7d55778a3527c6c6ea60ebaac1d6ec10.tar.bz2 |
Revert 151586 - [net/dns] Resolve AF_UNSPEC on dual-stacked systems. Sort addresses according to RFC3484.
BUG=113993
TEST=./net_unittests --gtest_filter=AddressSorter*:HostResolverImplDnsTest.DnsTaskUnspec
Review URL: https://chromiumcodereview.appspot.com/10442098
TBR=szym@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10855163
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@151603 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/host_resolver_impl.cc')
-rw-r--r-- | net/base/host_resolver_impl.cc | 162 |
1 files changed, 34 insertions, 128 deletions
diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc index 8b42a22..68b6bd5 100644 --- a/net/base/host_resolver_impl.cc +++ b/net/base/host_resolver_impl.cc @@ -38,7 +38,6 @@ #include "net/base/net_errors.h" #include "net/base/net_log.h" #include "net/base/net_util.h" -#include "net/dns/address_sorter.h" #include "net/dns/dns_client.h" #include "net/dns/dns_config_service.h" #include "net/dns/dns_protocol.h" @@ -610,7 +609,7 @@ class HostResolverImpl::ProcTask void Cancel() { DCHECK(origin_loop_->BelongsToCurrentThread()); - if (was_canceled() || was_completed()) + if (was_canceled()) return; callback_.Reset(); @@ -1043,33 +1042,32 @@ class HostResolverImpl::IPv6ProbeJob // Resolves the hostname using DnsTransaction. // TODO(szym): This could be moved to separate source file as well. -class HostResolverImpl::DnsTask : public base::SupportsWeakPtr<DnsTask> { +class HostResolverImpl::DnsTask { public: typedef base::Callback<void(int net_error, const AddressList& addr_list, base::TimeDelta ttl)> Callback; - DnsTask(DnsClient* client, + DnsTask(DnsTransactionFactory* factory, const Key& key, const Callback& callback, const BoundNetLog& job_net_log) - : client_(client), - family_(key.address_family), - callback_(callback), - net_log_(job_net_log) { - DCHECK(client); + : callback_(callback), net_log_(job_net_log) { + DCHECK(factory); DCHECK(!callback.is_null()); - // If unspecified, do IPv4 first, because suffix search will be faster. - uint16 qtype = (family_ == ADDRESS_FAMILY_IPV6) ? - dns_protocol::kTypeAAAA : - dns_protocol::kTypeA; - transaction_ = client_->GetTransactionFactory()->CreateTransaction( + // For now we treat ADDRESS_FAMILY_UNSPEC as if it was IPV4. + uint16 qtype = (key.address_family == ADDRESS_FAMILY_IPV6) + ? dns_protocol::kTypeAAAA + : dns_protocol::kTypeA; + // TODO(szym): Implement "happy eyeballs". + transaction_ = factory->CreateTransaction( key.hostname, qtype, base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this), - true /* first_query */, base::TimeTicks::Now()), + base::TimeTicks::Now()), net_log_); + DCHECK(transaction_.get()); } int Start() { @@ -1077,138 +1075,47 @@ class HostResolverImpl::DnsTask : public base::SupportsWeakPtr<DnsTask> { return transaction_->Start(); } - private: - void OnTransactionComplete(bool first_query, - const base::TimeTicks& start_time, + void OnTransactionComplete(const base::TimeTicks& start_time, DnsTransaction* transaction, int net_error, const DnsResponse* response) { DCHECK(transaction); // Run |callback_| last since the owning Job will then delete this DnsTask. - if (net_error != OK) { - DNS_HISTOGRAM("AsyncDNS.TransactionFailure", + DnsResponse::Result result = DnsResponse::DNS_SUCCESS; + if (net_error == OK) { + CHECK(response); + DNS_HISTOGRAM("AsyncDNS.TransactionSuccess", base::TimeTicks::Now() - start_time); - OnFailure(net_error, DnsResponse::DNS_PARSE_OK); - return; - } - - CHECK(response); - DNS_HISTOGRAM("AsyncDNS.TransactionSuccess", - base::TimeTicks::Now() - start_time); - AddressList addr_list; - base::TimeDelta ttl; - DnsResponse::Result result = response->ParseToAddressList(&addr_list, &ttl); - UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ParseToAddressList", - result, - DnsResponse::DNS_PARSE_RESULT_MAX); - if (result != DnsResponse::DNS_PARSE_OK) { - // Fail even if the other query succeeds. - OnFailure(ERR_DNS_MALFORMED_RESPONSE, result); - return; - } - - bool needs_sort = false; - if (first_query) { - DCHECK(client_->GetConfig()) << - "Transaction should have been aborted when config changed!"; - if (family_ == ADDRESS_FAMILY_IPV6) { - needs_sort = (addr_list.size() > 1); - } else if (family_ == ADDRESS_FAMILY_UNSPECIFIED) { - first_addr_list_ = addr_list; - first_ttl_ = ttl; - // Use fully-qualified domain name to avoid search. - transaction_ = client_->GetTransactionFactory()->CreateTransaction( - response->GetDottedName() + ".", - dns_protocol::kTypeAAAA, - base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this), - false /* first_query */, base::TimeTicks::Now()), - net_log_); - net_error = transaction_->Start(); - if (net_error != ERR_IO_PENDING) - OnFailure(net_error, DnsResponse::DNS_PARSE_OK); + AddressList addr_list; + base::TimeDelta ttl; + result = response->ParseToAddressList(&addr_list, &ttl); + UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ParseToAddressList", + result, + DnsResponse::DNS_PARSE_RESULT_MAX); + if (result == DnsResponse::DNS_SUCCESS) { + net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, + addr_list.CreateNetLogCallback()); + callback_.Run(net_error, addr_list, ttl); return; } + net_error = ERR_DNS_MALFORMED_RESPONSE; } else { - DCHECK_EQ(ADDRESS_FAMILY_UNSPECIFIED, family_); - bool has_ipv6_addresses = !addr_list.empty(); - if (!first_addr_list_.empty()) { - ttl = std::min(ttl, first_ttl_); - // Place IPv4 addresses after IPv6. - addr_list.insert(addr_list.end(), first_addr_list_.begin(), - first_addr_list_.end()); - } - needs_sort = (has_ipv6_addresses && addr_list.size() > 1); - } - - if (addr_list.empty()) { - // TODO(szym): Don't fallback to ProcTask in this case. - OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK); - return; - } - - if (needs_sort) { - // Sort could complete synchronously. - client_->GetAddressSorter()->Sort( - addr_list, - base::Bind(&DnsTask::OnSortComplete, AsWeakPtr(), - base::TimeTicks::Now(), - ttl)); - } else { - OnSuccess(addr_list, ttl); - } - } - - void OnSortComplete(base::TimeTicks start_time, - base::TimeDelta ttl, - bool success, - const AddressList& addr_list) { - if (!success) { - DNS_HISTOGRAM("AsyncDNS.SortFailure", + DNS_HISTOGRAM("AsyncDNS.TransactionFailure", base::TimeTicks::Now() - start_time); - OnFailure(ERR_DNS_SORT_ERROR, DnsResponse::DNS_PARSE_OK); - return; - } - - DNS_HISTOGRAM("AsyncDNS.SortSuccess", - base::TimeTicks::Now() - start_time); - - // AddressSorter prunes unusable destinations. - if (addr_list.empty()) { - LOG(WARNING) << "Address list empty after RFC3484 sort"; - OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK); - return; } - - OnSuccess(addr_list, ttl); - } - - void OnFailure(int net_error, DnsResponse::Result result) { - DCHECK_NE(OK, net_error); net_log_.EndEvent( NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, base::Bind(&NetLogDnsTaskFailedCallback, net_error, result)); callback_.Run(net_error, AddressList(), base::TimeDelta()); } - void OnSuccess(const AddressList& addr_list, base::TimeDelta ttl) { - net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, - addr_list.CreateNetLogCallback()); - callback_.Run(OK, addr_list, ttl); - } - - DnsClient* client_; - AddressFamily family_; + private: // The listener to the results of this DnsTask. Callback callback_; + const BoundNetLog net_log_; scoped_ptr<DnsTransaction> transaction_; - - // Results from the first transaction. Used only if |family_| is unspecified. - AddressList first_addr_list_; - base::TimeDelta first_ttl_; - - DISALLOW_COPY_AND_ASSIGN(DnsTask); }; //----------------------------------------------------------------------------- @@ -1307,7 +1214,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job { } // Marks |req| as cancelled. If it was the last active Request, also finishes - // this Job, marking it as cancelled, and deletes it. + // this Job marking it either as aborted or cancelled, and deletes it. void CancelRequest(Request* req) { DCHECK_EQ(key_.hostname, req->info().hostname()); DCHECK(!req->was_canceled()); @@ -1474,7 +1381,7 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job { void StartDnsTask() { DCHECK(resolver_->HaveDnsConfig()); dns_task_.reset(new DnsTask( - resolver_->dns_client_.get(), + resolver_->dns_client_->GetTransactionFactory(), key_, base::Bind(&Job::OnDnsTaskComplete, base::Unretained(this)), net_log_)); @@ -1508,7 +1415,6 @@ class HostResolverImpl::Job : public PrioritizedDispatcher::Job { } UmaAsyncDnsResolveStatus(RESOLVE_STATUS_DNS_SUCCESS); - CompleteRequests(net_error, addr_list, ttl); } |