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/ip_endpoint.h"
6
7 #include <string.h>
8
9 #include <optional>
10 #include <string>
11 #include <tuple>
12
13 #include "base/check_op.h"
14 #include "base/notreached.h"
15 #include "base/numerics/safe_conversions.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/sys_byteorder.h"
18 #include "base/values.h"
19 #include "build/build_config.h"
20 #include "net/base/ip_address.h"
21 #include "net/base/sockaddr_storage.h"
22 #include "net/base/sys_addrinfo.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "testing/platform_test.h"
26
27 #if BUILDFLAG(IS_WIN)
28 #include <winsock2.h>
29
30 #include <ws2bth.h>
31
32 #include "base/test/gtest_util.h" // For EXPECT_DCHECK_DEATH
33 #include "net/base/winsock_util.h" // For kBluetoothAddressSize
34 #elif BUILDFLAG(IS_POSIX)
35 #include <netinet/in.h>
36 #endif
37
38 using testing::Optional;
39
40 namespace net {
41
42 namespace {
43
44 // Retuns the port field of the |sockaddr|.
GetPortFieldFromSockaddr(const struct sockaddr * address,socklen_t address_len)45 const uint16_t* GetPortFieldFromSockaddr(const struct sockaddr* address,
46 socklen_t address_len) {
47 if (address->sa_family == AF_INET) {
48 DCHECK_LE(sizeof(sockaddr_in), static_cast<size_t>(address_len));
49 const struct sockaddr_in* sockaddr =
50 reinterpret_cast<const struct sockaddr_in*>(address);
51 return &sockaddr->sin_port;
52 } else if (address->sa_family == AF_INET6) {
53 DCHECK_LE(sizeof(sockaddr_in6), static_cast<size_t>(address_len));
54 const struct sockaddr_in6* sockaddr =
55 reinterpret_cast<const struct sockaddr_in6*>(address);
56 return &sockaddr->sin6_port;
57 } else {
58 NOTREACHED();
59 return nullptr;
60 }
61 }
62
63 // Returns the value of port in |sockaddr| (in host byte ordering).
GetPortFromSockaddr(const struct sockaddr * address,socklen_t address_len)64 int GetPortFromSockaddr(const struct sockaddr* address, socklen_t address_len) {
65 const uint16_t* port_field = GetPortFieldFromSockaddr(address, address_len);
66 if (!port_field)
67 return -1;
68 return base::NetToHost16(*port_field);
69 }
70
71 struct TestData {
72 std::string host;
73 std::string host_normalized;
74 bool ipv6;
75 IPAddress ip_address;
76 } tests[] = {
77 {"127.0.00.1", "127.0.0.1", false},
78 {"192.168.1.1", "192.168.1.1", false},
79 {"::1", "[::1]", true},
80 {"2001:db8:0::42", "[2001:db8::42]", true},
81 };
82
83 class IPEndPointTest : public PlatformTest {
84 public:
SetUp()85 void SetUp() override {
86 // This is where we populate the TestData.
87 for (auto& test : tests) {
88 EXPECT_TRUE(test.ip_address.AssignFromIPLiteral(test.host));
89 }
90 }
91 };
92
TEST_F(IPEndPointTest,Constructor)93 TEST_F(IPEndPointTest, Constructor) {
94 {
95 IPEndPoint endpoint;
96 EXPECT_EQ(0, endpoint.port());
97 }
98
99 for (const auto& test : tests) {
100 IPEndPoint endpoint(test.ip_address, 80);
101 EXPECT_EQ(80, endpoint.port());
102 EXPECT_EQ(test.ip_address, endpoint.address());
103 }
104 }
105
TEST_F(IPEndPointTest,Assignment)106 TEST_F(IPEndPointTest, Assignment) {
107 uint16_t port = 0;
108 for (const auto& test : tests) {
109 IPEndPoint src(test.ip_address, ++port);
110 IPEndPoint dest = src;
111
112 EXPECT_EQ(src.port(), dest.port());
113 EXPECT_EQ(src.address(), dest.address());
114 }
115 }
116
TEST_F(IPEndPointTest,Copy)117 TEST_F(IPEndPointTest, Copy) {
118 uint16_t port = 0;
119 for (const auto& test : tests) {
120 IPEndPoint src(test.ip_address, ++port);
121 IPEndPoint dest(src);
122
123 EXPECT_EQ(src.port(), dest.port());
124 EXPECT_EQ(src.address(), dest.address());
125 }
126 }
127
TEST_F(IPEndPointTest,ToFromSockAddr)128 TEST_F(IPEndPointTest, ToFromSockAddr) {
129 uint16_t port = 0;
130 for (const auto& test : tests) {
131 IPEndPoint ip_endpoint(test.ip_address, ++port);
132
133 // Convert to a sockaddr.
134 SockaddrStorage storage;
135 EXPECT_TRUE(ip_endpoint.ToSockAddr(storage.addr, &storage.addr_len));
136
137 // Basic verification.
138 socklen_t expected_size =
139 test.ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
140 EXPECT_EQ(expected_size, storage.addr_len);
141 EXPECT_EQ(ip_endpoint.port(),
142 GetPortFromSockaddr(storage.addr, storage.addr_len));
143 // And convert back to an IPEndPoint.
144 IPEndPoint ip_endpoint2;
145 EXPECT_TRUE(ip_endpoint2.FromSockAddr(storage.addr, storage.addr_len));
146 EXPECT_EQ(ip_endpoint.port(), ip_endpoint2.port());
147 EXPECT_EQ(ip_endpoint.address(), ip_endpoint2.address());
148 }
149 }
150
TEST_F(IPEndPointTest,ToSockAddrBufTooSmall)151 TEST_F(IPEndPointTest, ToSockAddrBufTooSmall) {
152 uint16_t port = 0;
153 for (const auto& test : tests) {
154 IPEndPoint ip_endpoint(test.ip_address, port);
155
156 SockaddrStorage storage;
157 storage.addr_len = 3; // size is too small!
158 EXPECT_FALSE(ip_endpoint.ToSockAddr(storage.addr, &storage.addr_len));
159 }
160 }
161
TEST_F(IPEndPointTest,FromSockAddrBufTooSmall)162 TEST_F(IPEndPointTest, FromSockAddrBufTooSmall) {
163 struct sockaddr_in addr;
164 memset(&addr, 0, sizeof(addr));
165 addr.sin_family = AF_INET;
166 IPEndPoint ip_endpoint;
167 struct sockaddr* sockaddr = reinterpret_cast<struct sockaddr*>(&addr);
168 EXPECT_FALSE(ip_endpoint.FromSockAddr(sockaddr, sizeof(addr) - 1));
169 }
170
171 #if BUILDFLAG(IS_WIN)
172
173 namespace {
174 constexpr uint8_t kBluetoothAddrBytes[kBluetoothAddressSize] = {1, 2, 3,
175 4, 5, 6};
176 constexpr uint8_t kBluetoothAddrBytes2[kBluetoothAddressSize] = {1, 2, 3,
177 4, 5, 7};
178 const IPAddress kBluetoothAddress(kBluetoothAddrBytes);
179 const IPAddress kBluetoothAddress2(kBluetoothAddrBytes2);
180
181 // Select a Bluetooth port that does not fit in a uint16_t.
182 constexpr uint32_t kBluetoothPort = std::numeric_limits<uint16_t>::max() + 1;
183
BuildBluetoothSockAddr(const IPAddress & ip_address,uint32_t port)184 SOCKADDR_BTH BuildBluetoothSockAddr(const IPAddress& ip_address,
185 uint32_t port) {
186 SOCKADDR_BTH addr = {};
187 addr.addressFamily = AF_BTH;
188 DCHECK_LE(ip_address.bytes().size(), sizeof(addr.btAddr));
189 memcpy(&addr.btAddr, ip_address.bytes().data(), ip_address.bytes().size());
190 addr.port = port;
191 return addr;
192 }
193 } // namespace
194
TEST_F(IPEndPointTest,WinBluetoothSockAddrCompareWithSelf)195 TEST_F(IPEndPointTest, WinBluetoothSockAddrCompareWithSelf) {
196 IPEndPoint bt_endpoint;
197 SOCKADDR_BTH addr = BuildBluetoothSockAddr(kBluetoothAddress, kBluetoothPort);
198 EXPECT_TRUE(bt_endpoint.FromSockAddr(
199 reinterpret_cast<const struct sockaddr*>(&addr), sizeof(addr)));
200 EXPECT_EQ(bt_endpoint.address(), kBluetoothAddress);
201 EXPECT_EQ(bt_endpoint.GetFamily(), AddressFamily::ADDRESS_FAMILY_UNSPECIFIED);
202 EXPECT_EQ(bt_endpoint.GetSockAddrFamily(), AF_BTH);
203 // Comparison functions should agree that `bt_endpoint` equals itself.
204 EXPECT_FALSE(bt_endpoint < bt_endpoint);
205 EXPECT_FALSE(bt_endpoint != bt_endpoint);
206 EXPECT_TRUE(bt_endpoint == bt_endpoint);
207 // Test that IPv4/IPv6-only methods crash.
208 EXPECT_DCHECK_DEATH(bt_endpoint.port());
209 SockaddrStorage storage;
210 EXPECT_DCHECK_DEATH(
211 std::ignore = bt_endpoint.ToSockAddr(storage.addr, &storage.addr_len));
212 EXPECT_DCHECK_DEATH(bt_endpoint.ToString());
213 EXPECT_DCHECK_DEATH(bt_endpoint.ToStringWithoutPort());
214 }
215
TEST_F(IPEndPointTest,WinBluetoothSockAddrCompareWithNonBluetooth)216 TEST_F(IPEndPointTest, WinBluetoothSockAddrCompareWithNonBluetooth) {
217 IPEndPoint bt_endpoint;
218 SOCKADDR_BTH addr = BuildBluetoothSockAddr(kBluetoothAddress, kBluetoothPort);
219 EXPECT_TRUE(bt_endpoint.FromSockAddr(
220 reinterpret_cast<const struct sockaddr*>(&addr), sizeof(addr)));
221
222 // Compare `bt_endpoint` with non-Bluetooth endpoints.
223 for (const auto& test : tests) {
224 IPEndPoint endpoint(test.ip_address, 80);
225 if (test.ip_address.IsIPv4()) {
226 EXPECT_FALSE(bt_endpoint < endpoint);
227 } else {
228 EXPECT_TRUE(test.ip_address.IsIPv6());
229 EXPECT_TRUE(bt_endpoint < endpoint);
230 }
231 EXPECT_TRUE(bt_endpoint != endpoint);
232 EXPECT_FALSE(bt_endpoint == endpoint);
233 }
234 }
235
TEST_F(IPEndPointTest,WinBluetoothSockAddrCompareWithCopy)236 TEST_F(IPEndPointTest, WinBluetoothSockAddrCompareWithCopy) {
237 IPEndPoint bt_endpoint;
238 SOCKADDR_BTH addr = BuildBluetoothSockAddr(kBluetoothAddress, kBluetoothPort);
239 EXPECT_TRUE(bt_endpoint.FromSockAddr(
240 reinterpret_cast<const struct sockaddr*>(&addr), sizeof(addr)));
241
242 // Verify that a copy's accessors return the same values as the original's.
243 IPEndPoint bt_endpoint_other(bt_endpoint);
244 EXPECT_EQ(bt_endpoint.address(), bt_endpoint_other.address());
245 EXPECT_EQ(bt_endpoint.GetFamily(), bt_endpoint_other.GetFamily());
246 EXPECT_EQ(bt_endpoint.GetSockAddrFamily(),
247 bt_endpoint_other.GetSockAddrFamily());
248 // Comparison functions should agree that the endpoints are equal.
249 EXPECT_FALSE(bt_endpoint < bt_endpoint_other);
250 EXPECT_FALSE(bt_endpoint != bt_endpoint_other);
251 EXPECT_TRUE(bt_endpoint == bt_endpoint_other);
252 // Test that IPv4/IPv6-only methods crash.
253 EXPECT_DCHECK_DEATH(bt_endpoint_other.port());
254 SockaddrStorage storage;
255 EXPECT_DCHECK_DEATH(std::ignore = bt_endpoint_other.ToSockAddr(
256 storage.addr, &storage.addr_len));
257 EXPECT_DCHECK_DEATH(bt_endpoint_other.ToString());
258 EXPECT_DCHECK_DEATH(bt_endpoint_other.ToStringWithoutPort());
259 }
260
TEST_F(IPEndPointTest,WinBluetoothSockAddrCompareWithDifferentPort)261 TEST_F(IPEndPointTest, WinBluetoothSockAddrCompareWithDifferentPort) {
262 IPEndPoint bt_endpoint;
263 SOCKADDR_BTH addr = BuildBluetoothSockAddr(kBluetoothAddress, kBluetoothPort);
264 EXPECT_TRUE(bt_endpoint.FromSockAddr(
265 reinterpret_cast<const struct sockaddr*>(&addr), sizeof(addr)));
266
267 // Compare with another IPEndPoint that has a different port.
268 IPEndPoint bt_endpoint_other;
269 SOCKADDR_BTH addr2 =
270 BuildBluetoothSockAddr(kBluetoothAddress, kBluetoothPort + 1);
271 EXPECT_TRUE(bt_endpoint_other.FromSockAddr(
272 reinterpret_cast<const struct sockaddr*>(&addr2), sizeof(addr2)));
273 EXPECT_EQ(bt_endpoint.address(), bt_endpoint_other.address());
274 EXPECT_EQ(bt_endpoint.GetFamily(), bt_endpoint_other.GetFamily());
275 EXPECT_EQ(bt_endpoint.GetSockAddrFamily(),
276 bt_endpoint_other.GetSockAddrFamily());
277 // Comparison functions should agree that `bt_endpoint == bt_endpoint_other`
278 // because they have the same address and Bluetooth ports are not considered
279 // by comparison functions.
280 EXPECT_FALSE(bt_endpoint < bt_endpoint_other);
281 EXPECT_FALSE(bt_endpoint != bt_endpoint_other);
282 EXPECT_TRUE(bt_endpoint == bt_endpoint_other);
283 // Test that IPv4/IPv6-only methods crash.
284 EXPECT_DCHECK_DEATH(bt_endpoint_other.port());
285 SockaddrStorage storage;
286 EXPECT_DCHECK_DEATH(std::ignore = bt_endpoint_other.ToSockAddr(
287 storage.addr, &storage.addr_len));
288 EXPECT_DCHECK_DEATH(bt_endpoint_other.ToString());
289 EXPECT_DCHECK_DEATH(bt_endpoint_other.ToStringWithoutPort());
290 }
291
TEST_F(IPEndPointTest,WinBluetoothSockAddrCompareWithDifferentAddress)292 TEST_F(IPEndPointTest, WinBluetoothSockAddrCompareWithDifferentAddress) {
293 IPEndPoint bt_endpoint;
294 SOCKADDR_BTH addr = BuildBluetoothSockAddr(kBluetoothAddress, kBluetoothPort);
295 EXPECT_TRUE(bt_endpoint.FromSockAddr(
296 reinterpret_cast<const struct sockaddr*>(&addr), sizeof(addr)));
297
298 // Compare with another IPEndPoint that has a different address.
299 IPEndPoint bt_endpoint_other;
300 SOCKADDR_BTH addr2 =
301 BuildBluetoothSockAddr(kBluetoothAddress2, kBluetoothPort);
302 EXPECT_TRUE(bt_endpoint_other.FromSockAddr(
303 reinterpret_cast<const struct sockaddr*>(&addr2), sizeof(addr2)));
304 EXPECT_LT(bt_endpoint.address(), bt_endpoint_other.address());
305 EXPECT_EQ(bt_endpoint.GetFamily(), bt_endpoint_other.GetFamily());
306 EXPECT_EQ(bt_endpoint.GetSockAddrFamily(),
307 bt_endpoint_other.GetSockAddrFamily());
308 // Comparison functions should agree that `bt_endpoint < bt_endpoint_other`
309 // due to lexicographic comparison of the address bytes.
310 EXPECT_TRUE(bt_endpoint < bt_endpoint_other);
311 EXPECT_TRUE(bt_endpoint != bt_endpoint_other);
312 EXPECT_FALSE(bt_endpoint == bt_endpoint_other);
313 // Test that IPv4/IPv6-only methods crash.
314 EXPECT_DCHECK_DEATH(bt_endpoint_other.port());
315 SockaddrStorage storage;
316 EXPECT_DCHECK_DEATH(std::ignore = bt_endpoint_other.ToSockAddr(
317 storage.addr, &storage.addr_len));
318 EXPECT_DCHECK_DEATH(bt_endpoint_other.ToString());
319 EXPECT_DCHECK_DEATH(bt_endpoint_other.ToStringWithoutPort());
320 }
321 #endif
322
TEST_F(IPEndPointTest,Equality)323 TEST_F(IPEndPointTest, Equality) {
324 uint16_t port = 0;
325 for (const auto& test : tests) {
326 IPEndPoint src(test.ip_address, ++port);
327 IPEndPoint dest(src);
328 EXPECT_TRUE(src == dest);
329 }
330 }
331
TEST_F(IPEndPointTest,LessThan)332 TEST_F(IPEndPointTest, LessThan) {
333 // Vary by port.
334 IPEndPoint ip_endpoint1(tests[0].ip_address, 100);
335 IPEndPoint ip_endpoint2(tests[0].ip_address, 1000);
336 EXPECT_TRUE(ip_endpoint1 < ip_endpoint2);
337 EXPECT_FALSE(ip_endpoint2 < ip_endpoint1);
338
339 // IPv4 vs IPv6
340 ip_endpoint1 = IPEndPoint(tests[0].ip_address, 81);
341 ip_endpoint2 = IPEndPoint(tests[2].ip_address, 80);
342 EXPECT_TRUE(ip_endpoint1 < ip_endpoint2);
343 EXPECT_FALSE(ip_endpoint2 < ip_endpoint1);
344
345 // IPv4 vs IPv4
346 ip_endpoint1 = IPEndPoint(tests[0].ip_address, 81);
347 ip_endpoint2 = IPEndPoint(tests[1].ip_address, 80);
348 EXPECT_TRUE(ip_endpoint1 < ip_endpoint2);
349 EXPECT_FALSE(ip_endpoint2 < ip_endpoint1);
350
351 // IPv6 vs IPv6
352 ip_endpoint1 = IPEndPoint(tests[2].ip_address, 81);
353 ip_endpoint2 = IPEndPoint(tests[3].ip_address, 80);
354 EXPECT_TRUE(ip_endpoint1 < ip_endpoint2);
355 EXPECT_FALSE(ip_endpoint2 < ip_endpoint1);
356
357 // Compare equivalent endpoints.
358 ip_endpoint1 = IPEndPoint(tests[0].ip_address, 80);
359 ip_endpoint2 = IPEndPoint(tests[0].ip_address, 80);
360 EXPECT_FALSE(ip_endpoint1 < ip_endpoint2);
361 EXPECT_FALSE(ip_endpoint2 < ip_endpoint1);
362 }
363
TEST_F(IPEndPointTest,ToString)364 TEST_F(IPEndPointTest, ToString) {
365 {
366 IPEndPoint endpoint;
367 EXPECT_EQ(0, endpoint.port());
368 }
369
370 uint16_t port = 100;
371 for (const auto& test : tests) {
372 ++port;
373 IPEndPoint endpoint(test.ip_address, port);
374 const std::string result = endpoint.ToString();
375 EXPECT_EQ(test.host_normalized + ":" + base::NumberToString(port), result);
376 }
377
378 // ToString() shouldn't crash on invalid addresses.
379 IPAddress invalid_address;
380 IPEndPoint invalid_endpoint(invalid_address, 8080);
381 EXPECT_EQ("", invalid_endpoint.ToString());
382 EXPECT_EQ("", invalid_endpoint.ToStringWithoutPort());
383 }
384
TEST_F(IPEndPointTest,RoundtripThroughValue)385 TEST_F(IPEndPointTest, RoundtripThroughValue) {
386 for (const auto& test : tests) {
387 IPEndPoint endpoint(test.ip_address, 1645);
388 base::Value value = endpoint.ToValue();
389
390 EXPECT_THAT(IPEndPoint::FromValue(value), Optional(endpoint));
391 }
392 }
393
TEST_F(IPEndPointTest,FromGarbageValue)394 TEST_F(IPEndPointTest, FromGarbageValue) {
395 base::Value value(123);
396 EXPECT_FALSE(IPEndPoint::FromValue(value).has_value());
397 }
398
TEST_F(IPEndPointTest,FromMalformedValues)399 TEST_F(IPEndPointTest, FromMalformedValues) {
400 for (const auto& test : tests) {
401 base::Value valid_value = IPEndPoint(test.ip_address, 1111).ToValue();
402 ASSERT_TRUE(IPEndPoint::FromValue(valid_value).has_value());
403
404 base::Value missing_address = valid_value.Clone();
405 ASSERT_TRUE(missing_address.GetDict().Remove("address"));
406 EXPECT_FALSE(IPEndPoint::FromValue(missing_address).has_value());
407
408 base::Value missing_port = valid_value.Clone();
409 ASSERT_TRUE(missing_port.GetDict().Remove("port"));
410 EXPECT_FALSE(IPEndPoint::FromValue(missing_port).has_value());
411
412 base::Value invalid_address = valid_value.Clone();
413 *invalid_address.GetDict().Find("address") = base::Value("1.2.3.4.5");
414 EXPECT_FALSE(IPEndPoint::FromValue(invalid_address).has_value());
415
416 base::Value negative_port = valid_value.Clone();
417 *negative_port.GetDict().Find("port") = base::Value(-1);
418 EXPECT_FALSE(IPEndPoint::FromValue(negative_port).has_value());
419
420 base::Value large_port = valid_value.Clone();
421 *large_port.GetDict().Find("port") = base::Value(66000);
422 EXPECT_FALSE(IPEndPoint::FromValue(large_port).has_value());
423 }
424 }
425
426 } // namespace
427
428 } // namespace net
429