• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
FirstAddress(const AddressList & address_list)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 
TEST(MappedHostResolverTest,Inclusion)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.
TEST(MappedHostResolverTest,Exclusion)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 
TEST(MappedHostResolverTest,SetRulesFromString)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).
TEST(MappedHostResolverTest,ParseInvalidRules)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.
TEST(MappedHostResolverTest,MapToError)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