address_list_unittest.cc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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 <algorithm>
  6. #include "base/strings/string_util.h"
  7. #include "base/sys_byteorder.h"
  8. #include "net/base/ip_address.h"
  9. #include "net/base/sockaddr_storage.h"
  10. #include "net/base/sys_addrinfo.h"
  11. #include "testing/gmock/include/gmock/gmock.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. using ::testing::ElementsAre;
  14. using ::testing::UnorderedElementsAre;
  15. namespace net {
  16. namespace {
  17. const char kCanonicalHostname[] = "canonical.bar.com";
  18. TEST(AddressListTest, Canonical) {
  19. // Create an addrinfo with a canonical name.
  20. struct sockaddr_in address;
  21. // The contents of address do not matter for this test,
  22. // so just zero-ing them out for consistency.
  23. memset(&address, 0x0, sizeof(address));
  24. // But we need to set the family.
  25. address.sin_family = AF_INET;
  26. struct addrinfo ai;
  27. memset(&ai, 0x0, sizeof(ai));
  28. ai.ai_family = AF_INET;
  29. ai.ai_socktype = SOCK_STREAM;
  30. ai.ai_addrlen = sizeof(address);
  31. ai.ai_addr = reinterpret_cast<sockaddr*>(&address);
  32. ai.ai_canonname = const_cast<char *>(kCanonicalHostname);
  33. // Copy the addrinfo struct into an AddressList object and
  34. // make sure it seems correct.
  35. AddressList addrlist1 = AddressList::CreateFromAddrinfo(&ai);
  36. EXPECT_THAT(addrlist1.dns_aliases(),
  37. UnorderedElementsAre("canonical.bar.com"));
  38. // Copy the AddressList to another one.
  39. AddressList addrlist2 = addrlist1;
  40. EXPECT_THAT(addrlist2.dns_aliases(),
  41. UnorderedElementsAre("canonical.bar.com"));
  42. }
  43. TEST(AddressListTest, CreateFromAddrinfo) {
  44. // Create an 4-element addrinfo.
  45. const unsigned kNumElements = 4;
  46. SockaddrStorage storage[kNumElements];
  47. struct addrinfo ai[kNumElements];
  48. for (unsigned i = 0; i < kNumElements; ++i) {
  49. struct sockaddr_in* addr =
  50. reinterpret_cast<struct sockaddr_in*>(storage[i].addr);
  51. storage[i].addr_len = sizeof(struct sockaddr_in);
  52. // Populating the address with { i, i, i, i }.
  53. memset(&addr->sin_addr, i, IPAddress::kIPv4AddressSize);
  54. addr->sin_family = AF_INET;
  55. // Set port to i << 2;
  56. addr->sin_port = base::HostToNet16(static_cast<uint16_t>(i << 2));
  57. memset(&ai[i], 0x0, sizeof(ai[i]));
  58. ai[i].ai_family = addr->sin_family;
  59. ai[i].ai_socktype = SOCK_STREAM;
  60. ai[i].ai_addrlen = storage[i].addr_len;
  61. ai[i].ai_addr = storage[i].addr;
  62. if (i + 1 < kNumElements)
  63. ai[i].ai_next = &ai[i + 1];
  64. }
  65. AddressList list = AddressList::CreateFromAddrinfo(&ai[0]);
  66. ASSERT_EQ(kNumElements, list.size());
  67. for (size_t i = 0; i < list.size(); ++i) {
  68. EXPECT_EQ(ADDRESS_FAMILY_IPV4, list[i].GetFamily());
  69. // Only check the first byte of the address.
  70. EXPECT_EQ(i, list[i].address().bytes()[0]);
  71. EXPECT_EQ(static_cast<int>(i << 2), list[i].port());
  72. }
  73. // Check if operator= works.
  74. AddressList copy;
  75. copy = list;
  76. ASSERT_EQ(kNumElements, copy.size());
  77. // Check if copy is independent.
  78. copy[1] = IPEndPoint(copy[2].address(), 0xBEEF);
  79. // Original should be unchanged.
  80. EXPECT_EQ(1u, list[1].address().bytes()[0]);
  81. EXPECT_EQ(1 << 2, list[1].port());
  82. }
  83. TEST(AddressListTest, CreateFromIPAddressList) {
  84. struct TestData {
  85. std::string ip_address;
  86. const char* in_addr;
  87. int ai_family;
  88. size_t ai_addrlen;
  89. size_t in_addr_offset;
  90. size_t in_addr_size;
  91. } tests[] = {
  92. { "127.0.0.1",
  93. "\x7f\x00\x00\x01",
  94. AF_INET,
  95. sizeof(struct sockaddr_in),
  96. offsetof(struct sockaddr_in, sin_addr),
  97. sizeof(struct in_addr),
  98. },
  99. { "2001:db8:0::42",
  100. "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42",
  101. AF_INET6,
  102. sizeof(struct sockaddr_in6),
  103. offsetof(struct sockaddr_in6, sin6_addr),
  104. sizeof(struct in6_addr),
  105. },
  106. { "192.168.1.1",
  107. "\xc0\xa8\x01\x01",
  108. AF_INET,
  109. sizeof(struct sockaddr_in),
  110. offsetof(struct sockaddr_in, sin_addr),
  111. sizeof(struct in_addr),
  112. },
  113. };
  114. const std::string kCanonicalName = "canonical.example.com";
  115. // Construct a list of ip addresses.
  116. IPAddressList ip_list;
  117. for (const auto& test : tests) {
  118. IPAddress ip_address;
  119. ASSERT_TRUE(ip_address.AssignFromIPLiteral(test.ip_address));
  120. ip_list.push_back(ip_address);
  121. }
  122. // Wrap the canonical name in an alias vector.
  123. std::vector<std::string> aliases({kCanonicalName});
  124. AddressList test_list =
  125. AddressList::CreateFromIPAddressList(ip_list, std::move(aliases));
  126. std::string canonical_name;
  127. EXPECT_THAT(test_list.dns_aliases(), UnorderedElementsAre(kCanonicalName));
  128. EXPECT_EQ(std::size(tests), test_list.size());
  129. }
  130. TEST(AddressListTest, GetCanonicalNameWhenUnset) {
  131. const IPAddress kAddress(1, 2, 3, 4);
  132. const IPEndPoint kEndpoint(kAddress, 0);
  133. AddressList addrlist(kEndpoint);
  134. EXPECT_TRUE(addrlist.dns_aliases().empty());
  135. }
  136. TEST(AddressListTest, SetDefaultCanonicalNameThenSetDnsAliases) {
  137. const IPAddress kAddress(1, 2, 3, 4);
  138. const IPEndPoint kEndpoint(kAddress, 0);
  139. AddressList addrlist(kEndpoint);
  140. addrlist.SetDefaultCanonicalName();
  141. EXPECT_THAT(addrlist.dns_aliases(), UnorderedElementsAre("1.2.3.4"));
  142. std::vector<std::string> aliases({"alias1", "alias2", "alias3"});
  143. addrlist.SetDnsAliases(std::move(aliases));
  144. // Setting the aliases after setting the default canonical name
  145. // replaces the default canonical name.
  146. EXPECT_THAT(addrlist.dns_aliases(),
  147. UnorderedElementsAre("alias1", "alias2", "alias3"));
  148. }
  149. TEST(AddressListTest, SetDefaultCanonicalNameThenAppendDnsAliases) {
  150. const IPAddress kAddress(1, 2, 3, 4);
  151. const IPEndPoint kEndpoint(kAddress, 0);
  152. AddressList addrlist(kEndpoint);
  153. addrlist.SetDefaultCanonicalName();
  154. EXPECT_THAT(addrlist.dns_aliases(), UnorderedElementsAre("1.2.3.4"));
  155. std::vector<std::string> aliases({"alias1", "alias2", "alias3"});
  156. addrlist.AppendDnsAliases(std::move(aliases));
  157. // Appending the aliases after setting the default canonical name
  158. // does not replace the default canonical name.
  159. EXPECT_THAT(addrlist.dns_aliases(),
  160. UnorderedElementsAre("1.2.3.4", "alias1", "alias2", "alias3"));
  161. }
  162. TEST(AddressListTest, DnsAliases) {
  163. const IPAddress kAddress(1, 2, 3, 4);
  164. const IPEndPoint kEndpoint(kAddress, 0);
  165. std::vector<std::string> aliases({"alias1", "alias2", "alias3"});
  166. AddressList addrlist(kEndpoint, std::move(aliases));
  167. EXPECT_THAT(addrlist.dns_aliases(),
  168. UnorderedElementsAre("alias1", "alias2", "alias3"));
  169. std::vector<std::string> more_aliases({"alias4", "alias5", "alias6"});
  170. addrlist.AppendDnsAliases(std::move(more_aliases));
  171. EXPECT_THAT(addrlist.dns_aliases(),
  172. UnorderedElementsAre("alias1", "alias2", "alias3", "alias4",
  173. "alias5", "alias6"));
  174. std::vector<std::string> new_aliases({"alias7", "alias8", "alias9"});
  175. addrlist.SetDnsAliases(std::move(new_aliases));
  176. EXPECT_THAT(addrlist.dns_aliases(),
  177. UnorderedElementsAre("alias7", "alias8", "alias9"));
  178. }
  179. TEST(AddressListTest, DeduplicatesEmptyAddressList) {
  180. AddressList empty;
  181. empty.Deduplicate();
  182. EXPECT_EQ(empty.size(), 0u);
  183. }
  184. TEST(AddressListTest, DeduplicatesSingletonAddressList) {
  185. AddressList singleton;
  186. singleton.push_back(IPEndPoint());
  187. singleton.Deduplicate();
  188. EXPECT_THAT(singleton.endpoints(), ElementsAre(IPEndPoint()));
  189. }
  190. TEST(AddressListTest, DeduplicatesLongerAddressList) {
  191. AddressList several;
  192. several.endpoints() = {IPEndPoint(IPAddress(0, 0, 0, 1), 0),
  193. IPEndPoint(IPAddress(0, 0, 0, 2), 0),
  194. IPEndPoint(IPAddress(0, 0, 0, 2), 0),
  195. IPEndPoint(IPAddress(0, 0, 0, 3), 0),
  196. IPEndPoint(IPAddress(0, 0, 0, 2), 0),
  197. IPEndPoint(IPAddress(0, 0, 0, 1), 0),
  198. IPEndPoint(IPAddress(0, 0, 0, 2), 0),
  199. IPEndPoint(IPAddress(0, 0, 0, 3), 0),
  200. IPEndPoint(IPAddress(0, 0, 0, 2), 0)};
  201. several.Deduplicate();
  202. // Deduplication should preserve the order of the first instances
  203. // of the unique addresses.
  204. EXPECT_THAT(several.endpoints(),
  205. ElementsAre(IPEndPoint(IPAddress(0, 0, 0, 1), 0),
  206. IPEndPoint(IPAddress(0, 0, 0, 2), 0),
  207. IPEndPoint(IPAddress(0, 0, 0, 3), 0)));
  208. }
  209. // Test that, for every permutation of a list of endpoints, deduplication
  210. // produces the same results as a naive reference implementation.
  211. TEST(AddressListTest, DeduplicatePreservesOrder) {
  212. std::vector<IPEndPoint> permutation = {IPEndPoint(IPAddress(0, 0, 0, 1), 0),
  213. IPEndPoint(IPAddress(0, 0, 0, 1), 0),
  214. IPEndPoint(IPAddress(0, 0, 0, 2), 0),
  215. IPEndPoint(IPAddress(0, 0, 0, 2), 0),
  216. IPEndPoint(IPAddress(0, 0, 0, 3), 0)};
  217. ASSERT_TRUE(std::is_sorted(permutation.begin(), permutation.end()));
  218. do {
  219. std::vector<IPEndPoint> expected;
  220. std::set<IPEndPoint> set;
  221. for (const IPEndPoint& endpoint : permutation) {
  222. if (set.insert(endpoint).second)
  223. expected.push_back(endpoint);
  224. }
  225. EXPECT_EQ(expected.size(), 3u);
  226. AddressList address_list;
  227. address_list.endpoints() = permutation;
  228. address_list.Deduplicate();
  229. EXPECT_EQ(address_list.endpoints(), expected);
  230. } while (std::next_permutation(permutation.begin(), permutation.end()));
  231. }
  232. } // namespace
  233. } // namespace net