15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ip_endpoint.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <winsock2.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <netinet/in.h>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TestData {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string host;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string host_normalized;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ipv6;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip_address;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} tests[] = {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "127.0.00.1", "127.0.0.1", false},
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "192.168.1.1", "192.168.1.1", false },
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "::1", "[::1]", true },
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "2001:db8:0::42", "[2001:db8::42]", true },
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int test_count = ARRAYSIZE_UNSAFE(tests);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IPEndPointTest : public PlatformTest {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is where we populate the TestData.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int index = 0; index < test_count; ++index) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(ParseIPLiteralToNumber(tests[index].host,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &tests[index].ip_address));
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPEndPointTest, Constructor) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint endpoint;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, endpoint.port());
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int index = 0; index < test_count; ++index) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPEndPoint endpoint(tests[index].ip_address, 80);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(80, endpoint.port());
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[index].ip_address, endpoint.address());
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPEndPointTest, Assignment) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int index = 0; index < test_count; ++index) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPEndPoint src(tests[index].ip_address, index);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPEndPoint dest = src;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(src.port(), dest.port());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(src.address(), dest.address());
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPEndPointTest, Copy) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int index = 0; index < test_count; ++index) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPEndPoint src(tests[index].ip_address, index);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPEndPoint dest(src);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(src.port(), dest.port());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(src.address(), dest.address());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPEndPointTest, ToFromSockAddr) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int index = 0; index < test_count; ++index) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPEndPoint ip_endpoint(tests[index].ip_address, index);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Convert to a sockaddr.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SockaddrStorage storage;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(ip_endpoint.ToSockAddr(storage.addr, &storage.addr_len));
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Basic verification.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    socklen_t expected_size = tests[index].ipv6 ?
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_size, storage.addr_len);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ip_endpoint.port(), GetPortFromSockaddr(storage.addr,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      storage.addr_len));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // And convert back to an IPEndPoint.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPEndPoint ip_endpoint2;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(ip_endpoint2.FromSockAddr(storage.addr, storage.addr_len));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ip_endpoint.port(), ip_endpoint2.port());
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ip_endpoint.address(), ip_endpoint2.address());
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPEndPointTest, ToSockAddrBufTooSmall) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int index = 0; index < test_count; ++index) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPEndPoint ip_endpoint(tests[index].ip_address, index);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SockaddrStorage storage;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    storage.addr_len = index;  // size is too small!
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(ip_endpoint.ToSockAddr(storage.addr, &storage.addr_len));
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPEndPointTest, FromSockAddrBufTooSmall) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct sockaddr_in addr;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&addr, 0, sizeof(addr));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addr.sin_family = AF_INET;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint ip_endpoint;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct sockaddr* sockaddr = reinterpret_cast<struct sockaddr*>(&addr);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ip_endpoint.FromSockAddr(sockaddr, sizeof(addr) - 1));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPEndPointTest, Equality) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int index = 0; index < test_count; ++index) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPEndPoint src(tests[index].ip_address, index);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPEndPoint dest(src);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(src == dest);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPEndPointTest, LessThan) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vary by port.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint ip_endpoint1(tests[0].ip_address, 100);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint ip_endpoint2(tests[0].ip_address, 1000);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ip_endpoint1 < ip_endpoint2);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ip_endpoint2 < ip_endpoint1);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IPv4 vs IPv6
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ip_endpoint1 = IPEndPoint(tests[0].ip_address, 81);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ip_endpoint2 = IPEndPoint(tests[2].ip_address, 80);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ip_endpoint1 < ip_endpoint2);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ip_endpoint2 < ip_endpoint1);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IPv4 vs IPv4
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ip_endpoint1 = IPEndPoint(tests[0].ip_address, 81);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ip_endpoint2 = IPEndPoint(tests[1].ip_address, 80);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ip_endpoint1 < ip_endpoint2);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ip_endpoint2 < ip_endpoint1);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IPv6 vs IPv6
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ip_endpoint1 = IPEndPoint(tests[2].ip_address, 81);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ip_endpoint2 = IPEndPoint(tests[3].ip_address, 80);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(ip_endpoint1 < ip_endpoint2);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ip_endpoint2 < ip_endpoint1);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compare equivalent endpoints.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ip_endpoint1 = IPEndPoint(tests[0].ip_address, 80);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ip_endpoint2 = IPEndPoint(tests[0].ip_address, 80);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ip_endpoint1 < ip_endpoint2);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(ip_endpoint2 < ip_endpoint1);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPEndPointTest, ToString) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint endpoint;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, endpoint.port());
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int index = 0; index < test_count; ++index) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int port = 100 + index;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPEndPoint endpoint(tests[index].ip_address, port);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string result = endpoint.ToString();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(tests[index].host_normalized + ":" + base::IntToString(port),
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              result);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
174