OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/dns/dns_config_service.h" | 5 #include "net/dns/dns_config_service.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "net/base/ip_endpoint.h" | 10 #include "net/base/ip_endpoint.h" |
11 | 11 |
12 namespace net { | 12 namespace net { |
13 | 13 |
14 namespace { | |
15 | |
16 // Check if particular nameserver address is rogue. See: | |
17 // http://www.fbi.gov/news/stories/2011/november/malware_110911/DNS-changer-malw
are.pdf | |
18 bool CheckRogueDnsAddress(const IPAddressNumber& address) { | |
19 #define U8(x) static_cast<unsigned char>(x) | |
20 const struct Bounds { | |
21 const unsigned char lower[4]; // inclusive | |
22 const unsigned char upper[4]; // exclusive | |
23 } cases[] = { | |
24 { { U8('\x55'), U8('\xFF'), U8('\x70'), U8('\x00') }, // 85.255.112.0 | |
25 { U8('\x55'), U8('\xFF'), U8('\x80'), U8('\x00') } }, // 85.255.128.0 | |
26 { { U8('\x43'), U8('\xD2'), U8('\x00'), U8('\x00') }, // 67.210.0.0 | |
27 { U8('\x43'), U8('\xD2'), U8('\x10'), U8('\x00') } }, // 67.210.16.0 | |
28 { { U8('\x5D'), U8('\xBC'), U8('\xA0'), U8('\x00') }, // 93.188.160.0 | |
29 { U8('\x5D'), U8('\xBC'), U8('\xA8'), U8('\x00') } }, // 93.188.168.0 | |
30 { { U8('\x4D'), U8('\x43'), U8('\x53'), U8('\x00') }, // 77.67.83.0 | |
31 { U8('\x4D'), U8('\x43'), U8('\x54'), U8('\x00') } }, // 77.67.84.0 | |
32 { { U8('\x40'), U8('\x1C'), U8('\xB2'), U8('\x00') }, // 64.28.178.0 | |
33 { U8('\x40'), U8('\x1C'), U8('\xC0'), U8('\x00') } }, // 64.28.192.0 | |
34 }; | |
35 #undef U8 | |
36 for (unsigned i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { | |
37 const Bounds& bounds = cases[i]; | |
38 IPAddressNumber lower(bounds.lower, bounds.lower + 4); | |
39 IPAddressNumber upper(bounds.upper, bounds.upper + 4); | |
40 if (address.size() == kIPv6AddressSize) { | |
41 lower = ConvertIPv4NumberToIPv6Number(lower); | |
42 upper = ConvertIPv4NumberToIPv6Number(upper); | |
43 } | |
44 if ((lower <= address) && (address < upper)) | |
45 return true; | |
46 } | |
47 return false; | |
48 } | |
49 | |
50 void CheckRogueDnsConfig(const DnsConfig& config) { | |
51 for (size_t i = 0; i < config.nameservers.size(); ++i) { | |
52 if (CheckRogueDnsAddress(config.nameservers[i].address())) { | |
53 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DNSChangerDetected", true); | |
54 return; | |
55 } | |
56 } | |
57 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DNSChangerDetected", false); | |
58 } | |
59 | |
60 } // namespace | |
61 | |
62 // Default values are taken from glibc resolv.h. | 14 // Default values are taken from glibc resolv.h. |
63 DnsConfig::DnsConfig() | 15 DnsConfig::DnsConfig() |
64 : append_to_multi_label_name(true), | 16 : append_to_multi_label_name(true), |
65 ndots(1), | 17 ndots(1), |
66 timeout(base::TimeDelta::FromSeconds(5)), | 18 timeout(base::TimeDelta::FromSeconds(5)), |
67 attempts(2), | 19 attempts(2), |
68 rotate(false), | 20 rotate(false), |
69 edns0(false) {} | 21 edns0(false) {} |
70 | 22 |
71 DnsConfig::~DnsConfig() {} | 23 DnsConfig::~DnsConfig() {} |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 dict->SetInteger("attempts", attempts); | 67 dict->SetInteger("attempts", attempts); |
116 dict->SetBoolean("rotate", rotate); | 68 dict->SetBoolean("rotate", rotate); |
117 dict->SetBoolean("edns0", edns0); | 69 dict->SetBoolean("edns0", edns0); |
118 dict->SetInteger("num_hosts", hosts.size()); | 70 dict->SetInteger("num_hosts", hosts.size()); |
119 | 71 |
120 return dict; | 72 return dict; |
121 } | 73 } |
122 | 74 |
123 | 75 |
124 DnsConfigService::DnsConfigService() | 76 DnsConfigService::DnsConfigService() |
125 : checked_rogue_dns_(false), | 77 : have_config_(false), |
126 have_config_(false), | |
127 have_hosts_(false), | 78 have_hosts_(false), |
128 need_update_(false), | 79 need_update_(false), |
129 last_sent_empty_(true) {} | 80 last_sent_empty_(true) {} |
130 | 81 |
131 DnsConfigService::~DnsConfigService() { | 82 DnsConfigService::~DnsConfigService() { |
132 // Must always clean up. | 83 // Must always clean up. |
133 NetworkChangeNotifier::RemoveDNSObserver(this); | 84 NetworkChangeNotifier::RemoveDNSObserver(this); |
134 } | 85 } |
135 | 86 |
136 void DnsConfigService::Read(const CallbackType& callback) { | 87 void DnsConfigService::Read(const CallbackType& callback) { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 // Empty config is considered invalid. | 206 // Empty config is considered invalid. |
256 last_sent_empty_ = true; | 207 last_sent_empty_ = true; |
257 last_sent_empty_time_ = base::TimeTicks::Now(); | 208 last_sent_empty_time_ = base::TimeTicks::Now(); |
258 callback_.Run(DnsConfig()); | 209 callback_.Run(DnsConfig()); |
259 } | 210 } |
260 | 211 |
261 void DnsConfigService::OnCompleteConfig() { | 212 void DnsConfigService::OnCompleteConfig() { |
262 timer_.Stop(); | 213 timer_.Stop(); |
263 if (!need_update_) | 214 if (!need_update_) |
264 return; | 215 return; |
265 if (!checked_rogue_dns_ && dns_config_.IsValid()) { | |
266 CheckRogueDnsConfig(dns_config_); | |
267 checked_rogue_dns_ = true; | |
268 } | |
269 need_update_ = false; | 216 need_update_ = false; |
270 last_sent_empty_ = false; | 217 last_sent_empty_ = false; |
271 callback_.Run(dns_config_); | 218 callback_.Run(dns_config_); |
272 } | 219 } |
273 | 220 |
274 } // namespace net | 221 } // namespace net |
275 | 222 |
OLD | NEW |