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

[email protected]
Review URL: https://chromiumcodereview.appspot.com/10855163

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@151603 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/base/host_resolver_impl.cc b/net/base/host_resolver_impl.cc
index 8b42a223..68b6bd52 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 @@
   void Cancel() {
     DCHECK(origin_loop_->BelongsToCurrentThread());
 
-    if (was_canceled() || was_completed())
+    if (was_canceled())
       return;
 
     callback_.Reset();
@@ -1043,33 +1042,32 @@
 
 // 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 @@
     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 @@
   }
 
   // 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 @@
   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 @@
     }
 
     UmaAsyncDnsResolveStatus(RESOLVE_STATUS_DNS_SUCCESS);
-
     CompleteRequests(net_error, addr_list, ttl);
   }