xref: /aosp_15_r20/external/cronet/net/base/address_list_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
2 // 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 
7 #include <algorithm>
8 
9 #include "base/strings/string_util.h"
10 #include "base/sys_byteorder.h"
11 #include "net/base/ip_address.h"
12 #include "net/base/sockaddr_storage.h"
13 #include "net/base/sys_addrinfo.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 
17 using ::testing::ElementsAre;
18 using ::testing::UnorderedElementsAre;
19 
20 namespace net {
21 namespace {
22 
23 const char kCanonicalHostname[] = "canonical.bar.com";
24 
TEST(AddressListTest,Canonical)25 TEST(AddressListTest, Canonical) {
26   // Create an addrinfo with a canonical name.
27   struct sockaddr_in address;
28   // 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));
31   // But we need to set the family.
32   address.sin_family = AF_INET;
33   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.
43   AddressList addrlist1 = AddressList::CreateFromAddrinfo(&ai);
44   EXPECT_THAT(addrlist1.dns_aliases(),
45               UnorderedElementsAre("canonical.bar.com"));
46 
47   // Copy the AddressList to another one.
48   AddressList addrlist2 = addrlist1;
49   EXPECT_THAT(addrlist2.dns_aliases(),
50               UnorderedElementsAre("canonical.bar.com"));
51 }
52 
TEST(AddressListTest,CreateFromAddrinfo)53 TEST(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 }.
63     memset(&addr->sin_addr, i, IPAddress::kIPv4AddressSize);
64     addr->sin_family = AF_INET;
65     // Set port to i << 2;
66     addr->sin_port = base::HostToNet16(static_cast<uint16_t>(i << 2));
67     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];
74   }
75 
76   AddressList list = AddressList::CreateFromAddrinfo(&ai[0]);
77 
78   ASSERT_EQ(kNumElements, list.size());
79   for (size_t i = 0; i < list.size(); ++i) {
80     EXPECT_EQ(ADDRESS_FAMILY_IPV4, list[i].GetFamily());
81     // Only check the first byte of the address.
82     EXPECT_EQ(i, list[i].address().bytes()[0]);
83     EXPECT_EQ(static_cast<int>(i << 2), list[i].port());
84   }
85 
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.
94   EXPECT_EQ(1u, list[1].address().bytes()[0]);
95   EXPECT_EQ(1 << 2, list[1].port());
96 }
97 
TEST(AddressListTest,CreateFromIPAddressList)98 TEST(AddressListTest, CreateFromIPAddressList) {
99   struct TestData {
100     std::string ip_address;
101     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;
106   } tests[] = {
107     { "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     },
128   };
129   const std::string kCanonicalName = "canonical.example.com";
130 
131   // Construct a list of ip addresses.
132   IPAddressList ip_list;
133   for (const auto& test : tests) {
134     IPAddress ip_address;
135     ASSERT_TRUE(ip_address.AssignFromIPLiteral(test.ip_address));
136     ip_list.push_back(ip_address);
137   }
138 
139   // 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));
144   std::string canonical_name;
145   EXPECT_THAT(test_list.dns_aliases(), UnorderedElementsAre(kCanonicalName));
146   EXPECT_EQ(std::size(tests), test_list.size());
147 }
148 
TEST(AddressListTest,GetCanonicalNameWhenUnset)149 TEST(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());
155 }
156 
TEST(AddressListTest,SetDefaultCanonicalNameThenSetDnsAliases)157 TEST(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 
164   EXPECT_THAT(addrlist.dns_aliases(), UnorderedElementsAre("1.2.3.4"));
165 
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.
171   EXPECT_THAT(addrlist.dns_aliases(),
172               UnorderedElementsAre("alias1", "alias2", "alias3"));
173 }
174 
TEST(AddressListTest,SetDefaultCanonicalNameThenAppendDnsAliases)175 TEST(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 
182   EXPECT_THAT(addrlist.dns_aliases(), UnorderedElementsAre("1.2.3.4"));
183 
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.
189   EXPECT_THAT(addrlist.dns_aliases(),
190               UnorderedElementsAre("1.2.3.4", "alias1", "alias2", "alias3"));
191 }
192 
TEST(AddressListTest,DnsAliases)193 TEST(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 
199   EXPECT_THAT(addrlist.dns_aliases(),
200               UnorderedElementsAre("alias1", "alias2", "alias3"));
201 
202   std::vector<std::string> more_aliases({"alias4", "alias5", "alias6"});
203   addrlist.AppendDnsAliases(std::move(more_aliases));
204 
205   EXPECT_THAT(addrlist.dns_aliases(),
206               UnorderedElementsAre("alias1", "alias2", "alias3", "alias4",
207                                    "alias5", "alias6"));
208 
209   std::vector<std::string> new_aliases({"alias7", "alias8", "alias9"});
210   addrlist.SetDnsAliases(std::move(new_aliases));
211 
212   EXPECT_THAT(addrlist.dns_aliases(),
213               UnorderedElementsAre("alias7", "alias8", "alias9"));
214 }
215 
TEST(AddressListTest,DeduplicatesEmptyAddressList)216 TEST(AddressListTest, DeduplicatesEmptyAddressList) {
217   AddressList empty;
218   empty.Deduplicate();
219   EXPECT_EQ(empty.size(), 0u);
220 }
221 
TEST(AddressListTest,DeduplicatesSingletonAddressList)222 TEST(AddressListTest, DeduplicatesSingletonAddressList) {
223   AddressList singleton;
224   singleton.push_back(IPEndPoint());
225   singleton.Deduplicate();
226   EXPECT_THAT(singleton.endpoints(), ElementsAre(IPEndPoint()));
227 }
228 
TEST(AddressListTest,DeduplicatesLongerAddressList)229 TEST(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 
250 // Test that, for every permutation of a list of endpoints, deduplication
251 // produces the same results as a naive reference implementation.
TEST(AddressListTest,DeduplicatePreservesOrder)252 TEST(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 
276 }  // namespace
277 }  // namespace net
278