| 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 // Default TTL for unsuccessful resolutions with ProcTask. | 63 // Default TTL for unsuccessful resolutions with ProcTask. |
| 64 const unsigned kNegativeCacheEntryTTLSeconds = 0; | 64 const unsigned kNegativeCacheEntryTTLSeconds = 0; |
| 65 | 65 |
| 66 // Maximum of 6 concurrent resolver threads (excluding retries). | 66 // Maximum of 6 concurrent resolver threads (excluding retries). |
| 67 // Some routers (or resolvers) appear to start to provide host-not-found if | 67 // Some routers (or resolvers) appear to start to provide host-not-found if |
| 68 // too many simultaneous resolutions are pending. This number needs to be | 68 // too many simultaneous resolutions are pending. This number needs to be |
| 69 // further optimized, but 8 is what FF currently does. We found some routers | 69 // further optimized, but 8 is what FF currently does. We found some routers |
| 70 // that limit this to 6, so we're temporarily holding it at that level. | 70 // that limit this to 6, so we're temporarily holding it at that level. |
| 71 static const size_t kDefaultMaxProcTasks = 6u; | 71 static const size_t kDefaultMaxProcTasks = 6u; |
| 72 | 72 |
| 73 // Helper to mutate the linked list contained by AddressList to the given | |
| 74 // port. Note that in general this is dangerous since the AddressList's | |
| 75 // data might be shared (and you should use AddressList::SetPort). | |
| 76 // | |
| 77 // However since we allocated the AddressList ourselves we can safely | |
| 78 // do this optimization and avoid reallocating the list. | |
| 79 void MutableSetPort(int port, AddressList* addr_list) { | |
| 80 struct addrinfo* mutable_head = | |
| 81 const_cast<struct addrinfo*>(addr_list->head()); | |
| 82 SetPortForAllAddrinfos(mutable_head, port); | |
| 83 } | |
| 84 | |
| 85 // We use a separate histogram name for each platform to facilitate the | 73 // We use a separate histogram name for each platform to facilitate the |
| 86 // display of error codes by their symbolic name (since each platform has | 74 // display of error codes by their symbolic name (since each platform has |
| 87 // different mappings). | 75 // different mappings). |
| 88 const char kOSErrorsForGetAddrinfoHistogramName[] = | 76 const char kOSErrorsForGetAddrinfoHistogramName[] = |
| 89 #if defined(OS_WIN) | 77 #if defined(OS_WIN) |
| 90 "Net.OSErrorsForGetAddrinfo_Win"; | 78 "Net.OSErrorsForGetAddrinfo_Win"; |
| 91 #elif defined(OS_MACOSX) | 79 #elif defined(OS_MACOSX) |
| 92 "Net.OSErrorsForGetAddrinfo_Mac"; | 80 "Net.OSErrorsForGetAddrinfo_Mac"; |
| 93 #elif defined(OS_LINUX) | 81 #elif defined(OS_LINUX) |
| 94 "Net.OSErrorsForGetAddrinfo_Linux"; | 82 "Net.OSErrorsForGetAddrinfo_Linux"; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 address_family, | 161 address_family, |
| 174 host_resolver_flags, | 162 host_resolver_flags, |
| 175 addr_list, | 163 addr_list, |
| 176 os_error); | 164 os_error); |
| 177 } | 165 } |
| 178 | 166 |
| 179 protected: | 167 protected: |
| 180 virtual ~CallSystemHostResolverProc() {} | 168 virtual ~CallSystemHostResolverProc() {} |
| 181 }; | 169 }; |
| 182 | 170 |
| 171 void EnsurePortOnAddressList(uint16 port, AddressList* list) { |
| 172 DCHECK(list); |
| 173 if (list->empty() || list->front().port() == port) |
| 174 return; |
| 175 SetPortOnAddressList(port, list); |
| 176 } |
| 177 |
| 183 // Extra parameters to attach to the NetLog when the resolve failed. | 178 // Extra parameters to attach to the NetLog when the resolve failed. |
| 184 class ProcTaskFailedParams : public NetLog::EventParameters { | 179 class ProcTaskFailedParams : public NetLog::EventParameters { |
| 185 public: | 180 public: |
| 186 ProcTaskFailedParams(uint32 attempt_number, int net_error, int os_error) | 181 ProcTaskFailedParams(uint32 attempt_number, int net_error, int os_error) |
| 187 : attempt_number_(attempt_number), | 182 : attempt_number_(attempt_number), |
| 188 net_error_(net_error), | 183 net_error_(net_error), |
| 189 os_error_(os_error) { | 184 os_error_(os_error) { |
| 190 } | 185 } |
| 191 | 186 |
| 192 virtual Value* ToValue() const OVERRIDE { | 187 virtual Value* ToValue() const OVERRIDE { |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 } | 522 } |
| 528 | 523 |
| 529 void set_job(Job* job) { | 524 void set_job(Job* job) { |
| 530 DCHECK(job); | 525 DCHECK(job); |
| 531 // Identify which job the request is waiting on. | 526 // Identify which job the request is waiting on. |
| 532 job_ = job; | 527 job_ = job; |
| 533 } | 528 } |
| 534 | 529 |
| 535 // Prepare final AddressList and call completion callback. | 530 // Prepare final AddressList and call completion callback. |
| 536 void OnComplete(int error, const AddressList& addr_list) { | 531 void OnComplete(int error, const AddressList& addr_list) { |
| 537 if (error == OK) | 532 if (error == OK) { |
| 538 *addresses_ = CreateAddressListUsingPort(addr_list, info_.port()); | 533 *addresses_ = addr_list; |
| 534 EnsurePortOnAddressList(info_.port(), addresses_); |
| 535 } |
| 539 CompletionCallback callback = callback_; | 536 CompletionCallback callback = callback_; |
| 540 MarkAsCanceled(); | 537 MarkAsCanceled(); |
| 541 callback.Run(error); | 538 callback.Run(error); |
| 542 } | 539 } |
| 543 | 540 |
| 544 Job* job() const { | 541 Job* job() const { |
| 545 return job_; | 542 return job_; |
| 546 } | 543 } |
| 547 | 544 |
| 548 // NetLog for the source, passed in HostResolver::Resolve. | 545 // NetLog for the source, passed in HostResolver::Resolve. |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 StartLookupAttempt(); | 726 StartLookupAttempt(); |
| 730 } | 727 } |
| 731 | 728 |
| 732 // Callback for when DoLookup() completes (runs on origin thread). | 729 // Callback for when DoLookup() completes (runs on origin thread). |
| 733 void OnLookupComplete(const AddressList& results, | 730 void OnLookupComplete(const AddressList& results, |
| 734 const base::TimeTicks& start_time, | 731 const base::TimeTicks& start_time, |
| 735 const uint32 attempt_number, | 732 const uint32 attempt_number, |
| 736 int error, | 733 int error, |
| 737 const int os_error) { | 734 const int os_error) { |
| 738 DCHECK(origin_loop_->BelongsToCurrentThread()); | 735 DCHECK(origin_loop_->BelongsToCurrentThread()); |
| 739 DCHECK(error || results.head()); | 736 DCHECK(error || !results.empty()); |
| 740 | 737 |
| 741 bool was_retry_attempt = attempt_number > 1; | 738 bool was_retry_attempt = attempt_number > 1; |
| 742 | 739 |
| 743 // Ideally the following code would be part of host_resolver_proc.cc, | 740 // Ideally the following code would be part of host_resolver_proc.cc, |
| 744 // however it isn't safe to call NetworkChangeNotifier from worker threads. | 741 // however it isn't safe to call NetworkChangeNotifier from worker threads. |
| 745 // So we do it here on the IO thread instead. | 742 // So we do it here on the IO thread instead. |
| 746 if (error != OK && NetworkChangeNotifier::IsOffline()) | 743 if (error != OK && NetworkChangeNotifier::IsOffline()) |
| 747 error = ERR_INTERNET_DISCONNECTED; | 744 error = ERR_INTERNET_DISCONNECTED; |
| 748 | 745 |
| 749 // If this is the first attempt that is finishing later, then record data | 746 // If this is the first attempt that is finishing later, then record data |
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1420 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, | 1417 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
| 1421 OK); | 1418 OK); |
| 1422 return; | 1419 return; |
| 1423 } | 1420 } |
| 1424 | 1421 |
| 1425 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, | 1422 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
| 1426 net_error); | 1423 net_error); |
| 1427 | 1424 |
| 1428 DCHECK(!requests_.empty()); | 1425 DCHECK(!requests_.empty()); |
| 1429 | 1426 |
| 1430 // We are the only consumer of |list|, so we can safely change the port | |
| 1431 // without copy-on-write. This pays off, when job has only one request. | |
| 1432 if (net_error == OK) | 1427 if (net_error == OK) |
| 1433 MutableSetPort(requests_->front()->info().port(), &list); | 1428 SetPortOnAddressList(requests_->front()->info().port(), &list); |
| 1434 | 1429 |
| 1435 if ((net_error != ERR_ABORTED) && | 1430 if ((net_error != ERR_ABORTED) && |
| 1436 (net_error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)) { | 1431 (net_error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)) { |
| 1437 resolver_->CacheResult(key_, net_error, list, ttl); | 1432 resolver_->CacheResult(key_, net_error, list, ttl); |
| 1438 } | 1433 } |
| 1439 | 1434 |
| 1440 // Complete all of the requests that were attached to the job. | 1435 // Complete all of the requests that were attached to the job. |
| 1441 for (RequestsList::const_iterator it = requests_.begin(); | 1436 for (RequestsList::const_iterator it = requests_.begin(); |
| 1442 it != requests_.end(); ++it) { | 1437 it != requests_.end(); ++it) { |
| 1443 Request* req = *it; | 1438 Request* req = *it; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1751 DCHECK_EQ(key.host_resolver_flags & | 1746 DCHECK_EQ(key.host_resolver_flags & |
| 1752 ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY | | 1747 ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY | |
| 1753 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6), | 1748 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6), |
| 1754 0) << " Unhandled flag"; | 1749 0) << " Unhandled flag"; |
| 1755 bool ipv6_disabled = (default_address_family_ == ADDRESS_FAMILY_IPV4) && | 1750 bool ipv6_disabled = (default_address_family_ == ADDRESS_FAMILY_IPV4) && |
| 1756 !ipv6_probe_monitoring_; | 1751 !ipv6_probe_monitoring_; |
| 1757 *net_error = OK; | 1752 *net_error = OK; |
| 1758 if ((ip_number.size() == kIPv6AddressSize) && ipv6_disabled) { | 1753 if ((ip_number.size() == kIPv6AddressSize) && ipv6_disabled) { |
| 1759 *net_error = ERR_NAME_NOT_RESOLVED; | 1754 *net_error = ERR_NAME_NOT_RESOLVED; |
| 1760 } else { | 1755 } else { |
| 1761 *addresses = AddressList::CreateFromIPAddressWithCname( | 1756 *addresses = AddressList::CreateFromIPAddress(ip_number, info.port()); |
| 1762 ip_number, info.port(), | 1757 if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME) |
| 1763 (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)); | 1758 addresses->SetDefaultCanonicalName(); |
| 1764 } | 1759 } |
| 1765 return true; | 1760 return true; |
| 1766 } | 1761 } |
| 1767 | 1762 |
| 1768 bool HostResolverImpl::ServeFromCache(const Key& key, | 1763 bool HostResolverImpl::ServeFromCache(const Key& key, |
| 1769 const RequestInfo& info, | 1764 const RequestInfo& info, |
| 1770 int* net_error, | 1765 int* net_error, |
| 1771 AddressList* addresses) { | 1766 AddressList* addresses) { |
| 1772 DCHECK(addresses); | 1767 DCHECK(addresses); |
| 1773 DCHECK(net_error); | 1768 DCHECK(net_error); |
| 1774 if (!info.allow_cached_response() || !cache_.get()) | 1769 if (!info.allow_cached_response() || !cache_.get()) |
| 1775 return false; | 1770 return false; |
| 1776 | 1771 |
| 1777 const HostCache::Entry* cache_entry = cache_->Lookup( | 1772 const HostCache::Entry* cache_entry = cache_->Lookup( |
| 1778 key, base::TimeTicks::Now()); | 1773 key, base::TimeTicks::Now()); |
| 1779 if (!cache_entry) | 1774 if (!cache_entry) |
| 1780 return false; | 1775 return false; |
| 1781 | 1776 |
| 1782 *net_error = cache_entry->error; | 1777 *net_error = cache_entry->error; |
| 1783 if (*net_error == OK) | 1778 if (*net_error == OK) { |
| 1784 *addresses = CreateAddressListUsingPort(cache_entry->addrlist, info.port()); | 1779 *addresses = cache_entry->addrlist; |
| 1780 EnsurePortOnAddressList(info.port(), addresses); |
| 1781 } |
| 1785 return true; | 1782 return true; |
| 1786 } | 1783 } |
| 1787 | 1784 |
| 1788 bool HostResolverImpl::ServeFromHosts(const Key& key, | 1785 bool HostResolverImpl::ServeFromHosts(const Key& key, |
| 1789 const RequestInfo& info, | 1786 const RequestInfo& info, |
| 1790 AddressList* addresses) { | 1787 AddressList* addresses) { |
| 1791 DCHECK(addresses); | 1788 DCHECK(addresses); |
| 1792 if (!HaveDnsConfig()) | 1789 if (!HaveDnsConfig()) |
| 1793 return false; | 1790 return false; |
| 1794 | 1791 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1975 | 1972 |
| 1976 if (self && dns_config.IsValid()) | 1973 if (self && dns_config.IsValid()) |
| 1977 TryServingAllJobsFromHosts(); | 1974 TryServingAllJobsFromHosts(); |
| 1978 } | 1975 } |
| 1979 | 1976 |
| 1980 bool HostResolverImpl::HaveDnsConfig() const { | 1977 bool HostResolverImpl::HaveDnsConfig() const { |
| 1981 return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL); | 1978 return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL); |
| 1982 } | 1979 } |
| 1983 | 1980 |
| 1984 } // namespace net | 1981 } // namespace net |
| OLD | NEW |