Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 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/memory/scoped_ptr.h"
      8 #include "base/string_util.h"
      9 #include "net/base/host_resolver_proc.h"
     10 #include "net/base/net_util.h"
     11 #include "net/base/sys_addrinfo.h"
     12 #if defined(OS_WIN)
     13 #include "net/base/winsock_init.h"
     14 #endif
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace net {
     18 namespace {
     19 
     20 // Use getaddrinfo() to allocate an addrinfo structure.
     21 int CreateAddressList(const std::string& hostname, int port,
     22                       AddressList* addrlist) {
     23 #if defined(OS_WIN)
     24   EnsureWinsockInit();
     25 #endif
     26   int rv = SystemHostResolverProc(hostname,
     27                                   ADDRESS_FAMILY_UNSPECIFIED,
     28                                   0,
     29                                   addrlist, NULL);
     30   if (rv == 0)
     31     addrlist->SetPort(port);
     32   return rv;
     33 }
     34 
     35 void CreateLongAddressList(AddressList* addrlist, int port) {
     36   EXPECT_EQ(0, CreateAddressList("192.168.1.1", port, addrlist));
     37   AddressList second_list;
     38   EXPECT_EQ(0, CreateAddressList("192.168.1.2", port, &second_list));
     39   addrlist->Append(second_list.head());
     40 }
     41 
     42 TEST(AddressListTest, GetPort) {
     43   AddressList addrlist;
     44   EXPECT_EQ(0, CreateAddressList("192.168.1.1", 81, &addrlist));
     45   EXPECT_EQ(81, addrlist.GetPort());
     46 
     47   addrlist.SetPort(83);
     48   EXPECT_EQ(83, addrlist.GetPort());
     49 }
     50 
     51 TEST(AddressListTest, Assignment) {
     52   AddressList addrlist1;
     53   EXPECT_EQ(0, CreateAddressList("192.168.1.1", 85, &addrlist1));
     54   EXPECT_EQ(85, addrlist1.GetPort());
     55 
     56   // Should reference the same data as addrlist1 -- so when we change addrlist1
     57   // both are changed.
     58   AddressList addrlist2 = addrlist1;
     59   EXPECT_EQ(85, addrlist2.GetPort());
     60 
     61   addrlist1.SetPort(80);
     62   EXPECT_EQ(80, addrlist1.GetPort());
     63   EXPECT_EQ(80, addrlist2.GetPort());
     64 }
     65 
     66 TEST(AddressListTest, CopyRecursive) {
     67   AddressList addrlist1;
     68   CreateLongAddressList(&addrlist1, 85);
     69   EXPECT_EQ(85, addrlist1.GetPort());
     70 
     71   AddressList addrlist2;
     72   addrlist2.Copy(addrlist1.head(), true);
     73 
     74   ASSERT_TRUE(addrlist2.head()->ai_next != NULL);
     75 
     76   // addrlist1 is the same as addrlist2 at this point.
     77   EXPECT_EQ(85, addrlist1.GetPort());
     78   EXPECT_EQ(85, addrlist2.GetPort());
     79 
     80   // Changes to addrlist1 are not reflected in addrlist2.
     81   addrlist1.SetPort(70);
     82   addrlist2.SetPort(90);
     83 
     84   EXPECT_EQ(70, addrlist1.GetPort());
     85   EXPECT_EQ(90, addrlist2.GetPort());
     86 }
     87 
     88 TEST(AddressListTest, CopyNonRecursive) {
     89   AddressList addrlist1;
     90   CreateLongAddressList(&addrlist1, 85);
     91   EXPECT_EQ(85, addrlist1.GetPort());
     92 
     93   AddressList addrlist2;
     94   addrlist2.Copy(addrlist1.head(), false);
     95 
     96   ASSERT_TRUE(addrlist2.head()->ai_next == NULL);
     97 
     98   // addrlist1 is the same as addrlist2 at this point.
     99   EXPECT_EQ(85, addrlist1.GetPort());
    100   EXPECT_EQ(85, addrlist2.GetPort());
    101 
    102   // Changes to addrlist1 are not reflected in addrlist2.
    103   addrlist1.SetPort(70);
    104   addrlist2.SetPort(90);
    105 
    106   EXPECT_EQ(70, addrlist1.GetPort());
    107   EXPECT_EQ(90, addrlist2.GetPort());
    108 }
    109 
    110 TEST(AddressListTest, Append) {
    111   AddressList addrlist1;
    112   EXPECT_EQ(0, CreateAddressList("192.168.1.1", 11, &addrlist1));
    113   EXPECT_EQ(11, addrlist1.GetPort());
    114   AddressList addrlist2;
    115   EXPECT_EQ(0, CreateAddressList("192.168.1.2", 12, &addrlist2));
    116   EXPECT_EQ(12, addrlist2.GetPort());
    117 
    118   ASSERT_TRUE(addrlist1.head()->ai_next == NULL);
    119   addrlist1.Append(addrlist2.head());
    120   ASSERT_TRUE(addrlist1.head()->ai_next != NULL);
    121 
    122   AddressList addrlist3;
    123   addrlist3.Copy(addrlist1.head()->ai_next, false);
    124   EXPECT_EQ(12, addrlist3.GetPort());
    125 }
    126 
    127 static const char* kCanonicalHostname = "canonical.bar.com";
    128 
    129 TEST(AddressListTest, Canonical) {
    130   // Create an addrinfo with a canonical name.
    131   sockaddr_in address;
    132   // The contents of address do not matter for this test,
    133   // so just zero-ing them out for consistency.
    134   memset(&address, 0x0, sizeof(address));
    135   struct addrinfo ai;
    136   memset(&ai, 0x0, sizeof(ai));
    137   ai.ai_family = AF_INET;
    138   ai.ai_socktype = SOCK_STREAM;
    139   ai.ai_addrlen = sizeof(address);
    140   ai.ai_addr = reinterpret_cast<sockaddr*>(&address);
    141   ai.ai_canonname = const_cast<char *>(kCanonicalHostname);
    142 
    143   // Copy the addrinfo struct into an AddressList object and
    144   // make sure it seems correct.
    145   AddressList addrlist1;
    146   addrlist1.Copy(&ai, true);
    147   const struct addrinfo* addrinfo1 = addrlist1.head();
    148   EXPECT_TRUE(addrinfo1 != NULL);
    149   EXPECT_TRUE(addrinfo1->ai_next == NULL);
    150   std::string canon_name1;
    151   EXPECT_TRUE(addrlist1.GetCanonicalName(&canon_name1));
    152   EXPECT_EQ("canonical.bar.com", canon_name1);
    153 
    154   // Copy the AddressList to another one.
    155   AddressList addrlist2;
    156   addrlist2.Copy(addrinfo1, true);
    157   const struct addrinfo* addrinfo2 = addrlist2.head();
    158   EXPECT_TRUE(addrinfo2 != NULL);
    159   EXPECT_TRUE(addrinfo2->ai_next == NULL);
    160   EXPECT_TRUE(addrinfo2->ai_canonname != NULL);
    161   EXPECT_NE(addrinfo1, addrinfo2);
    162   EXPECT_NE(addrinfo1->ai_canonname, addrinfo2->ai_canonname);
    163   std::string canon_name2;
    164   EXPECT_TRUE(addrlist2.GetCanonicalName(&canon_name2));
    165   EXPECT_EQ("canonical.bar.com", canon_name2);
    166 
    167   // Make sure that GetCanonicalName correctly returns false
    168   // when ai_canonname is NULL.
    169   ai.ai_canonname = NULL;
    170   AddressList addrlist_no_canon;
    171   addrlist_no_canon.Copy(&ai, true);
    172   std::string canon_name3 = "blah";
    173   EXPECT_FALSE(addrlist_no_canon.GetCanonicalName(&canon_name3));
    174   EXPECT_EQ("blah", canon_name3);
    175 }
    176 
    177 TEST(AddressListTest, IPLiteralConstructor) {
    178   struct TestData {
    179     std::string ip_address;
    180     std::string canonical_ip_address;
    181     bool is_ipv6;
    182   } tests[] = {
    183     { "127.0.00.1", "127.0.0.1", false },
    184     { "192.168.1.1", "192.168.1.1", false },
    185     { "::1", "::1", true },
    186     { "2001:db8:0::42", "2001:db8::42", true },
    187   };
    188   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); i++) {
    189     AddressList expected_list;
    190     int rv = CreateAddressList(tests[i].canonical_ip_address, 80,
    191                                &expected_list);
    192     if (tests[i].is_ipv6 && rv != 0) {
    193       LOG(WARNING) << "Unable to resolve ip literal '" << tests[i].ip_address
    194                    << "' test skipped.";
    195       continue;
    196     }
    197     ASSERT_EQ(0, rv);
    198     const struct addrinfo* good_ai = expected_list.head();
    199 
    200     IPAddressNumber ip_number;
    201     ParseIPLiteralToNumber(tests[i].ip_address, &ip_number);
    202     AddressList test_list(ip_number, 80, true);
    203     const struct addrinfo* test_ai = test_list.head();
    204 
    205     EXPECT_EQ(good_ai->ai_family, test_ai->ai_family);
    206     EXPECT_EQ(good_ai->ai_socktype, test_ai->ai_socktype);
    207     EXPECT_EQ(good_ai->ai_addrlen, test_ai->ai_addrlen);
    208     size_t sockaddr_size =
    209         good_ai->ai_socktype == AF_INET ? sizeof(struct sockaddr_in) :
    210         good_ai->ai_socktype == AF_INET6 ? sizeof(struct sockaddr_in6) : 0;
    211     EXPECT_EQ(memcmp(good_ai->ai_addr, test_ai->ai_addr, sockaddr_size), 0);
    212     EXPECT_EQ(good_ai->ai_next, test_ai->ai_next);
    213     EXPECT_EQ(strcmp(tests[i].canonical_ip_address.c_str(),
    214                      test_ai->ai_canonname), 0);
    215   }
    216 }
    217 
    218 TEST(AddressListTest, AddressFromAddrInfo) {
    219   struct TestData {
    220     std::string ip_address;
    221     std::string canonical_ip_address;
    222     bool is_ipv6;
    223   } tests[] = {
    224     { "127.0.00.1", "127.0.0.1", false },
    225     { "192.168.1.1", "192.168.1.1", false },
    226     { "::1", "::1", true },
    227     { "2001:db8:0::42", "2001:db8::42", true },
    228   };
    229   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); i++) {
    230     AddressList expected_list;
    231     int rv = CreateAddressList(tests[i].canonical_ip_address, 80,
    232                                &expected_list);
    233     if (tests[i].is_ipv6 && rv != 0) {
    234       LOG(WARNING) << "Unable to resolve ip literal '" << tests[i].ip_address
    235                    << "' test skipped.";
    236       continue;
    237     }
    238     ASSERT_EQ(0, rv);
    239     const struct addrinfo* good_ai = expected_list.head();
    240 
    241     scoped_ptr<AddressList> test_list(
    242         AddressList::CreateAddressListFromSockaddr(good_ai->ai_addr,
    243                                                    good_ai->ai_addrlen,
    244                                                    SOCK_STREAM,
    245                                                    IPPROTO_TCP));
    246     const struct addrinfo* test_ai = test_list->head();
    247 
    248     EXPECT_EQ(good_ai->ai_family, test_ai->ai_family);
    249     EXPECT_EQ(good_ai->ai_addrlen, test_ai->ai_addrlen);
    250     size_t sockaddr_size =
    251         good_ai->ai_socktype == AF_INET ? sizeof(struct sockaddr_in) :
    252         good_ai->ai_socktype == AF_INET6 ? sizeof(struct sockaddr_in6) : 0;
    253     EXPECT_EQ(memcmp(good_ai->ai_addr, test_ai->ai_addr, sockaddr_size), 0);
    254     EXPECT_EQ(good_ai->ai_next, test_ai->ai_next);
    255   }
    256 }
    257 
    258 }  // namespace
    259 }  // namespace net
    260