ip_endpoint_unittest.cc 13 KB

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