Home | History | Annotate | Download | only in dns
      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/dns/dns_hosts.h"
      6 
      7 #include "testing/gtest/include/gtest/gtest.h"
      8 
      9 namespace net {
     10 
     11 namespace {
     12 
     13 struct ExpectedHostsEntry {
     14   const char* host;
     15   AddressFamily family;
     16   const char* ip;
     17 };
     18 
     19 void PopulateExpectedHosts(const ExpectedHostsEntry* entries,
     20                            size_t num_entries,
     21                            DnsHosts* expected_hosts_out) {
     22   for (size_t i = 0; i < num_entries; ++i) {
     23     DnsHostsKey key(entries[i].host, entries[i].family);
     24     IPAddressNumber& ip_ref = (*expected_hosts_out)[key];
     25     ASSERT_TRUE(ip_ref.empty());
     26     ASSERT_TRUE(ParseIPLiteralToNumber(entries[i].ip, &ip_ref));
     27     ASSERT_EQ(ip_ref.size(),
     28         (entries[i].family == ADDRESS_FAMILY_IPV4) ? 4u : 16u);
     29   }
     30 }
     31 
     32 TEST(DnsHostsTest, ParseHosts) {
     33   const std::string kContents =
     34       "127.0.0.1       localhost\tlocalhost.localdomain # standard\n"
     35       "\n"
     36       "1.0.0.1 localhost # ignored, first hit above\n"
     37       "fe00::x example company # ignored, malformed IPv6\n"
     38       "1.0.0.300 company # ignored, malformed IPv4\n"
     39       "1.0.0.1 # ignored, missing hostname\n"
     40       "1.0.0.1\t CoMpANy # normalized to 'company' \n"
     41       "::1\tlocalhost ip6-localhost ip6-loopback # comment # within a comment\n"
     42       "\t fe00::0 ip6-localnet\r\n"
     43       "2048::2 example\n"
     44       "2048::1 company example # ignored for 'example' \n"
     45       "127.0.0.1 cache1\n"
     46       "127.0.0.1 cache2 # should reuse parsed IP\n"
     47       "256.0.0.0 cache3 # bogus IP should not clear parsed IP cache\n"
     48       "127.0.0.1 cache4 # should still be reused\n"
     49       "127.0.0.2 cache5\n"
     50       "gibberish";
     51 
     52   const ExpectedHostsEntry kEntries[] = {
     53     { "localhost", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
     54     { "localhost.localdomain", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
     55     { "company", ADDRESS_FAMILY_IPV4, "1.0.0.1" },
     56     { "localhost", ADDRESS_FAMILY_IPV6, "::1" },
     57     { "ip6-localhost", ADDRESS_FAMILY_IPV6, "::1" },
     58     { "ip6-loopback", ADDRESS_FAMILY_IPV6, "::1" },
     59     { "ip6-localnet", ADDRESS_FAMILY_IPV6, "fe00::0" },
     60     { "company", ADDRESS_FAMILY_IPV6, "2048::1" },
     61     { "example", ADDRESS_FAMILY_IPV6, "2048::2" },
     62     { "cache1", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
     63     { "cache2", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
     64     { "cache4", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
     65     { "cache5", ADDRESS_FAMILY_IPV4, "127.0.0.2" },
     66   };
     67 
     68   DnsHosts expected_hosts, actual_hosts;
     69   PopulateExpectedHosts(kEntries, ARRAYSIZE_UNSAFE(kEntries), &expected_hosts);
     70   ParseHosts(kContents, &actual_hosts);
     71   ASSERT_EQ(expected_hosts, actual_hosts);
     72 }
     73 
     74 TEST(DnsHostsTest, ParseHosts_CommaIsToken) {
     75   const std::string kContents = "127.0.0.1 comma1,comma2";
     76 
     77   const ExpectedHostsEntry kEntries[] = {
     78     { "comma1,comma2", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
     79   };
     80 
     81   DnsHosts expected_hosts, actual_hosts;
     82   PopulateExpectedHosts(kEntries, ARRAYSIZE_UNSAFE(kEntries), &expected_hosts);
     83   ParseHostsWithCommaModeForTesting(
     84       kContents, &actual_hosts, PARSE_HOSTS_COMMA_IS_TOKEN);
     85   ASSERT_EQ(expected_hosts, actual_hosts);
     86 }
     87 
     88 TEST(DnsHostsTest, ParseHosts_CommaIsWhitespace) {
     89   std::string kContents = "127.0.0.1 comma1,comma2";
     90 
     91   const ExpectedHostsEntry kEntries[] = {
     92     { "comma1", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
     93     { "comma2", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
     94   };
     95 
     96   DnsHosts expected_hosts, actual_hosts;
     97   PopulateExpectedHosts(kEntries, ARRAYSIZE_UNSAFE(kEntries), &expected_hosts);
     98   ParseHostsWithCommaModeForTesting(
     99       kContents, &actual_hosts, PARSE_HOSTS_COMMA_IS_WHITESPACE);
    100   ASSERT_EQ(expected_hosts, actual_hosts);
    101 }
    102 
    103 // Test that the right comma mode is used on each platform.
    104 TEST(DnsHostsTest, ParseHosts_CommaModeByPlatform) {
    105   std::string kContents = "127.0.0.1 comma1,comma2";
    106 
    107 #if defined(OS_MACOSX)
    108   const ExpectedHostsEntry kEntries[] = {
    109     { "comma1", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
    110     { "comma2", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
    111   };
    112 #else
    113   const ExpectedHostsEntry kEntries[] = {
    114     { "comma1,comma2", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
    115   };
    116 #endif
    117 
    118   DnsHosts expected_hosts, actual_hosts;
    119   PopulateExpectedHosts(kEntries, ARRAYSIZE_UNSAFE(kEntries), &expected_hosts);
    120   ParseHosts(kContents, &actual_hosts);
    121   ASSERT_EQ(expected_hosts, actual_hosts);
    122 }
    123 
    124 TEST(DnsHostsTest, HostsParser_Empty) {
    125   DnsHosts hosts;
    126   ParseHosts("", &hosts);
    127   EXPECT_EQ(0u, hosts.size());
    128 }
    129 
    130 TEST(DnsHostsTest, HostsParser_OnlyWhitespace) {
    131   DnsHosts hosts;
    132   ParseHosts(" ", &hosts);
    133   EXPECT_EQ(0u, hosts.size());
    134 }
    135 
    136 TEST(DnsHostsTest, HostsParser_EndsWithNothing) {
    137   DnsHosts hosts;
    138   ParseHosts("127.0.0.1 localhost", &hosts);
    139   EXPECT_EQ(1u, hosts.size());
    140 }
    141 
    142 TEST(DnsHostsTest, HostsParser_EndsWithWhitespace) {
    143   DnsHosts hosts;
    144   ParseHosts("127.0.0.1 localhost ", &hosts);
    145   EXPECT_EQ(1u, hosts.size());
    146 }
    147 
    148 TEST(DnsHostsTest, HostsParser_EndsWithComment) {
    149   DnsHosts hosts;
    150   ParseHosts("127.0.0.1 localhost # comment", &hosts);
    151   EXPECT_EQ(1u, hosts.size());
    152 }
    153 
    154 TEST(DnsHostsTest, HostsParser_EndsWithNewline) {
    155   DnsHosts hosts;
    156   ParseHosts("127.0.0.1 localhost\n", &hosts);
    157   EXPECT_EQ(1u, hosts.size());
    158 }
    159 
    160 TEST(DnsHostsTest, HostsParser_EndsWithTwoNewlines) {
    161   DnsHosts hosts;
    162   ParseHosts("127.0.0.1 localhost\n\n", &hosts);
    163   EXPECT_EQ(1u, hosts.size());
    164 }
    165 
    166 TEST(DnsHostsTest, HostsParser_EndsWithNewlineAndWhitespace) {
    167   DnsHosts hosts;
    168   ParseHosts("127.0.0.1 localhost\n ", &hosts);
    169   EXPECT_EQ(1u, hosts.size());
    170 }
    171 
    172 TEST(DnsHostsTest, HostsParser_EndsWithNewlineAndToken) {
    173   DnsHosts hosts;
    174   ParseHosts("127.0.0.1 localhost\ntoken", &hosts);
    175   EXPECT_EQ(1u, hosts.size());
    176 }
    177 
    178 }  // namespace
    179 
    180 }  // namespace net
    181 
    182