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/mapped_host_resolver.h"
      6 
      7 #include "net/base/address_list.h"
      8 #include "net/base/net_errors.h"
      9 #include "net/base/net_log.h"
     10 #include "net/base/net_util.h"
     11 #include "net/base/test_completion_callback.h"
     12 #include "net/dns/mock_host_resolver.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 namespace net {
     16 
     17 namespace {
     18 
     19 std::string FirstAddress(const AddressList& address_list) {
     20   if (address_list.empty())
     21     return std::string();
     22   return address_list.front().ToString();
     23 }
     24 
     25 TEST(MappedHostResolverTest, Inclusion) {
     26   // Create a mock host resolver, with specific hostname to IP mappings.
     27   scoped_ptr<MockHostResolver> resolver_impl(new MockHostResolver());
     28   resolver_impl->rules()->AddSimulatedFailure("*google.com");
     29   resolver_impl->rules()->AddRule("baz.com", "192.168.1.5");
     30   resolver_impl->rules()->AddRule("foo.com", "192.168.1.8");
     31   resolver_impl->rules()->AddRule("proxy", "192.168.1.11");
     32 
     33   // Create a remapped resolver that uses |resolver_impl|.
     34   scoped_ptr<MappedHostResolver> resolver(
     35       new MappedHostResolver(resolver_impl.PassAs<HostResolver>()));
     36 
     37   int rv;
     38   AddressList address_list;
     39 
     40   // Try resolving "www.google.com:80". There are no mappings yet, so this
     41   // hits |resolver_impl| and fails.
     42   TestCompletionCallback callback;
     43   rv = resolver->Resolve(
     44       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
     45       DEFAULT_PRIORITY,
     46       &address_list,
     47       callback.callback(),
     48       NULL,
     49       BoundNetLog());
     50   EXPECT_EQ(ERR_IO_PENDING, rv);
     51   rv = callback.WaitForResult();
     52   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
     53 
     54   // Remap *.google.com to baz.com.
     55   EXPECT_TRUE(resolver->AddRuleFromString("map *.google.com baz.com"));
     56 
     57   // Try resolving "www.google.com:80". Should be remapped to "baz.com:80".
     58   rv = resolver->Resolve(
     59       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
     60       DEFAULT_PRIORITY,
     61       &address_list,
     62       callback.callback(),
     63       NULL,
     64       BoundNetLog());
     65   EXPECT_EQ(ERR_IO_PENDING, rv);
     66   rv = callback.WaitForResult();
     67   EXPECT_EQ(OK, rv);
     68   EXPECT_EQ("192.168.1.5:80", FirstAddress(address_list));
     69 
     70   // Try resolving "foo.com:77". This will NOT be remapped, so result
     71   // is "foo.com:77".
     72   rv = resolver->Resolve(HostResolver::RequestInfo(HostPortPair("foo.com", 77)),
     73                          DEFAULT_PRIORITY,
     74                          &address_list,
     75                          callback.callback(),
     76                          NULL,
     77                          BoundNetLog());
     78   EXPECT_EQ(ERR_IO_PENDING, rv);
     79   rv = callback.WaitForResult();
     80   EXPECT_EQ(OK, rv);
     81   EXPECT_EQ("192.168.1.8:77", FirstAddress(address_list));
     82 
     83   // Remap "*.org" to "proxy:99".
     84   EXPECT_TRUE(resolver->AddRuleFromString("Map *.org proxy:99"));
     85 
     86   // Try resolving "chromium.org:61". Should be remapped to "proxy:99".
     87   rv = resolver->Resolve(
     88       HostResolver::RequestInfo(HostPortPair("chromium.org", 61)),
     89       DEFAULT_PRIORITY,
     90       &address_list,
     91       callback.callback(),
     92       NULL,
     93       BoundNetLog());
     94   EXPECT_EQ(ERR_IO_PENDING, rv);
     95   rv = callback.WaitForResult();
     96   EXPECT_EQ(OK, rv);
     97   EXPECT_EQ("192.168.1.11:99", FirstAddress(address_list));
     98 }
     99 
    100 // Tests that exclusions are respected.
    101 TEST(MappedHostResolverTest, Exclusion) {
    102   // Create a mock host resolver, with specific hostname to IP mappings.
    103   scoped_ptr<MockHostResolver> resolver_impl(new MockHostResolver());
    104   resolver_impl->rules()->AddRule("baz", "192.168.1.5");
    105   resolver_impl->rules()->AddRule("www.google.com", "192.168.1.3");
    106 
    107   // Create a remapped resolver that uses |resolver_impl|.
    108   scoped_ptr<MappedHostResolver> resolver(
    109       new MappedHostResolver(resolver_impl.PassAs<HostResolver>()));
    110 
    111   int rv;
    112   AddressList address_list;
    113   TestCompletionCallback callback;
    114 
    115   // Remap "*.com" to "baz".
    116   EXPECT_TRUE(resolver->AddRuleFromString("map *.com baz"));
    117 
    118   // Add an exclusion for "*.google.com".
    119   EXPECT_TRUE(resolver->AddRuleFromString("EXCLUDE *.google.com"));
    120 
    121   // Try resolving "www.google.com". Should not be remapped due to exclusion).
    122   rv = resolver->Resolve(
    123       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
    124       DEFAULT_PRIORITY,
    125       &address_list,
    126       callback.callback(),
    127       NULL,
    128       BoundNetLog());
    129   EXPECT_EQ(ERR_IO_PENDING, rv);
    130   rv = callback.WaitForResult();
    131   EXPECT_EQ(OK, rv);
    132   EXPECT_EQ("192.168.1.3:80", FirstAddress(address_list));
    133 
    134   // Try resolving "chrome.com:80". Should be remapped to "baz:80".
    135   rv = resolver->Resolve(
    136       HostResolver::RequestInfo(HostPortPair("chrome.com", 80)),
    137       DEFAULT_PRIORITY,
    138       &address_list,
    139       callback.callback(),
    140       NULL,
    141       BoundNetLog());
    142   EXPECT_EQ(ERR_IO_PENDING, rv);
    143   rv = callback.WaitForResult();
    144   EXPECT_EQ(OK, rv);
    145   EXPECT_EQ("192.168.1.5:80", FirstAddress(address_list));
    146 }
    147 
    148 TEST(MappedHostResolverTest, SetRulesFromString) {
    149   // Create a mock host resolver, with specific hostname to IP mappings.
    150   scoped_ptr<MockHostResolver> resolver_impl(new MockHostResolver());
    151   resolver_impl->rules()->AddRule("baz", "192.168.1.7");
    152   resolver_impl->rules()->AddRule("bar", "192.168.1.9");
    153 
    154   // Create a remapped resolver that uses |resolver_impl|.
    155   scoped_ptr<MappedHostResolver> resolver(
    156       new MappedHostResolver(resolver_impl.PassAs<HostResolver>()));
    157 
    158   int rv;
    159   AddressList address_list;
    160   TestCompletionCallback callback;
    161 
    162   // Remap "*.com" to "baz", and *.net to "bar:60".
    163   resolver->SetRulesFromString("map *.com baz , map *.net bar:60");
    164 
    165   // Try resolving "www.google.com". Should be remapped to "baz".
    166   rv = resolver->Resolve(
    167       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
    168       DEFAULT_PRIORITY,
    169       &address_list,
    170       callback.callback(),
    171       NULL,
    172       BoundNetLog());
    173   EXPECT_EQ(ERR_IO_PENDING, rv);
    174   rv = callback.WaitForResult();
    175   EXPECT_EQ(OK, rv);
    176   EXPECT_EQ("192.168.1.7:80", FirstAddress(address_list));
    177 
    178   // Try resolving "chrome.net:80". Should be remapped to "bar:60".
    179   rv = resolver->Resolve(
    180       HostResolver::RequestInfo(HostPortPair("chrome.net", 80)),
    181       DEFAULT_PRIORITY,
    182       &address_list,
    183       callback.callback(),
    184       NULL,
    185       BoundNetLog());
    186   EXPECT_EQ(ERR_IO_PENDING, rv);
    187   rv = callback.WaitForResult();
    188   EXPECT_EQ(OK, rv);
    189   EXPECT_EQ("192.168.1.9:60", FirstAddress(address_list));
    190 }
    191 
    192 // Parsing bad rules should silently discard the rule (and never crash).
    193 TEST(MappedHostResolverTest, ParseInvalidRules) {
    194   scoped_ptr<MappedHostResolver> resolver(
    195       new MappedHostResolver(scoped_ptr<HostResolver>()));
    196 
    197   EXPECT_FALSE(resolver->AddRuleFromString("xyz"));
    198   EXPECT_FALSE(resolver->AddRuleFromString(std::string()));
    199   EXPECT_FALSE(resolver->AddRuleFromString(" "));
    200   EXPECT_FALSE(resolver->AddRuleFromString("EXCLUDE"));
    201   EXPECT_FALSE(resolver->AddRuleFromString("EXCLUDE foo bar"));
    202   EXPECT_FALSE(resolver->AddRuleFromString("INCLUDE"));
    203   EXPECT_FALSE(resolver->AddRuleFromString("INCLUDE x"));
    204   EXPECT_FALSE(resolver->AddRuleFromString("INCLUDE x :10"));
    205 }
    206 
    207 // Test mapping hostnames to resolving failures.
    208 TEST(MappedHostResolverTest, MapToError) {
    209   scoped_ptr<MockHostResolver> resolver_impl(new MockHostResolver());
    210   resolver_impl->rules()->AddRule("*", "192.168.1.5");
    211 
    212   scoped_ptr<MappedHostResolver> resolver(
    213       new MappedHostResolver(resolver_impl.PassAs<HostResolver>()));
    214 
    215   int rv;
    216   AddressList address_list;
    217 
    218   // Remap *.google.com to resolving failures.
    219   EXPECT_TRUE(resolver->AddRuleFromString("MAP *.google.com ~NOTFOUND"));
    220 
    221   // Try resolving www.google.com --> Should give an error.
    222   TestCompletionCallback callback1;
    223   rv = resolver->Resolve(
    224       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
    225       DEFAULT_PRIORITY,
    226       &address_list,
    227       callback1.callback(),
    228       NULL,
    229       BoundNetLog());
    230   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
    231 
    232   // Try resolving www.foo.com --> Should succeed.
    233   TestCompletionCallback callback2;
    234   rv = resolver->Resolve(
    235       HostResolver::RequestInfo(HostPortPair("www.foo.com", 80)),
    236       DEFAULT_PRIORITY,
    237       &address_list,
    238       callback2.callback(),
    239       NULL,
    240       BoundNetLog());
    241   EXPECT_EQ(ERR_IO_PENDING, rv);
    242   rv = callback2.WaitForResult();
    243   EXPECT_EQ(OK, rv);
    244   EXPECT_EQ("192.168.1.5:80", FirstAddress(address_list));
    245 }
    246 
    247 }  // namespace
    248 
    249 }  // namespace net
    250