address_list.cc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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
  3. // found in the LICENSE file.
  4. #include "net/base/address_list.h"
  5. #include <iterator>
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. #include "base/containers/flat_map.h"
  10. #include "base/logging.h"
  11. #include "base/values.h"
  12. #include "net/base/sys_addrinfo.h"
  13. namespace net {
  14. AddressList::AddressList() = default;
  15. AddressList::AddressList(const AddressList&) = default;
  16. AddressList& AddressList::operator=(const AddressList&) = default;
  17. AddressList::AddressList(AddressList&&) = default;
  18. AddressList& AddressList::operator=(AddressList&&) = default;
  19. AddressList::~AddressList() = default;
  20. AddressList::AddressList(const IPEndPoint& endpoint) {
  21. push_back(endpoint);
  22. }
  23. AddressList::AddressList(const IPEndPoint& endpoint,
  24. std::vector<std::string> aliases)
  25. : dns_aliases_(std::move(aliases)) {
  26. push_back(endpoint);
  27. }
  28. AddressList::AddressList(std::vector<IPEndPoint> endpoints)
  29. : endpoints_(std::move(endpoints)) {}
  30. // static
  31. AddressList AddressList::CreateFromIPAddress(const IPAddress& address,
  32. uint16_t port) {
  33. return AddressList(IPEndPoint(address, port));
  34. }
  35. // static
  36. AddressList AddressList::CreateFromIPAddressList(
  37. const IPAddressList& addresses,
  38. std::vector<std::string> aliases) {
  39. AddressList list;
  40. for (const auto& address : addresses) {
  41. list.push_back(IPEndPoint(address, 0));
  42. }
  43. list.SetDnsAliases(std::move(aliases));
  44. return list;
  45. }
  46. // static
  47. AddressList AddressList::CreateFromAddrinfo(const struct addrinfo* head) {
  48. DCHECK(head);
  49. AddressList list;
  50. if (head->ai_canonname) {
  51. std::vector<std::string> aliases({std::string(head->ai_canonname)});
  52. list.SetDnsAliases(std::move(aliases));
  53. }
  54. for (const struct addrinfo* ai = head; ai; ai = ai->ai_next) {
  55. IPEndPoint ipe;
  56. // NOTE: Ignoring non-INET* families.
  57. if (ipe.FromSockAddr(ai->ai_addr, static_cast<socklen_t>(ai->ai_addrlen)))
  58. list.push_back(ipe);
  59. else
  60. DLOG(WARNING) << "Unknown family found in addrinfo: " << ai->ai_family;
  61. }
  62. return list;
  63. }
  64. // static
  65. AddressList AddressList::CopyWithPort(const AddressList& list, uint16_t port) {
  66. AddressList out;
  67. out.SetDnsAliases(list.dns_aliases());
  68. for (const auto& i : list)
  69. out.push_back(IPEndPoint(i.address(), port));
  70. return out;
  71. }
  72. void AddressList::SetDefaultCanonicalName() {
  73. DCHECK(!empty());
  74. DCHECK(dns_aliases_.empty());
  75. SetDnsAliases({front().ToStringWithoutPort()});
  76. }
  77. void AddressList::SetDnsAliases(std::vector<std::string> aliases) {
  78. // TODO(cammie): Track down the callers who use {""} for `aliases` and
  79. // update so that we can enforce by DCHECK below.
  80. // The empty canonical name is represented by a empty `dns_aliases_`
  81. // vector, so in this case we reset the field.
  82. if (aliases == std::vector<std::string>({""})) {
  83. dns_aliases_ = std::vector<std::string>();
  84. return;
  85. }
  86. dns_aliases_ = std::move(aliases);
  87. }
  88. void AddressList::AppendDnsAliases(std::vector<std::string> aliases) {
  89. DCHECK(aliases != std::vector<std::string>({""}));
  90. using iter_t = std::vector<std::string>::iterator;
  91. dns_aliases_.insert(dns_aliases_.end(),
  92. std::move_iterator<iter_t>(aliases.begin()),
  93. std::move_iterator<iter_t>(aliases.end()));
  94. }
  95. base::Value AddressList::NetLogParams() const {
  96. base::Value::Dict dict;
  97. base::Value::List address_list;
  98. for (const auto& ip_endpoint : *this)
  99. address_list.Append(ip_endpoint.ToString());
  100. dict.Set("address_list", std::move(address_list));
  101. base::Value::List alias_list;
  102. for (const std::string& alias : dns_aliases_)
  103. alias_list.Append(alias);
  104. dict.Set("aliases", std::move(alias_list));
  105. return base::Value(std::move(dict));
  106. }
  107. void AddressList::Deduplicate() {
  108. if (size() > 1) {
  109. std::vector<std::pair<IPEndPoint, int>> make_me_into_a_map(size());
  110. for (auto& addr : *this)
  111. make_me_into_a_map.emplace_back(addr, 0);
  112. base::flat_map<IPEndPoint, int> inserted(std::move(make_me_into_a_map));
  113. std::vector<IPEndPoint> deduplicated_addresses;
  114. deduplicated_addresses.reserve(inserted.size());
  115. for (const auto& addr : *this) {
  116. int& count = inserted[addr];
  117. if (!count) {
  118. deduplicated_addresses.push_back(addr);
  119. ++count;
  120. }
  121. }
  122. endpoints_.swap(deduplicated_addresses);
  123. }
  124. }
  125. } // namespace net