Home | History | Annotate | Download | only in base
      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