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

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

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

Powered by Google App Engine
This is Rietveld 408576698