blob: 1b5945b60861a32aeeda6b899ddd425de26bdfd4 [file] [log] [blame]
Avi Drissman64595482022-09-14 20:52:291// Copyright 2012 The Chromium Authors
[email protected]8a00f00a2009-06-12 00:49:382// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/base/address_list.h"
6
Dan McArdle18d4753a2022-02-03 18:23:057#include <algorithm>
8
[email protected]4b355212013-06-11 10:35:199#include "base/strings/string_util.h"
[email protected]7054e78f2012-05-07 21:44:5610#include "base/sys_byteorder.h"
martijn99403292016-03-10 21:20:5811#include "net/base/ip_address.h"
tfarina3d87d7cd2016-01-13 02:26:5912#include "net/base/sockaddr_storage.h"
[email protected]ac9eec62010-02-20 18:50:3813#include "net/base/sys_addrinfo.h"
David Van Cleve34c74c72019-10-31 19:58:0114#include "testing/gmock/include/gmock/gmock.h"
[email protected]8a00f00a2009-06-12 00:49:3815#include "testing/gtest/include/gtest/gtest.h"
16
David Van Cleve34c74c72019-10-31 19:58:0117using ::testing::ElementsAre;
Eric Orth38eb27be2022-01-20 21:24:4918using ::testing::UnorderedElementsAre;
David Van Cleve34c74c72019-10-31 19:58:0119
[email protected]8effd3f62011-03-25 16:29:0720namespace net {
[email protected]8a00f00a2009-06-12 00:49:3821namespace {
22
thestig9d3bb0c2015-01-24 00:49:5123const char kCanonicalHostname[] = "canonical.bar.com";
[email protected]5ea28dea2010-04-08 15:35:1324
25TEST(AddressListTest, Canonical) {
26 // Create an addrinfo with a canonical name.
[email protected]7054e78f2012-05-07 21:44:5627 struct sockaddr_in address;
[email protected]5ea28dea2010-04-08 15:35:1328 // The contents of address do not matter for this test,
29 // so just zero-ing them out for consistency.
30 memset(&address, 0x0, sizeof(address));
[email protected]7054e78f2012-05-07 21:44:5631 // But we need to set the family.
32 address.sin_family = AF_INET;
[email protected]5ea28dea2010-04-08 15:35:1333 struct addrinfo ai;
34 memset(&ai, 0x0, sizeof(ai));
35 ai.ai_family = AF_INET;
36 ai.ai_socktype = SOCK_STREAM;
37 ai.ai_addrlen = sizeof(address);
38 ai.ai_addr = reinterpret_cast<sockaddr*>(&address);
39 ai.ai_canonname = const_cast<char *>(kCanonicalHostname);
40
41 // Copy the addrinfo struct into an AddressList object and
42 // make sure it seems correct.
[email protected]7054e78f2012-05-07 21:44:5643 AddressList addrlist1 = AddressList::CreateFromAddrinfo(&ai);
Eric Orth38eb27be2022-01-20 21:24:4944 EXPECT_THAT(addrlist1.dns_aliases(),
45 UnorderedElementsAre("canonical.bar.com"));
[email protected]5ea28dea2010-04-08 15:35:1346
47 // Copy the AddressList to another one.
[email protected]7054e78f2012-05-07 21:44:5648 AddressList addrlist2 = addrlist1;
Eric Orth38eb27be2022-01-20 21:24:4949 EXPECT_THAT(addrlist2.dns_aliases(),
50 UnorderedElementsAre("canonical.bar.com"));
[email protected]5ea28dea2010-04-08 15:35:1351}
52
[email protected]7054e78f2012-05-07 21:44:5653TEST(AddressListTest, CreateFromAddrinfo) {
54 // Create an 4-element addrinfo.
55 const unsigned kNumElements = 4;
56 SockaddrStorage storage[kNumElements];
57 struct addrinfo ai[kNumElements];
58 for (unsigned i = 0; i < kNumElements; ++i) {
59 struct sockaddr_in* addr =
60 reinterpret_cast<struct sockaddr_in*>(storage[i].addr);
61 storage[i].addr_len = sizeof(struct sockaddr_in);
62 // Populating the address with { i, i, i, i }.
martijn56506d02016-05-03 18:44:0063 memset(&addr->sin_addr, i, IPAddress::kIPv4AddressSize);
[email protected]7054e78f2012-05-07 21:44:5664 addr->sin_family = AF_INET;
65 // Set port to i << 2;
wtc69f8ea82015-06-04 00:08:1366 addr->sin_port = base::HostToNet16(static_cast<uint16_t>(i << 2));
[email protected]7054e78f2012-05-07 21:44:5667 memset(&ai[i], 0x0, sizeof(ai[i]));
68 ai[i].ai_family = addr->sin_family;
69 ai[i].ai_socktype = SOCK_STREAM;
70 ai[i].ai_addrlen = storage[i].addr_len;
71 ai[i].ai_addr = storage[i].addr;
72 if (i + 1 < kNumElements)
73 ai[i].ai_next = &ai[i + 1];
[email protected]de114d6a2010-08-18 23:26:5174 }
[email protected]de114d6a2010-08-18 23:26:5175
[email protected]7054e78f2012-05-07 21:44:5676 AddressList list = AddressList::CreateFromAddrinfo(&ai[0]);
[email protected]4e5572f2011-03-02 01:30:1677
[email protected]7054e78f2012-05-07 21:44:5678 ASSERT_EQ(kNumElements, list.size());
79 for (size_t i = 0; i < list.size(); ++i) {
[email protected]e466aaf2012-12-13 01:46:4480 EXPECT_EQ(ADDRESS_FAMILY_IPV4, list[i].GetFamily());
[email protected]7054e78f2012-05-07 21:44:5681 // Only check the first byte of the address.
martijn98acb9b2016-01-27 07:14:0782 EXPECT_EQ(i, list[i].address().bytes()[0]);
[email protected]7054e78f2012-05-07 21:44:5683 EXPECT_EQ(static_cast<int>(i << 2), list[i].port());
[email protected]4e5572f2011-03-02 01:30:1684 }
[email protected]7054e78f2012-05-07 21:44:5685
86 // Check if operator= works.
87 AddressList copy;
88 copy = list;
89 ASSERT_EQ(kNumElements, copy.size());
90
91 // Check if copy is independent.
92 copy[1] = IPEndPoint(copy[2].address(), 0xBEEF);
93 // Original should be unchanged.
martijn98acb9b2016-01-27 07:14:0794 EXPECT_EQ(1u, list[1].address().bytes()[0]);
[email protected]7054e78f2012-05-07 21:44:5695 EXPECT_EQ(1 << 2, list[1].port());
[email protected]4e5572f2011-03-02 01:30:1696}
97
[email protected]a506e8f2011-05-26 17:55:0598TEST(AddressListTest, CreateFromIPAddressList) {
99 struct TestData {
100 std::string ip_address;
[email protected]338318b2011-06-07 20:41:06101 const char* in_addr;
102 int ai_family;
103 size_t ai_addrlen;
104 size_t in_addr_offset;
105 size_t in_addr_size;
[email protected]a506e8f2011-05-26 17:55:05106 } tests[] = {
[email protected]338318b2011-06-07 20:41:06107 { "127.0.0.1",
108 "\x7f\x00\x00\x01",
109 AF_INET,
110 sizeof(struct sockaddr_in),
111 offsetof(struct sockaddr_in, sin_addr),
112 sizeof(struct in_addr),
113 },
114 { "2001:db8:0::42",
115 "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42",
116 AF_INET6,
117 sizeof(struct sockaddr_in6),
118 offsetof(struct sockaddr_in6, sin6_addr),
119 sizeof(struct in6_addr),
120 },
121 { "192.168.1.1",
122 "\xc0\xa8\x01\x01",
123 AF_INET,
124 sizeof(struct sockaddr_in),
125 offsetof(struct sockaddr_in, sin_addr),
126 sizeof(struct in_addr),
127 },
[email protected]a506e8f2011-05-26 17:55:05128 };
[email protected]b3601bc22012-02-21 21:23:20129 const std::string kCanonicalName = "canonical.example.com";
[email protected]a506e8f2011-05-26 17:55:05130
131 // Construct a list of ip addresses.
[email protected]d3911162011-07-18 15:12:46132 IPAddressList ip_list;
Ryan Sleevi4625214fa2018-05-10 16:42:45133 for (const auto& test : tests) {
martijn99403292016-03-10 21:20:58134 IPAddress ip_address;
Ryan Sleevi4625214fa2018-05-10 16:42:45135 ASSERT_TRUE(ip_address.AssignFromIPLiteral(test.ip_address));
martijn99403292016-03-10 21:20:58136 ip_list.push_back(ip_address);
[email protected]a506e8f2011-05-26 17:55:05137 }
138
Cammie Smith Barnes78c07782020-12-07 23:27:04139 // Wrap the canonical name in an alias vector.
140 std::vector<std::string> aliases({kCanonicalName});
141
142 AddressList test_list =
143 AddressList::CreateFromIPAddressList(ip_list, std::move(aliases));
[email protected]b3601bc22012-02-21 21:23:20144 std::string canonical_name;
Eric Orth38eb27be2022-01-20 21:24:49145 EXPECT_THAT(test_list.dns_aliases(), UnorderedElementsAre(kCanonicalName));
Daniel Cheng5feb16f2022-02-28 06:52:07146 EXPECT_EQ(std::size(tests), test_list.size());
[email protected]a506e8f2011-05-26 17:55:05147}
148
Cammie Smith Barnes78c07782020-12-07 23:27:04149TEST(AddressListTest, GetCanonicalNameWhenUnset) {
150 const IPAddress kAddress(1, 2, 3, 4);
151 const IPEndPoint kEndpoint(kAddress, 0);
152 AddressList addrlist(kEndpoint);
153
154 EXPECT_TRUE(addrlist.dns_aliases().empty());
Cammie Smith Barnes78c07782020-12-07 23:27:04155}
156
157TEST(AddressListTest, SetDefaultCanonicalNameThenSetDnsAliases) {
158 const IPAddress kAddress(1, 2, 3, 4);
159 const IPEndPoint kEndpoint(kAddress, 0);
160 AddressList addrlist(kEndpoint);
161
162 addrlist.SetDefaultCanonicalName();
163
Eric Orth38eb27be2022-01-20 21:24:49164 EXPECT_THAT(addrlist.dns_aliases(), UnorderedElementsAre("1.2.3.4"));
Cammie Smith Barnes78c07782020-12-07 23:27:04165
166 std::vector<std::string> aliases({"alias1", "alias2", "alias3"});
167 addrlist.SetDnsAliases(std::move(aliases));
168
169 // Setting the aliases after setting the default canonical name
170 // replaces the default canonical name.
Cammie Smith Barnes78c07782020-12-07 23:27:04171 EXPECT_THAT(addrlist.dns_aliases(),
Eric Orth38eb27be2022-01-20 21:24:49172 UnorderedElementsAre("alias1", "alias2", "alias3"));
Cammie Smith Barnes78c07782020-12-07 23:27:04173}
174
175TEST(AddressListTest, SetDefaultCanonicalNameThenAppendDnsAliases) {
176 const IPAddress kAddress(1, 2, 3, 4);
177 const IPEndPoint kEndpoint(kAddress, 0);
178 AddressList addrlist(kEndpoint);
179
180 addrlist.SetDefaultCanonicalName();
181
Eric Orth38eb27be2022-01-20 21:24:49182 EXPECT_THAT(addrlist.dns_aliases(), UnorderedElementsAre("1.2.3.4"));
Cammie Smith Barnes78c07782020-12-07 23:27:04183
184 std::vector<std::string> aliases({"alias1", "alias2", "alias3"});
185 addrlist.AppendDnsAliases(std::move(aliases));
186
187 // Appending the aliases after setting the default canonical name
188 // does not replace the default canonical name.
Cammie Smith Barnes78c07782020-12-07 23:27:04189 EXPECT_THAT(addrlist.dns_aliases(),
Eric Orth38eb27be2022-01-20 21:24:49190 UnorderedElementsAre("1.2.3.4", "alias1", "alias2", "alias3"));
Cammie Smith Barnes78c07782020-12-07 23:27:04191}
192
193TEST(AddressListTest, DnsAliases) {
194 const IPAddress kAddress(1, 2, 3, 4);
195 const IPEndPoint kEndpoint(kAddress, 0);
196 std::vector<std::string> aliases({"alias1", "alias2", "alias3"});
197 AddressList addrlist(kEndpoint, std::move(aliases));
198
Cammie Smith Barnes78c07782020-12-07 23:27:04199 EXPECT_THAT(addrlist.dns_aliases(),
Eric Orth38eb27be2022-01-20 21:24:49200 UnorderedElementsAre("alias1", "alias2", "alias3"));
Cammie Smith Barnes78c07782020-12-07 23:27:04201
202 std::vector<std::string> more_aliases({"alias4", "alias5", "alias6"});
203 addrlist.AppendDnsAliases(std::move(more_aliases));
204
Eric Orth38eb27be2022-01-20 21:24:49205 EXPECT_THAT(addrlist.dns_aliases(),
206 UnorderedElementsAre("alias1", "alias2", "alias3", "alias4",
207 "alias5", "alias6"));
Cammie Smith Barnes78c07782020-12-07 23:27:04208
209 std::vector<std::string> new_aliases({"alias7", "alias8", "alias9"});
210 addrlist.SetDnsAliases(std::move(new_aliases));
211
Cammie Smith Barnes78c07782020-12-07 23:27:04212 EXPECT_THAT(addrlist.dns_aliases(),
Eric Orth38eb27be2022-01-20 21:24:49213 UnorderedElementsAre("alias7", "alias8", "alias9"));
Cammie Smith Barnes78c07782020-12-07 23:27:04214}
215
David Van Cleve34c74c72019-10-31 19:58:01216TEST(AddressListTest, DeduplicatesEmptyAddressList) {
217 AddressList empty;
218 empty.Deduplicate();
219 EXPECT_EQ(empty.size(), 0u);
220}
221
222TEST(AddressListTest, DeduplicatesSingletonAddressList) {
223 AddressList singleton;
224 singleton.push_back(IPEndPoint());
225 singleton.Deduplicate();
226 EXPECT_THAT(singleton.endpoints(), ElementsAre(IPEndPoint()));
227}
228
229TEST(AddressListTest, DeduplicatesLongerAddressList) {
230 AddressList several;
231 several.endpoints() = {IPEndPoint(IPAddress(0, 0, 0, 1), 0),
232 IPEndPoint(IPAddress(0, 0, 0, 2), 0),
233 IPEndPoint(IPAddress(0, 0, 0, 2), 0),
234 IPEndPoint(IPAddress(0, 0, 0, 3), 0),
235 IPEndPoint(IPAddress(0, 0, 0, 2), 0),
236 IPEndPoint(IPAddress(0, 0, 0, 1), 0),
237 IPEndPoint(IPAddress(0, 0, 0, 2), 0),
238 IPEndPoint(IPAddress(0, 0, 0, 3), 0),
239 IPEndPoint(IPAddress(0, 0, 0, 2), 0)};
240 several.Deduplicate();
241
242 // Deduplication should preserve the order of the first instances
243 // of the unique addresses.
244 EXPECT_THAT(several.endpoints(),
245 ElementsAre(IPEndPoint(IPAddress(0, 0, 0, 1), 0),
246 IPEndPoint(IPAddress(0, 0, 0, 2), 0),
247 IPEndPoint(IPAddress(0, 0, 0, 3), 0)));
248}
249
Dan McArdle18d4753a2022-02-03 18:23:05250// Test that, for every permutation of a list of endpoints, deduplication
251// produces the same results as a naive reference implementation.
252TEST(AddressListTest, DeduplicatePreservesOrder) {
253 std::vector<IPEndPoint> permutation = {IPEndPoint(IPAddress(0, 0, 0, 1), 0),
254 IPEndPoint(IPAddress(0, 0, 0, 1), 0),
255 IPEndPoint(IPAddress(0, 0, 0, 2), 0),
256 IPEndPoint(IPAddress(0, 0, 0, 2), 0),
257 IPEndPoint(IPAddress(0, 0, 0, 3), 0)};
258 ASSERT_TRUE(std::is_sorted(permutation.begin(), permutation.end()));
259
260 do {
261 std::vector<IPEndPoint> expected;
262 std::set<IPEndPoint> set;
263 for (const IPEndPoint& endpoint : permutation) {
264 if (set.insert(endpoint).second)
265 expected.push_back(endpoint);
266 }
267 EXPECT_EQ(expected.size(), 3u);
268
269 AddressList address_list;
270 address_list.endpoints() = permutation;
271 address_list.Deduplicate();
272 EXPECT_EQ(address_list.endpoints(), expected);
273 } while (std::next_permutation(permutation.begin(), permutation.end()));
274}
275
[email protected]8a00f00a2009-06-12 00:49:38276} // namespace
[email protected]8effd3f62011-03-25 16:29:07277} // namespace net