Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: net/base/host_resolver_impl.cc

Issue 10855163: Revert 151586 - [net/dns] Resolve AF_UNSPEC on dual-stacked systems. Sort addresses according to RF… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/host_resolver_impl.h ('k') | net/base/host_resolver_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/host_resolver_impl.h" 5 #include "net/base/host_resolver_impl.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <Winsock2.h> 8 #include <Winsock2.h>
9 #elif defined(OS_POSIX) 9 #elif defined(OS_POSIX)
10 #include <netdb.h> 10 #include <netdb.h>
(...skipping 20 matching lines...) Expand all
31 #include "base/utf_string_conversions.h" 31 #include "base/utf_string_conversions.h"
32 #include "base/values.h" 32 #include "base/values.h"
33 #include "net/base/address_family.h" 33 #include "net/base/address_family.h"
34 #include "net/base/address_list.h" 34 #include "net/base/address_list.h"
35 #include "net/base/dns_reloader.h" 35 #include "net/base/dns_reloader.h"
36 #include "net/base/host_port_pair.h" 36 #include "net/base/host_port_pair.h"
37 #include "net/base/host_resolver_proc.h" 37 #include "net/base/host_resolver_proc.h"
38 #include "net/base/net_errors.h" 38 #include "net/base/net_errors.h"
39 #include "net/base/net_log.h" 39 #include "net/base/net_log.h"
40 #include "net/base/net_util.h" 40 #include "net/base/net_util.h"
41 #include "net/dns/address_sorter.h"
42 #include "net/dns/dns_client.h" 41 #include "net/dns/dns_client.h"
43 #include "net/dns/dns_config_service.h" 42 #include "net/dns/dns_config_service.h"
44 #include "net/dns/dns_protocol.h" 43 #include "net/dns/dns_protocol.h"
45 #include "net/dns/dns_response.h" 44 #include "net/dns/dns_response.h"
46 #include "net/dns/dns_transaction.h" 45 #include "net/dns/dns_transaction.h"
47 46
48 #if defined(OS_WIN) 47 #if defined(OS_WIN)
49 #include "net/base/winsock_init.h" 48 #include "net/base/winsock_init.h"
50 #endif 49 #endif
51 50
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); 602 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK);
604 StartLookupAttempt(); 603 StartLookupAttempt();
605 } 604 }
606 605
607 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve 606 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve
608 // attempts running on worker threads will continue running. Only once all the 607 // attempts running on worker threads will continue running. Only once all the
609 // attempts complete will the final reference to this ProcTask be released. 608 // attempts complete will the final reference to this ProcTask be released.
610 void Cancel() { 609 void Cancel() {
611 DCHECK(origin_loop_->BelongsToCurrentThread()); 610 DCHECK(origin_loop_->BelongsToCurrentThread());
612 611
613 if (was_canceled() || was_completed()) 612 if (was_canceled())
614 return; 613 return;
615 614
616 callback_.Reset(); 615 callback_.Reset();
617 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); 616 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK);
618 } 617 }
619 618
620 void set_had_non_speculative_request() { 619 void set_had_non_speculative_request() {
621 DCHECK(origin_loop_->BelongsToCurrentThread()); 620 DCHECK(origin_loop_->BelongsToCurrentThread());
622 had_non_speculative_request_ = true; 621 had_non_speculative_request_ = true;
623 } 622 }
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 1035
1037 BoundNetLog net_log_; 1036 BoundNetLog net_log_;
1038 1037
1039 DISALLOW_COPY_AND_ASSIGN(IPv6ProbeJob); 1038 DISALLOW_COPY_AND_ASSIGN(IPv6ProbeJob);
1040 }; 1039 };
1041 1040
1042 //----------------------------------------------------------------------------- 1041 //-----------------------------------------------------------------------------
1043 1042
1044 // Resolves the hostname using DnsTransaction. 1043 // Resolves the hostname using DnsTransaction.
1045 // TODO(szym): This could be moved to separate source file as well. 1044 // TODO(szym): This could be moved to separate source file as well.
1046 class HostResolverImpl::DnsTask : public base::SupportsWeakPtr<DnsTask> { 1045 class HostResolverImpl::DnsTask {
1047 public: 1046 public:
1048 typedef base::Callback<void(int net_error, 1047 typedef base::Callback<void(int net_error,
1049 const AddressList& addr_list, 1048 const AddressList& addr_list,
1050 base::TimeDelta ttl)> Callback; 1049 base::TimeDelta ttl)> Callback;
1051 1050
1052 DnsTask(DnsClient* client, 1051 DnsTask(DnsTransactionFactory* factory,
1053 const Key& key, 1052 const Key& key,
1054 const Callback& callback, 1053 const Callback& callback,
1055 const BoundNetLog& job_net_log) 1054 const BoundNetLog& job_net_log)
1056 : client_(client), 1055 : callback_(callback), net_log_(job_net_log) {
1057 family_(key.address_family), 1056 DCHECK(factory);
1058 callback_(callback),
1059 net_log_(job_net_log) {
1060 DCHECK(client);
1061 DCHECK(!callback.is_null()); 1057 DCHECK(!callback.is_null());
1062 1058
1063 // If unspecified, do IPv4 first, because suffix search will be faster. 1059 // For now we treat ADDRESS_FAMILY_UNSPEC as if it was IPV4.
1064 uint16 qtype = (family_ == ADDRESS_FAMILY_IPV6) ? 1060 uint16 qtype = (key.address_family == ADDRESS_FAMILY_IPV6)
1065 dns_protocol::kTypeAAAA : 1061 ? dns_protocol::kTypeAAAA
1066 dns_protocol::kTypeA; 1062 : dns_protocol::kTypeA;
1067 transaction_ = client_->GetTransactionFactory()->CreateTransaction( 1063 // TODO(szym): Implement "happy eyeballs".
1064 transaction_ = factory->CreateTransaction(
1068 key.hostname, 1065 key.hostname,
1069 qtype, 1066 qtype,
1070 base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this), 1067 base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this),
1071 true /* first_query */, base::TimeTicks::Now()), 1068 base::TimeTicks::Now()),
1072 net_log_); 1069 net_log_);
1070 DCHECK(transaction_.get());
1073 } 1071 }
1074 1072
1075 int Start() { 1073 int Start() {
1076 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK); 1074 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK);
1077 return transaction_->Start(); 1075 return transaction_->Start();
1078 } 1076 }
1079 1077
1080 private: 1078 void OnTransactionComplete(const base::TimeTicks& start_time,
1081 void OnTransactionComplete(bool first_query,
1082 const base::TimeTicks& start_time,
1083 DnsTransaction* transaction, 1079 DnsTransaction* transaction,
1084 int net_error, 1080 int net_error,
1085 const DnsResponse* response) { 1081 const DnsResponse* response) {
1086 DCHECK(transaction); 1082 DCHECK(transaction);
1087 // Run |callback_| last since the owning Job will then delete this DnsTask. 1083 // Run |callback_| last since the owning Job will then delete this DnsTask.
1088 if (net_error != OK) { 1084 DnsResponse::Result result = DnsResponse::DNS_SUCCESS;
1085 if (net_error == OK) {
1086 CHECK(response);
1087 DNS_HISTOGRAM("AsyncDNS.TransactionSuccess",
1088 base::TimeTicks::Now() - start_time);
1089 AddressList addr_list;
1090 base::TimeDelta ttl;
1091 result = response->ParseToAddressList(&addr_list, &ttl);
1092 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ParseToAddressList",
1093 result,
1094 DnsResponse::DNS_PARSE_RESULT_MAX);
1095 if (result == DnsResponse::DNS_SUCCESS) {
1096 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK,
1097 addr_list.CreateNetLogCallback());
1098 callback_.Run(net_error, addr_list, ttl);
1099 return;
1100 }
1101 net_error = ERR_DNS_MALFORMED_RESPONSE;
1102 } else {
1089 DNS_HISTOGRAM("AsyncDNS.TransactionFailure", 1103 DNS_HISTOGRAM("AsyncDNS.TransactionFailure",
1090 base::TimeTicks::Now() - start_time); 1104 base::TimeTicks::Now() - start_time);
1091 OnFailure(net_error, DnsResponse::DNS_PARSE_OK);
1092 return;
1093 } 1105 }
1094
1095 CHECK(response);
1096 DNS_HISTOGRAM("AsyncDNS.TransactionSuccess",
1097 base::TimeTicks::Now() - start_time);
1098 AddressList addr_list;
1099 base::TimeDelta ttl;
1100 DnsResponse::Result result = response->ParseToAddressList(&addr_list, &ttl);
1101 UMA_HISTOGRAM_ENUMERATION("AsyncDNS.ParseToAddressList",
1102 result,
1103 DnsResponse::DNS_PARSE_RESULT_MAX);
1104 if (result != DnsResponse::DNS_PARSE_OK) {
1105 // Fail even if the other query succeeds.
1106 OnFailure(ERR_DNS_MALFORMED_RESPONSE, result);
1107 return;
1108 }
1109
1110 bool needs_sort = false;
1111 if (first_query) {
1112 DCHECK(client_->GetConfig()) <<
1113 "Transaction should have been aborted when config changed!";
1114 if (family_ == ADDRESS_FAMILY_IPV6) {
1115 needs_sort = (addr_list.size() > 1);
1116 } else if (family_ == ADDRESS_FAMILY_UNSPECIFIED) {
1117 first_addr_list_ = addr_list;
1118 first_ttl_ = ttl;
1119 // Use fully-qualified domain name to avoid search.
1120 transaction_ = client_->GetTransactionFactory()->CreateTransaction(
1121 response->GetDottedName() + ".",
1122 dns_protocol::kTypeAAAA,
1123 base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this),
1124 false /* first_query */, base::TimeTicks::Now()),
1125 net_log_);
1126 net_error = transaction_->Start();
1127 if (net_error != ERR_IO_PENDING)
1128 OnFailure(net_error, DnsResponse::DNS_PARSE_OK);
1129 return;
1130 }
1131 } else {
1132 DCHECK_EQ(ADDRESS_FAMILY_UNSPECIFIED, family_);
1133 bool has_ipv6_addresses = !addr_list.empty();
1134 if (!first_addr_list_.empty()) {
1135 ttl = std::min(ttl, first_ttl_);
1136 // Place IPv4 addresses after IPv6.
1137 addr_list.insert(addr_list.end(), first_addr_list_.begin(),
1138 first_addr_list_.end());
1139 }
1140 needs_sort = (has_ipv6_addresses && addr_list.size() > 1);
1141 }
1142
1143 if (addr_list.empty()) {
1144 // TODO(szym): Don't fallback to ProcTask in this case.
1145 OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK);
1146 return;
1147 }
1148
1149 if (needs_sort) {
1150 // Sort could complete synchronously.
1151 client_->GetAddressSorter()->Sort(
1152 addr_list,
1153 base::Bind(&DnsTask::OnSortComplete, AsWeakPtr(),
1154 base::TimeTicks::Now(),
1155 ttl));
1156 } else {
1157 OnSuccess(addr_list, ttl);
1158 }
1159 }
1160
1161 void OnSortComplete(base::TimeTicks start_time,
1162 base::TimeDelta ttl,
1163 bool success,
1164 const AddressList& addr_list) {
1165 if (!success) {
1166 DNS_HISTOGRAM("AsyncDNS.SortFailure",
1167 base::TimeTicks::Now() - start_time);
1168 OnFailure(ERR_DNS_SORT_ERROR, DnsResponse::DNS_PARSE_OK);
1169 return;
1170 }
1171
1172 DNS_HISTOGRAM("AsyncDNS.SortSuccess",
1173 base::TimeTicks::Now() - start_time);
1174
1175 // AddressSorter prunes unusable destinations.
1176 if (addr_list.empty()) {
1177 LOG(WARNING) << "Address list empty after RFC3484 sort";
1178 OnFailure(ERR_NAME_NOT_RESOLVED, DnsResponse::DNS_PARSE_OK);
1179 return;
1180 }
1181
1182 OnSuccess(addr_list, ttl);
1183 }
1184
1185 void OnFailure(int net_error, DnsResponse::Result result) {
1186 DCHECK_NE(OK, net_error);
1187 net_log_.EndEvent( 1106 net_log_.EndEvent(
1188 NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, 1107 NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK,
1189 base::Bind(&NetLogDnsTaskFailedCallback, net_error, result)); 1108 base::Bind(&NetLogDnsTaskFailedCallback, net_error, result));
1190 callback_.Run(net_error, AddressList(), base::TimeDelta()); 1109 callback_.Run(net_error, AddressList(), base::TimeDelta());
1191 } 1110 }
1192 1111
1193 void OnSuccess(const AddressList& addr_list, base::TimeDelta ttl) { 1112 private:
1194 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK,
1195 addr_list.CreateNetLogCallback());
1196 callback_.Run(OK, addr_list, ttl);
1197 }
1198
1199 DnsClient* client_;
1200 AddressFamily family_;
1201 // The listener to the results of this DnsTask. 1113 // The listener to the results of this DnsTask.
1202 Callback callback_; 1114 Callback callback_;
1115
1203 const BoundNetLog net_log_; 1116 const BoundNetLog net_log_;
1204 1117
1205 scoped_ptr<DnsTransaction> transaction_; 1118 scoped_ptr<DnsTransaction> transaction_;
1206
1207 // Results from the first transaction. Used only if |family_| is unspecified.
1208 AddressList first_addr_list_;
1209 base::TimeDelta first_ttl_;
1210
1211 DISALLOW_COPY_AND_ASSIGN(DnsTask);
1212 }; 1119 };
1213 1120
1214 //----------------------------------------------------------------------------- 1121 //-----------------------------------------------------------------------------
1215 1122
1216 // Aggregates all Requests for the same Key. Dispatched via PriorityDispatch. 1123 // Aggregates all Requests for the same Key. Dispatched via PriorityDispatch.
1217 class HostResolverImpl::Job : public PrioritizedDispatcher::Job { 1124 class HostResolverImpl::Job : public PrioritizedDispatcher::Job {
1218 public: 1125 public:
1219 // Creates new job for |key| where |request_net_log| is bound to the 1126 // Creates new job for |key| where |request_net_log| is bound to the
1220 // request that spawned it. 1127 // request that spawned it.
1221 Job(HostResolverImpl* resolver, 1128 Job(HostResolverImpl* resolver,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 if (proc_task_) 1207 if (proc_task_)
1301 proc_task_->set_had_non_speculative_request(); 1208 proc_task_->set_had_non_speculative_request();
1302 } 1209 }
1303 1210
1304 requests_.push_back(req.release()); 1211 requests_.push_back(req.release());
1305 1212
1306 UpdatePriority(); 1213 UpdatePriority();
1307 } 1214 }
1308 1215
1309 // Marks |req| as cancelled. If it was the last active Request, also finishes 1216 // Marks |req| as cancelled. If it was the last active Request, also finishes
1310 // this Job, marking it as cancelled, and deletes it. 1217 // this Job marking it either as aborted or cancelled, and deletes it.
1311 void CancelRequest(Request* req) { 1218 void CancelRequest(Request* req) {
1312 DCHECK_EQ(key_.hostname, req->info().hostname()); 1219 DCHECK_EQ(key_.hostname, req->info().hostname());
1313 DCHECK(!req->was_canceled()); 1220 DCHECK(!req->was_canceled());
1314 1221
1315 // Don't remove it from |requests_| just mark it canceled. 1222 // Don't remove it from |requests_| just mark it canceled.
1316 req->MarkAsCanceled(); 1223 req->MarkAsCanceled();
1317 LogCancelRequest(req->source_net_log(), req->request_net_log(), 1224 LogCancelRequest(req->source_net_log(), req->request_net_log(),
1318 req->info()); 1225 req->info());
1319 1226
1320 priority_tracker_.Remove(req->info().priority()); 1227 priority_tracker_.Remove(req->info().priority());
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1467 kNegativeCacheEntryTTLSeconds); 1374 kNegativeCacheEntryTTLSeconds);
1468 if (net_error == OK) 1375 if (net_error == OK)
1469 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds); 1376 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds);
1470 1377
1471 CompleteRequests(net_error, addr_list, ttl); 1378 CompleteRequests(net_error, addr_list, ttl);
1472 } 1379 }
1473 1380
1474 void StartDnsTask() { 1381 void StartDnsTask() {
1475 DCHECK(resolver_->HaveDnsConfig()); 1382 DCHECK(resolver_->HaveDnsConfig());
1476 dns_task_.reset(new DnsTask( 1383 dns_task_.reset(new DnsTask(
1477 resolver_->dns_client_.get(), 1384 resolver_->dns_client_->GetTransactionFactory(),
1478 key_, 1385 key_,
1479 base::Bind(&Job::OnDnsTaskComplete, base::Unretained(this)), 1386 base::Bind(&Job::OnDnsTaskComplete, base::Unretained(this)),
1480 net_log_)); 1387 net_log_));
1481 1388
1482 int rv = dns_task_->Start(); 1389 int rv = dns_task_->Start();
1483 if (rv != ERR_IO_PENDING) { 1390 if (rv != ERR_IO_PENDING) {
1484 DCHECK_NE(OK, rv); 1391 DCHECK_NE(OK, rv);
1485 dns_task_error_ = rv; 1392 dns_task_error_ = rv;
1486 dns_task_.reset(); 1393 dns_task_.reset();
1487 StartProcTask(); 1394 StartProcTask();
(...skipping 13 matching lines...) Expand all
1501 // TODO(szym): Run ServeFromHosts now if nsswitch.conf says so. 1408 // TODO(szym): Run ServeFromHosts now if nsswitch.conf says so.
1502 // http://crbug.com/117655 1409 // http://crbug.com/117655
1503 1410
1504 // TODO(szym): Some net errors indicate lack of connectivity. Starting 1411 // TODO(szym): Some net errors indicate lack of connectivity. Starting
1505 // ProcTask in that case is a waste of time. 1412 // ProcTask in that case is a waste of time.
1506 StartProcTask(); 1413 StartProcTask();
1507 return; 1414 return;
1508 } 1415 }
1509 1416
1510 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_DNS_SUCCESS); 1417 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_DNS_SUCCESS);
1511
1512 CompleteRequests(net_error, addr_list, ttl); 1418 CompleteRequests(net_error, addr_list, ttl);
1513 } 1419 }
1514 1420
1515 // Performs Job's last rites. Completes all Requests. Deletes this. 1421 // Performs Job's last rites. Completes all Requests. Deletes this.
1516 void CompleteRequests(int net_error, 1422 void CompleteRequests(int net_error,
1517 const AddressList& addr_list, 1423 const AddressList& addr_list,
1518 base::TimeDelta ttl) { 1424 base::TimeDelta ttl) {
1519 CHECK(resolver_); 1425 CHECK(resolver_);
1520 1426
1521 // This job must be removed from resolver's |jobs_| now to make room for a 1427 // This job must be removed from resolver's |jobs_| now to make room for a
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after
2145 // |this| may be deleted inside AbortAllInProgressJobs(). 2051 // |this| may be deleted inside AbortAllInProgressJobs().
2146 if (self) 2052 if (self)
2147 TryServingAllJobsFromHosts(); 2053 TryServingAllJobsFromHosts();
2148 } 2054 }
2149 2055
2150 bool HostResolverImpl::HaveDnsConfig() const { 2056 bool HostResolverImpl::HaveDnsConfig() const {
2151 return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL); 2057 return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL);
2152 } 2058 }
2153 2059
2154 } // namespace net 2060 } // namespace net
OLDNEW
« no previous file with comments | « net/base/host_resolver_impl.h ('k') | net/base/host_resolver_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698