address_info.cc 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Copyright (c) 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/dns/address_info.h"
  5. #include <memory>
  6. #include "base/logging.h"
  7. #include "base/notreached.h"
  8. #include "base/sys_byteorder.h"
  9. #include "build/build_config.h"
  10. #include "net/base/address_list.h"
  11. #include "net/base/net_errors.h"
  12. #include "net/base/sys_addrinfo.h"
  13. #if BUILDFLAG(IS_ANDROID)
  14. #include "net/android/network_library.h"
  15. #endif // BUILDFLAG(IS_ANDROID)
  16. namespace net {
  17. namespace {
  18. const addrinfo* Next(const addrinfo* ai) {
  19. return ai->ai_next;
  20. }
  21. } // namespace
  22. //// iterator
  23. AddressInfo::const_iterator::const_iterator(const addrinfo* ai) : ai_(ai) {}
  24. bool AddressInfo::const_iterator::operator!=(
  25. const AddressInfo::const_iterator& o) const {
  26. return ai_ != o.ai_;
  27. }
  28. AddressInfo::const_iterator& AddressInfo::const_iterator::operator++() {
  29. ai_ = Next(ai_);
  30. return *this;
  31. }
  32. const addrinfo* AddressInfo::const_iterator::operator->() const {
  33. return ai_;
  34. }
  35. const addrinfo& AddressInfo::const_iterator::operator*() const {
  36. return *ai_;
  37. }
  38. //// constructors
  39. AddressInfo::AddressInfoAndResult AddressInfo::Get(
  40. const std::string& host,
  41. const addrinfo& hints,
  42. std::unique_ptr<AddrInfoGetter> getter,
  43. handles::NetworkHandle network) {
  44. if (getter == nullptr)
  45. getter = std::make_unique<AddrInfoGetter>();
  46. int err = OK;
  47. int os_error = 0;
  48. std::unique_ptr<addrinfo, FreeAddrInfoFunc> ai =
  49. getter->getaddrinfo(host, &hints, &os_error, network);
  50. if (!ai) {
  51. err = ERR_NAME_NOT_RESOLVED;
  52. // If the call to getaddrinfo() failed because of a system error, report
  53. // it separately from ERR_NAME_NOT_RESOLVED.
  54. #if BUILDFLAG(IS_WIN)
  55. if (os_error != WSAHOST_NOT_FOUND && os_error != WSANO_DATA)
  56. err = ERR_NAME_RESOLUTION_FAILED;
  57. #elif BUILDFLAG(IS_ANDROID)
  58. // Workaround for Android's getaddrinfo leaving ai==nullptr without an
  59. // error.
  60. // http://crbug.com/134142
  61. err = ERR_NAME_NOT_RESOLVED;
  62. #elif BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_FREEBSD)
  63. if (os_error != EAI_NONAME && os_error != EAI_NODATA)
  64. err = ERR_NAME_RESOLUTION_FAILED;
  65. #endif
  66. return AddressInfoAndResult(absl::optional<AddressInfo>(), err, os_error);
  67. }
  68. return AddressInfoAndResult(absl::optional<AddressInfo>(AddressInfo(
  69. std::move(ai), std::move(getter))),
  70. OK, 0);
  71. }
  72. AddressInfo::AddressInfo(AddressInfo&& other) = default;
  73. AddressInfo& AddressInfo::operator=(AddressInfo&& other) = default;
  74. AddressInfo::~AddressInfo() = default;
  75. //// public methods
  76. AddressInfo::const_iterator AddressInfo::begin() const {
  77. return const_iterator(ai_.get());
  78. }
  79. AddressInfo::const_iterator AddressInfo::end() const {
  80. return const_iterator(nullptr);
  81. }
  82. absl::optional<std::string> AddressInfo::GetCanonicalName() const {
  83. return (ai_->ai_canonname != nullptr)
  84. ? absl::optional<std::string>(std::string(ai_->ai_canonname))
  85. : absl::optional<std::string>();
  86. }
  87. bool AddressInfo::IsAllLocalhostOfOneFamily() const {
  88. bool saw_v4_localhost = false;
  89. bool saw_v6_localhost = false;
  90. const auto* ai = ai_.get();
  91. for (; ai != nullptr; ai = Next(ai)) {
  92. switch (ai->ai_family) {
  93. case AF_INET: {
  94. const struct sockaddr_in* addr_in =
  95. reinterpret_cast<struct sockaddr_in*>(ai->ai_addr);
  96. if ((base::NetToHost32(addr_in->sin_addr.s_addr) & 0xff000000) ==
  97. 0x7f000000)
  98. saw_v4_localhost = true;
  99. else
  100. return false;
  101. break;
  102. }
  103. case AF_INET6: {
  104. const struct sockaddr_in6* addr_in6 =
  105. reinterpret_cast<struct sockaddr_in6*>(ai->ai_addr);
  106. if (IN6_IS_ADDR_LOOPBACK(&addr_in6->sin6_addr))
  107. saw_v6_localhost = true;
  108. else
  109. return false;
  110. break;
  111. }
  112. default:
  113. NOTREACHED();
  114. return false;
  115. }
  116. }
  117. return saw_v4_localhost != saw_v6_localhost;
  118. }
  119. AddressList AddressInfo::CreateAddressList() const {
  120. AddressList list;
  121. auto canonical_name = GetCanonicalName();
  122. if (canonical_name) {
  123. std::vector<std::string> aliases({*canonical_name});
  124. list.SetDnsAliases(std::move(aliases));
  125. }
  126. for (auto&& ai : *this) {
  127. IPEndPoint ipe;
  128. // NOTE: Ignoring non-INET* families.
  129. if (ipe.FromSockAddr(ai.ai_addr, ai.ai_addrlen))
  130. list.push_back(ipe);
  131. else
  132. DLOG(WARNING) << "Unknown family found in addrinfo: " << ai.ai_family;
  133. }
  134. return list;
  135. }
  136. //// private methods
  137. AddressInfo::AddressInfo(std::unique_ptr<addrinfo, FreeAddrInfoFunc> ai,
  138. std::unique_ptr<AddrInfoGetter> getter)
  139. : ai_(std::move(ai)), getter_(std::move(getter)) {}
  140. //// AddrInfoGetter
  141. AddrInfoGetter::AddrInfoGetter() = default;
  142. AddrInfoGetter::~AddrInfoGetter() = default;
  143. std::unique_ptr<addrinfo, FreeAddrInfoFunc> AddrInfoGetter::getaddrinfo(
  144. const std::string& host,
  145. const addrinfo* hints,
  146. int* out_os_error,
  147. handles::NetworkHandle network) {
  148. addrinfo* ai;
  149. // We wrap freeaddrinfo() in a lambda just in case some operating systems use
  150. // a different signature for it.
  151. FreeAddrInfoFunc deleter = [](addrinfo* ai) { ::freeaddrinfo(ai); };
  152. std::unique_ptr<addrinfo, FreeAddrInfoFunc> rv = {nullptr, deleter};
  153. if (network != handles::kInvalidNetworkHandle) {
  154. // Currently, only Android supports lookups for a specific network.
  155. #if BUILDFLAG(IS_ANDROID)
  156. *out_os_error = android::GetAddrInfoForNetwork(network, host.c_str(),
  157. nullptr, hints, &ai);
  158. #elif BUILDFLAG(IS_WIN)
  159. *out_os_error = WSAEOPNOTSUPP;
  160. return rv;
  161. #else
  162. errno = ENOSYS;
  163. *out_os_error = EAI_SYSTEM;
  164. return rv;
  165. #endif // BUILDFLAG(IS_ANDROID)
  166. } else {
  167. *out_os_error = ::getaddrinfo(host.c_str(), nullptr, hints, &ai);
  168. }
  169. if (*out_os_error) {
  170. #if BUILDFLAG(IS_WIN)
  171. *out_os_error = WSAGetLastError();
  172. #endif
  173. return rv;
  174. }
  175. rv.reset(ai);
  176. return rv;
  177. }
  178. } // namespace net