Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: chrome/browser/net/dns_probe_service.cc

Issue 13270005: Display DNS probe results. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Round two. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "chrome/browser/net/dns_probe_service.h" 5 #include "chrome/browser/net/dns_probe_service.h"
6 6
7 #include "base/metrics/field_trial.h" 7 #include "base/metrics/field_trial.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "chrome/browser/net/dns_probe_job.h" 10 #include "chrome/browser/net/dns_probe_job.h"
11 #include "chrome/common/net/net_error_info.h" 11 #include "chrome/common/net/net_error_info.h"
12 #include "net/base/ip_endpoint.h" 12 #include "net/base/ip_endpoint.h"
13 #include "net/base/net_util.h" 13 #include "net/base/net_util.h"
14 #include "net/dns/dns_client.h" 14 #include "net/dns/dns_client.h"
15 #include "net/dns/dns_config_service.h" 15 #include "net/dns/dns_config_service.h"
16 #include "net/dns/dns_protocol.h" 16 #include "net/dns/dns_protocol.h"
17 17
18 using base::FieldTrialList; 18 using base::FieldTrialList;
19 using base::StringToInt; 19 using base::StringToInt;
20 using chrome_common_net::DnsProbeResult; 20 using chrome_common_net::DnsProbeStatus;
21 using net::DnsClient; 21 using net::DnsClient;
22 using net::DnsConfig; 22 using net::DnsConfig;
23 using net::IPAddressNumber; 23 using net::IPAddressNumber;
24 using net::IPEndPoint; 24 using net::IPEndPoint;
25 using net::ParseIPLiteralToNumber; 25 using net::ParseIPLiteralToNumber;
26 using net::NetworkChangeNotifier; 26 using net::NetworkChangeNotifier;
27 27
28 namespace chrome_browser_net { 28 namespace chrome_browser_net {
29 29
30 namespace { 30 namespace {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 69
70 // The maximum number of nameservers counted in histograms. 70 // The maximum number of nameservers counted in histograms.
71 const int kNameserverCountMax = 10; 71 const int kNameserverCountMax = 10;
72 72
73 } // namespace 73 } // namespace
74 74
75 DnsProbeService::DnsProbeService() 75 DnsProbeService::DnsProbeService()
76 : system_result_(DnsProbeJob::SERVERS_UNKNOWN), 76 : system_result_(DnsProbeJob::SERVERS_UNKNOWN),
77 public_result_(DnsProbeJob::SERVERS_UNKNOWN), 77 public_result_(DnsProbeJob::SERVERS_UNKNOWN),
78 state_(STATE_NO_RESULTS), 78 state_(STATE_NO_RESULTS),
79 result_(chrome_common_net::DNS_PROBE_UNKNOWN), 79 result_(chrome_common_net::DNS_PROBE_FINISHED_UNKNOWN),
80 dns_attempts_(GetAttemptsFromFieldTrial()) { 80 dns_attempts_(GetAttemptsFromFieldTrial()) {
81 NetworkChangeNotifier::AddIPAddressObserver(this); 81 NetworkChangeNotifier::AddIPAddressObserver(this);
82 } 82 }
83 83
84 DnsProbeService::~DnsProbeService() { 84 DnsProbeService::~DnsProbeService() {
85 NetworkChangeNotifier::RemoveIPAddressObserver(this); 85 NetworkChangeNotifier::RemoveIPAddressObserver(this);
86 } 86 }
87 87
88 void DnsProbeService::ProbeDns(const DnsProbeService::CallbackType& callback) { 88 void DnsProbeService::ProbeDns(const DnsProbeService::CallbackType& callback) {
89 callbacks_.push_back(callback); 89 callbacks_.push_back(callback);
(...skipping 30 matching lines...) Expand all
120 120
121 void DnsProbeService::OnIPAddressChanged() { 121 void DnsProbeService::OnIPAddressChanged() {
122 if (state_ == STATE_RESULTS_CACHED) 122 if (state_ == STATE_RESULTS_CACHED)
123 ExpireResults(); 123 ExpireResults();
124 } 124 }
125 125
126 void DnsProbeService::ExpireResults() { 126 void DnsProbeService::ExpireResults() {
127 DCHECK_EQ(STATE_RESULTS_CACHED, state_); 127 DCHECK_EQ(STATE_RESULTS_CACHED, state_);
128 128
129 state_ = STATE_NO_RESULTS; 129 state_ = STATE_NO_RESULTS;
130 result_ = chrome_common_net::DNS_PROBE_UNKNOWN; 130 result_ = chrome_common_net::DNS_PROBE_FINISHED_UNKNOWN;
mmenke 2013/04/10 16:56:58 Should this actually be DNS_PROBE_MAX? Seems like
Deprecated (see juliatuttle) 2013/04/10 23:42:32 Done.
131 } 131 }
132 132
133 void DnsProbeService::StartProbes() { 133 void DnsProbeService::StartProbes() {
134 DCHECK_NE(STATE_PROBE_RUNNING, state_); 134 DCHECK_NE(STATE_PROBE_RUNNING, state_);
135 DCHECK(!system_job_.get()); 135 DCHECK(!system_job_.get());
136 DCHECK(!public_job_.get()); 136 DCHECK(!public_job_.get());
137 137
138 DnsProbeJob::CallbackType job_callback = 138 DnsProbeJob::CallbackType job_callback =
139 base::Bind(&DnsProbeService::OnProbeJobComplete, 139 base::Bind(&DnsProbeService::OnProbeJobComplete,
140 base::Unretained(this)); 140 base::Unretained(this));
141 141
142 // TODO(ttuttle): Do we want to keep explicit flags for "job done"? 142 // TODO(ttuttle): Do we want to keep explicit flags for "job done"?
143 // Or maybe DnsProbeJob should have a "finished" flag? 143 // Or maybe DnsProbeJob should have a "finished" flag?
144 system_result_ = DnsProbeJob::SERVERS_UNKNOWN; 144 system_result_ = DnsProbeJob::SERVERS_UNKNOWN;
145 public_result_ = DnsProbeJob::SERVERS_UNKNOWN; 145 public_result_ = DnsProbeJob::SERVERS_UNKNOWN;
146 146
147 system_job_ = CreateSystemProbeJob(job_callback); 147 system_job_ = CreateSystemProbeJob(job_callback);
148 public_job_ = CreatePublicProbeJob(job_callback); 148 public_job_ = CreatePublicProbeJob(job_callback);
149 149
150 // If we can't create one or both jobs, fail the probe immediately. 150 // If we can't create one or both jobs, fail the probe immediately.
151 if (!system_job_.get() || !public_job_.get()) { 151 if (!system_job_.get() || !public_job_.get()) {
152 system_job_.reset(); 152 system_job_.reset();
153 public_job_.reset(); 153 public_job_.reset();
154 state_ = STATE_RESULTS_CACHED; 154 state_ = STATE_RESULTS_CACHED;
155 // TODO(ttuttle): Should this be BAD_CONFIG? Currently I think it only 155 // TODO(ttuttle): Should this be BAD_CONFIG? Currently I think it only
156 // happens when the system DnsConfig has no servers. 156 // happens when the system DnsConfig has no servers.
157 result_ = chrome_common_net::DNS_PROBE_UNKNOWN; 157 result_ = chrome_common_net::DNS_PROBE_FINISHED_UNKNOWN;
158 CallCallbacks(); 158 CallCallbacks();
159 return; 159 return;
160 } 160 }
161 161
162 state_ = STATE_PROBE_RUNNING; 162 state_ = STATE_PROBE_RUNNING;
163 probe_start_time_ = base::Time::Now(); 163 probe_start_time_ = base::Time::Now();
164 } 164 }
165 165
166 void DnsProbeService::OnProbesComplete() { 166 void DnsProbeService::OnProbesComplete() {
167 DCHECK_EQ(STATE_PROBE_RUNNING, state_); 167 DCHECK_EQ(STATE_PROBE_RUNNING, state_);
168 168
169 state_ = STATE_RESULTS_CACHED; 169 state_ = STATE_RESULTS_CACHED;
170 result_ = EvaluateResults(); 170 result_ = EvaluateResults();
171 171
172 HistogramProbes(); 172 HistogramProbes();
173 173
174 CallCallbacks(); 174 CallCallbacks();
175 } 175 }
176 176
177 void DnsProbeService::HistogramProbes() const { 177 void DnsProbeService::HistogramProbes() const {
178 const DnsProbeResult kMaxResult = chrome_common_net::DNS_PROBE_MAX; 178 const DnsProbeStatus kMinFinishedStatus =
179 chrome_common_net::DNS_PROBE_FINISHED_UNKNOWN;
180 const DnsProbeStatus kMaxStatus = chrome_common_net::DNS_PROBE_MAX;
179 181
180 DCHECK_EQ(STATE_RESULTS_CACHED, state_); 182 DCHECK_EQ(STATE_RESULTS_CACHED, state_);
181 DCHECK_NE(kMaxResult, result_); 183 DCHECK_GE(result_, kMinFinishedStatus);
184 DCHECK_NE(result_, kMaxStatus);
mmenke 2013/04/10 16:56:58 DCHECK_LT?
Deprecated (see juliatuttle) 2013/04/10 23:42:32 Done.
182 185
183 base::TimeDelta elapsed = base::Time::Now() - probe_start_time_; 186 base::TimeDelta elapsed = base::Time::Now() - probe_start_time_;
184 187
185 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Probe.Result", result_, kMaxResult); 188 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Status", result_, kMaxStatus);
186 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.Elapsed", elapsed); 189 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed", elapsed);
187 190
188 if (NetworkChangeNotifier::IsOffline()) { 191 if (NetworkChangeNotifier::IsOffline()) {
189 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Probe.NcnOffline.Result", 192 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Status_NcnOffline",
190 result_, kMaxResult); 193 result_, kMaxStatus);
191 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.NcnOffline.Elapsed", elapsed); 194 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_NcnOffline", elapsed);
192 } else { 195 } else {
193 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Probe.NcnOnline.Result", 196 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Status_NcnOnline",
194 result_, kMaxResult); 197 result_, kMaxStatus);
195 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.NcnOnline.Elapsed", elapsed); 198 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_NcnOnline", elapsed);
196 } 199 }
197 200
198 switch (result_) { 201 switch (result_) {
199 case chrome_common_net::DNS_PROBE_UNKNOWN: 202 case chrome_common_net::DNS_PROBE_FINISHED_UNKNOWN:
200 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.ResultUnknown.Elapsed", 203 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_Unknown",
201 elapsed); 204 elapsed);
202 break; 205 break;
203 case chrome_common_net::DNS_PROBE_NO_INTERNET: 206 case chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET:
204 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.ResultNoInternet.Elapsed", 207 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_NoInternet",
205 elapsed); 208 elapsed);
206 break; 209 break;
207 case chrome_common_net::DNS_PROBE_BAD_CONFIG: 210 case chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG:
208 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.ResultBadConfig.Elapsed", 211 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_BadConfig",
209 elapsed);
210
211 // Histogram some extra data to see why BAD_CONFIG is happening.
212 UMA_HISTOGRAM_ENUMERATION(
213 "DnsProbe.Probe.ResultBadConfig.SystemJobResult",
214 system_result_,
215 DnsProbeJob::MAX_RESULT);
216 UMA_HISTOGRAM_CUSTOM_COUNTS(
217 "DnsProbe.Probe.ResultBadConfig.SystemNameserverCount",
218 system_nameserver_count_,
219 0, kNameserverCountMax, kNameserverCountMax + 1);
220 UMA_HISTOGRAM_BOOLEAN(
221 "DnsProbe.Probe.ResultBadConfig.SystemIsLocalhost",
222 system_is_localhost_);
223 break;
224 case chrome_common_net::DNS_PROBE_NXDOMAIN:
225 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.ResultNxdomain.Elapsed",
226 elapsed); 212 elapsed);
227 break; 213 break;
214 case chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN:
215 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_Nxdomain",
216 elapsed);
217 break;
218
219 // These aren't actually results.
220 case chrome_common_net::DNS_PROBE_POSSIBLE:
221 case chrome_common_net::DNS_PROBE_NOT_RUN:
222 case chrome_common_net::DNS_PROBE_STARTED:
228 case chrome_common_net::DNS_PROBE_MAX: 223 case chrome_common_net::DNS_PROBE_MAX:
mmenke 2013/04/10 16:56:58 Maybe just a "default:"?
Deprecated (see juliatuttle) 2013/04/10 23:42:32 I didn't use default: to preserve the warning if w
229 NOTREACHED(); 224 NOTREACHED();
230 break; 225 break;
231 } 226 }
232 } 227 }
233 228
234 DnsProbeResult DnsProbeService::EvaluateResults() const { 229 DnsProbeStatus DnsProbeService::EvaluateResults() const {
235 DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, system_result_); 230 DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, system_result_);
236 DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, public_result_); 231 DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, public_result_);
237 232
238 // If the system DNS is working, assume the domain doesn't exist. 233 // If the system DNS is working, assume the domain doesn't exist.
239 if (system_result_ == DnsProbeJob::SERVERS_CORRECT) 234 if (system_result_ == DnsProbeJob::SERVERS_CORRECT)
240 return chrome_common_net::DNS_PROBE_NXDOMAIN; 235 return chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN;
241 236
242 // If the system DNS is not working but another public server is, assume the 237 // If the system DNS is not working but another public server is, assume the
243 // DNS config is bad (or perhaps the DNS servers are down or broken). 238 // DNS config is bad (or perhaps the DNS servers are down or broken).
244 if (public_result_ == DnsProbeJob::SERVERS_CORRECT) 239 if (public_result_ == DnsProbeJob::SERVERS_CORRECT)
245 return chrome_common_net::DNS_PROBE_BAD_CONFIG; 240 return chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG;
246 241
247 // If the system DNS is not working and another public server is unreachable, 242 // If the system DNS is not working and another public server is unreachable,
248 // assume the internet connection is down (note that system DNS may be a 243 // assume the internet connection is down (note that system DNS may be a
249 // router on the LAN, so it may be reachable but returning errors.) 244 // router on the LAN, so it may be reachable but returning errors.)
250 if (public_result_ == DnsProbeJob::SERVERS_UNREACHABLE) 245 if (public_result_ == DnsProbeJob::SERVERS_UNREACHABLE)
251 return chrome_common_net::DNS_PROBE_NO_INTERNET; 246 return chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET;
252 247
253 // Otherwise: the system DNS is not working and another public server is 248 // Otherwise: the system DNS is not working and another public server is
254 // responding but with errors or incorrect results. This is an awkward case; 249 // responding but with errors or incorrect results. This is an awkward case;
255 // an invasive captive portal or a restrictive firewall may be intercepting 250 // an invasive captive portal or a restrictive firewall may be intercepting
256 // or rewriting DNS traffic, or the public server may itself be failing or 251 // or rewriting DNS traffic, or the public server may itself be failing or
257 // down. 252 // down.
258 return chrome_common_net::DNS_PROBE_UNKNOWN; 253 return chrome_common_net::DNS_PROBE_FINISHED_UNKNOWN;
259 } 254 }
260 255
261 void DnsProbeService::CallCallbacks() { 256 void DnsProbeService::CallCallbacks() {
262 DCHECK_EQ(STATE_RESULTS_CACHED, state_); 257 DCHECK_EQ(STATE_RESULTS_CACHED, state_);
263 DCHECK(!callbacks_.empty()); 258 DCHECK(!callbacks_.empty());
264 259
265 std::vector<CallbackType> callbacks = callbacks_; 260 std::vector<CallbackType> callbacks = callbacks_;
266 callbacks_.clear(); 261 callbacks_.clear();
267 262
268 for (std::vector<CallbackType>::const_iterator i = callbacks.begin(); 263 for (std::vector<CallbackType>::const_iterator i = callbacks.begin();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 300
306 void DnsProbeService::GetSystemDnsConfig(DnsConfig* config) { 301 void DnsProbeService::GetSystemDnsConfig(DnsConfig* config) {
307 NetworkChangeNotifier::GetDnsConfig(config); 302 NetworkChangeNotifier::GetDnsConfig(config);
308 303
309 // DNS probes don't need or want the suffix search list populated 304 // DNS probes don't need or want the suffix search list populated
310 config->search.clear(); 305 config->search.clear();
311 306
312 if (dns_attempts_ != kAttemptsUseDefault) 307 if (dns_attempts_ != kAttemptsUseDefault)
313 config->attempts = dns_attempts_; 308 config->attempts = dns_attempts_;
314 309
315 // Take notes in case the config turns out to be bad, so we can histogram
316 // some useful data.
317 system_nameserver_count_ = config->nameservers.size();
318 system_is_localhost_ = (system_nameserver_count_ == 1)
319 && IsLocalhost(config->nameservers[0].address());
320
321 // Disable port randomization. 310 // Disable port randomization.
322 config->randomize_ports = false; 311 config->randomize_ports = false;
323 } 312 }
324 313
325 void DnsProbeService::GetPublicDnsConfig(DnsConfig* config) { 314 void DnsProbeService::GetPublicDnsConfig(DnsConfig* config) {
326 *config = DnsConfig(); 315 *config = DnsConfig();
327 316
328 config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsPrimary)); 317 config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsPrimary));
329 config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsSecondary)); 318 config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsSecondary));
330 319
331 if (dns_attempts_ != kAttemptsUseDefault) 320 if (dns_attempts_ != kAttemptsUseDefault)
332 config->attempts = dns_attempts_; 321 config->attempts = dns_attempts_;
333 322
334 // Disable port randomization. 323 // Disable port randomization.
335 config->randomize_ports = false; 324 config->randomize_ports = false;
336 } 325 }
337 326
338 bool DnsProbeService::ResultsExpired() { 327 bool DnsProbeService::ResultsExpired() {
339 const base::TimeDelta kMaxResultAge = 328 const base::TimeDelta kMaxResultAge =
340 base::TimeDelta::FromMilliseconds(kMaxResultAgeMs); 329 base::TimeDelta::FromMilliseconds(kMaxResultAgeMs);
341 return base::Time::Now() - probe_start_time_ > kMaxResultAge; 330 return base::Time::Now() - probe_start_time_ > kMaxResultAge;
342 } 331 }
343 332
344 } // namespace chrome_browser_net 333 } // namespace chrome_browser_net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698