OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/host_resolver_impl.h" | 5 #include "net/base/host_resolver_impl.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <Winsock2.h> | 8 #include <Winsock2.h> |
9 #elif defined(OS_POSIX) | 9 #elif defined(OS_POSIX) |
10 #include <netdb.h> | 10 #include <netdb.h> |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |