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.
5 #include "net/dns/dns_config_service.h"
7 #include "base/basictypes.h"
9 #include "base/cancelable_callback.h"
10 #include "base/location.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/strings/string_split.h"
15 #include "base/test/test_timeouts.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "net/base/net_util.h"
18 #include "net/dns/dns_protocol.h"
19 #include "testing/gtest/include/gtest/gtest.h"
25 const NameServerClassifier::NameServersType kNone
=
26 NameServerClassifier::NAME_SERVERS_TYPE_NONE
;
27 const NameServerClassifier::NameServersType kGoogle
=
28 NameServerClassifier::NAME_SERVERS_TYPE_GOOGLE_PUBLIC_DNS
;
29 const NameServerClassifier::NameServersType kPrivate
=
30 NameServerClassifier::NAME_SERVERS_TYPE_PRIVATE
;
31 const NameServerClassifier::NameServersType kPublic
=
32 NameServerClassifier::NAME_SERVERS_TYPE_PUBLIC
;
33 const NameServerClassifier::NameServersType kMixed
=
34 NameServerClassifier::NAME_SERVERS_TYPE_MIXED
;
36 class NameServerClassifierTest
: public testing::Test
{
38 NameServerClassifier::NameServersType
Classify(
39 const std::string
& servers_string
) {
40 std::vector
<std::string
> server_strings
;
41 base::SplitString(servers_string
, ' ', &server_strings
);
43 std::vector
<IPEndPoint
> servers
;
44 for (std::vector
<std::string
>::const_iterator it
= server_strings
.begin();
45 it
!= server_strings
.end();
50 IPAddressNumber address
;
51 bool parsed
= ParseIPLiteralToNumber(*it
, &address
);
53 servers
.push_back(IPEndPoint(address
, dns_protocol::kDefaultPort
));
56 return classifier_
.GetNameServersType(servers
);
60 NameServerClassifier classifier_
;
63 TEST_F(NameServerClassifierTest
, None
) {
64 EXPECT_EQ(kNone
, Classify(""));
67 TEST_F(NameServerClassifierTest
, Google
) {
68 EXPECT_EQ(kGoogle
, Classify("8.8.8.8"));
69 EXPECT_EQ(kGoogle
, Classify("8.8.8.8 8.8.4.4"));
70 EXPECT_EQ(kGoogle
, Classify("2001:4860:4860::8888"));
71 EXPECT_EQ(kGoogle
, Classify("2001:4860:4860::8888 2001:4860:4860::8844"));
72 EXPECT_EQ(kGoogle
, Classify("2001:4860:4860::8888 8.8.8.8"));
74 // Make sure nobody took any shortcuts on the IP matching:
75 EXPECT_EQ(kPublic
, Classify("8.8.8.4"));
76 EXPECT_EQ(kPublic
, Classify("8.8.4.8"));
77 EXPECT_EQ(kPublic
, Classify("2001:4860:4860::8884"));
78 EXPECT_EQ(kPublic
, Classify("2001:4860:4860::8848"));
79 EXPECT_EQ(kPublic
, Classify("2001:4860:4860::1:8888"));
80 EXPECT_EQ(kPublic
, Classify("2001:4860:4860:1::8888"));
83 TEST_F(NameServerClassifierTest
, PrivateLocalhost
) {
84 EXPECT_EQ(kPrivate
, Classify("127.0.0.1"));
85 EXPECT_EQ(kPrivate
, Classify("::1"));
88 TEST_F(NameServerClassifierTest
, PrivateRfc1918
) {
89 EXPECT_EQ(kPrivate
, Classify("10.0.0.0 10.255.255.255"));
90 EXPECT_EQ(kPrivate
, Classify("172.16.0.0 172.31.255.255"));
91 EXPECT_EQ(kPrivate
, Classify("192.168.0.0 192.168.255.255"));
92 EXPECT_EQ(kPrivate
, Classify("10.1.1.1 172.16.1.1 192.168.1.1"));
95 TEST_F(NameServerClassifierTest
, PrivateIPv4LinkLocal
) {
96 EXPECT_EQ(kPrivate
, Classify("169.254.0.0 169.254.255.255"));
99 TEST_F(NameServerClassifierTest
, PrivateIPv6LinkLocal
) {
101 Classify("fe80:: fe80:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
104 TEST_F(NameServerClassifierTest
, Public
) {
105 EXPECT_EQ(kPublic
, Classify("4.2.2.1"));
106 EXPECT_EQ(kPublic
, Classify("4.2.2.1 4.2.2.2"));
109 TEST_F(NameServerClassifierTest
, Mixed
) {
110 EXPECT_EQ(kMixed
, Classify("8.8.8.8 192.168.1.1"));
111 EXPECT_EQ(kMixed
, Classify("8.8.8.8 4.2.2.1"));
112 EXPECT_EQ(kMixed
, Classify("192.168.1.1 4.2.2.1"));
113 EXPECT_EQ(kMixed
, Classify("8.8.8.8 192.168.1.1 4.2.2.1"));
116 class DnsConfigServiceTest
: public testing::Test
{
118 void OnConfigChanged(const DnsConfig
& config
) {
119 last_config_
= config
;
121 base::MessageLoop::current()->Quit();
125 class TestDnsConfigService
: public DnsConfigService
{
127 void ReadNow() override
{}
128 bool StartWatching() override
{ return true; }
130 // Expose the protected methods to this test suite.
131 void InvalidateConfig() {
132 DnsConfigService::InvalidateConfig();
135 void InvalidateHosts() {
136 DnsConfigService::InvalidateHosts();
139 void OnConfigRead(const DnsConfig
& config
) {
140 DnsConfigService::OnConfigRead(config
);
143 void OnHostsRead(const DnsHosts
& hosts
) {
144 DnsConfigService::OnHostsRead(hosts
);
147 void set_watch_failed(bool value
) {
148 DnsConfigService::set_watch_failed(value
);
152 void WaitForConfig(base::TimeDelta timeout
) {
153 base::CancelableClosure
closure(base::MessageLoop::QuitClosure());
154 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
155 FROM_HERE
, closure
.callback(), timeout
);
156 quit_on_config_
= true;
157 base::MessageLoop::current()->Run();
158 quit_on_config_
= false;
162 // Generate a config using the given seed..
163 DnsConfig
MakeConfig(unsigned seed
) {
166 CHECK(ParseIPLiteralToNumber("1.2.3.4", &ip
));
167 config
.nameservers
.push_back(IPEndPoint(ip
, seed
& 0xFFFF));
168 EXPECT_TRUE(config
.IsValid());
172 // Generate hosts using the given seed.
173 DnsHosts
MakeHosts(unsigned seed
) {
175 std::string hosts_content
= "127.0.0.1 localhost";
176 hosts_content
.append(seed
, '1');
177 ParseHosts(hosts_content
, &hosts
);
178 EXPECT_FALSE(hosts
.empty());
182 void SetUp() override
{
183 quit_on_config_
= false;
185 service_
.reset(new TestDnsConfigService());
186 service_
->WatchConfig(base::Bind(&DnsConfigServiceTest::OnConfigChanged
,
187 base::Unretained(this)));
188 EXPECT_FALSE(last_config_
.IsValid());
191 DnsConfig last_config_
;
192 bool quit_on_config_
;
194 // Service under test.
195 scoped_ptr
<TestDnsConfigService
> service_
;
200 TEST_F(DnsConfigServiceTest
, FirstConfig
) {
201 DnsConfig config
= MakeConfig(1);
203 service_
->OnConfigRead(config
);
204 // No hosts yet, so no config.
205 EXPECT_TRUE(last_config_
.Equals(DnsConfig()));
207 service_
->OnHostsRead(config
.hosts
);
208 EXPECT_TRUE(last_config_
.Equals(config
));
211 TEST_F(DnsConfigServiceTest
, Timeout
) {
212 DnsConfig config
= MakeConfig(1);
213 config
.hosts
= MakeHosts(1);
214 ASSERT_TRUE(config
.IsValid());
216 service_
->OnConfigRead(config
);
217 service_
->OnHostsRead(config
.hosts
);
218 EXPECT_FALSE(last_config_
.Equals(DnsConfig()));
219 EXPECT_TRUE(last_config_
.Equals(config
));
221 service_
->InvalidateConfig();
222 WaitForConfig(TestTimeouts::action_timeout());
223 EXPECT_FALSE(last_config_
.Equals(config
));
224 EXPECT_TRUE(last_config_
.Equals(DnsConfig()));
226 service_
->OnConfigRead(config
);
227 EXPECT_FALSE(last_config_
.Equals(DnsConfig()));
228 EXPECT_TRUE(last_config_
.Equals(config
));
230 service_
->InvalidateHosts();
231 WaitForConfig(TestTimeouts::action_timeout());
232 EXPECT_FALSE(last_config_
.Equals(config
));
233 EXPECT_TRUE(last_config_
.Equals(DnsConfig()));
235 DnsConfig bad_config
= last_config_
= MakeConfig(0xBAD);
236 service_
->InvalidateConfig();
237 // We don't expect an update. This should time out.
238 WaitForConfig(base::TimeDelta::FromMilliseconds(100) +
239 TestTimeouts::tiny_timeout());
240 EXPECT_TRUE(last_config_
.Equals(bad_config
)) << "Unexpected change";
242 last_config_
= DnsConfig();
243 service_
->OnConfigRead(config
);
244 service_
->OnHostsRead(config
.hosts
);
245 EXPECT_FALSE(last_config_
.Equals(DnsConfig()));
246 EXPECT_TRUE(last_config_
.Equals(config
));
249 TEST_F(DnsConfigServiceTest
, SameConfig
) {
250 DnsConfig config
= MakeConfig(1);
251 config
.hosts
= MakeHosts(1);
253 service_
->OnConfigRead(config
);
254 service_
->OnHostsRead(config
.hosts
);
255 EXPECT_FALSE(last_config_
.Equals(DnsConfig()));
256 EXPECT_TRUE(last_config_
.Equals(config
));
258 last_config_
= DnsConfig();
259 service_
->OnConfigRead(config
);
260 EXPECT_TRUE(last_config_
.Equals(DnsConfig())) << "Unexpected change";
262 service_
->OnHostsRead(config
.hosts
);
263 EXPECT_TRUE(last_config_
.Equals(DnsConfig())) << "Unexpected change";
266 TEST_F(DnsConfigServiceTest
, DifferentConfig
) {
267 DnsConfig config1
= MakeConfig(1);
268 DnsConfig config2
= MakeConfig(2);
269 DnsConfig config3
= MakeConfig(1);
270 config1
.hosts
= MakeHosts(1);
271 config2
.hosts
= MakeHosts(1);
272 config3
.hosts
= MakeHosts(2);
273 ASSERT_TRUE(config1
.EqualsIgnoreHosts(config3
));
274 ASSERT_FALSE(config1
.Equals(config2
));
275 ASSERT_FALSE(config1
.Equals(config3
));
276 ASSERT_FALSE(config2
.Equals(config3
));
278 service_
->OnConfigRead(config1
);
279 service_
->OnHostsRead(config1
.hosts
);
280 EXPECT_FALSE(last_config_
.Equals(DnsConfig()));
281 EXPECT_TRUE(last_config_
.Equals(config1
));
283 // It doesn't matter for this tests, but increases coverage.
284 service_
->InvalidateConfig();
285 service_
->InvalidateHosts();
287 service_
->OnConfigRead(config2
);
288 EXPECT_TRUE(last_config_
.Equals(config1
)) << "Unexpected change";
289 service_
->OnHostsRead(config2
.hosts
); // Not an actual change.
290 EXPECT_FALSE(last_config_
.Equals(config1
));
291 EXPECT_TRUE(last_config_
.Equals(config2
));
293 service_
->OnConfigRead(config3
);
294 EXPECT_TRUE(last_config_
.EqualsIgnoreHosts(config3
));
295 service_
->OnHostsRead(config3
.hosts
);
296 EXPECT_FALSE(last_config_
.Equals(config2
));
297 EXPECT_TRUE(last_config_
.Equals(config3
));
300 TEST_F(DnsConfigServiceTest
, WatchFailure
) {
301 DnsConfig config1
= MakeConfig(1);
302 DnsConfig config2
= MakeConfig(2);
303 config1
.hosts
= MakeHosts(1);
304 config2
.hosts
= MakeHosts(2);
306 service_
->OnConfigRead(config1
);
307 service_
->OnHostsRead(config1
.hosts
);
308 EXPECT_FALSE(last_config_
.Equals(DnsConfig()));
309 EXPECT_TRUE(last_config_
.Equals(config1
));
311 // Simulate watch failure.
312 service_
->set_watch_failed(true);
313 service_
->InvalidateConfig();
314 WaitForConfig(TestTimeouts::action_timeout());
315 EXPECT_FALSE(last_config_
.Equals(config1
));
316 EXPECT_TRUE(last_config_
.Equals(DnsConfig()));
318 DnsConfig bad_config
= last_config_
= MakeConfig(0xBAD);
319 // Actual change in config, so expect an update, but it should be empty.
320 service_
->OnConfigRead(config1
);
321 EXPECT_FALSE(last_config_
.Equals(bad_config
));
322 EXPECT_TRUE(last_config_
.Equals(DnsConfig()));
324 last_config_
= bad_config
;
325 // Actual change in config, so expect an update, but it should be empty.
326 service_
->InvalidateConfig();
327 service_
->OnConfigRead(config2
);
328 EXPECT_FALSE(last_config_
.Equals(bad_config
));
329 EXPECT_TRUE(last_config_
.Equals(DnsConfig()));
331 last_config_
= bad_config
;
332 // No change, so no update.
333 service_
->InvalidateConfig();
334 service_
->OnConfigRead(config2
);
335 EXPECT_TRUE(last_config_
.Equals(bad_config
));