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

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

Issue 9667025: [net/dns] Serve requests from HOSTS file if possible. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/host_resolver_impl.h ('k') | net/base/net_log_event_type_list.h » ('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 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 handle_.Reset(); 1198 handle_.Reset();
1199 1199
1200 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_EVICTED, NULL); 1200 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB_EVICTED, NULL);
1201 1201
1202 // This signals to CompleteRequests that this job never ran. 1202 // This signals to CompleteRequests that this job never ran.
1203 CompleteRequests(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE, 1203 CompleteRequests(ERR_HOST_RESOLVER_QUEUE_TOO_LARGE,
1204 AddressList(), 1204 AddressList(),
1205 base::TimeDelta()); 1205 base::TimeDelta());
1206 } 1206 }
1207 1207
1208 // Attempt to serve the job from hosts.
1209 void ServeFromHosts() {
szym 2012/03/10 06:48:49 Add a bool return so that the caller knows if this
1210 DCHECK_GT(num_active_requests(), 0u);
1211 AddressList addr_list;
1212 if (resolver_->ServeFromHosts(key(),
1213 requests_.front()->info(),
1214 &addr_list)) {
1215 CompleteRequests(OK, addr_list, base::TimeDelta());
1216 }
1217 }
1218
1208 private: 1219 private:
1209 RequestPriority priority() const { 1220 RequestPriority priority() const {
1210 return priority_tracker_.highest_priority(); 1221 return priority_tracker_.highest_priority();
1211 } 1222 }
1212 1223
1213 // Number of non-canceled requests in |requests_|. 1224 // Number of non-canceled requests in |requests_|.
1214 size_t num_active_requests() const { 1225 size_t num_active_requests() const {
1215 return priority_tracker_.total_count(); 1226 return priority_tracker_.total_count();
1216 } 1227 }
1217 1228
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 } 1296 }
1286 1297
1287 // Called by DnsTask when it completes. 1298 // Called by DnsTask when it completes.
1288 void OnDnsTaskComplete(int net_error, 1299 void OnDnsTaskComplete(int net_error,
1289 const AddressList& addr_list, 1300 const AddressList& addr_list,
1290 base::TimeDelta ttl) { 1301 base::TimeDelta ttl) {
1291 DCHECK(is_dns_running()); 1302 DCHECK(is_dns_running());
1292 1303
1293 if (net_error != OK) { 1304 if (net_error != OK) {
1294 dns_task_.reset(); 1305 dns_task_.reset();
1306
1307 // TODO(szym): Run ServeFromHosts now if nsswitch.conf says so.
1308 // http://crbug.com/117655
1309
1295 // TODO(szym): Some net errors indicate lack of connectivity. Starting 1310 // TODO(szym): Some net errors indicate lack of connectivity. Starting
1296 // ProcTask in that case is a waste of time. 1311 // ProcTask in that case is a waste of time.
1297 StartProcTask(); 1312 StartProcTask();
1298 return; 1313 return;
1299 } 1314 }
1300 1315
1301 CompleteRequests(net_error, addr_list, ttl); 1316 CompleteRequests(net_error, addr_list, ttl);
1302 } 1317 }
1303 1318
1304 // Performs Job's last rites. Completes all Requests. Deletes this. 1319 // Performs Job's last rites. Completes all Requests. Deletes this.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 if (num_active_requests() == 0) { 1352 if (num_active_requests() == 0) {
1338 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); 1353 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL);
1339 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, 1354 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB,
1340 OK); 1355 OK);
1341 return; 1356 return;
1342 } 1357 }
1343 1358
1344 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, 1359 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB,
1345 net_error); 1360 net_error);
1346 1361
1362 DCHECK(!requests_.empty());
1363
1347 // We are the only consumer of |list|, so we can safely change the port 1364 // 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. 1365 // without copy-on-write. This pays off, when job has only one request.
1349 if (net_error == OK && !requests_.empty()) 1366 if (net_error == OK)
1350 MutableSetPort(requests_.front()->info().port(), &list); 1367 MutableSetPort(requests_.front()->info().port(), &list);
1351 1368
1352 if ((net_error != ERR_ABORTED) && 1369 if ((net_error != ERR_ABORTED) &&
1353 (net_error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)) { 1370 (net_error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)) {
1354 resolver_->CacheResult(key_, net_error, list, ttl); 1371 resolver_->CacheResult(key_, net_error, list, ttl);
1355 } 1372 }
1356 1373
1357 // Complete all of the requests that were attached to the job. 1374 // Complete all of the requests that were attached to the job.
1358 for (RequestsList::const_iterator it = requests_.begin(); 1375 for (RequestsList::const_iterator it = requests_.begin();
1359 it != requests_.end(); ++it) { 1376 it != requests_.end(); ++it) {
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 const BoundNetLog& request_net_log) { 1562 const BoundNetLog& request_net_log) {
1546 // The result of |getaddrinfo| for empty hosts is inconsistent across systems. 1563 // 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 1564 // 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. 1565 // gives an error. We will make it fail on all platforms for consistency.
1549 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) 1566 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength)
1550 return ERR_NAME_NOT_RESOLVED; 1567 return ERR_NAME_NOT_RESOLVED;
1551 1568
1552 int net_error = ERR_UNEXPECTED; 1569 int net_error = ERR_UNEXPECTED;
1553 if (ResolveAsIP(key, info, &net_error, addresses)) 1570 if (ResolveAsIP(key, info, &net_error, addresses))
1554 return net_error; 1571 return net_error;
1555 net_error = ERR_DNS_CACHE_MISS; 1572 if (ServeFromCache(key, info, &net_error, addresses)) {
1556 ServeFromCache(key, info, request_net_log, &net_error, addresses); 1573 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL);
1557 return net_error; 1574 return net_error;
1575 }
1576 // TODO(szym): Do not do this if nsswitch.conf instructs not to.
1577 // http://crbug.com/117655
1578 if (ServeFromHosts(key, info, addresses)) {
1579 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT, NULL);
1580 return OK;
1581 }
1582 return ERR_DNS_CACHE_MISS;
1558 } 1583 }
1559 1584
1560 int HostResolverImpl::ResolveFromCache(const RequestInfo& info, 1585 int HostResolverImpl::ResolveFromCache(const RequestInfo& info,
1561 AddressList* addresses, 1586 AddressList* addresses,
1562 const BoundNetLog& source_net_log) { 1587 const BoundNetLog& source_net_log) {
1563 DCHECK(CalledOnValidThread()); 1588 DCHECK(CalledOnValidThread());
1564 DCHECK(addresses); 1589 DCHECK(addresses);
1565 1590
1566 // Make a log item for the request. 1591 // Make a log item for the request.
1567 BoundNetLog request_net_log = BoundNetLog::Make(net_log_, 1592 BoundNetLog request_net_log = BoundNetLog::Make(net_log_,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 } else { 1655 } else {
1631 *addresses = AddressList::CreateFromIPAddressWithCname( 1656 *addresses = AddressList::CreateFromIPAddressWithCname(
1632 ip_number, info.port(), 1657 ip_number, info.port(),
1633 (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)); 1658 (key.host_resolver_flags & HOST_RESOLVER_CANONNAME));
1634 } 1659 }
1635 return true; 1660 return true;
1636 } 1661 }
1637 1662
1638 bool HostResolverImpl::ServeFromCache(const Key& key, 1663 bool HostResolverImpl::ServeFromCache(const Key& key,
1639 const RequestInfo& info, 1664 const RequestInfo& info,
1640 const BoundNetLog& request_net_log,
1641 int* net_error, 1665 int* net_error,
1642 AddressList* addresses) { 1666 AddressList* addresses) {
1643 DCHECK(addresses); 1667 DCHECK(addresses);
1644 DCHECK(net_error); 1668 DCHECK(net_error);
1645 if (!info.allow_cached_response() || !cache_.get()) 1669 if (!info.allow_cached_response() || !cache_.get())
1646 return false; 1670 return false;
1647 1671
1648 const HostCache::Entry* cache_entry = cache_->Lookup( 1672 const HostCache::Entry* cache_entry = cache_->Lookup(
1649 key, base::TimeTicks::Now()); 1673 key, base::TimeTicks::Now());
1650 if (!cache_entry) 1674 if (!cache_entry)
1651 return false; 1675 return false;
1652 1676
1653 request_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT, NULL); 1677
1654 *net_error = cache_entry->error; 1678 *net_error = cache_entry->error;
1655 if (*net_error == OK) 1679 if (*net_error == OK)
1656 *addresses = CreateAddressListUsingPort(cache_entry->addrlist, info.port()); 1680 *addresses = CreateAddressListUsingPort(cache_entry->addrlist, info.port());
1657 return true; 1681 return true;
1658 } 1682 }
1659 1683
1684 bool HostResolverImpl::ServeFromHosts(const Key& key,
1685 const RequestInfo& info,
1686 AddressList* addresses) {
1687 DCHECK(addresses);
1688 if (!dns_session_)
1689 return false;
1690
1691 const DnsHosts& hosts = dns_session_->config().hosts;
1692 DnsHosts::const_iterator it = hosts.find(DnsHostsKey(key.hostname,
1693 key.address_family));
1694 if (it == hosts.end())
1695 return false;
1696
1697 *addresses = AddressList::CreateFromIPAddress(it->second, info.port());
1698 return true;
1699 }
1700
1660 void HostResolverImpl::CacheResult(const Key& key, 1701 void HostResolverImpl::CacheResult(const Key& key,
1661 int net_error, 1702 int net_error,
1662 const AddressList& addr_list, 1703 const AddressList& addr_list,
1663 base::TimeDelta ttl) { 1704 base::TimeDelta ttl) {
1664 if (cache_.get()) 1705 if (cache_.get())
1665 cache_->Set(key, net_error, addr_list, base::TimeTicks::Now(), ttl); 1706 cache_->Set(key, net_error, addr_list, base::TimeTicks::Now(), ttl);
1666 } 1707 }
1667 1708
1668 void HostResolverImpl::RemoveJob(Job* job) { 1709 void HostResolverImpl::RemoveJob(Job* job) {
1669 DCHECK(job); 1710 DCHECK(job);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 1768
1728 // Life check to bail once |this| is deleted. 1769 // Life check to bail once |this| is deleted.
1729 base::WeakPtr<HostResolverImpl> self = AsWeakPtr(); 1770 base::WeakPtr<HostResolverImpl> self = AsWeakPtr();
1730 1771
1731 // Then Abort them. 1772 // Then Abort them.
1732 for (size_t i = 0; self && i < jobs_to_abort.size(); ++i) { 1773 for (size_t i = 0; self && i < jobs_to_abort.size(); ++i) {
1733 jobs_to_abort[i]->Abort(); 1774 jobs_to_abort[i]->Abort();
1734 } 1775 }
1735 } 1776 }
1736 1777
1778 void HostResolverImpl::TryServingAllJobsFromHosts() {
1779 if (!dns_session_)
1780 return;
1781
1782 // TODO(szym): Do not do this if nsswitch.conf instructs not to.
1783 // http://crbug.com/117655
1784
1785 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) {
1786 Job* job = (it++)->second;
1787 // This could remove |job| from |jobs_|, but iterators remain valid.
1788 job->ServeFromHosts();
szym 2012/03/10 06:48:49 HostResolverImpl could be destroyed in Request cal
1789 }
1790 }
1791
1737 void HostResolverImpl::OnIPAddressChanged() { 1792 void HostResolverImpl::OnIPAddressChanged() {
1738 if (cache_.get()) 1793 if (cache_.get())
1739 cache_->clear(); 1794 cache_->clear();
1740 if (ipv6_probe_monitoring_) { 1795 if (ipv6_probe_monitoring_) {
1741 DiscardIPv6ProbeJob(); 1796 DiscardIPv6ProbeJob();
1742 ipv6_probe_job_ = new IPv6ProbeJob(this); 1797 ipv6_probe_job_ = new IPv6ProbeJob(this);
1743 ipv6_probe_job_->Start(); 1798 ipv6_probe_job_->Start();
1744 } 1799 }
1745 #if defined(OS_POSIX) && !defined(OS_MACOSX) 1800 #if defined(OS_POSIX) && !defined(OS_MACOSX)
1746 if (HaveOnlyLoopbackAddresses()) { 1801 if (HaveOnlyLoopbackAddresses()) {
(...skipping 17 matching lines...) Expand all
1764 // be aborted. TODO(Craig): Should these jobs be restarted? 1819 // be aborted. TODO(Craig): Should these jobs be restarted?
1765 AbortAllInProgressJobs(); 1820 AbortAllInProgressJobs();
1766 // |this| may be deleted inside AbortAllInProgressJobs(). 1821 // |this| may be deleted inside AbortAllInProgressJobs().
1767 } 1822 }
1768 1823
1769 void HostResolverImpl::OnConfigChanged(const DnsConfig& dns_config) { 1824 void HostResolverImpl::OnConfigChanged(const DnsConfig& dns_config) {
1770 // We want a new factory in place, before we Abort running Jobs, so that the 1825 // We want a new factory in place, before we Abort running Jobs, so that the
1771 // newly started jobs use the new factory. 1826 // newly started jobs use the new factory.
1772 bool had_factory = (dns_transaction_factory_.get() != NULL); 1827 bool had_factory = (dns_transaction_factory_.get() != NULL);
1773 if (dns_config.IsValid()) { 1828 if (dns_config.IsValid()) {
1774 dns_transaction_factory_ = DnsTransactionFactory::CreateFactory( 1829 dns_session_ = new DnsSession(dns_config,
1775 new DnsSession(dns_config, 1830 ClientSocketFactory::GetDefaultFactory(),
1776 ClientSocketFactory::GetDefaultFactory(), 1831 base::Bind(&base::RandInt),
1777 base::Bind(&base::RandInt), 1832 net_log_);
1778 net_log_)); 1833 dns_transaction_factory_ =
1834 DnsTransactionFactory::CreateFactory(dns_session_);
1835
1836 TryServingAllJobsFromHosts();
1779 } else { 1837 } else {
1780 dns_transaction_factory_.reset(); 1838 dns_transaction_factory_.reset();
1839 dns_session_.release();
1781 } 1840 }
1782 // Don't Abort running Jobs unless they were running on DnsTransaction. 1841 // Don't Abort running Jobs unless they were running on DnsTransaction.
1783 // TODO(szym): This will change once http://crbug.com/114827 is fixed. 1842 // TODO(szym): This will change once http://crbug.com/114827 is fixed.
1784 if (had_factory) 1843 if (had_factory)
1785 OnDNSChanged(NetworkChangeNotifier::CHANGE_DNS_SETTINGS); 1844 OnDNSChanged(NetworkChangeNotifier::CHANGE_DNS_SETTINGS);
1786 } 1845 }
1787 1846
1788 } // namespace net 1847 } // namespace net
OLDNEW
« no previous file with comments | « net/base/host_resolver_impl.h ('k') | net/base/net_log_event_type_list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698