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

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

Powered by Google App Engine
This is Rietveld 408576698