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

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

Issue 9667025: [net/dns] Serve requests from HOSTS file if possible. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updated ResolveFromCache comment Created 8 years, 9 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"
28 #include "base/stl_util.h" 27 #include "base/stl_util.h"
29 #include "base/string_util.h" 28 #include "base/string_util.h"
30 #include "base/threading/worker_pool.h" 29 #include "base/threading/worker_pool.h"
31 #include "base/time.h" 30 #include "base/time.h"
32 #include "base/utf_string_conversions.h" 31 #include "base/utf_string_conversions.h"
33 #include "base/values.h" 32 #include "base/values.h"
34 #include "net/base/address_family.h" 33 #include "net/base/address_family.h"
35 #include "net/base/address_list.h" 34 #include "net/base/address_list.h"
36 #include "net/base/address_list_net_log_param.h" 35 #include "net/base/address_list_net_log_param.h"
37 #include "net/base/dns_reloader.h" 36 #include "net/base/dns_reloader.h"
38 #include "net/base/host_port_pair.h" 37 #include "net/base/host_port_pair.h"
39 #include "net/base/host_resolver_proc.h" 38 #include "net/base/host_resolver_proc.h"
40 #include "net/base/net_errors.h" 39 #include "net/base/net_errors.h"
41 #include "net/base/net_log.h" 40 #include "net/base/net_log.h"
42 #include "net/base/net_util.h" 41 #include "net/base/net_util.h"
42 #include "net/dns/dns_client.h"
43 #include "net/dns/dns_config_service.h" 43 #include "net/dns/dns_config_service.h"
44 #include "net/dns/dns_protocol.h" 44 #include "net/dns/dns_protocol.h"
45 #include "net/dns/dns_response.h" 45 #include "net/dns/dns_response.h"
46 #include "net/dns/dns_session.h"
47 #include "net/dns/dns_transaction.h" 46 #include "net/dns/dns_transaction.h"
48 #include "net/socket/client_socket_factory.h"
49 47
50 #if defined(OS_WIN) 48 #if defined(OS_WIN)
51 #include "net/base/winsock_init.h" 49 #include "net/base/winsock_init.h"
52 #endif 50 #endif
53 51
54 namespace net { 52 namespace net {
55 53
56 namespace { 54 namespace {
57 55
58 // Limit the size of hostnames that will be resolved to combat issues in 56 // Limit the size of hostnames that will be resolved to combat issues in
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 base::TimeDelta duration = base::TimeTicks::Now() - start_time; 746 base::TimeDelta duration = base::TimeTicks::Now() - start_time;
749 if (error == OK) { 747 if (error == OK) {
750 if (had_non_speculative_request_) { 748 if (had_non_speculative_request_) {
751 category = RESOLVE_SUCCESS; 749 category = RESOLVE_SUCCESS;
752 DNS_HISTOGRAM("DNS.ResolveSuccess", duration); 750 DNS_HISTOGRAM("DNS.ResolveSuccess", duration);
753 } else { 751 } else {
754 category = RESOLVE_SPECULATIVE_SUCCESS; 752 category = RESOLVE_SPECULATIVE_SUCCESS;
755 DNS_HISTOGRAM("DNS.ResolveSpeculativeSuccess", duration); 753 DNS_HISTOGRAM("DNS.ResolveSpeculativeSuccess", duration);
756 } 754 }
757 755
758 // Log DNS lookups based on address_family. This will help us determine 756 // Log DNS lookups based on |address_family|. This will help us determine
759 // if IPv4 or IPv4/6 lookups are faster or slower. 757 // if IPv4 or IPv4/6 lookups are faster or slower.
760 switch(key_.address_family) { 758 switch(key_.address_family) {
761 case ADDRESS_FAMILY_IPV4: 759 case ADDRESS_FAMILY_IPV4:
762 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_IPV4", duration); 760 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_IPV4", duration);
763 break; 761 break;
764 case ADDRESS_FAMILY_IPV6: 762 case ADDRESS_FAMILY_IPV6:
765 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_IPV6", duration); 763 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_IPV6", duration);
766 break; 764 break;
767 case ADDRESS_FAMILY_UNSPECIFIED: 765 case ADDRESS_FAMILY_UNSPECIFIED:
768 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_UNSPEC", duration); 766 DNS_HISTOGRAM("DNS.ResolveSuccess_FAMILY_UNSPEC", duration);
769 break; 767 break;
770 } 768 }
771 } else { 769 } else {
772 if (had_non_speculative_request_) { 770 if (had_non_speculative_request_) {
773 category = RESOLVE_FAIL; 771 category = RESOLVE_FAIL;
774 DNS_HISTOGRAM("DNS.ResolveFail", duration); 772 DNS_HISTOGRAM("DNS.ResolveFail", duration);
775 } else { 773 } else {
776 category = RESOLVE_SPECULATIVE_FAIL; 774 category = RESOLVE_SPECULATIVE_FAIL;
777 DNS_HISTOGRAM("DNS.ResolveSpeculativeFail", duration); 775 DNS_HISTOGRAM("DNS.ResolveSpeculativeFail", duration);
778 } 776 }
779 // Log DNS lookups based on address_family. This will help us determine 777 // Log DNS lookups based on |address_family|. This will help us determine
780 // if IPv4 or IPv4/6 lookups are faster or slower. 778 // if IPv4 or IPv4/6 lookups are faster or slower.
781 switch(key_.address_family) { 779 switch(key_.address_family) {
782 case ADDRESS_FAMILY_IPV4: 780 case ADDRESS_FAMILY_IPV4:
783 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_IPV4", duration); 781 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_IPV4", duration);
784 break; 782 break;
785 case ADDRESS_FAMILY_IPV6: 783 case ADDRESS_FAMILY_IPV6:
786 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_IPV6", duration); 784 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_IPV6", duration);
787 break; 785 break;
788 case ADDRESS_FAMILY_UNSPECIFIED: 786 case ADDRESS_FAMILY_UNSPECIFIED:
789 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_UNSPEC", duration); 787 DNS_HISTOGRAM("DNS.ResolveFail_FAMILY_UNSPEC", duration);
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 handle_.Reset(); 1196 handle_.Reset();
1199 1197
1200 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_EVICTED, NULL); 1198 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_EVICTED, NULL);
1201 1199
1202 // This signals to CompleteRequests that this job never ran. 1200 // This signals to CompleteRequests that this job never ran.
1203 CompleteRequests(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, 1201 CompleteRequests(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE,
1204 AddressList(), 1202 AddressList(),
1205 base::TimeDelta()); 1203 base::TimeDelta());
1206 } 1204 }
1207 1205
1206 // Attempts to serve the job from HOSTS. Returns true if succeeded and
1207 // this Job was destroyed.
1208 bool ServeFromHosts() {
1209 DCHECK_GT(num_active_requests(), 0u);
1210 AddressList addr_list;
1211 if (resolver_->ServeFromHosts(key(),
1212 requests_.front()->info(),
1213 &addr_list)) {
1214 // This will destroy the Job.
1215 CompleteRequests(OK, addr_list, base::TimeDelta());
1216 return true;
1217 }
1218 return false;
1219 }
1220
1208 private: 1221 private:
1209 RequestPriority priority() const { 1222 RequestPriority priority() const {
1210 return priority_tracker_.highest_priority(); 1223 return priority_tracker_.highest_priority();
1211 } 1224 }
1212 1225
1213 // Number of non-canceled requests in |requests_|. 1226 // Number of non-canceled requests in |requests_|.
1214 size_t num_active_requests() const { 1227 size_t num_active_requests() const {
1215 return priority_tracker_.total_count(); 1228 return priority_tracker_.total_count();
1216 } 1229 }
1217 1230
1218 bool is_dns_running() const { 1231 bool is_dns_running() const {
1219 return dns_task_.get() != NULL; 1232 return dns_task_.get() != NULL;
1220 } 1233 }
1221 1234
1222 bool is_proc_running() const { 1235 bool is_proc_running() const {
1223 return proc_task_.get() != NULL; 1236 return proc_task_.get() != NULL;
1224 } 1237 }
1225 1238
1226 // PriorityDispatch::Job: 1239 // PriorityDispatch::Job:
1227 virtual void Start() OVERRIDE { 1240 virtual void Start() OVERRIDE {
1228 DCHECK(!is_running()); 1241 DCHECK(!is_running());
1229 handle_.Reset(); 1242 handle_.Reset();
1230 1243
1231 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_STARTED, NULL); 1244 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_STARTED, NULL);
1232 1245
1233 // Job::Start must not complete synchronously. 1246 // Job::Start must not complete synchronously.
1234 if (resolver_->dns_transaction_factory_.get()) { 1247 if (resolver_->HaveDnsConfig()) {
1235 StartDnsTask(); 1248 StartDnsTask();
1236 } else { 1249 } else {
1237 StartProcTask(); 1250 StartProcTask();
1238 } 1251 }
1239 } 1252 }
1240 1253
1241 // TODO(szym): Since DnsTransaction does not consume threads, we can increase 1254 // TODO(szym): Since DnsTransaction does not consume threads, we can increase
1242 // the limits on |dispatcher_|. But in order to keep the number of WorkerPool 1255 // the limits on |dispatcher_|. But in order to keep the number of WorkerPool
1243 // threads low, we will need to use an "inner" PrioritizedDispatcher with 1256 // threads low, we will need to use an "inner" PrioritizedDispatcher with
1244 // tighter limits. 1257 // tighter limits.
(...skipping 18 matching lines...) Expand all
1263 1276
1264 base::TimeDelta ttl = base::TimeDelta::FromSeconds( 1277 base::TimeDelta ttl = base::TimeDelta::FromSeconds(
1265 kNegativeCacheEntryTTLSeconds); 1278 kNegativeCacheEntryTTLSeconds);
1266 if (net_error == OK) 1279 if (net_error == OK)
1267 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds); 1280 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds);
1268 1281
1269 CompleteRequests(net_error, addr_list, ttl); 1282 CompleteRequests(net_error, addr_list, ttl);
1270 } 1283 }
1271 1284
1272 void StartDnsTask() { 1285 void StartDnsTask() {
1286 DCHECK(resolver_->HaveDnsConfig());
1273 dns_task_.reset(new DnsTask( 1287 dns_task_.reset(new DnsTask(
1274 resolver_->dns_transaction_factory_.get(), 1288 resolver_->dns_client_->GetTransactionFactory(),
1275 key_, 1289 key_,
1276 base::Bind(&Job::OnDnsTaskComplete, base::Unretained(this)), 1290 base::Bind(&Job::OnDnsTaskComplete, base::Unretained(this)),
1277 net_log_)); 1291 net_log_));
1278 1292
1279 int rv = dns_task_->Start(); 1293 int rv = dns_task_->Start();
1280 if (rv != ERR_IO_PENDING) { 1294 if (rv != ERR_IO_PENDING) {
1281 DCHECK_NE(OK, rv); 1295 DCHECK_NE(OK, rv);
1282 dns_task_.reset(); 1296 dns_task_.reset();
1283 StartProcTask(); 1297 StartProcTask();
1284 } 1298 }
1285 } 1299 }
1286 1300
1287 // Called by DnsTask when it completes. 1301 // Called by DnsTask when it completes.
1288 void OnDnsTaskComplete(int net_error, 1302 void OnDnsTaskComplete(int net_error,
1289 const AddressList& addr_list, 1303 const AddressList& addr_list,
1290 base::TimeDelta ttl) { 1304 base::TimeDelta ttl) {
1291 DCHECK(is_dns_running()); 1305 DCHECK(is_dns_running());
1292 1306
1293 if (net_error != OK) { 1307 if (net_error != OK) {
1294 dns_task_.reset(); 1308 dns_task_.reset();
1309
1310 // TODO(szym): Run ServeFromHosts now if nsswitch.conf says so.
1311 // http://crbug.com/117655
1312
1295 // TODO(szym): Some net errors indicate lack of connectivity. Starting 1313 // TODO(szym): Some net errors indicate lack of connectivity. Starting
1296 // ProcTask in that case is a waste of time. 1314 // ProcTask in that case is a waste of time.
1297 StartProcTask(); 1315 StartProcTask();
1298 return; 1316 return;
1299 } 1317 }
1300 1318
1301 CompleteRequests(net_error, addr_list, ttl); 1319 CompleteRequests(net_error, addr_list, ttl);
1302 } 1320 }
1303 1321
1304 // Performs Job's last rites. Completes all Requests. Deletes this. 1322 // Performs Job's last rites. Completes all Requests. Deletes this.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 if (num_active_requests() == 0) { 1355 if (num_active_requests() == 0) {
1338 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); 1356 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL);
1339 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, 1357 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB,
1340 OK); 1358 OK);
1341 return; 1359 return;
1342 } 1360 }
1343 1361
1344 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, 1362 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB,
1345 net_error); 1363 net_error);
1346 1364
1365 DCHECK(!requests_.empty());
1366
1347 // We are the only consumer of |list|, so we can safely change the port 1367 // We are the only consumer of |list|, so we can safely change the port
1348 // without copy-on-write. This pays off, when job has only one request. 1368 // without copy-on-write. This pays off, when job has only one request.
1349 if (net_error == OK && !requests_.empty()) 1369 if (net_error == OK)
1350 MutableSetPort(requests_.front()->info().port(), &list); 1370 MutableSetPort(requests_.front()->info().port(), &list);
1351 1371
1352 if ((net_error != ERR_ABORTED) && 1372 if ((net_error != ERR_ABORTED) &&
1353 (net_error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)) { 1373 (net_error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)) {
1354 resolver_->CacheResult(key_, net_error, list, ttl); 1374 resolver_->CacheResult(key_, net_error, list, ttl);
1355 } 1375 }
1356 1376
1357 // Complete all of the requests that were attached to the job. 1377 // Complete all of the requests that were attached to the job.
1358 for (RequestsList::const_iterator it = requests_.begin(); 1378 for (RequestsList::const_iterator it = requests_.begin();
1359 it != requests_.end(); ++it) { 1379 it != requests_.end(); ++it) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 HostCache* cache, 1437 HostCache* cache,
1418 const PrioritizedDispatcher::Limits& job_limits, 1438 const PrioritizedDispatcher::Limits& job_limits,
1419 const ProcTaskParams& proc_params, 1439 const ProcTaskParams& proc_params,
1420 scoped_ptr<DnsConfigService> dns_config_service, 1440 scoped_ptr<DnsConfigService> dns_config_service,
1421 NetLog* net_log) 1441 NetLog* net_log)
1422 : cache_(cache), 1442 : cache_(cache),
1423 dispatcher_(job_limits), 1443 dispatcher_(job_limits),
1424 max_queued_jobs_(job_limits.total_jobs * 100u), 1444 max_queued_jobs_(job_limits.total_jobs * 100u),
1425 proc_params_(proc_params), 1445 proc_params_(proc_params),
1426 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), 1446 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED),
1447 dns_client_(NULL),
1427 dns_config_service_(dns_config_service.Pass()), 1448 dns_config_service_(dns_config_service.Pass()),
1428 ipv6_probe_monitoring_(false), 1449 ipv6_probe_monitoring_(false),
1429 additional_resolver_flags_(0), 1450 additional_resolver_flags_(0),
1430 net_log_(net_log) { 1451 net_log_(net_log) {
1431 1452
1432 DCHECK_GE(dispatcher_.num_priorities(), static_cast<size_t>(NUM_PRIORITIES)); 1453 DCHECK_GE(dispatcher_.num_priorities(), static_cast<size_t>(NUM_PRIORITIES));
1433 1454
1434 // Maximum of 4 retry attempts for host resolution. 1455 // Maximum of 4 retry attempts for host resolution.
1435 static const size_t kDefaultMaxRetryAttempts = 4u; 1456 static const size_t kDefaultMaxRetryAttempts = 4u;
1436 1457
1437 if (proc_params_.max_retry_attempts == HostResolver::kDefaultRetryAttempts) 1458 if (proc_params_.max_retry_attempts == HostResolver::kDefaultRetryAttempts)
1438 proc_params_.max_retry_attempts = kDefaultMaxRetryAttempts; 1459 proc_params_.max_retry_attempts = kDefaultMaxRetryAttempts;
1439 1460
1440 #if defined(OS_WIN) 1461 #if defined(OS_WIN)
1441 EnsureWinsockInit(); 1462 EnsureWinsockInit();
1442 #endif 1463 #endif
1443 #if defined(OS_POSIX) && !defined(OS_MACOSX) 1464 #if defined(OS_POSIX) && !defined(OS_MACOSX)
1444 if (HaveOnlyLoopbackAddresses()) 1465 if (HaveOnlyLoopbackAddresses())
1445 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; 1466 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY;
1446 #endif 1467 #endif
1447 NetworkChangeNotifier::AddIPAddressObserver(this); 1468 NetworkChangeNotifier::AddIPAddressObserver(this);
1448 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) 1469 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
1449 #if !defined(OS_ANDROID) 1470 #if !defined(OS_ANDROID)
1450 EnsureDnsReloaderInit(); 1471 EnsureDnsReloaderInit();
1451 #endif 1472 #endif
1452 NetworkChangeNotifier::AddDNSObserver(this); 1473 NetworkChangeNotifier::AddDNSObserver(this);
1453 #endif 1474 #endif
1454 1475
1455 if (dns_config_service_.get()) 1476 if (dns_config_service_.get()) {
1456 dns_config_service_->AddObserver(this); 1477 dns_config_service_->AddObserver(this);
1478 dns_client_ = DnsClient::CreateClient(net_log_);
1479 }
1457 } 1480 }
1458 1481
1459 HostResolverImpl::~HostResolverImpl() { 1482 HostResolverImpl::~HostResolverImpl() {
1460 DiscardIPv6ProbeJob(); 1483 DiscardIPv6ProbeJob();
1461 1484
1462 // This will also cancel all outstanding requests. 1485 // This will also cancel all outstanding requests.
1463 STLDeleteValues(&jobs_); 1486 STLDeleteValues(&jobs_);
1464 1487
1465 NetworkChangeNotifier::RemoveIPAddressObserver(this); 1488 NetworkChangeNotifier::RemoveIPAddressObserver(this);
1466 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) 1489 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 const BoundNetLog& request_net_log) { 1568 const BoundNetLog& request_net_log) {
1546 // The result of |getaddrinfo| for empty hosts is inconsistent across systems. 1569 // The result of |getaddrinfo| for empty hosts is inconsistent across systems.
1547 // On Windows it gives the default interface's address, whereas on Linux it 1570 // On Windows it gives the default interface's address, whereas on Linux it
1548 // gives an error. We will make it fail on all platforms for consistency. 1571 // gives an error. We will make it fail on all platforms for consistency.
1549 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) 1572 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength)
1550 return ERR_NAME_NOT_RESOLVED; 1573 return ERR_NAME_NOT_RESOLVED;
1551 1574
1552 int net_error = ERR_UNEXPECTED; 1575 int net_error = ERR_UNEXPECTED;
1553 if (ResolveAsIP(key, info, &net_error, addresses)) 1576 if (ResolveAsIP(key, info, &net_error, addresses))
1554 return net_error; 1577 return net_error;
1555 net_error = ERR_DNS_CACHE_MISS; 1578 if (ServeFromCache(key, info, &net_error, addresses)) {
1556 ServeFromCache(key, info, request_net_log, &net_error, addresses); 1579 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL);
1557 return net_error; 1580 return net_error;
1581 }
1582 // TODO(szym): Do not do this if nsswitch.conf instructs not to.
1583 // http://crbug.com/117655
1584 if (ServeFromHosts(key, info, addresses)) {
1585 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT, NULL);
1586 return OK;
1587 }
1588 return ERR_DNS_CACHE_MISS;
1558 } 1589 }
1559 1590
1560 int HostResolverImpl::ResolveFromCache(const RequestInfo& info, 1591 int HostResolverImpl::ResolveFromCache(const RequestInfo& info,
1561 AddressList* addresses, 1592 AddressList* addresses,
1562 const BoundNetLog& source_net_log) { 1593 const BoundNetLog& source_net_log) {
1563 DCHECK(CalledOnValidThread()); 1594 DCHECK(CalledOnValidThread());
1564 DCHECK(addresses); 1595 DCHECK(addresses);
1565 1596
1566 // Make a log item for the request. 1597 // Make a log item for the request.
1567 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, 1598 BoundNetLog request_net_log = BoundNetLog::Make(net_log_,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 } else { 1661 } else {
1631 *addresses = AddressList::CreateFromIPAddressWithCname( 1662 *addresses = AddressList::CreateFromIPAddressWithCname(
1632 ip_number, info.port(), 1663 ip_number, info.port(),
1633 (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)); 1664 (key.host_resolver_flags & HOST_RESOLVER_CANONNAME));
1634 } 1665 }
1635 return true; 1666 return true;
1636 } 1667 }
1637 1668
1638 bool HostResolverImpl::ServeFromCache(const Key& key, 1669 bool HostResolverImpl::ServeFromCache(const Key& key,
1639 const RequestInfo& info, 1670 const RequestInfo& info,
1640 const BoundNetLog& request_net_log,
1641 int* net_error, 1671 int* net_error,
1642 AddressList* addresses) { 1672 AddressList* addresses) {
1643 DCHECK(addresses); 1673 DCHECK(addresses);
1644 DCHECK(net_error); 1674 DCHECK(net_error);
1645 if (!info.allow_cached_response() || !cache_.get()) 1675 if (!info.allow_cached_response() || !cache_.get())
1646 return false; 1676 return false;
1647 1677
1648 const HostCache::Entry* cache_entry = cache_->Lookup( 1678 const HostCache::Entry* cache_entry = cache_->Lookup(
1649 key, base::TimeTicks::Now()); 1679 key, base::TimeTicks::Now());
1650 if (!cache_entry) 1680 if (!cache_entry)
1651 return false; 1681 return false;
1652 1682
1653 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); 1683
1654 *net_error = cache_entry->error; 1684 *net_error = cache_entry->error;
1655 if (*net_error == OK) 1685 if (*net_error == OK)
1656 *addresses = CreateAddressListUsingPort(cache_entry->addrlist, info.port()); 1686 *addresses = CreateAddressListUsingPort(cache_entry->addrlist, info.port());
1657 return true; 1687 return true;
1658 } 1688 }
1659 1689
1690 bool HostResolverImpl::ServeFromHosts(const Key& key,
1691 const RequestInfo& info,
1692 AddressList* addresses) {
1693 DCHECK(addresses);
1694 if (!HaveDnsConfig())
1695 return false;
1696
1697 // If |address_family| is ADDRESS_FAMILY_UNSPECIFIED other implementations
1698 // (glibc and c-ares) return the first matching line. We have more
1699 // flexibility, but lose implicit ordering.
1700 // TODO(szym) http://crbug.com/117850
1701 const DnsHosts& hosts = dns_client_->GetConfig()->hosts;
1702 DnsHosts::const_iterator it = hosts.find(
1703 DnsHostsKey(key.hostname,
1704 key.address_family == ADDRESS_FAMILY_UNSPECIFIED ?
1705 ADDRESS_FAMILY_IPV4 : key.address_family));
1706
1707 if (it == hosts.end()) {
1708 if (key.address_family != ADDRESS_FAMILY_UNSPECIFIED)
1709 return false;
1710
1711 it = hosts.find(DnsHostsKey(key.hostname, ADDRESS_FAMILY_IPV6));
1712 if (it == hosts.end())
1713 return false;
1714 }
1715
1716 *addresses = AddressList::CreateFromIPAddress(it->second, info.port());
1717 return true;
1718 }
1719
1660 void HostResolverImpl::CacheResult(const Key& key, 1720 void HostResolverImpl::CacheResult(const Key& key,
1661 int net_error, 1721 int net_error,
1662 const AddressList& addr_list, 1722 const AddressList& addr_list,
1663 base::TimeDelta ttl) { 1723 base::TimeDelta ttl) {
1664 if (cache_.get()) 1724 if (cache_.get())
1665 cache_->Set(key, net_error, addr_list, base::TimeTicks::Now(), ttl); 1725 cache_->Set(key, net_error, addr_list, base::TimeTicks::Now(), ttl);
1666 } 1726 }
1667 1727
1668 void HostResolverImpl::RemoveJob(Job* job) { 1728 void HostResolverImpl::RemoveJob(Job* job) {
1669 DCHECK(job); 1729 DCHECK(job);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 1787
1728 // Life check to bail once |this| is deleted. 1788 // Life check to bail once |this| is deleted.
1729 base::WeakPtr<HostResolverImpl> self = AsWeakPtr(); 1789 base::WeakPtr<HostResolverImpl> self = AsWeakPtr();
1730 1790
1731 // Then Abort them. 1791 // Then Abort them.
1732 for (size_t i = 0; self && i < jobs_to_abort.size(); ++i) { 1792 for (size_t i = 0; self && i < jobs_to_abort.size(); ++i) {
1733 jobs_to_abort[i]->Abort(); 1793 jobs_to_abort[i]->Abort();
1734 } 1794 }
1735 } 1795 }
1736 1796
1797 void HostResolverImpl::TryServingAllJobsFromHosts() {
1798 if (!HaveDnsConfig())
1799 return;
1800
1801 // TODO(szym): Do not do this if nsswitch.conf instructs not to.
1802 // http://crbug.com/117655
1803
1804 // Life check to bail once |this| is deleted.
1805 base::WeakPtr<HostResolverImpl> self = AsWeakPtr();
1806
1807 for (JobMap::iterator it = jobs_.begin(); self && it != jobs_.end(); ) {
1808 Job* job = it->second;
1809 ++it;
1810 // This could remove |job| from |jobs_|, but iterator will remain valid.
1811 job->ServeFromHosts();
1812 }
1813 }
1814
1737 void HostResolverImpl::OnIPAddressChanged() { 1815 void HostResolverImpl::OnIPAddressChanged() {
1738 if (cache_.get()) 1816 if (cache_.get())
1739 cache_->clear(); 1817 cache_->clear();
1740 if (ipv6_probe_monitoring_) { 1818 if (ipv6_probe_monitoring_) {
1741 DiscardIPv6ProbeJob(); 1819 DiscardIPv6ProbeJob();
1742 ipv6_probe_job_ = new IPv6ProbeJob(this); 1820 ipv6_probe_job_ = new IPv6ProbeJob(this);
1743 ipv6_probe_job_->Start(); 1821 ipv6_probe_job_->Start();
1744 } 1822 }
1745 #if defined(OS_POSIX) && !defined(OS_MACOSX) 1823 #if defined(OS_POSIX) && !defined(OS_MACOSX)
1746 if (HaveOnlyLoopbackAddresses()) { 1824 if (HaveOnlyLoopbackAddresses()) {
(...skipping 15 matching lines...) Expand all
1762 cache_->clear(); 1840 cache_->clear();
1763 // Existing jobs will have been sent to the original server so they need to 1841 // Existing jobs will have been sent to the original server so they need to
1764 // be aborted. TODO(Craig): Should these jobs be restarted? 1842 // be aborted. TODO(Craig): Should these jobs be restarted?
1765 AbortAllInProgressJobs(); 1843 AbortAllInProgressJobs();
1766 // |this| may be deleted inside AbortAllInProgressJobs(). 1844 // |this| may be deleted inside AbortAllInProgressJobs().
1767 } 1845 }
1768 1846
1769 void HostResolverImpl::OnConfigChanged(const DnsConfig& dns_config) { 1847 void HostResolverImpl::OnConfigChanged(const DnsConfig& dns_config) {
1770 // We want a new factory in place, before we Abort running Jobs, so that the 1848 // We want a new factory in place, before we Abort running Jobs, so that the
1771 // newly started jobs use the new factory. 1849 // newly started jobs use the new factory.
1772 bool had_factory = (dns_transaction_factory_.get() != NULL); 1850 DCHECK(dns_client_.get());
1773 if (dns_config.IsValid()) { 1851
1774 dns_transaction_factory_ = DnsTransactionFactory::CreateFactory( 1852 // Life check to bail once |this| is deleted.
1775 new DnsSession(dns_config, 1853 base::WeakPtr<HostResolverImpl> self = AsWeakPtr();
1776 ClientSocketFactory::GetDefaultFactory(), 1854
1777 base::Bind(&base::RandInt), 1855 bool had_factory = (dns_client_->GetConfig() != NULL);
1778 net_log_)); 1856 dns_client_->SetConfig(dns_config);
1779 } else { 1857
1780 dns_transaction_factory_.reset();
1781 }
1782 // Don't Abort running Jobs unless they were running on DnsTransaction. 1858 // Don't Abort running Jobs unless they were running on DnsTransaction.
1783 // TODO(szym): This will change once http://crbug.com/114827 is fixed. 1859 // TODO(szym): This will change once http://crbug.com/114827 is fixed.
1784 if (had_factory) 1860 if (had_factory)
1785 OnDNSChanged(NetworkChangeNotifier::CHANGE_DNS_SETTINGS); 1861 OnDNSChanged(NetworkChangeNotifier::CHANGE_DNS_SETTINGS);
1862
1863 if (self && dns_config.IsValid())
1864 TryServingAllJobsFromHosts();
1865 }
1866
1867 bool HostResolverImpl::HaveDnsConfig() const {
1868 return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL);
1786 } 1869 }
1787 1870
1788 } // namespace net 1871 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698