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 5 #include "net/base/address_list.h" 6 7 #include "base/strings/string_util.h" 8 #include "base/sys_byteorder.h" 9 #include "net/base/net_util.h" 10 #include "net/base/sys_addrinfo.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 namespace net { 14 namespace { 15 16 static const char* kCanonicalHostname = "canonical.bar.com"; 17 18 TEST(AddressListTest, Canonical) { 19 // Create an addrinfo with a canonical name. 20 struct sockaddr_in address; 21 // The contents of address do not matter for this test, 22 // so just zero-ing them out for consistency. 23 memset(&address, 0x0, sizeof(address)); 24 // But we need to set the family. 25 address.sin_family = AF_INET; 26 struct addrinfo ai; 27 memset(&ai, 0x0, sizeof(ai)); 28 ai.ai_family = AF_INET; 29 ai.ai_socktype = SOCK_STREAM; 30 ai.ai_addrlen = sizeof(address); 31 ai.ai_addr = reinterpret_cast<sockaddr*>(&address); 32 ai.ai_canonname = const_cast<char *>(kCanonicalHostname); 33 34 // Copy the addrinfo struct into an AddressList object and 35 // make sure it seems correct. 36 AddressList addrlist1 = AddressList::CreateFromAddrinfo(&ai); 37 EXPECT_EQ("canonical.bar.com", addrlist1.canonical_name()); 38 39 // Copy the AddressList to another one. 40 AddressList addrlist2 = addrlist1; 41 EXPECT_EQ("canonical.bar.com", addrlist2.canonical_name()); 42 } 43 44 TEST(AddressListTest, CreateFromAddrinfo) { 45 // Create an 4-element addrinfo. 46 const unsigned kNumElements = 4; 47 SockaddrStorage storage[kNumElements]; 48 struct addrinfo ai[kNumElements]; 49 for (unsigned i = 0; i < kNumElements; ++i) { 50 struct sockaddr_in* addr = 51 reinterpret_cast<struct sockaddr_in*>(storage[i].addr); 52 storage[i].addr_len = sizeof(struct sockaddr_in); 53 // Populating the address with { i, i, i, i }. 54 memset(&addr->sin_addr, i, kIPv4AddressSize); 55 addr->sin_family = AF_INET; 56 // Set port to i << 2; 57 addr->sin_port = base::HostToNet16(static_cast<uint16>(i << 2)); 58 memset(&ai[i], 0x0, sizeof(ai[i])); 59 ai[i].ai_family = addr->sin_family; 60 ai[i].ai_socktype = SOCK_STREAM; 61 ai[i].ai_addrlen = storage[i].addr_len; 62 ai[i].ai_addr = storage[i].addr; 63 if (i + 1 < kNumElements) 64 ai[i].ai_next = &ai[i + 1]; 65 } 66 67 AddressList list = AddressList::CreateFromAddrinfo(&ai[0]); 68 69 ASSERT_EQ(kNumElements, list.size()); 70 for (size_t i = 0; i < list.size(); ++i) { 71 EXPECT_EQ(ADDRESS_FAMILY_IPV4, list[i].GetFamily()); 72 // Only check the first byte of the address. 73 EXPECT_EQ(i, list[i].address()[0]); 74 EXPECT_EQ(static_cast<int>(i << 2), list[i].port()); 75 } 76 77 // Check if operator= works. 78 AddressList copy; 79 copy = list; 80 ASSERT_EQ(kNumElements, copy.size()); 81 82 // Check if copy is independent. 83 copy[1] = IPEndPoint(copy[2].address(), 0xBEEF); 84 // Original should be unchanged. 85 EXPECT_EQ(1u, list[1].address()[0]); 86 EXPECT_EQ(1 << 2, list[1].port()); 87 } 88 89 TEST(AddressListTest, CreateFromIPAddressList) { 90 struct TestData { 91 std::string ip_address; 92 const char* in_addr; 93 int ai_family; 94 size_t ai_addrlen; 95 size_t in_addr_offset; 96 size_t in_addr_size; 97 } tests[] = { 98 { "127.0.0.1", 99 "\x7f\x00\x00\x01", 100 AF_INET, 101 sizeof(struct sockaddr_in), 102 offsetof(struct sockaddr_in, sin_addr), 103 sizeof(struct in_addr), 104 }, 105 { "2001:db8:0::42", 106 "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42", 107 AF_INET6, 108 sizeof(struct sockaddr_in6), 109 offsetof(struct sockaddr_in6, sin6_addr), 110 sizeof(struct in6_addr), 111 }, 112 { "192.168.1.1", 113 "\xc0\xa8\x01\x01", 114 AF_INET, 115 sizeof(struct sockaddr_in), 116 offsetof(struct sockaddr_in, sin_addr), 117 sizeof(struct in_addr), 118 }, 119 }; 120 const std::string kCanonicalName = "canonical.example.com"; 121 122 // Construct a list of ip addresses. 123 IPAddressList ip_list; 124 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 125 IPAddressNumber ip_number; 126 ASSERT_TRUE(ParseIPLiteralToNumber(tests[i].ip_address, &ip_number)); 127 ip_list.push_back(ip_number); 128 } 129 130 AddressList test_list = AddressList::CreateFromIPAddressList(ip_list, 131 kCanonicalName); 132 std::string canonical_name; 133 EXPECT_EQ(kCanonicalName, test_list.canonical_name()); 134 EXPECT_EQ(ARRAYSIZE_UNSAFE(tests), test_list.size()); 135 } 136 137 } // namespace 138 } // namespace net 139