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/address_list.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sys_byteorder.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/sys_addrinfo.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kCanonicalHostname = "canonical.bar.com";
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(AddressListTest, Canonical) {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create an addrinfo with a canonical name.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct sockaddr_in address;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The contents of address do not matter for this test,
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so just zero-ing them out for consistency.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&address, 0x0, sizeof(address));
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // But we need to set the family.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  address.sin_family = AF_INET;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct addrinfo ai;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&ai, 0x0, sizeof(ai));
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ai.ai_family = AF_INET;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ai.ai_socktype = SOCK_STREAM;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ai.ai_addrlen = sizeof(address);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ai.ai_addr = reinterpret_cast<sockaddr*>(&address);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ai.ai_canonname = const_cast<char *>(kCanonicalHostname);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy the addrinfo struct into an AddressList object and
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // make sure it seems correct.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList addrlist1 = AddressList::CreateFromAddrinfo(&ai);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("canonical.bar.com", addrlist1.canonical_name());
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy the AddressList to another one.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList addrlist2 = addrlist1;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("canonical.bar.com", addrlist2.canonical_name());
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(AddressListTest, CreateFromAddrinfo) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create an 4-element addrinfo.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned kNumElements = 4;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SockaddrStorage storage[kNumElements];
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct addrinfo ai[kNumElements];
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned i = 0; i < kNumElements; ++i) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct sockaddr_in* addr =
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<struct sockaddr_in*>(storage[i].addr);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    storage[i].addr_len = sizeof(struct sockaddr_in);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Populating the address with { i, i, i, i }.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(&addr->sin_addr, i, kIPv4AddressSize);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    addr->sin_family = AF_INET;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set port to i << 2;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    addr->sin_port = base::HostToNet16(static_cast<uint16>(i << 2));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(&ai[i], 0x0, sizeof(ai[i]));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ai[i].ai_family = addr->sin_family;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ai[i].ai_socktype = SOCK_STREAM;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ai[i].ai_addrlen = storage[i].addr_len;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ai[i].ai_addr = storage[i].addr;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i + 1 < kNumElements)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ai[i].ai_next = &ai[i + 1];
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList list = AddressList::CreateFromAddrinfo(&ai[0]);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(kNumElements, list.size());
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < list.size(); ++i) {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(ADDRESS_FAMILY_IPV4, list[i].GetFamily());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only check the first byte of the address.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(i, list[i].address()[0]);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(static_cast<int>(i << 2), list[i].port());
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if operator= works.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList copy;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  copy = list;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(kNumElements, copy.size());
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if copy is independent.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  copy[1] = IPEndPoint(copy[2].address(), 0xBEEF);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Original should be unchanged.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, list[1].address()[0]);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1 << 2, list[1].port());
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(AddressListTest, CreateFromIPAddressList) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestData {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string ip_address;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* in_addr;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ai_family;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t ai_addrlen;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t in_addr_offset;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t in_addr_size;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } tests[] = {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "127.0.0.1",
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x7f\x00\x00\x01",
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AF_INET,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sizeof(struct sockaddr_in),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      offsetof(struct sockaddr_in, sin_addr),
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sizeof(struct in_addr),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "2001:db8:0::42",
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42",
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AF_INET6,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sizeof(struct sockaddr_in6),
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      offsetof(struct sockaddr_in6, sin6_addr),
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sizeof(struct in6_addr),
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "192.168.1.1",
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\xc0\xa8\x01\x01",
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AF_INET,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sizeof(struct sockaddr_in),
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      offsetof(struct sockaddr_in, sin_addr),
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sizeof(struct in_addr),
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kCanonicalName = "canonical.example.com";
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct a list of ip addresses.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressList ip_list;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPAddressNumber ip_number;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(ParseIPLiteralToNumber(tests[i].ip_address, &ip_number));
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ip_list.push_back(ip_number);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList test_list = AddressList::CreateFromIPAddressList(ip_list,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                               kCanonicalName);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string canonical_name;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kCanonicalName, test_list.canonical_name());
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ARRAYSIZE_UNSAFE(tests), test_list.size());
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
139