blob: 90a64200acabacffd09a9c3c3512c81fa1c7b979 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/base/address_list.h"
#include "base/string_util.h"
#include "base/sys_byteorder.h"
#include "build/build_config.h"
#include "net/base/net_util.h"
#include "net/base/sys_addrinfo.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_STARBOARD)
#include "starboard/memory.h"
#include "starboard/socket.h"
#endif
namespace net {
namespace {
static const char* kCanonicalHostname = "canonical.bar.com";
#if defined(OS_STARBOARD)
TEST(AddressListTest, CreateFromSbSocketResolution) {
// Create an 4-element addrinfo.
const unsigned kNumElements = 4;
SbSocketResolution resolution = {0};
resolution.address_count = kNumElements;
struct SbSocketAddress addresses[kNumElements];
resolution.addresses = addresses;
for (int i = 0; i < kNumElements; ++i) {
SbSocketAddress* address = &addresses[i];
// Populating the address with { i, i, i, i }.
SbMemorySet(address->address, i, kIPv4AddressSize);
address->type = kSbSocketAddressTypeIpv4;
// Set port to i << 2;
address->port = i << 2;
}
AddressList list = AddressList::CreateFromSbSocketResolution(&resolution);
ASSERT_EQ(kNumElements, list.size());
for (size_t i = 0; i < list.size(); ++i) {
EXPECT_EQ(ADDRESS_FAMILY_IPV4, list[i].GetFamily());
// Only check the first byte of the address.
EXPECT_EQ(i, list[i].address()[0]);
EXPECT_EQ(static_cast<int>(i << 2), list[i].port());
}
// Check if operator= works.
AddressList copy;
copy = list;
ASSERT_EQ(kNumElements, copy.size());
// Check if copy is independent.
copy[1] = IPEndPoint(copy[2].address(), 0xBEEF);
// Original should be unchanged.
EXPECT_EQ(1u, list[1].address()[0]);
EXPECT_EQ(1 << 2, list[1].port());
}
#else // defined(OS_STARBOARD)
TEST(AddressListTest, Canonical) {
// Create an addrinfo with a canonical name.
struct sockaddr_in address;
// The contents of address do not matter for this test,
// so just zero-ing them out for consistency.
memset(&address, 0x0, sizeof(address));
// But we need to set the family.
address.sin_family = AF_INET;
struct addrinfo ai;
memset(&ai, 0x0, sizeof(ai));
ai.ai_family = AF_INET;
ai.ai_socktype = SOCK_STREAM;
ai.ai_addrlen = sizeof(address);
ai.ai_addr = reinterpret_cast<sockaddr*>(&address);
ai.ai_canonname = const_cast<char *>(kCanonicalHostname);
// Copy the addrinfo struct into an AddressList object and
// make sure it seems correct.
AddressList addrlist1 = AddressList::CreateFromAddrinfo(&ai);
EXPECT_EQ("canonical.bar.com", addrlist1.canonical_name());
// Copy the AddressList to another one.
AddressList addrlist2 = addrlist1;
EXPECT_EQ("canonical.bar.com", addrlist2.canonical_name());
}
TEST(AddressListTest, CreateFromAddrinfo) {
// Create an 4-element addrinfo.
const unsigned kNumElements = 4;
SockaddrStorage storage[kNumElements];
struct addrinfo ai[kNumElements];
for (unsigned i = 0; i < kNumElements; ++i) {
struct sockaddr_in* addr =
reinterpret_cast<struct sockaddr_in*>(storage[i].addr);
storage[i].addr_len = sizeof(struct sockaddr_in);
// Populating the address with { i, i, i, i }.
memset(&addr->sin_addr, i, kIPv4AddressSize);
addr->sin_family = AF_INET;
// Set port to i << 2;
addr->sin_port = base::HostToNet16(static_cast<uint16>(i << 2));
memset(&ai[i], 0x0, sizeof(ai[i]));
ai[i].ai_family = addr->sin_family;
ai[i].ai_socktype = SOCK_STREAM;
ai[i].ai_addrlen = storage[i].addr_len;
ai[i].ai_addr = storage[i].addr;
if (i + 1 < kNumElements)
ai[i].ai_next = &ai[i + 1];
}
AddressList list = AddressList::CreateFromAddrinfo(&ai[0]);
ASSERT_EQ(kNumElements, list.size());
for (size_t i = 0; i < list.size(); ++i) {
EXPECT_EQ(ADDRESS_FAMILY_IPV4, list[i].GetFamily());
// Only check the first byte of the address.
EXPECT_EQ(i, list[i].address()[0]);
EXPECT_EQ(static_cast<int>(i << 2), list[i].port());
}
// Check if operator= works.
AddressList copy;
copy = list;
ASSERT_EQ(kNumElements, copy.size());
// Check if copy is independent.
copy[1] = IPEndPoint(copy[2].address(), 0xBEEF);
// Original should be unchanged.
EXPECT_EQ(1u, list[1].address()[0]);
EXPECT_EQ(1 << 2, list[1].port());
}
#endif // defined(OS_STARBOARD)
TEST(AddressListTest, CreateFromIPAddressList) {
struct TestData {
std::string ip_address;
} tests[] = {
{ "127.0.0.1" },
#if defined(IN6ADDR_ANY_INIT)
{ "2001:db8:0::42" },
#endif
{ "192.168.1.1" },
};
const std::string kCanonicalName = "canonical.example.com";
// Construct a list of ip addresses.
IPAddressList ip_list;
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
IPAddressNumber ip_number;
ASSERT_TRUE(ParseIPLiteralToNumber(tests[i].ip_address, &ip_number));
ip_list.push_back(ip_number);
}
AddressList test_list = AddressList::CreateFromIPAddressList(ip_list,
kCanonicalName);
std::string canonical_name;
EXPECT_EQ(kCanonicalName, test_list.canonical_name());
EXPECT_EQ(ARRAYSIZE_UNSAFE(tests), test_list.size());
}
} // namespace
} // namespace net