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