| 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 |