| 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 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 } | 515 } |
| 528 | 516 |
| 529 void set_job(Job* job) { | 517 void set_job(Job* job) { |
| 530 DCHECK(job); | 518 DCHECK(job); |
| 531 // Identify which job the request is waiting on. | 519 // Identify which job the request is waiting on. |
| 532 job_ = job; | 520 job_ = job; |
| 533 } | 521 } |
| 534 | 522 |
| 535 // Prepare final AddressList and call completion callback. | 523 // Prepare final AddressList and call completion callback. |
| 536 void OnComplete(int error, const AddressList& addr_list) { | 524 void OnComplete(int error, const AddressList& addr_list) { |
| 537 if (error == OK) | 525 if (error == OK) { |
| 538 *addresses_ = CreateAddressListUsingPort(addr_list, info_.port()); | 526 *addresses_ = addr_list; |
| 527 EnsurePortOnAddressList(info_.port(), addresses_); |
| 528 } |
| 539 CompletionCallback callback = callback_; | 529 CompletionCallback callback = callback_; |
| 540 MarkAsCanceled(); | 530 MarkAsCanceled(); |
| 541 callback.Run(error); | 531 callback.Run(error); |
| 542 } | 532 } |
| 543 | 533 |
| 544 Job* job() const { | 534 Job* job() const { |
| 545 return job_; | 535 return job_; |
| 546 } | 536 } |
| 547 | 537 |
| 548 // NetLog for the source, passed in HostResolver::Resolve. | 538 // NetLog for the source, passed in HostResolver::Resolve. |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 StartLookupAttempt(); | 719 StartLookupAttempt(); |
| 730 } | 720 } |
| 731 | 721 |
| 732 // Callback for when DoLookup() completes (runs on origin thread). | 722 // Callback for when DoLookup() completes (runs on origin thread). |
| 733 void OnLookupComplete(const AddressList& results, | 723 void OnLookupComplete(const AddressList& results, |
| 734 const base::TimeTicks& start_time, | 724 const base::TimeTicks& start_time, |
| 735 const uint32 attempt_number, | 725 const uint32 attempt_number, |
| 736 int error, | 726 int error, |
| 737 const int os_error) { | 727 const int os_error) { |
| 738 DCHECK(origin_loop_->BelongsToCurrentThread()); | 728 DCHECK(origin_loop_->BelongsToCurrentThread()); |
| 739 DCHECK(error || results.head()); | 729 DCHECK(error || !results.empty()); |
| 740 | 730 |
| 741 bool was_retry_attempt = attempt_number > 1; | 731 bool was_retry_attempt = attempt_number > 1; |
| 742 | 732 |
| 743 // Ideally the following code would be part of host_resolver_proc.cc, | 733 // Ideally the following code would be part of host_resolver_proc.cc, |
| 744 // however it isn't safe to call NetworkChangeNotifier from worker threads. | 734 // however it isn't safe to call NetworkChangeNotifier from worker threads. |
| 745 // So we do it here on the IO thread instead. | 735 // So we do it here on the IO thread instead. |
| 746 if (error != OK && NetworkChangeNotifier::IsOffline()) | 736 if (error != OK && NetworkChangeNotifier::IsOffline()) |
| 747 error = ERR_INTERNET_DISCONNECTED; | 737 error = ERR_INTERNET_DISCONNECTED; |
| 748 | 738 |
| 749 // If this is the first attempt that is finishing later, then record data | 739 // 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, | 1410 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
| 1421 OK); | 1411 OK); |
| 1422 return; | 1412 return; |
| 1423 } | 1413 } |
| 1424 | 1414 |
| 1425 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, | 1415 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HOST_RESOLVER_IMPL_JOB, |
| 1426 net_error); | 1416 net_error); |
| 1427 | 1417 |
| 1428 DCHECK(!requests_.empty()); | 1418 DCHECK(!requests_.empty()); |
| 1429 | 1419 |
| 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) | 1420 if (net_error == OK) |
| 1433 MutableSetPort(requests_->front()->info().port(), &list); | 1421 SetPortOnAddressList(requests_->front()->info().port(), &list); |
| 1434 | 1422 |
| 1435 if ((net_error != ERR_ABORTED) && | 1423 if ((net_error != ERR_ABORTED) && |
| 1436 (net_error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)) { | 1424 (net_error != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE)) { |
| 1437 resolver_->CacheResult(key_, net_error, list, ttl); | 1425 resolver_->CacheResult(key_, net_error, list, ttl); |
| 1438 } | 1426 } |
| 1439 | 1427 |
| 1440 // Complete all of the requests that were attached to the job. | 1428 // Complete all of the requests that were attached to the job. |
| 1441 for (RequestsList::const_iterator it = requests_.begin(); | 1429 for (RequestsList::const_iterator it = requests_.begin(); |
| 1442 it != requests_.end(); ++it) { | 1430 it != requests_.end(); ++it) { |
| 1443 Request* req = *it; | 1431 Request* req = *it; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1751 DCHECK_EQ(key.host_resolver_flags & | 1739 DCHECK_EQ(key.host_resolver_flags & |
| 1752 ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY | | 1740 ~(HOST_RESOLVER_CANONNAME | HOST_RESOLVER_LOOPBACK_ONLY | |
| 1753 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6), | 1741 HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6), |
| 1754 0) << " Unhandled flag"; | 1742 0) << " Unhandled flag"; |
| 1755 bool ipv6_disabled = (default_address_family_ == ADDRESS_FAMILY_IPV4) && | 1743 bool ipv6_disabled = (default_address_family_ == ADDRESS_FAMILY_IPV4) && |
| 1756 !ipv6_probe_monitoring_; | 1744 !ipv6_probe_monitoring_; |
| 1757 *net_error = OK; | 1745 *net_error = OK; |
| 1758 if ((ip_number.size() == kIPv6AddressSize) && ipv6_disabled) { | 1746 if ((ip_number.size() == kIPv6AddressSize) && ipv6_disabled) { |
| 1759 *net_error = ERR_NAME_NOT_RESOLVED; | 1747 *net_error = ERR_NAME_NOT_RESOLVED; |
| 1760 } else { | 1748 } else { |
| 1761 *addresses = AddressList::CreateFromIPAddressWithCname( | 1749 *addresses = AddressList::CreateFromIPAddress(ip_number, info.port()); |
| 1762 ip_number, info.port(), | 1750 if (key.host_resolver_flags & HOST_RESOLVER_CANONNAME) |
| 1763 (key.host_resolver_flags & HOST_RESOLVER_CANONNAME)); | 1751 addresses->SetDefaultCanonicalName(); |
| 1764 } | 1752 } |
| 1765 return true; | 1753 return true; |
| 1766 } | 1754 } |
| 1767 | 1755 |
| 1768 bool HostResolverImpl::ServeFromCache(const Key& key, | 1756 bool HostResolverImpl::ServeFromCache(const Key& key, |
| 1769 const RequestInfo& info, | 1757 const RequestInfo& info, |
| 1770 int* net_error, | 1758 int* net_error, |
| 1771 AddressList* addresses) { | 1759 AddressList* addresses) { |
| 1772 DCHECK(addresses); | 1760 DCHECK(addresses); |
| 1773 DCHECK(net_error); | 1761 DCHECK(net_error); |
| 1774 if (!info.allow_cached_response() || !cache_.get()) | 1762 if (!info.allow_cached_response() || !cache_.get()) |
| 1775 return false; | 1763 return false; |
| 1776 | 1764 |
| 1777 const HostCache::Entry* cache_entry = cache_->Lookup( | 1765 const HostCache::Entry* cache_entry = cache_->Lookup( |
| 1778 key, base::TimeTicks::Now()); | 1766 key, base::TimeTicks::Now()); |
| 1779 if (!cache_entry) | 1767 if (!cache_entry) |
| 1780 return false; | 1768 return false; |
| 1781 | 1769 |
| 1782 *net_error = cache_entry->error; | 1770 *net_error = cache_entry->error; |
| 1783 if (*net_error == OK) | 1771 if (*net_error == OK) { |
| 1784 *addresses = CreateAddressListUsingPort(cache_entry->addrlist, info.port()); | 1772 *addresses = cache_entry->addrlist; |
| 1773 EnsurePortOnAddressList(info.port(), addresses); |
| 1774 } |
| 1785 return true; | 1775 return true; |
| 1786 } | 1776 } |
| 1787 | 1777 |
| 1788 bool HostResolverImpl::ServeFromHosts(const Key& key, | 1778 bool HostResolverImpl::ServeFromHosts(const Key& key, |
| 1789 const RequestInfo& info, | 1779 const RequestInfo& info, |
| 1790 AddressList* addresses) { | 1780 AddressList* addresses) { |
| 1791 DCHECK(addresses); | 1781 DCHECK(addresses); |
| 1792 if (!HaveDnsConfig()) | 1782 if (!HaveDnsConfig()) |
| 1793 return false; | 1783 return false; |
| 1794 | 1784 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1975 | 1965 |
| 1976 if (self && dns_config.IsValid()) | 1966 if (self && dns_config.IsValid()) |
| 1977 TryServingAllJobsFromHosts(); | 1967 TryServingAllJobsFromHosts(); |
| 1978 } | 1968 } |
| 1979 | 1969 |
| 1980 bool HostResolverImpl::HaveDnsConfig() const { | 1970 bool HostResolverImpl::HaveDnsConfig() const { |
| 1981 return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL); | 1971 return (dns_client_.get() != NULL) && (dns_client_->GetConfig() != NULL); |
| 1982 } | 1972 } |
| 1983 | 1973 |
| 1984 } // namespace net | 1974 } // namespace net |
| OLD | NEW |