Chromium Code Reviews| 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> |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 } | 198 } |
| 199 } else { | 199 } else { |
| 200 if (speculative) { | 200 if (speculative) { |
| 201 DNS_HISTOGRAM("DNS.TotalTime_speculative", duration); | 201 DNS_HISTOGRAM("DNS.TotalTime_speculative", duration); |
| 202 } else { | 202 } else { |
| 203 DNS_HISTOGRAM("DNS.TotalTime", duration); | 203 DNS_HISTOGRAM("DNS.TotalTime", duration); |
| 204 } | 204 } |
| 205 } | 205 } |
| 206 } | 206 } |
| 207 | 207 |
| 208 void RecordTTL(base::TimeDelta ttl) { | |
| 209 UMA_HISTOGRAM_CUSTOM_COUNTS("AsyncDNS.TTL", ttl.InSeconds(), 1, 86400, 100); | |
|
cbentzel
2012/10/13 10:50:45
Should be UMA_HISTOGRAM_CUSTOM_TIMES?
szym
2012/10/15 19:45:36
I initially used _TIMES, but then I looked at the
| |
| 210 } | |
| 211 | |
| 208 //----------------------------------------------------------------------------- | 212 //----------------------------------------------------------------------------- |
| 209 | 213 |
| 210 // Wraps call to SystemHostResolverProc as an instance of HostResolverProc. | 214 // Wraps call to SystemHostResolverProc as an instance of HostResolverProc. |
| 211 // TODO(szym): This should probably be declared in host_resolver_proc.h. | 215 // TODO(szym): This should probably be declared in host_resolver_proc.h. |
| 212 class CallSystemHostResolverProc : public HostResolverProc { | 216 class CallSystemHostResolverProc : public HostResolverProc { |
| 213 public: | 217 public: |
| 214 CallSystemHostResolverProc() : HostResolverProc(NULL) {} | 218 CallSystemHostResolverProc() : HostResolverProc(NULL) {} |
| 215 virtual int Resolve(const std::string& hostname, | 219 virtual int Resolve(const std::string& hostname, |
| 216 AddressFamily address_family, | 220 AddressFamily address_family, |
| 217 HostResolverFlags host_resolver_flags, | 221 HostResolverFlags host_resolver_flags, |
| (...skipping 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1324 base::Bind(&NetLogJobAttachCallback, | 1328 base::Bind(&NetLogJobAttachCallback, |
| 1325 req->request_net_log().source(), | 1329 req->request_net_log().source(), |
| 1326 priority())); | 1330 priority())); |
| 1327 | 1331 |
| 1328 if (num_active_requests() > 0) { | 1332 if (num_active_requests() > 0) { |
| 1329 UpdatePriority(); | 1333 UpdatePriority(); |
| 1330 } else { | 1334 } else { |
| 1331 // If we were called from a Request's callback within CompleteRequests, | 1335 // If we were called from a Request's callback within CompleteRequests, |
| 1332 // that Request could not have been cancelled, so num_active_requests() | 1336 // that Request could not have been cancelled, so num_active_requests() |
| 1333 // could not be 0. Therefore, we are not in CompleteRequests(). | 1337 // could not be 0. Therefore, we are not in CompleteRequests(). |
| 1334 CompleteRequests(OK, AddressList(), base::TimeDelta()); | 1338 CompleteRequestsWithError(OK /* cancelled */); |
| 1335 } | 1339 } |
| 1336 } | 1340 } |
| 1337 | 1341 |
| 1338 // Called from AbortAllInProgressJobs. Completes all requests as aborted | 1342 // Called from AbortAllInProgressJobs. Completes all requests as aborted |
| 1339 // and destroys the job. | 1343 // and destroys the job. |
| 1340 void Abort() { | 1344 void Abort() { |
| 1341 DCHECK(is_running()); | 1345 DCHECK(is_running()); |
| 1342 CompleteRequests(ERR_ABORTED, AddressList(), base::TimeDelta()); | 1346 CompleteRequestsWithError(ERR_ABORTED); |
| 1343 } | 1347 } |
| 1344 | 1348 |
| 1345 // Called by HostResolverImpl when this job is evicted due to queue overflow. | 1349 // Called by HostResolverImpl when this job is evicted due to queue overflow. |
| 1346 // Completes all requests and destroys the job. | 1350 // Completes all requests and destroys the job. |
| 1347 void OnEvicted() { | 1351 void OnEvicted() { |
| 1348 DCHECK(!is_running()); | 1352 DCHECK(!is_running()); |
| 1349 DCHECK(is_queued()); | 1353 DCHECK(is_queued()); |
| 1350 handle_.Reset(); | 1354 handle_.Reset(); |
| 1351 | 1355 |
| 1352 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_EVICTED); | 1356 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_EVICTED); |
| 1353 | 1357 |
| 1354 // This signals to CompleteRequests that this job never ran. | 1358 // This signals to CompleteRequests that this job never ran. |
| 1355 CompleteRequests(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, | 1359 CompleteRequestsWithError(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE); |
| 1356 AddressList(), | |
| 1357 base::TimeDelta()); | |
| 1358 } | 1360 } |
| 1359 | 1361 |
| 1360 // Attempts to serve the job from HOSTS. Returns true if succeeded and | 1362 // Attempts to serve the job from HOSTS. Returns true if succeeded and |
| 1361 // this Job was destroyed. | 1363 // this Job was destroyed. |
| 1362 bool ServeFromHosts() { | 1364 bool ServeFromHosts() { |
| 1363 DCHECK_GT(num_active_requests(), 0u); | 1365 DCHECK_GT(num_active_requests(), 0u); |
| 1364 AddressList addr_list; | 1366 AddressList addr_list; |
| 1365 if (resolver_->ServeFromHosts(key(), | 1367 if (resolver_->ServeFromHosts(key(), |
| 1366 requests_.front()->info(), | 1368 requests_.front()->info(), |
| 1367 &addr_list)) { | 1369 &addr_list)) { |
| 1368 // This will destroy the Job. | 1370 // This will destroy the Job. |
| 1369 CompleteRequests(OK, addr_list, base::TimeDelta()); | 1371 CompleteRequests(OK, addr_list, base::TimeDelta(), false /* true_ttl */); |
|
cbentzel
2012/10/13 10:50:45
Would it make sense to change to CompleteRequests(
szym
2012/10/15 19:45:36
I don't see the benefit. Wouldn't this be the only
| |
| 1370 return true; | 1372 return true; |
| 1371 } | 1373 } |
| 1372 return false; | 1374 return false; |
| 1373 } | 1375 } |
| 1374 | 1376 |
| 1375 const Key key() const { | 1377 const Key key() const { |
| 1376 return key_; | 1378 return key_; |
| 1377 } | 1379 } |
| 1378 | 1380 |
| 1379 bool is_queued() const { | 1381 bool is_queued() const { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1457 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_PROC_SUCCESS); | 1459 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_PROC_SUCCESS); |
| 1458 } | 1460 } |
| 1459 UMA_HISTOGRAM_CUSTOM_ENUMERATION("AsyncDNS.ResolveError", | 1461 UMA_HISTOGRAM_CUSTOM_ENUMERATION("AsyncDNS.ResolveError", |
| 1460 std::abs(dns_task_error_), | 1462 std::abs(dns_task_error_), |
| 1461 GetAllErrorCodesForUma()); | 1463 GetAllErrorCodesForUma()); |
| 1462 } else { | 1464 } else { |
| 1463 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_FAIL); | 1465 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_FAIL); |
| 1464 } | 1466 } |
| 1465 } | 1467 } |
| 1466 | 1468 |
| 1467 base::TimeDelta ttl = base::TimeDelta::FromSeconds( | 1469 base::TimeDelta ttl = |
| 1468 kNegativeCacheEntryTTLSeconds); | 1470 base::TimeDelta::FromSeconds(kNegativeCacheEntryTTLSeconds); |
| 1469 if (net_error == OK) | 1471 if (net_error == OK) |
| 1470 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds); | 1472 ttl = base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds); |
| 1471 | 1473 |
| 1472 CompleteRequests(net_error, addr_list, ttl); | 1474 CompleteRequests(net_error, addr_list, ttl, false /* true_ttl */); |
| 1473 } | 1475 } |
| 1474 | 1476 |
| 1475 void StartDnsTask() { | 1477 void StartDnsTask() { |
| 1476 DCHECK(resolver_->HaveDnsConfig()); | 1478 DCHECK(resolver_->HaveDnsConfig()); |
| 1477 dns_task_.reset(new DnsTask( | 1479 dns_task_.reset(new DnsTask( |
| 1478 resolver_->dns_client_.get(), | 1480 resolver_->dns_client_.get(), |
| 1479 key_, | 1481 key_, |
| 1480 base::Bind(&Job::OnDnsTaskComplete, base::Unretained(this)), | 1482 base::Bind(&Job::OnDnsTaskComplete, base::Unretained(this)), |
| 1481 net_log_)); | 1483 net_log_)); |
| 1482 | 1484 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1502 // TODO(szym): Run ServeFromHosts now if nsswitch.conf says so. | 1504 // TODO(szym): Run ServeFromHosts now if nsswitch.conf says so. |
| 1503 // http://crbug.com/117655 | 1505 // http://crbug.com/117655 |
| 1504 | 1506 |
| 1505 // TODO(szym): Some net errors indicate lack of connectivity. Starting | 1507 // TODO(szym): Some net errors indicate lack of connectivity. Starting |
| 1506 // ProcTask in that case is a waste of time. | 1508 // ProcTask in that case is a waste of time. |
| 1507 StartProcTask(); | 1509 StartProcTask(); |
| 1508 return; | 1510 return; |
| 1509 } | 1511 } |
| 1510 | 1512 |
| 1511 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_DNS_SUCCESS); | 1513 UmaAsyncDnsResolveStatus(RESOLVE_STATUS_DNS_SUCCESS); |
| 1514 RecordTTL(ttl); | |
| 1512 | 1515 |
| 1513 CompleteRequests(net_error, addr_list, ttl); | 1516 CompleteRequests(net_error, addr_list, ttl, true /* true_ttl */); |
| 1514 } | 1517 } |
| 1515 | 1518 |
| 1516 // Performs Job's last rites. Completes all Requests. Deletes this. | 1519 // Performs Job's last rites. Completes all Requests. Deletes this. |
| 1517 void CompleteRequests(int net_error, | 1520 void CompleteRequests(int net_error, |
| 1518 const AddressList& addr_list, | 1521 const AddressList& addr_list, |
| 1519 base::TimeDelta ttl) { | 1522 base::TimeDelta ttl, |
| 1523 bool true_ttl) { | |
| 1520 CHECK(resolver_); | 1524 CHECK(resolver_); |
| 1521 | 1525 |
| 1522 // This job must be removed from resolver's |jobs_| now to make room for a | 1526 // This job must be removed from resolver's |jobs_| now to make room for a |
| 1523 // new job with the same key in case one of the OnComplete callbacks decides | 1527 // new job with the same key in case one of the OnComplete callbacks decides |
| 1524 // to spawn one. Consequently, the job deletes itself when CompleteRequests | 1528 // to spawn one. Consequently, the job deletes itself when CompleteRequests |
| 1525 // is done. | 1529 // is done. |
| 1526 scoped_ptr<Job> self_deleter(this); | 1530 scoped_ptr<Job> self_deleter(this); |
| 1527 | 1531 |
| 1528 resolver_->RemoveJob(this); | 1532 resolver_->RemoveJob(this); |
| 1529 | 1533 |
| 1530 // |addr_list| will be destroyed once we destroy |proc_task_| and | 1534 // |addr_list| will be destroyed with |proc_task_| and |dns_task_|. |
| 1531 // |dns_task_|. | |
| 1532 AddressList list = addr_list; | 1535 AddressList list = addr_list; |
| 1533 | 1536 |
| 1534 if (is_running()) { | 1537 if (is_running()) { |
| 1535 DCHECK(!is_queued()); | 1538 DCHECK(!is_queued()); |
| 1536 if (is_proc_running()) { | 1539 if (is_proc_running()) { |
| 1537 proc_task_->Cancel(); | 1540 proc_task_->Cancel(); |
| 1538 proc_task_ = NULL; | 1541 proc_task_ = NULL; |
| 1539 } | 1542 } |
| 1540 dns_task_.reset(); | 1543 dns_task_.reset(); |
| 1541 | 1544 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1561 if (net_error == OK) { | 1564 if (net_error == OK) { |
| 1562 SetPortOnAddressList(requests_.front()->info().port(), &list); | 1565 SetPortOnAddressList(requests_.front()->info().port(), &list); |
| 1563 // Record this histogram here, when we know the system has a valid DNS | 1566 // Record this histogram here, when we know the system has a valid DNS |
| 1564 // configuration. | 1567 // configuration. |
| 1565 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HaveDnsConfig", | 1568 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HaveDnsConfig", |
| 1566 resolver_->received_dns_config_); | 1569 resolver_->received_dns_config_); |
| 1567 } | 1570 } |
| 1568 | 1571 |
| 1569 bool did_complete = (net_error != ERR_ABORTED) && | 1572 bool did_complete = (net_error != ERR_ABORTED) && |
| 1570 (net_error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE); | 1573 (net_error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE); |
| 1571 if (did_complete) | 1574 if (did_complete) { |
| 1572 resolver_->CacheResult(key_, net_error, list, ttl); | 1575 HostCache::Entry entry = true_ttl ? |
| 1576 HostCache::Entry(net_error, list, ttl) : | |
| 1577 HostCache::Entry(net_error, list); | |
| 1578 resolver_->CacheResult(key_, entry, ttl); | |
| 1579 } | |
| 1573 | 1580 |
| 1574 // Complete all of the requests that were attached to the job. | 1581 // Complete all of the requests that were attached to the job. |
| 1575 for (RequestsList::const_iterator it = requests_.begin(); | 1582 for (RequestsList::const_iterator it = requests_.begin(); |
| 1576 it != requests_.end(); ++it) { | 1583 it != requests_.end(); ++it) { |
| 1577 Request* req = *it; | 1584 Request* req = *it; |
| 1578 | 1585 |
| 1579 if (req->was_canceled()) | 1586 if (req->was_canceled()) |
| 1580 continue; | 1587 continue; |
| 1581 | 1588 |
| 1582 DCHECK_EQ(this, req->job()); | 1589 DCHECK_EQ(this, req->job()); |
| 1583 // Update the net log and notify registered observers. | 1590 // Update the net log and notify registered observers. |
| 1584 LogFinishRequest(req->source_net_log(), req->request_net_log(), | 1591 LogFinishRequest(req->source_net_log(), req->request_net_log(), |
| 1585 req->info(), net_error); | 1592 req->info(), net_error); |
| 1586 if (did_complete) { | 1593 if (did_complete) { |
| 1587 // Record effective total time from creation to completion. | 1594 // Record effective total time from creation to completion. |
| 1588 RecordTotalTime(had_dns_config_, req->info().is_speculative(), | 1595 RecordTotalTime(had_dns_config_, req->info().is_speculative(), |
| 1589 base::TimeTicks::Now() - req->request_time()); | 1596 base::TimeTicks::Now() - req->request_time()); |
| 1590 } | 1597 } |
| 1591 req->OnComplete(net_error, list); | 1598 req->OnComplete(net_error, list); |
| 1592 | 1599 |
| 1593 // Check if the resolver was destroyed as a result of running the | 1600 // Check if the resolver was destroyed as a result of running the |
| 1594 // callback. If it was, we could continue, but we choose to bail. | 1601 // callback. If it was, we could continue, but we choose to bail. |
| 1595 if (!resolver_) | 1602 if (!resolver_) |
| 1596 return; | 1603 return; |
| 1597 } | 1604 } |
| 1598 } | 1605 } |
| 1599 | 1606 |
| 1607 // Convenience wrapper for CompleteRequests in case of failure. | |
| 1608 void CompleteRequestsWithError(int net_error) { | |
| 1609 CompleteRequests(net_error, AddressList(), base::TimeDelta(), false); | |
| 1610 } | |
| 1611 | |
| 1600 RequestPriority priority() const { | 1612 RequestPriority priority() const { |
| 1601 return priority_tracker_.highest_priority(); | 1613 return priority_tracker_.highest_priority(); |
| 1602 } | 1614 } |
| 1603 | 1615 |
| 1604 // Number of non-canceled requests in |requests_|. | 1616 // Number of non-canceled requests in |requests_|. |
| 1605 size_t num_active_requests() const { | 1617 size_t num_active_requests() const { |
| 1606 return priority_tracker_.total_count(); | 1618 return priority_tracker_.total_count(); |
| 1607 } | 1619 } |
| 1608 | 1620 |
| 1609 bool is_dns_running() const { | 1621 bool is_dns_running() const { |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1951 if (!info.allow_cached_response() || !cache_.get()) | 1963 if (!info.allow_cached_response() || !cache_.get()) |
| 1952 return false; | 1964 return false; |
| 1953 | 1965 |
| 1954 const HostCache::Entry* cache_entry = cache_->Lookup( | 1966 const HostCache::Entry* cache_entry = cache_->Lookup( |
| 1955 key, base::TimeTicks::Now()); | 1967 key, base::TimeTicks::Now()); |
| 1956 if (!cache_entry) | 1968 if (!cache_entry) |
| 1957 return false; | 1969 return false; |
| 1958 | 1970 |
| 1959 *net_error = cache_entry->error; | 1971 *net_error = cache_entry->error; |
| 1960 if (*net_error == OK) { | 1972 if (*net_error == OK) { |
| 1973 if (cache_entry->has_ttl()) | |
| 1974 RecordTTL(cache_entry->ttl); | |
| 1961 *addresses = cache_entry->addrlist; | 1975 *addresses = cache_entry->addrlist; |
| 1962 EnsurePortOnAddressList(info.port(), addresses); | 1976 EnsurePortOnAddressList(info.port(), addresses); |
| 1963 } | 1977 } |
| 1964 return true; | 1978 return true; |
| 1965 } | 1979 } |
| 1966 | 1980 |
| 1967 bool HostResolverImpl::ServeFromHosts(const Key& key, | 1981 bool HostResolverImpl::ServeFromHosts(const Key& key, |
| 1968 const RequestInfo& info, | 1982 const RequestInfo& info, |
| 1969 AddressList* addresses) { | 1983 AddressList* addresses) { |
| 1970 DCHECK(addresses); | 1984 DCHECK(addresses); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1991 it = hosts.find(DnsHostsKey(hostname, ADDRESS_FAMILY_IPV6)); | 2005 it = hosts.find(DnsHostsKey(hostname, ADDRESS_FAMILY_IPV6)); |
| 1992 if (it == hosts.end()) | 2006 if (it == hosts.end()) |
| 1993 return false; | 2007 return false; |
| 1994 } | 2008 } |
| 1995 | 2009 |
| 1996 *addresses = AddressList::CreateFromIPAddress(it->second, info.port()); | 2010 *addresses = AddressList::CreateFromIPAddress(it->second, info.port()); |
| 1997 return true; | 2011 return true; |
| 1998 } | 2012 } |
| 1999 | 2013 |
| 2000 void HostResolverImpl::CacheResult(const Key& key, | 2014 void HostResolverImpl::CacheResult(const Key& key, |
| 2001 int net_error, | 2015 const HostCache::Entry& entry, |
| 2002 const AddressList& addr_list, | |
| 2003 base::TimeDelta ttl) { | 2016 base::TimeDelta ttl) { |
| 2004 if (cache_.get()) | 2017 if (cache_.get()) |
| 2005 cache_->Set(key, net_error, addr_list, base::TimeTicks::Now(), ttl); | 2018 cache_->Set(key, entry, base::TimeTicks::Now(), ttl); |
| 2006 } | 2019 } |
| 2007 | 2020 |
| 2008 void HostResolverImpl::RemoveJob(Job* job) { | 2021 void HostResolverImpl::RemoveJob(Job* job) { |
| 2009 DCHECK(job); | 2022 DCHECK(job); |
| 2010 JobMap::iterator it = jobs_.find(job->key()); | 2023 JobMap::iterator it = jobs_.find(job->key()); |
| 2011 if (it != jobs_.end() && it->second == job) | 2024 if (it != jobs_.end() && it->second == job) |
| 2012 jobs_.erase(it); | 2025 jobs_.erase(it); |
| 2013 } | 2026 } |
| 2014 | 2027 |
| 2015 void HostResolverImpl::DiscardIPv6ProbeJob() { | 2028 void HostResolverImpl::DiscardIPv6ProbeJob() { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2146 // |this| may be deleted inside AbortAllInProgressJobs(). | 2159 // |this| may be deleted inside AbortAllInProgressJobs(). |
| 2147 if (self) | 2160 if (self) |
| 2148 TryServingAllJobsFromHosts(); | 2161 TryServingAllJobsFromHosts(); |
| 2149 } | 2162 } |
| 2150 | 2163 |
| 2151 bool HostResolverImpl::HaveDnsConfig() const { | 2164 bool HostResolverImpl::HaveDnsConfig() const { |
| 2152 return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL); | 2165 return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL); |
| 2153 } | 2166 } |
| 2154 | 2167 |
| 2155 } // namespace net | 2168 } // namespace net |
| OLD | NEW |