| OLD | NEW |
| 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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 base::Bind(&NetLogRequestInfoCallback, source_net_log.source(), &info)); | 280 base::Bind(&NetLogRequestInfoCallback, source_net_log.source(), &info)); |
| 281 } | 281 } |
| 282 | 282 |
| 283 // Logs when a request has just completed (before its callback is run). | 283 // Logs when a request has just completed (before its callback is run). |
| 284 void LogFinishRequest(const BoundNetLog& source_net_log, | 284 void LogFinishRequest(const BoundNetLog& source_net_log, |
| 285 const BoundNetLog& request_net_log, | 285 const BoundNetLog& request_net_log, |
| 286 const HostResolver::RequestInfo& info, | 286 const HostResolver::RequestInfo& info, |
| 287 int net_error) { | 287 int net_error) { |
| 288 request_net_log.EndEventWithNetErrorCode( | 288 request_net_log.EndEventWithNetErrorCode( |
| 289 NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, net_error); | 289 NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, net_error); |
| 290 source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); | 290 source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL); |
| 291 } | 291 } |
| 292 | 292 |
| 293 // Logs when a request has been cancelled. | 293 // Logs when a request has been cancelled. |
| 294 void LogCancelRequest(const BoundNetLog& source_net_log, | 294 void LogCancelRequest(const BoundNetLog& source_net_log, |
| 295 const BoundNetLog& request_net_log, | 295 const BoundNetLog& request_net_log, |
| 296 const HostResolverImpl::RequestInfo& info) { | 296 const HostResolverImpl::RequestInfo& info) { |
| 297 request_net_log.AddEvent(NetLog::TYPE_CANCELLED, NULL); | 297 request_net_log.AddEvent(NetLog::TYPE_CANCELLED); |
| 298 request_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, NULL); | 298 request_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST); |
| 299 source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); | 299 source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL); |
| 300 } | 300 } |
| 301 | 301 |
| 302 //----------------------------------------------------------------------------- | 302 //----------------------------------------------------------------------------- |
| 303 | 303 |
| 304 // Keeps track of the highest priority. | 304 // Keeps track of the highest priority. |
| 305 class PriorityTracker { | 305 class PriorityTracker { |
| 306 public: | 306 public: |
| 307 PriorityTracker() | 307 PriorityTracker() |
| 308 : highest_priority_(IDLE), total_count_(0) { | 308 : highest_priority_(IDLE), total_count_(0) { |
| 309 memset(counts_, 0, sizeof(counts_)); | 309 memset(counts_, 0, sizeof(counts_)); |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 net_log_(job_net_log) { | 531 net_log_(job_net_log) { |
| 532 if (!params_.resolver_proc) | 532 if (!params_.resolver_proc) |
| 533 params_.resolver_proc = HostResolverProc::GetDefault(); | 533 params_.resolver_proc = HostResolverProc::GetDefault(); |
| 534 // If default is unset, use the system proc. | 534 // If default is unset, use the system proc. |
| 535 if (!params_.resolver_proc) | 535 if (!params_.resolver_proc) |
| 536 params_.resolver_proc = new CallSystemHostResolverProc(); | 536 params_.resolver_proc = new CallSystemHostResolverProc(); |
| 537 } | 537 } |
| 538 | 538 |
| 539 void Start() { | 539 void Start() { |
| 540 DCHECK(origin_loop_->BelongsToCurrentThread()); | 540 DCHECK(origin_loop_->BelongsToCurrentThread()); |
| 541 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK, NULL); | 541 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); |
| 542 StartLookupAttempt(); | 542 StartLookupAttempt(); |
| 543 } | 543 } |
| 544 | 544 |
| 545 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve | 545 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve |
| 546 // attempts running on worker threads will continue running. Only once all the | 546 // attempts running on worker threads will continue running. Only once all the |
| 547 // attempts complete will the final reference to this ProcTask be released. | 547 // attempts complete will the final reference to this ProcTask be released. |
| 548 void Cancel() { | 548 void Cancel() { |
| 549 DCHECK(origin_loop_->BelongsToCurrentThread()); | 549 DCHECK(origin_loop_->BelongsToCurrentThread()); |
| 550 | 550 |
| 551 if (was_canceled()) | 551 if (was_canceled()) |
| 552 return; | 552 return; |
| 553 | 553 |
| 554 callback_.Reset(); | 554 callback_.Reset(); |
| 555 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK, NULL); | 555 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); |
| 556 } | 556 } |
| 557 | 557 |
| 558 void set_had_non_speculative_request() { | 558 void set_had_non_speculative_request() { |
| 559 DCHECK(origin_loop_->BelongsToCurrentThread()); | 559 DCHECK(origin_loop_->BelongsToCurrentThread()); |
| 560 had_non_speculative_request_ = true; | 560 had_non_speculative_request_ = true; |
| 561 } | 561 } |
| 562 | 562 |
| 563 bool was_canceled() const { | 563 bool was_canceled() const { |
| 564 DCHECK(origin_loop_->BelongsToCurrentThread()); | 564 DCHECK(origin_loop_->BelongsToCurrentThread()); |
| 565 return callback_.is_null(); | 565 return callback_.is_null(); |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 transaction_ = factory->CreateTransaction( | 988 transaction_ = factory->CreateTransaction( |
| 989 key.hostname, | 989 key.hostname, |
| 990 qtype, | 990 qtype, |
| 991 base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this), | 991 base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this), |
| 992 base::TimeTicks::Now()), | 992 base::TimeTicks::Now()), |
| 993 net_log_); | 993 net_log_); |
| 994 DCHECK(transaction_.get()); | 994 DCHECK(transaction_.get()); |
| 995 } | 995 } |
| 996 | 996 |
| 997 int Start() { | 997 int Start() { |
| 998 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK, NULL); | 998 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_DNS_TASK); |
| 999 return transaction_->Start(); | 999 return transaction_->Start(); |
| 1000 } | 1000 } |
| 1001 | 1001 |
| 1002 void OnTransactionComplete(const base::TimeTicks& start_time, | 1002 void OnTransactionComplete(const base::TimeTicks& start_time, |
| 1003 DnsTransaction* transaction, | 1003 DnsTransaction* transaction, |
| 1004 int net_error, | 1004 int net_error, |
| 1005 const DnsResponse* response) { | 1005 const DnsResponse* response) { |
| 1006 DCHECK(transaction); | 1006 DCHECK(transaction); |
| 1007 // Run |callback_| last since the owning Job will then delete this DnsTask. | 1007 // Run |callback_| last since the owning Job will then delete this DnsTask. |
| 1008 DnsResponse::Result result = DnsResponse::DNS_SUCCESS; | 1008 DnsResponse::Result result = DnsResponse::DNS_SUCCESS; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 // request that spawned it. | 1051 // request that spawned it. |
| 1052 Job(HostResolverImpl* resolver, | 1052 Job(HostResolverImpl* resolver, |
| 1053 const Key& key, | 1053 const Key& key, |
| 1054 const BoundNetLog& request_net_log) | 1054 const BoundNetLog& request_net_log) |
| 1055 : resolver_(resolver->AsWeakPtr()), | 1055 : resolver_(resolver->AsWeakPtr()), |
| 1056 key_(key), | 1056 key_(key), |
| 1057 had_non_speculative_request_(false), | 1057 had_non_speculative_request_(false), |
| 1058 had_dns_config_(false), | 1058 had_dns_config_(false), |
| 1059 net_log_(BoundNetLog::Make(request_net_log.net_log(), | 1059 net_log_(BoundNetLog::Make(request_net_log.net_log(), |
| 1060 NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) { | 1060 NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) { |
| 1061 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB, NULL); | 1061 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB); |
| 1062 | 1062 |
| 1063 net_log_.BeginEvent( | 1063 net_log_.BeginEvent( |
| 1064 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, | 1064 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
| 1065 base::Bind(&NetLogJobCreationCallback, | 1065 base::Bind(&NetLogJobCreationCallback, |
| 1066 request_net_log.source(), | 1066 request_net_log.source(), |
| 1067 &key_.hostname)); | 1067 &key_.hostname)); |
| 1068 } | 1068 } |
| 1069 | 1069 |
| 1070 virtual ~Job() { | 1070 virtual ~Job() { |
| 1071 if (is_running()) { | 1071 if (is_running()) { |
| 1072 // |resolver_| was destroyed with this Job still in flight. | 1072 // |resolver_| was destroyed with this Job still in flight. |
| 1073 // Clean-up, record in the log, but don't run any callbacks. | 1073 // Clean-up, record in the log, but don't run any callbacks. |
| 1074 if (is_proc_running()) { | 1074 if (is_proc_running()) { |
| 1075 proc_task_->Cancel(); | 1075 proc_task_->Cancel(); |
| 1076 proc_task_ = NULL; | 1076 proc_task_ = NULL; |
| 1077 } | 1077 } |
| 1078 // Clean up now for nice NetLog. | 1078 // Clean up now for nice NetLog. |
| 1079 dns_task_.reset(NULL); | 1079 dns_task_.reset(NULL); |
| 1080 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, | 1080 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
| 1081 ERR_ABORTED); | 1081 ERR_ABORTED); |
| 1082 } else if (is_queued()) { | 1082 } else if (is_queued()) { |
| 1083 // |resolver_| was destroyed without running this Job. | 1083 // |resolver_| was destroyed without running this Job. |
| 1084 // TODO(szym): is there any benefit in having this distinction? | 1084 // TODO(szym): is there any benefit in having this distinction? |
| 1085 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); | 1085 net_log_.AddEvent(NetLog::TYPE_CANCELLED); |
| 1086 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, NULL); | 1086 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB); |
| 1087 } | 1087 } |
| 1088 // else CompleteRequests logged EndEvent. | 1088 // else CompleteRequests logged EndEvent. |
| 1089 | 1089 |
| 1090 // Log any remaining Requests as cancelled. | 1090 // Log any remaining Requests as cancelled. |
| 1091 for (RequestsList::const_iterator it = requests_.begin(); | 1091 for (RequestsList::const_iterator it = requests_.begin(); |
| 1092 it != requests_.end(); ++it) { | 1092 it != requests_.end(); ++it) { |
| 1093 Request* req = *it; | 1093 Request* req = *it; |
| 1094 if (req->was_canceled()) | 1094 if (req->was_canceled()) |
| 1095 continue; | 1095 continue; |
| 1096 DCHECK_EQ(this, req->job()); | 1096 DCHECK_EQ(this, req->job()); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 CompleteRequests(ERR_ABORTED, AddressList(), base::TimeDelta()); | 1169 CompleteRequests(ERR_ABORTED, AddressList(), base::TimeDelta()); |
| 1170 } | 1170 } |
| 1171 | 1171 |
| 1172 // Called by HostResolverImpl when this job is evicted due to queue overflow. | 1172 // Called by HostResolverImpl when this job is evicted due to queue overflow. |
| 1173 // Completes all requests and destroys the job. | 1173 // Completes all requests and destroys the job. |
| 1174 void OnEvicted() { | 1174 void OnEvicted() { |
| 1175 DCHECK(!is_running()); | 1175 DCHECK(!is_running()); |
| 1176 DCHECK(is_queued()); | 1176 DCHECK(is_queued()); |
| 1177 handle_.Reset(); | 1177 handle_.Reset(); |
| 1178 | 1178 |
| 1179 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_EVICTED, NULL); | 1179 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_EVICTED); |
| 1180 | 1180 |
| 1181 // This signals to CompleteRequests that this job never ran. | 1181 // This signals to CompleteRequests that this job never ran. |
| 1182 CompleteRequests(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, | 1182 CompleteRequests(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, |
| 1183 AddressList(), | 1183 AddressList(), |
| 1184 base::TimeDelta()); | 1184 base::TimeDelta()); |
| 1185 } | 1185 } |
| 1186 | 1186 |
| 1187 // Attempts to serve the job from HOSTS. Returns true if succeeded and | 1187 // Attempts to serve the job from HOSTS. Returns true if succeeded and |
| 1188 // this Job was destroyed. | 1188 // this Job was destroyed. |
| 1189 bool ServeFromHosts() { | 1189 bool ServeFromHosts() { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1210 bool is_running() const { | 1210 bool is_running() const { |
| 1211 return is_dns_running() || is_proc_running(); | 1211 return is_dns_running() || is_proc_running(); |
| 1212 } | 1212 } |
| 1213 | 1213 |
| 1214 private: | 1214 private: |
| 1215 // PriorityDispatch::Job: | 1215 // PriorityDispatch::Job: |
| 1216 virtual void Start() OVERRIDE { | 1216 virtual void Start() OVERRIDE { |
| 1217 DCHECK(!is_running()); | 1217 DCHECK(!is_running()); |
| 1218 handle_.Reset(); | 1218 handle_.Reset(); |
| 1219 | 1219 |
| 1220 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_STARTED, NULL); | 1220 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_STARTED); |
| 1221 | 1221 |
| 1222 had_dns_config_ = resolver_->HaveDnsConfig(); | 1222 had_dns_config_ = resolver_->HaveDnsConfig(); |
| 1223 // Job::Start must not complete synchronously. | 1223 // Job::Start must not complete synchronously. |
| 1224 if (had_dns_config_) { | 1224 if (had_dns_config_) { |
| 1225 StartDnsTask(); | 1225 StartDnsTask(); |
| 1226 } else { | 1226 } else { |
| 1227 StartProcTask(); | 1227 StartProcTask(); |
| 1228 } | 1228 } |
| 1229 } | 1229 } |
| 1230 | 1230 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1333 dns_task_.reset(); | 1333 dns_task_.reset(); |
| 1334 | 1334 |
| 1335 // Signal dispatcher that a slot has opened. | 1335 // Signal dispatcher that a slot has opened. |
| 1336 resolver_->dispatcher_.OnJobFinished(); | 1336 resolver_->dispatcher_.OnJobFinished(); |
| 1337 } else if (is_queued()) { | 1337 } else if (is_queued()) { |
| 1338 resolver_->dispatcher_.Cancel(handle_); | 1338 resolver_->dispatcher_.Cancel(handle_); |
| 1339 handle_.Reset(); | 1339 handle_.Reset(); |
| 1340 } | 1340 } |
| 1341 | 1341 |
| 1342 if (num_active_requests() == 0) { | 1342 if (num_active_requests() == 0) { |
| 1343 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); | 1343 net_log_.AddEvent(NetLog::TYPE_CANCELLED); |
| 1344 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, | 1344 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
| 1345 OK); | 1345 OK); |
| 1346 return; | 1346 return; |
| 1347 } | 1347 } |
| 1348 | 1348 |
| 1349 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, | 1349 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
| 1350 net_error); | 1350 net_error); |
| 1351 | 1351 |
| 1352 DCHECK(!requests_.empty()); | 1352 DCHECK(!requests_.empty()); |
| 1353 | 1353 |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1580 // The result of |getaddrinfo| for empty hosts is inconsistent across systems. | 1580 // The result of |getaddrinfo| for empty hosts is inconsistent across systems. |
| 1581 // On Windows it gives the default interface's address, whereas on Linux it | 1581 // On Windows it gives the default interface's address, whereas on Linux it |
| 1582 // gives an error. We will make it fail on all platforms for consistency. | 1582 // gives an error. We will make it fail on all platforms for consistency. |
| 1583 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) | 1583 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) |
| 1584 return ERR_NAME_NOT_RESOLVED; | 1584 return ERR_NAME_NOT_RESOLVED; |
| 1585 | 1585 |
| 1586 int net_error = ERR_UNEXPECTED; | 1586 int net_error = ERR_UNEXPECTED; |
| 1587 if (ResolveAsIP(key, info, &net_error, addresses)) | 1587 if (ResolveAsIP(key, info, &net_error, addresses)) |
| 1588 return net_error; | 1588 return net_error; |
| 1589 if (ServeFromCache(key, info, &net_error, addresses)) { | 1589 if (ServeFromCache(key, info, &net_error, addresses)) { |
| 1590 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); | 1590 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT); |
| 1591 return net_error; | 1591 return net_error; |
| 1592 } | 1592 } |
| 1593 // TODO(szym): Do not do this if nsswitch.conf instructs not to. | 1593 // TODO(szym): Do not do this if nsswitch.conf instructs not to. |
| 1594 // http://crbug.com/117655 | 1594 // http://crbug.com/117655 |
| 1595 if (ServeFromHosts(key, info, addresses)) { | 1595 if (ServeFromHosts(key, info, addresses)) { |
| 1596 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT, NULL); | 1596 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT); |
| 1597 return OK; | 1597 return OK; |
| 1598 } | 1598 } |
| 1599 return ERR_DNS_CACHE_MISS; | 1599 return ERR_DNS_CACHE_MISS; |
| 1600 } | 1600 } |
| 1601 | 1601 |
| 1602 int HostResolverImpl::ResolveFromCache(const RequestInfo& info, | 1602 int HostResolverImpl::ResolveFromCache(const RequestInfo& info, |
| 1603 AddressList* addresses, | 1603 AddressList* addresses, |
| 1604 const BoundNetLog& source_net_log) { | 1604 const BoundNetLog& source_net_log) { |
| 1605 DCHECK(CalledOnValidThread()); | 1605 DCHECK(CalledOnValidThread()); |
| 1606 DCHECK(addresses); | 1606 DCHECK(addresses); |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1902 if (self) | 1902 if (self) |
| 1903 TryServingAllJobsFromHosts(); | 1903 TryServingAllJobsFromHosts(); |
| 1904 } | 1904 } |
| 1905 } | 1905 } |
| 1906 | 1906 |
| 1907 bool HostResolverImpl::HaveDnsConfig() const { | 1907 bool HostResolverImpl::HaveDnsConfig() const { |
| 1908 return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL); | 1908 return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL); |
| 1909 } | 1909 } |
| 1910 | 1910 |
| 1911 } // namespace net | 1911 } // namespace net |
| OLD | NEW |