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

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

Issue 9369045: [net] HostResolverImpl + DnsTransaction + DnsConfigService = Asynchronous DNS ready for experiments. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Ready for test-drive. Created 8 years, 10 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
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>
11 #endif 11 #endif
12 12
13 #include <cmath> 13 #include <cmath>
14 #include <utility> 14 #include <utility>
15 #include <vector> 15 #include <vector>
16 16
17 #include "base/basictypes.h" 17 #include "base/basictypes.h"
18 #include "base/bind.h" 18 #include "base/bind.h"
19 #include "base/bind_helpers.h" 19 #include "base/bind_helpers.h"
20 #include "base/callback.h" 20 #include "base/callback.h"
21 #include "base/compiler_specific.h" 21 #include "base/compiler_specific.h"
22 #include "base/debug/debugger.h" 22 #include "base/debug/debugger.h"
23 #include "base/debug/stack_trace.h" 23 #include "base/debug/stack_trace.h"
24 #include "base/message_loop_proxy.h" 24 #include "base/message_loop_proxy.h"
25 #include "base/metrics/field_trial.h" 25 #include "base/metrics/field_trial.h"
26 #include "base/metrics/histogram.h" 26 #include "base/metrics/histogram.h"
27 #include "base/rand_util.h"
27 #include "base/stl_util.h" 28 #include "base/stl_util.h"
28 #include "base/string_util.h" 29 #include "base/string_util.h"
29 #include "base/threading/worker_pool.h" 30 #include "base/threading/worker_pool.h"
30 #include "base/time.h" 31 #include "base/time.h"
31 #include "base/utf_string_conversions.h" 32 #include "base/utf_string_conversions.h"
32 #include "base/values.h" 33 #include "base/values.h"
34 #include "net/base/address_family.h"
33 #include "net/base/address_list.h" 35 #include "net/base/address_list.h"
34 #include "net/base/address_list_net_log_param.h" 36 #include "net/base/address_list_net_log_param.h"
35 #include "net/base/dns_reloader.h" 37 #include "net/base/dns_reloader.h"
36 #include "net/base/host_port_pair.h" 38 #include "net/base/host_port_pair.h"
37 #include "net/base/host_resolver_proc.h" 39 #include "net/base/host_resolver_proc.h"
38 #include "net/base/net_errors.h" 40 #include "net/base/net_errors.h"
39 #include "net/base/net_log.h" 41 #include "net/base/net_log.h"
40 #include "net/base/net_util.h" 42 #include "net/base/net_util.h"
43 #include "net/dns/dns_config_service.h"
44 #include "net/dns/dns_protocol.h"
45 #include "net/dns/dns_response.h"
46 #include "net/dns/dns_session.h"
47 #include "net/dns/dns_transaction.h"
48 #include "net/socket/client_socket_factory.h"
41 49
42 #if defined(OS_WIN) 50 #if defined(OS_WIN)
43 #include "net/base/winsock_init.h" 51 #include "net/base/winsock_init.h"
44 #endif 52 #endif
45 53
46 namespace net { 54 namespace net {
47 55
48 namespace { 56 namespace {
49 57
50 // Limit the size of hostnames that will be resolved to combat issues in 58 // Limit the size of hostnames that will be resolved to combat issues in
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 request_net_log.AddEvent(NetLog::TYPE_CANCELLED, NULL); 316 request_net_log.AddEvent(NetLog::TYPE_CANCELLED, NULL);
309 request_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, NULL); 317 request_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, NULL);
310 source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL); 318 source_net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL, NULL);
311 } 319 }
312 320
313 //----------------------------------------------------------------------------- 321 //-----------------------------------------------------------------------------
314 322
315 // Keeps track of the highest priority. 323 // Keeps track of the highest priority.
316 class PriorityTracker { 324 class PriorityTracker {
317 public: 325 public:
318 PriorityTracker() 326 PriorityTracker(RequestPriority priority)
319 : highest_priority_(IDLE), total_count_(0) { 327 : highest_priority_(priority), total_count_(0) {
320 memset(counts_, 0, sizeof(counts_)); 328 memset(counts_, 0, sizeof(counts_));
321 } 329 }
322 330
323 RequestPriority highest_priority() const { 331 RequestPriority highest_priority() const {
324 return highest_priority_; 332 return highest_priority_;
325 } 333 }
326 334
327 size_t total_count() const { 335 size_t total_count() const {
328 return total_count_; 336 return total_count_;
329 } 337 }
(...skipping 22 matching lines...) Expand all
352 } 360 }
353 361
354 private: 362 private:
355 RequestPriority highest_priority_; 363 RequestPriority highest_priority_;
356 size_t total_count_; 364 size_t total_count_;
357 size_t counts_[NUM_PRIORITIES]; 365 size_t counts_[NUM_PRIORITIES];
358 }; 366 };
359 367
360 //----------------------------------------------------------------------------- 368 //-----------------------------------------------------------------------------
361 369
370 // Convenience wrapper for PrioritizedDispatcher::Handle so that we don't forget
371 // to update it when cancelling or changing the priority.
372 // TODO(szym): consider making PrioritizedDispatcher::Handle into this.
373 class DispatcherHandle {
374 public:
375 DispatcherHandle() : dispatcher_(NULL) {}
376 DispatcherHandle(PrioritizedDispatcher* dispatcher,
377 const PrioritizedDispatcher::Handle& handle)
378 : dispatcher_(dispatcher), handle_(handle) {
379 if (handle_.is_null())
380 dispatcher_ = NULL;
381 }
382
383 bool is_null() const {
384 return dispatcher_ == NULL;
385 }
386
387 void Reset() {
388 dispatcher_ = NULL;
389 handle_ = PrioritizedDispatcher::Handle();
390 }
391
392 void ChangePriority(RequestPriority priority) {
393 DCHECK(!is_null());
394 handle_ = dispatcher_->ChangePriority(handle_, priority);
395 }
396
397 void Cancel() {
398 DCHECK(!is_null());
399 dispatcher_->Cancel(handle_);
400 Reset();
401 }
402
403 private:
404 PrioritizedDispatcher* dispatcher_;
405 PrioritizedDispatcher::Handle handle_;
406 };
407
408 //-----------------------------------------------------------------------------
409
362 HostResolver* CreateHostResolver(size_t max_concurrent_resolves, 410 HostResolver* CreateHostResolver(size_t max_concurrent_resolves,
363 size_t max_retry_attempts, 411 size_t max_retry_attempts,
364 bool use_cache, 412 bool use_cache,
413 bool use_async,
365 NetLog* net_log) { 414 NetLog* net_log) {
366 if (max_concurrent_resolves == HostResolver::kDefaultParallelism) 415 if (max_concurrent_resolves == HostResolver::kDefaultParallelism)
367 max_concurrent_resolves = kDefaultMaxProcTasks; 416 max_concurrent_resolves = kDefaultMaxProcTasks;
368 417
369 // TODO(szym): Add experiments with reserved slots for higher priority 418 // TODO(szym): Add experiments with reserved slots for higher priority
370 // requests. 419 // requests.
420 // TODO(szym): Add tighter limits for proc_dispatcher_
371 421
372 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, max_concurrent_resolves); 422 PrioritizedDispatcher::Limits limits(NUM_PRIORITIES, max_concurrent_resolves);
373 423
424 scoped_ptr<DnsConfigService> config_service;
425 if (use_async) {
426 config_service = DnsConfigService::CreateSystemService();
427 config_service->Watch();
428 }
429
374 HostResolverImpl* resolver = new HostResolverImpl( 430 HostResolverImpl* resolver = new HostResolverImpl(
375 use_cache ? HostCache::CreateDefaultCache() : NULL, 431 use_cache ? HostCache::CreateDefaultCache() : NULL,
376 limits, 432 limits,
433 limits,
377 HostResolverImpl::ProcTaskParams(NULL, max_retry_attempts), 434 HostResolverImpl::ProcTaskParams(NULL, max_retry_attempts),
435 config_service.Pass(),
378 net_log); 436 net_log);
379 437
380 return resolver; 438 return resolver;
381 } 439 }
382 440
383 } // anonymous namespace 441 } // anonymous namespace
384 442
385 //----------------------------------------------------------------------------- 443 //-----------------------------------------------------------------------------
386 444
387 HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves, 445 HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves,
388 size_t max_retry_attempts, 446 size_t max_retry_attempts,
389 NetLog* net_log) { 447 NetLog* net_log) {
390 return CreateHostResolver(max_concurrent_resolves, 448 return CreateHostResolver(max_concurrent_resolves,
391 max_retry_attempts, 449 max_retry_attempts,
392 true /* use_cache */, 450 true /* use_cache */,
451 false /* use_async */,
393 net_log); 452 net_log);
394 } 453 }
395 454
396 HostResolver* CreateNonCachingSystemHostResolver(size_t max_concurrent_resolves, 455 HostResolver* CreateNonCachingSystemHostResolver(size_t max_concurrent_resolves,
397 size_t max_retry_attempts, 456 size_t max_retry_attempts,
398 NetLog* net_log) { 457 NetLog* net_log) {
399 return CreateHostResolver(max_concurrent_resolves, 458 return CreateHostResolver(max_concurrent_resolves,
400 max_retry_attempts, 459 max_retry_attempts,
401 false /* use_cache */, 460 false /* use_cache */,
461 false /* use_async */,
402 net_log); 462 net_log);
403 } 463 }
404 464
465 HostResolver* CreateAsyncHostResolver(size_t max_concurrent_resolves,
466 size_t max_retry_attempts,
467 NetLog* net_log) {
468 return CreateHostResolver(max_concurrent_resolves,
469 max_retry_attempts,
470 true /* use_cache */,
cbentzel 2012/02/10 19:51:08 I don't like these comments - would rather have a
szym 2012/02/10 21:49:36 Not a fan of bit flag or enum in this case. If we
471 true /* use_async */,
472 net_log);
473 }
474
405 //----------------------------------------------------------------------------- 475 //-----------------------------------------------------------------------------
406 476
407 // Holds the data for a request that could not be completed synchronously. 477 // Holds the data for a request that could not be completed synchronously.
408 // It is owned by a Job. Canceled Requests are only marked as canceled rather 478 // It is owned by a Job. Canceled Requests are only marked as canceled rather
409 // than removed from the Job's |requests_| list. 479 // than removed from the Job's |requests_| list.
410 class HostResolverImpl::Request { 480 class HostResolverImpl::Request {
411 public: 481 public:
412 Request(const BoundNetLog& source_net_log, 482 Request(const BoundNetLog& source_net_log,
413 const BoundNetLog& request_net_log, 483 const BoundNetLog& request_net_log,
414 const RequestInfo& info, 484 const RequestInfo& info,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 // resolution (OnLookupComplete) is completed or not. If the original attempt 568 // resolution (OnLookupComplete) is completed or not. If the original attempt
499 // hasn't completed, then we start another attempt for host resolution. We take 569 // hasn't completed, then we start another attempt for host resolution. We take
500 // the results from the first attempt that finishes and ignore the results from 570 // the results from the first attempt that finishes and ignore the results from
501 // all other attempts. 571 // all other attempts.
502 // 572 //
503 // TODO(szym): Move to separate source file for testing and mocking. 573 // TODO(szym): Move to separate source file for testing and mocking.
504 // 574 //
505 class HostResolverImpl::ProcTask 575 class HostResolverImpl::ProcTask
506 : public base::RefCountedThreadSafe<HostResolverImpl::ProcTask> { 576 : public base::RefCountedThreadSafe<HostResolverImpl::ProcTask> {
507 public: 577 public:
508 typedef base::Callback<void(int, int, const AddressList&)> Callback; 578 typedef base::Callback<void(int net_error,
579 int os_error,
580 const AddressList& addr_list)> Callback;
509 581
510 ProcTask(const Key& key, 582 ProcTask(const Key& key,
511 const ProcTaskParams& params, 583 const ProcTaskParams& params,
512 const Callback& callback, 584 const Callback& callback,
513 const BoundNetLog& job_net_log) 585 const BoundNetLog& job_net_log)
514 : key_(key), 586 : key_(key),
515 params_(params), 587 params_(params),
516 callback_(callback), 588 callback_(callback),
517 origin_loop_(base::MessageLoopProxy::current()), 589 origin_loop_(base::MessageLoopProxy::current()),
518 attempt_number_(0), 590 attempt_number_(0),
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 AddressList results_; 956 AddressList results_;
885 957
886 BoundNetLog net_log_; 958 BoundNetLog net_log_;
887 959
888 DISALLOW_COPY_AND_ASSIGN(ProcTask); 960 DISALLOW_COPY_AND_ASSIGN(ProcTask);
889 }; 961 };
890 962
891 //----------------------------------------------------------------------------- 963 //-----------------------------------------------------------------------------
892 964
893 // Represents a request to the worker pool for a "probe for IPv6 support" call. 965 // Represents a request to the worker pool for a "probe for IPv6 support" call.
966 //
967 // TODO(szym): This could also be replaced with PostTaskAndReply and Callbacks.
894 class HostResolverImpl::IPv6ProbeJob 968 class HostResolverImpl::IPv6ProbeJob
895 : public base::RefCountedThreadSafe<HostResolverImpl::IPv6ProbeJob> { 969 : public base::RefCountedThreadSafe<HostResolverImpl::IPv6ProbeJob> {
896 public: 970 public:
897 explicit IPv6ProbeJob(HostResolverImpl* resolver) 971 explicit IPv6ProbeJob(HostResolverImpl* resolver)
898 : resolver_(resolver), 972 : resolver_(resolver),
899 origin_loop_(base::MessageLoopProxy::current()) { 973 origin_loop_(base::MessageLoopProxy::current()) {
900 DCHECK(resolver); 974 DCHECK(resolver);
901 } 975 }
902 976
903 void Start() { 977 void Start() {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 HostResolverImpl* resolver_; 1025 HostResolverImpl* resolver_;
952 1026
953 // Used to post ourselves onto the origin thread. 1027 // Used to post ourselves onto the origin thread.
954 scoped_refptr<base::MessageLoopProxy> origin_loop_; 1028 scoped_refptr<base::MessageLoopProxy> origin_loop_;
955 1029
956 DISALLOW_COPY_AND_ASSIGN(IPv6ProbeJob); 1030 DISALLOW_COPY_AND_ASSIGN(IPv6ProbeJob);
957 }; 1031 };
958 1032
959 //----------------------------------------------------------------------------- 1033 //-----------------------------------------------------------------------------
960 1034
1035 // Resolves the hostname using DnsTransaction.
1036 // TODO(szym): This could be moved to separate source file as well.
1037 class HostResolverImpl::DnsTask {
1038 public:
1039 typedef base::Callback<void(int net_error,
1040 const AddressList& addr_list,
1041 base::TimeDelta ttl)> Callback;
1042
1043 DnsTask(DnsTransactionFactory* factory,
1044 const Key& key,
1045 const Callback& callback,
1046 const BoundNetLog& source_net_log) : callback_(callback) {
1047 DCHECK(factory);
1048 DCHECK(!callback.is_null());
1049
1050 // For now we treat ADDRESS_FAMILY_UNSPEC as if it was IPV4.
1051 uint16 qtype = (key.address_family == ADDRESS_FAMILY_IPV6)
1052 ? dns_protocol::kTypeAAAA
1053 : dns_protocol::kTypeA;
1054 // TODO(szym): Implement "happy eyeballs".
1055 transaction_ = factory->CreateTransaction(
1056 key.hostname,
1057 qtype,
1058 base::Bind(&DnsTask::OnTransactionComplete, base::Unretained(this)),
1059 source_net_log);
1060 DCHECK(transaction_.get());
1061 }
1062
1063 int Start() {
1064 return transaction_->Start();
1065 }
1066
1067 void OnTransactionComplete(DnsTransaction* transaction,
1068 int net_error,
1069 const DnsResponse* response) {
1070 // TODO(szym): Record performance histograms.
1071 if (net_error == OK) {
1072 AddressList addr_list;
1073 base::TimeDelta ttl;
1074 if (DnsResponseToAddressList(response, &addr_list, &ttl)) {
1075 callback_.Run(net_error, addr_list, ttl);
1076 return;
1077 }
1078 net_error = ERR_DNS_MALFORMED_RESPONSE;
1079 }
1080 callback_.Run(net_error, AddressList(), base::TimeDelta());
1081 }
1082
1083 private:
1084 // The listener to the results of this DnsTask.
1085 Callback callback_;
1086
1087 scoped_ptr<DnsTransaction> transaction_;
1088 };
1089
1090 //-----------------------------------------------------------------------------
1091
961 // Aggregates all Requests for the same Key. Dispatched via PriorityDispatch. 1092 // Aggregates all Requests for the same Key. Dispatched via PriorityDispatch.
962 // Spawns ProcTask when started. 1093 // Spawns ProcTask when started.
963 class HostResolverImpl::Job : public PrioritizedDispatcher::Job { 1094 class HostResolverImpl::Job : public PrioritizedDispatcher::Job {
964 public: 1095 public:
965 // Creates new job for |key| where |request_net_log| is bound to the 1096 // Creates new job for |key| where |request_net_log| is bound to the
966 // request that spawned it. 1097 // request that spawned it.
967 Job(HostResolverImpl* resolver, 1098 Job(HostResolverImpl* resolver,
968 const Key& key, 1099 const Key& key,
969 const BoundNetLog& request_net_log) 1100 const BoundNetLog& request_net_log,
1101 RequestPriority priority)
970 : resolver_(resolver->AsWeakPtr()), 1102 : resolver_(resolver->AsWeakPtr()),
971 key_(key), 1103 key_(key),
1104 priority_tracker_(priority),
972 had_non_speculative_request_(false), 1105 had_non_speculative_request_(false),
973 net_log_(BoundNetLog::Make(request_net_log.net_log(), 1106 net_log_(BoundNetLog::Make(request_net_log.net_log(),
974 NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)), 1107 NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)),
975 net_error_(ERR_IO_PENDING), 1108 net_error_(ERR_IO_PENDING),
976 os_error_(0) { 1109 os_error_(0) {
977 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB, NULL); 1110 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB, NULL);
978 1111
979 net_log_.BeginEvent( 1112 net_log_.BeginEvent(
980 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, 1113 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB,
981 make_scoped_refptr(new JobCreationParameters( 1114 make_scoped_refptr(new JobCreationParameters(
(...skipping 20 matching lines...) Expand all
1002 DCHECK_EQ(this, req->job()); 1135 DCHECK_EQ(this, req->job());
1003 LogCancelRequest(req->source_net_log(), req->request_net_log(), 1136 LogCancelRequest(req->source_net_log(), req->request_net_log(),
1004 req->info()); 1137 req->info());
1005 } 1138 }
1006 } 1139 }
1007 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, 1140 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB,
1008 net_error_); 1141 net_error_);
1009 STLDeleteElements(&requests_); 1142 STLDeleteElements(&requests_);
1010 } 1143 }
1011 1144
1012 HostResolverImpl* resolver() const {
1013 return resolver_;
1014 }
1015
1016 RequestPriority priority() const { 1145 RequestPriority priority() const {
1017 return priority_tracker_.highest_priority(); 1146 return priority_tracker_.highest_priority();
1018 } 1147 }
1019 1148
1020 // Number of non-canceled requests in |requests_|. 1149 // Number of non-canceled requests in |requests_|.
1021 size_t num_active_requests() const { 1150 size_t num_active_requests() const {
1022 return priority_tracker_.total_count(); 1151 return priority_tracker_.total_count();
1023 } 1152 }
1024 1153
1025 const Key& key() const { 1154 const Key& key() const {
1026 return key_; 1155 return key_;
1027 } 1156 }
1028 1157
1029 int net_error() const { 1158 int net_error() const {
1030 return net_error_; 1159 return net_error_;
1031 } 1160 }
1032 1161
1033 // Used by HostResolverImpl with |dispatcher_|. 1162 void AddToDispatcher(PrioritizedDispatcher* dispatcher) {
1034 const PrioritizedDispatcher::Handle& handle() const { 1163 DCHECK(handle_.is_null());
1035 return handle_; 1164 handle_ = DispatcherHandle(dispatcher, dispatcher->Add(this, priority()));
1036 } 1165 }
1037 1166
1038 void set_handle(const PrioritizedDispatcher::Handle& handle) { 1167 bool IsWaitingInDispatch() const {
1039 handle_ = handle; 1168 return !handle_.is_null();
1040 } 1169 }
1041 1170
1042 // The Job will own |req| and destroy it in ~Job. 1171 // The Job will own |req| and destroy it in ~Job.
1043 void AddRequest(Request* req) { 1172 void AddRequest(Request* req) {
1044 DCHECK_EQ(key_.hostname, req->info().hostname()); 1173 DCHECK_EQ(key_.hostname, req->info().hostname());
1045 1174
1046 req->set_job(this); 1175 req->set_job(this);
1047 requests_.push_back(req); 1176 requests_.push_back(req);
1048 1177
1049 priority_tracker_.Add(req->info().priority()); 1178 priority_tracker_.Add(req->info().priority());
1050 1179
1051 req->request_net_log().AddEvent( 1180 req->request_net_log().AddEvent(
1052 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH, 1181 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_ATTACH,
1053 make_scoped_refptr(new NetLogSourceParameter( 1182 make_scoped_refptr(new NetLogSourceParameter(
1054 "source_dependency", net_log_.source()))); 1183 "source_dependency", net_log_.source())));
1055 1184
1056 net_log_.AddEvent( 1185 net_log_.AddEvent(
1057 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_ATTACH, 1186 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_ATTACH,
1058 make_scoped_refptr(new JobAttachParameters( 1187 make_scoped_refptr(new JobAttachParameters(
1059 req->request_net_log().source(), priority()))); 1188 req->request_net_log().source(), priority())));
1060 1189
1061 // TODO(szym): Check if this is still needed. 1190 // TODO(szym): Check if this is still needed.
1062 if (!req->info().is_speculative()) { 1191 if (!req->info().is_speculative()) {
1063 had_non_speculative_request_ = true; 1192 had_non_speculative_request_ = true;
1064 if (proc_task_) 1193 if (proc_task_)
1065 proc_task_->set_had_non_speculative_request(); 1194 proc_task_->set_had_non_speculative_request();
1066 } 1195 }
1196
1197 if (!handle_.is_null())
1198 handle_.ChangePriority(priority());
1067 } 1199 }
1068 1200
1069 void CancelRequest(Request* req) { 1201 void CancelRequest(Request* req) {
1070 DCHECK_EQ(key_.hostname, req->info().hostname()); 1202 DCHECK_EQ(key_.hostname, req->info().hostname());
1071 DCHECK(!req->was_canceled()); 1203 DCHECK(!req->was_canceled());
1072 // Don't remove it from |requests_| just mark it canceled. 1204 // Don't remove it from |requests_| just mark it canceled.
1073 req->MarkAsCanceled(); 1205 req->MarkAsCanceled();
1074 LogCancelRequest(req->source_net_log(), req->request_net_log(), 1206 LogCancelRequest(req->source_net_log(), req->request_net_log(),
1075 req->info()); 1207 req->info());
1076 priority_tracker_.Remove(req->info().priority()); 1208 priority_tracker_.Remove(req->info().priority());
1077 net_log_.AddEvent( 1209 net_log_.AddEvent(
1078 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_DETACH, 1210 NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_REQUEST_DETACH,
1079 make_scoped_refptr(new JobAttachParameters( 1211 make_scoped_refptr(new JobAttachParameters(
1080 req->request_net_log().source(), priority()))); 1212 req->request_net_log().source(), priority())));
1213
1214 if (!handle_.is_null()) {
1215 if (num_active_requests() > 0) {
1216 handle_.ChangePriority(priority());
1217 } else {
1218 handle_.Cancel();
1219 }
1220 }
1081 } 1221 }
1082 1222
1083 // Aborts and destroys the job, completes all requests as aborted. 1223 // Aborts and destroys the job, completes all requests as aborted.
1084 void Abort() { 1224 void Abort() {
1085 // Job should only be aborted if it's running. 1225 // Job should only be aborted if it's running.
1086 DCHECK(is_running()); 1226 DCHECK(is_running());
1087 proc_task_->Cancel(); 1227 if (proc_task_.get()) {
1088 proc_task_ = NULL; 1228 proc_task_->Cancel();
1229 proc_task_ = NULL;
1230 }
1231 dns_task_.reset();
1089 net_error_ = ERR_ABORTED; 1232 net_error_ = ERR_ABORTED;
1090 os_error_ = 0; 1233 os_error_ = 0;
1091 CompleteRequests(AddressList()); 1234 CompleteRequests(AddressList(), base::TimeDelta());
1235 }
1236
1237 bool is_dns_running() const {
1238 return dns_task_.get() != NULL;
1239 }
1240
1241 bool is_proc_running() const {
1242 return proc_task_.get() != NULL;
1092 } 1243 }
1093 1244
1094 bool is_running() const { 1245 bool is_running() const {
1095 return proc_task_.get() != NULL; 1246 return is_dns_running() || is_proc_running();
1096 } 1247 }
1097 1248
1098 // Called by HostResolverImpl when this job is evicted due to queue overflow. 1249 // Called by HostResolverImpl when this job is evicted due to queue overflow.
1099 void OnEvicted() { 1250 void OnEvicted() {
1100 // Must not be running. 1251 // Must not be running.
1101 DCHECK(!is_running()); 1252 DCHECK(!is_running());
1102 handle_ = PrioritizedDispatcher::Handle(); 1253 handle_.Reset();
1103 1254
1104 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_EVICTED, NULL); 1255 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_EVICTED, NULL);
1105 1256
1106 // This signals to CompleteRequests that this job never ran. 1257 // This signals to CompleteRequests that this job never ran.
1107 net_error_ = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; 1258 net_error_ = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE;
1108 os_error_ = 0; 1259 os_error_ = 0;
1109 CompleteRequests(AddressList()); 1260 CompleteRequests(AddressList(), base::TimeDelta());
1110 } 1261 }
1111 1262
1112 // PriorityDispatch::Job interface. 1263 // PriorityDispatch::Job interface.
1113 virtual void Start() OVERRIDE { 1264 virtual void Start() OVERRIDE {
1114 DCHECK(!is_running()); 1265 DCHECK(!is_running());
1115 handle_ = PrioritizedDispatcher::Handle(); 1266 handle_.Reset();
1116 1267
1117 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_STARTED, NULL); 1268 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_STARTED, NULL);
1118 1269
1270 if (resolver_->dns_transaction_factory_.get()) {
1271 StartDnsTask();
1272 } else {
1273 StartProcTask();
1274 }
1275 }
1276
1277 private:
1278 void StartProcTask() {
1119 proc_task_ = new ProcTask( 1279 proc_task_ = new ProcTask(
1120 key_, 1280 key_,
1121 resolver_->proc_params_, 1281 resolver_->proc_params_,
1122 base::Bind(&Job::OnProcTaskComplete, base::Unretained(this)), 1282 base::Bind(&Job::OnProcTaskComplete, base::Unretained(this)),
1123 net_log_); 1283 net_log_);
1124 1284
1125 if (had_non_speculative_request_) 1285 if (had_non_speculative_request_)
1126 proc_task_->set_had_non_speculative_request(); 1286 proc_task_->set_had_non_speculative_request();
1127 // Start() could be called from within Resolve(), hence it must NOT directly 1287 // Start() could be called from within Resolve(), hence it must NOT directly
1128 // call OnProcTaskComplete, for example, on synchronous failure. 1288 // call OnProcTaskComplete, for example, on synchronous failure.
1129 proc_task_->Start(); 1289 proc_task_->Start();
1130 } 1290 }
1131 1291
1132 private: 1292 void StartDnsTask() {
1293 dns_task_.reset(new DnsTask(
1294 resolver_->dns_transaction_factory_.get(),
1295 key_,
1296 base::Bind(&Job::OnDnsTaskComplete, base::Unretained(this)),
1297 net_log_));
1298
1299 int rv = dns_task_->Start();
1300 if (rv != ERR_IO_PENDING) {
1301 DCHECK_NE(OK, rv);
1302 // TODO(szym): AddToDispatcher(resolver_->proc_dispatcher_);
1303 StartProcTask();
1304 }
1305 }
1306
1133 // Called by ProcTask when it completes. 1307 // Called by ProcTask when it completes.
1134 void OnProcTaskComplete(int net_error, int os_error, 1308 void OnProcTaskComplete(int net_error, int os_error,
1135 const AddressList& addrlist) { 1309 const AddressList& addr_list) {
1136 DCHECK(is_running()); 1310 DCHECK(is_proc_running());
1137 proc_task_ = NULL; 1311 proc_task_ = NULL;
1138 net_error_ = net_error; 1312 net_error_ = net_error;
1139 os_error_ = os_error; 1313 os_error_ = os_error;
1140 1314
1141 // We are the only consumer of |addrlist|, so we can safely change the port 1315 base::TimeDelta ttl = base::TimeDelta::FromSeconds(0);
1142 // without copy-on-write. This pays off, when job has only one request. 1316 if (net_error == OK)
1143 AddressList list = addrlist; 1317 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds);
1144 if (net_error == OK && !requests_.empty()) 1318 CompleteRequests(addr_list, ttl);
1145 MutableSetPort(requests_.front()->info().port(), &list); 1319 }
1146 CompleteRequests(list); 1320
1321 // Called by DnsTask when it completes.
1322 void OnDnsTaskComplete(int net_error,
1323 const AddressList& addr_list,
1324 base::TimeDelta ttl) {
1325 DCHECK(is_dns_running());
1326 dns_task_.reset();
1327
1328 if (net_error != OK) {
1329 // TODO(szym): Some net errors indicate lack of connectivity. Starting
1330 // ProcTask in that case is a waste of time.
1331 StartProcTask();
1332 return;
1333 }
1334
1335 net_error_ = OK;
1336 os_error_ = 0;
1337 CompleteRequests(addr_list, ttl);
1147 } 1338 }
1148 1339
1149 // Completes all Requests. Calls OnJobFinished and deletes self. 1340 // Completes all Requests. Calls OnJobFinished and deletes self.
1150 void CompleteRequests(const AddressList& addrlist) { 1341 void CompleteRequests(const AddressList& addr_list, base::TimeDelta ttl) {
1151 CHECK(resolver_); 1342 CHECK(resolver_);
1152 1343
1344 // We are the only consumer of |addr_list|, so we can safely change the port
1345 // without copy-on-write. This pays off, when job has only one request.
1346 AddressList list = addr_list;
1347 if (net_error_ == OK && !requests_.empty())
1348 MutableSetPort(requests_.front()->info().port(), &list);
1349
1153 // This job must be removed from resolver's |jobs_| now to make room for a 1350 // This job must be removed from resolver's |jobs_| now to make room for a
1154 // new job with the same key in case one of the OnComplete callbacks decides 1351 // new job with the same key in case one of the OnComplete callbacks decides
1155 // to spawn one. Consequently, the job deletes itself when CompleteRequests 1352 // to spawn one. Consequently, the job deletes itself when CompleteRequests
1156 // is done. 1353 // is done.
1157 scoped_ptr<Job> self_deleter(this); 1354 scoped_ptr<Job> self_deleter(this);
1158 resolver_->OnJobFinished(this, addrlist); 1355 resolver_->OnJobFinished(this, addr_list, ttl);
1159 1356
1160 // Complete all of the requests that were attached to the job. 1357 // Complete all of the requests that were attached to the job.
1161 for (RequestsList::const_iterator it = requests_.begin(); 1358 for (RequestsList::const_iterator it = requests_.begin();
1162 it != requests_.end(); ++it) { 1359 it != requests_.end(); ++it) {
1163 Request* req = *it; 1360 Request* req = *it;
1164 1361
1165 if (req->was_canceled()) 1362 if (req->was_canceled())
1166 continue; 1363 continue;
1167 1364
1168 DCHECK_EQ(this, req->job()); 1365 DCHECK_EQ(this, req->job());
1169 // Update the net log and notify registered observers. 1366 // Update the net log and notify registered observers.
1170 LogFinishRequest(req->source_net_log(), req->request_net_log(), 1367 LogFinishRequest(req->source_net_log(), req->request_net_log(),
1171 req->info(), net_error_, os_error_); 1368 req->info(), net_error_, os_error_);
1172 1369
1173 req->OnComplete(net_error_, addrlist); 1370 req->OnComplete(net_error_, addr_list);
1174 1371
1175 // Check if the resolver was destroyed as a result of running the 1372 // Check if the resolver was destroyed as a result of running the
1176 // callback. If it was, we could continue, but we choose to bail. 1373 // callback. If it was, we could continue, but we choose to bail.
1177 if (!resolver_) 1374 if (!resolver_)
1178 return; 1375 return;
1179 } 1376 }
1180 } 1377 }
1181 1378
1182 // Used to call OnJobFinished and RemoveJob. 1379 // Used to call OnJobFinished.
1183 base::WeakPtr<HostResolverImpl> resolver_; 1380 base::WeakPtr<HostResolverImpl> resolver_;
1184 1381
1185 Key key_; 1382 Key key_;
1186 1383
1187 // Tracks the highest priority across |requests_|. 1384 // Tracks the highest priority across |requests_|.
1188 PriorityTracker priority_tracker_; 1385 PriorityTracker priority_tracker_;
1189 1386
1190 bool had_non_speculative_request_; 1387 bool had_non_speculative_request_;
1191 1388
1192 BoundNetLog net_log_; 1389 BoundNetLog net_log_;
1193 1390
1194 // Store result here in case the job fails fast in Resolve(). 1391 // Store result here in case the job fails fast in Resolve().
1195 int net_error_; 1392 int net_error_;
1196 int os_error_; 1393 int os_error_;
1197 1394
1198 // A ProcTask created and started when this Job is dispatched.. 1395 // Resolves the host using a HostResolverProc.
1199 scoped_refptr<ProcTask> proc_task_; 1396 scoped_refptr<ProcTask> proc_task_;
1200 1397
1398 // Resolves the host using a DnsTransaction.
1399 scoped_ptr<DnsTask> dns_task_;
1400
1201 // All Requests waiting for the result of this Job. Some can be canceled. 1401 // All Requests waiting for the result of this Job. Some can be canceled.
1202 RequestsList requests_; 1402 RequestsList requests_;
1203 1403
1204 // A handle used by HostResolverImpl in |dispatcher_|. 1404 // A handle used by HostResolverImpl in |dispatcher_|.
1205 PrioritizedDispatcher::Handle handle_; 1405 DispatcherHandle handle_;
1206 }; 1406 };
1207 1407
1208 //----------------------------------------------------------------------------- 1408 //-----------------------------------------------------------------------------
1209 1409
1210 HostResolverImpl::ProcTaskParams::ProcTaskParams( 1410 HostResolverImpl::ProcTaskParams::ProcTaskParams(
1211 HostResolverProc* resolver_proc, 1411 HostResolverProc* resolver_proc,
1212 size_t max_retry_attempts) 1412 size_t max_retry_attempts)
1213 : resolver_proc(resolver_proc), 1413 : resolver_proc(resolver_proc),
1214 max_retry_attempts(max_retry_attempts), 1414 max_retry_attempts(max_retry_attempts),
1215 unresponsive_delay(base::TimeDelta::FromMilliseconds(6000)), 1415 unresponsive_delay(base::TimeDelta::FromMilliseconds(6000)),
1216 retry_factor(2) { 1416 retry_factor(2) {
1217 } 1417 }
1218 1418
1219 HostResolverImpl::ProcTaskParams::~ProcTaskParams() {} 1419 HostResolverImpl::ProcTaskParams::~ProcTaskParams() {}
1220 1420
1221 HostResolverImpl::HostResolverImpl( 1421 HostResolverImpl::HostResolverImpl(
1222 HostCache* cache, 1422 HostCache* cache,
1223 const PrioritizedDispatcher::Limits& job_limits, 1423 const PrioritizedDispatcher::Limits& job_limits,
1424 const PrioritizedDispatcher::Limits& proc_limits,
1224 const ProcTaskParams& proc_params, 1425 const ProcTaskParams& proc_params,
1426 scoped_ptr<DnsConfigService> dns_config_service,
1225 NetLog* net_log) 1427 NetLog* net_log)
1226 : cache_(cache), 1428 : cache_(cache),
1227 dispatcher_(job_limits), 1429 dispatcher_(job_limits),
1430 proc_dispatcher_(proc_limits),
1228 max_queued_jobs_(job_limits.total_jobs * 100u), 1431 max_queued_jobs_(job_limits.total_jobs * 100u),
1229 proc_params_(proc_params), 1432 proc_params_(proc_params),
1230 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), 1433 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED),
1434 dns_config_service_(dns_config_service.Pass()),
1231 ipv6_probe_monitoring_(false), 1435 ipv6_probe_monitoring_(false),
1232 additional_resolver_flags_(0), 1436 additional_resolver_flags_(0),
1233 net_log_(net_log) { 1437 net_log_(net_log) {
1234 1438
1235 DCHECK_GE(dispatcher_.num_priorities(), static_cast<size_t>(NUM_PRIORITIES)); 1439 DCHECK_GE(dispatcher_.num_priorities(), static_cast<size_t>(NUM_PRIORITIES));
1440 DCHECK_EQ(proc_dispatcher_.num_priorities(), dispatcher_.num_priorities());
1236 1441
1237 // Maximum of 4 retry attempts for host resolution. 1442 // Maximum of 4 retry attempts for host resolution.
1238 static const size_t kDefaultMaxRetryAttempts = 4u; 1443 static const size_t kDefaultMaxRetryAttempts = 4u;
1239 1444
1240 if (proc_params_.max_retry_attempts == HostResolver::kDefaultRetryAttempts) 1445 if (proc_params_.max_retry_attempts == HostResolver::kDefaultRetryAttempts)
1241 proc_params_.max_retry_attempts = kDefaultMaxRetryAttempts; 1446 proc_params_.max_retry_attempts = kDefaultMaxRetryAttempts;
1242 1447
1243 #if defined(OS_WIN) 1448 #if defined(OS_WIN)
1244 EnsureWinsockInit(); 1449 EnsureWinsockInit();
1245 #endif 1450 #endif
1246 #if defined(OS_POSIX) && !defined(OS_MACOSX) 1451 #if defined(OS_POSIX) && !defined(OS_MACOSX)
1247 if (HaveOnlyLoopbackAddresses()) 1452 if (HaveOnlyLoopbackAddresses())
1248 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; 1453 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY;
1249 #endif 1454 #endif
1250 NetworkChangeNotifier::AddIPAddressObserver(this); 1455 NetworkChangeNotifier::AddIPAddressObserver(this);
1251 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) 1456 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
1252 #if !defined(OS_ANDROID) 1457 #if !defined(OS_ANDROID)
1253 EnsureDnsReloaderInit(); 1458 EnsureDnsReloaderInit();
1254 #endif 1459 #endif
1255 NetworkChangeNotifier::AddDNSObserver(this); 1460 NetworkChangeNotifier::AddDNSObserver(this);
1256 #endif 1461 #endif
1462
1463 if (dns_config_service_.get())
1464 dns_config_service_->AddObserver(this);
1257 } 1465 }
1258 1466
1259 HostResolverImpl::~HostResolverImpl() { 1467 HostResolverImpl::~HostResolverImpl() {
1260 DiscardIPv6ProbeJob(); 1468 DiscardIPv6ProbeJob();
1261 1469
1262 // This will also cancel all outstanding requests. 1470 // This will also cancel all outstanding requests.
1263 STLDeleteValues(&jobs_); 1471 STLDeleteValues(&jobs_);
1264 1472
1265 NetworkChangeNotifier::RemoveIPAddressObserver(this); 1473 NetworkChangeNotifier::RemoveIPAddressObserver(this);
1266 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) 1474 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 return rv; 1508 return rv;
1301 } 1509 }
1302 1510
1303 // Next we need to attach our request to a "job". This job is responsible for 1511 // Next we need to attach our request to a "job". This job is responsible for
1304 // calling "getaddrinfo(hostname)" on a worker thread. 1512 // calling "getaddrinfo(hostname)" on a worker thread.
1305 1513
1306 JobMap::iterator jobit = jobs_.find(key); 1514 JobMap::iterator jobit = jobs_.find(key);
1307 Job* job; 1515 Job* job;
1308 if (jobit == jobs_.end()) { 1516 if (jobit == jobs_.end()) {
1309 // Create new Job. 1517 // Create new Job.
1310 job = new Job(this, key, request_net_log); 1518 job = new Job(this, key, request_net_log, info.priority());
1311 job->set_handle(dispatcher_.Add(job, info.priority())); 1519 job->AddToDispatcher(&dispatcher_);
1312 1520
1313 // Check for queue overflow. 1521 // Check for queue overflow.
1314 if (dispatcher_.num_queued_jobs() > max_queued_jobs_) { 1522 if (dispatcher_.num_queued_jobs() > max_queued_jobs_) {
1315 Job* evicted = static_cast<Job*>(dispatcher_.EvictOldestLowest()); 1523 Job* evicted = static_cast<Job*>(dispatcher_.EvictOldestLowest());
1316 DCHECK(evicted); 1524 DCHECK(evicted);
1317 if (evicted == job) { 1525 if (evicted == job) {
1318 delete job; 1526 delete job;
1319 rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; 1527 rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE;
1320 LogFinishRequest(source_net_log, request_net_log, info, rv, 0); 1528 LogFinishRequest(source_net_log, request_net_log, info, rv, 0);
1321 return rv; 1529 return rv;
1322 } 1530 }
1323 evicted->OnEvicted(); // Deletes |evicted|. 1531 evicted->OnEvicted(); // Deletes |evicted|.
1324 } 1532 }
1325 1533
1326 jobs_.insert(jobit, std::make_pair(key, job)); 1534 jobs_.insert(jobit, std::make_pair(key, job));
1327 } else { 1535 } else {
1328 job = jobit->second; 1536 job = jobit->second;
1329 } 1537 }
1330 1538
1331 // Can't complete synchronously. Create and attach request. 1539 // Can't complete synchronously. Create and attach request.
1332 Request* req = new Request(source_net_log, request_net_log, info, callback, 1540 Request* req = new Request(source_net_log, request_net_log, info, callback,
1333 addresses); 1541 addresses);
1334 job->AddRequest(req); 1542 job->AddRequest(req);
1335 if (!job->handle().is_null())
1336 job->set_handle(dispatcher_.ChangePriority(job->handle(), job->priority()));
1337 if (out_req) 1543 if (out_req)
1338 *out_req = reinterpret_cast<RequestHandle>(req); 1544 *out_req = reinterpret_cast<RequestHandle>(req);
1339 1545
1340 DCHECK_EQ(ERR_IO_PENDING, job->net_error()); 1546 DCHECK_EQ(ERR_IO_PENDING, job->net_error());
1341 // Completion happens during Job::CompleteRequests(). 1547 // Completion happens during Job::CompleteRequests().
1342 return ERR_IO_PENDING; 1548 return ERR_IO_PENDING;
1343 } 1549 }
1344 1550
1345 int HostResolverImpl::ResolveHelper(const Key& key, 1551 int HostResolverImpl::ResolveHelper(const Key& key,
1346 const RequestInfo& info, 1552 const RequestInfo& info,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1384 void HostResolverImpl::CancelRequest(RequestHandle req_handle) { 1590 void HostResolverImpl::CancelRequest(RequestHandle req_handle) {
1385 DCHECK(CalledOnValidThread()); 1591 DCHECK(CalledOnValidThread());
1386 Request* req = reinterpret_cast<Request*>(req_handle); 1592 Request* req = reinterpret_cast<Request*>(req_handle);
1387 DCHECK(req); 1593 DCHECK(req);
1388 1594
1389 Job* job = req->job(); 1595 Job* job = req->job();
1390 DCHECK(job); 1596 DCHECK(job);
1391 1597
1392 job->CancelRequest(req); 1598 job->CancelRequest(req);
1393 1599
1394 if (!job->handle().is_null()) { 1600 if (job->num_active_requests() == 0) {
1395 // Still in queue. 1601 if (job->is_running()) {
1396 if (job->num_active_requests()) { 1602 // Job is running (and could be in CompleteRequests right now).
1397 job->set_handle(dispatcher_.ChangePriority(job->handle(), 1603 // But to be in Request::OnComplete we would have to have a non-canceled
1398 job->priority())); 1604 // request. So it is safe to Abort it if it has no more active requests.
1605 job->Abort();
1399 } else { 1606 } else {
1400 dispatcher_.Cancel(job->handle());
1401 RemoveJob(job); 1607 RemoveJob(job);
1402 delete job; 1608 delete job;
1403 } 1609 }
1404 } else {
1405 // Job is running (and could be in CompleteRequests right now).
1406 // But to be in Request::OnComplete we would have to have a non-canceled
1407 // request. So it is safe to Abort it if it has no more active requests.
1408 if (!job->num_active_requests()) {
1409 job->Abort();
1410 }
1411 } 1610 }
1412 } 1611 }
1413 1612
1414 void HostResolverImpl::SetDefaultAddressFamily(AddressFamily address_family) { 1613 void HostResolverImpl::SetDefaultAddressFamily(AddressFamily address_family) {
1415 DCHECK(CalledOnValidThread()); 1614 DCHECK(CalledOnValidThread());
1416 ipv6_probe_monitoring_ = false; 1615 ipv6_probe_monitoring_ = false;
1417 DiscardIPv6ProbeJob(); 1616 DiscardIPv6ProbeJob();
1418 default_address_family_ = address_family; 1617 default_address_family_ = address_family;
1419 } 1618 }
1420 1619
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 if (!cache_entry) 1674 if (!cache_entry)
1476 return false; 1675 return false;
1477 1676
1478 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); 1677 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL);
1479 *net_error = cache_entry->error; 1678 *net_error = cache_entry->error;
1480 if (*net_error == OK) 1679 if (*net_error == OK)
1481 *addresses = CreateAddressListUsingPort(cache_entry->addrlist, info.port()); 1680 *addresses = CreateAddressListUsingPort(cache_entry->addrlist, info.port());
1482 return true; 1681 return true;
1483 } 1682 }
1484 1683
1485 void HostResolverImpl::OnJobFinished(Job* job, const AddressList& addrlist) { 1684 void HostResolverImpl::OnJobFinished(Job* job,
1685 const AddressList& addrlist,
1686 base::TimeDelta ttl) {
1486 DCHECK(job); 1687 DCHECK(job);
1487 DCHECK(job->handle().is_null()); 1688 DCHECK(!job->IsWaitingInDispatch());
1488 RemoveJob(job); 1689 RemoveJob(job);
1489 if (job->net_error() == ERR_HOST_RESOLVER_QUEUE_TOO_LARGE) 1690 if (job->net_error() == ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)
1490 return; 1691 return;
1491 1692
1492 // Signal dispatcher that a slot has opened. 1693 // Signal dispatcher that a slot has opened.
1493 dispatcher_.OnJobFinished(); 1694 dispatcher_.OnJobFinished();
1494 if (job->net_error() == ERR_ABORTED) 1695 if (job->net_error() == ERR_ABORTED)
1495 return; 1696 return;
1496 // Write result to the cache. 1697 // Write result to the cache.
1497 if (cache_.get()) { 1698 if (cache_.get()) {
1498 base::TimeDelta ttl = base::TimeDelta::FromSeconds(0);
1499 if (job->net_error() == OK)
1500 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds);
1501 cache_->Set(job->key(), job->net_error(), addrlist, 1699 cache_->Set(job->key(), job->net_error(), addrlist,
1502 base::TimeTicks::Now(), ttl); 1700 base::TimeTicks::Now(), ttl);
1503 } 1701 }
1504 } 1702 }
1505 1703
1506 void HostResolverImpl::RemoveJob(Job* job) { 1704 void HostResolverImpl::RemoveJob(Job* job) {
1507 DCHECK(job); 1705 DCHECK(job);
1508 jobs_.erase(job->key()); 1706 jobs_.erase(job->key());
1509 } 1707 }
1510 1708
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 Job* job = it->second; 1748 Job* job = it->second;
1551 // Advance the iterator before we might erase it. 1749 // Advance the iterator before we might erase it.
1552 ++it; 1750 ++it;
1553 if (job->is_running()) { 1751 if (job->is_running()) {
1554 job->Abort(); 1752 job->Abort();
1555 // Check if resolver was deleted in a request callback. 1753 // Check if resolver was deleted in a request callback.
1556 if (!self) 1754 if (!self)
1557 return; 1755 return;
1558 } else { 1756 } else {
1559 // Keep it in |dispatch_|. 1757 // Keep it in |dispatch_|.
1560 DCHECK(!job->handle().is_null()); 1758 DCHECK(job->IsWaitingInDispatch());
1561 } 1759 }
1562 } 1760 }
1563 } 1761 }
1564 1762
1565 void HostResolverImpl::OnIPAddressChanged() { 1763 void HostResolverImpl::OnIPAddressChanged() {
1566 if (cache_.get()) 1764 if (cache_.get())
1567 cache_->clear(); 1765 cache_->clear();
1568 if (ipv6_probe_monitoring_) { 1766 if (ipv6_probe_monitoring_) {
1569 DiscardIPv6ProbeJob(); 1767 DiscardIPv6ProbeJob();
1570 ipv6_probe_job_ = new IPv6ProbeJob(this); 1768 ipv6_probe_job_ = new IPv6ProbeJob(this);
(...skipping 16 matching lines...) Expand all
1587 // as NSCD's cache should be dropped automatically by the OS when 1785 // as NSCD's cache should be dropped automatically by the OS when
1588 // resolv.conf changes so we don't need to do anything to clear that cache. 1786 // resolv.conf changes so we don't need to do anything to clear that cache.
1589 if (cache_.get()) 1787 if (cache_.get())
1590 cache_->clear(); 1788 cache_->clear();
1591 // Existing jobs will have been sent to the original server so they need to 1789 // Existing jobs will have been sent to the original server so they need to
1592 // be aborted. TODO(Craig): Should these jobs be restarted? 1790 // be aborted. TODO(Craig): Should these jobs be restarted?
1593 AbortAllInProgressJobs(); 1791 AbortAllInProgressJobs();
1594 // |this| may be deleted inside AbortAllInProgressJobs(). 1792 // |this| may be deleted inside AbortAllInProgressJobs().
1595 } 1793 }
1596 1794
1795 void HostResolverImpl::OnConfigChanged(const DnsConfig& dns_config) {
1796 // We want a new factory in place, before we Abort running Jobs, so that the
1797 // newly started jobs use the new factory.
1798 bool had_factory = (dns_transaction_factory_.get() != NULL);
1799 if (dns_config.IsValid()) {
1800 dns_transaction_factory_ = DnsTransactionFactory::CreateFactory(
1801 new DnsSession(dns_config,
1802 ClientSocketFactory::GetDefaultFactory(),
1803 base::Bind(&base::RandInt),
1804 net_log_));
1805 } else {
1806 dns_transaction_factory_.reset();
1807 }
1808 if (had_factory) {
1809 OnDNSChanged();
1810 }
1811 }
1812
1597 } // namespace net 1813 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698