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

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: Refactor a bit again (DnsProbeRunner is now tied to a single DnsClient), other fixes Created 7 years, 6 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_runner.h"
mmenke 2013/06/11 16:15:35 nit: Already used in header.
Deprecated (see juliatuttle) 2013/06/13 14:37:04 Done.
11 #include "chrome/common/net/net_error_info.h" 11 #include "chrome/common/net/net_error_info.h"
mmenke 2013/06/11 16:15:35 nit: Already used in header.
Deprecated (see juliatuttle) 2013/06/13 14:37:04 Done.
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/base/network_change_notifier.h"
mmenke 2013/06/11 16:15:35 nit: Already used in header.
Deprecated (see juliatuttle) 2013/06/13 14:37:04 Done.
14 #include "net/dns/dns_client.h" 15 #include "net/dns/dns_client.h"
15 #include "net/dns/dns_config_service.h" 16 #include "net/dns/dns_config_service.h"
16 #include "net/dns/dns_protocol.h" 17 #include "net/dns/dns_protocol.h"
17 18
18 using base::FieldTrialList; 19 using base::FieldTrialList;
19 using base::StringToInt; 20 using base::StringToInt;
20 using chrome_common_net::DnsProbeResult; 21 using chrome_common_net::DnsProbeStatus;
21 using net::DnsClient; 22 using net::DnsClient;
22 using net::DnsConfig; 23 using net::DnsConfig;
23 using net::IPAddressNumber; 24 using net::IPAddressNumber;
24 using net::IPEndPoint; 25 using net::IPEndPoint;
25 using net::ParseIPLiteralToNumber; 26 using net::ParseIPLiteralToNumber;
26 using net::NetworkChangeNotifier; 27 using net::NetworkChangeNotifier;
27 28
28 namespace chrome_browser_net {
29
30 namespace { 29 namespace {
31 30
32 // How long the DnsProbeService will cache the probe result for. 31 // How long the DnsProbeService will cache the probe result for.
33 // If it's older than this and we get a probe request, the service expires it 32 // If it's older than this and we get a probe request, the service expires it
34 // and starts a new probe. 33 // and starts a new probe.
35 const int kMaxResultAgeMs = 5000; 34 const int kMaxResultAgeMs = 5000;
36 35
37 // The public DNS servers used by the DnsProbeService to verify internet 36 // The public DNS servers used by the DnsProbeService to verify internet
38 // connectivity. 37 // connectivity.
39 const char kPublicDnsPrimary[] = "8.8.8.8"; 38 const char kGooglePublicDns1[] = "8.8.8.8";
mmenke 2013/06/12 19:17:12 nit: Remove extra spaces.
Deprecated (see juliatuttle) 2013/06/13 14:37:04 Done.
40 const char kPublicDnsSecondary[] = "8.8.4.4"; 39 const char kGooglePublicDns2[] = "8.8.4.4";
41 40
42 IPEndPoint MakeDnsEndPoint(const std::string& dns_ip_literal) { 41 IPEndPoint MakeDnsEndPoint(const std::string& dns_ip_literal) {
43 IPAddressNumber dns_ip_number; 42 IPAddressNumber dns_ip_number;
44 bool rv = ParseIPLiteralToNumber(dns_ip_literal, &dns_ip_number); 43 bool rv = ParseIPLiteralToNumber(dns_ip_literal, &dns_ip_number);
45 DCHECK(rv); 44 DCHECK(rv);
46 return IPEndPoint(dns_ip_number, net::dns_protocol::kDefaultPort); 45 return IPEndPoint(dns_ip_number, net::dns_protocol::kDefaultPort);
47 } 46 }
48 47
49 const int kAttemptsUseDefault = -1; 48 const int kAttemptsUseDefault = -1;
50 49
51 const char kAttemptsFieldTrialName[] = "DnsProbe-Attempts"; 50 const char kAttemptsFieldTrialName[] = "DnsProbe-Attempts";
52 51
53 int GetAttemptsFromFieldTrial() { 52 int GetAttemptsFromFieldTrial() {
54 std::string group = FieldTrialList::FindFullName(kAttemptsFieldTrialName); 53 std::string group = FieldTrialList::FindFullName(kAttemptsFieldTrialName);
55 if (group == "" || group == "default") 54 if (group == "" || group == "default")
56 return kAttemptsUseDefault; 55 return kAttemptsUseDefault;
57 56
58 int attempts; 57 int attempts;
59 if (!StringToInt(group, &attempts)) 58 if (!StringToInt(group, &attempts))
60 return kAttemptsUseDefault; 59 return kAttemptsUseDefault;
61 60
62 return attempts; 61 return attempts;
63 } 62 }
mmenke 2013/06/11 16:15:35 This function is not currently being used, nor is
Deprecated (see juliatuttle) 2013/06/13 14:37:04 Nah, we didn't decide. I'll remove it, and we can
64 63
65 bool IsLocalhost(const IPAddressNumber& ip) {
66 return (ip.size() == net::kIPv4AddressSize)
67 && (ip[0] == 127) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 1);
68 }
69
70 // The maximum number of nameservers counted in histograms.
71 const int kNameserverCountMax = 10;
72
73 } // namespace 64 } // namespace
74 65
66 namespace chrome_browser_net {
67
75 DnsProbeService::DnsProbeService() 68 DnsProbeService::DnsProbeService()
76 : system_result_(DnsProbeJob::SERVERS_UNKNOWN), 69 : state_(STATE_NO_RESULTS) {
77 public_result_(DnsProbeJob::SERVERS_UNKNOWN), 70 NetworkChangeNotifier::AddDNSObserver(this);
78 state_(STATE_NO_RESULTS), 71 SetSystemClientToCurrentConfig();
79 result_(chrome_common_net::DNS_PROBE_UNKNOWN), 72 SetPublicClientToGooglePublicDns();
80 dns_attempts_(GetAttemptsFromFieldTrial()) {
81 NetworkChangeNotifier::AddIPAddressObserver(this);
82 } 73 }
83 74
84 DnsProbeService::~DnsProbeService() { 75 DnsProbeService::~DnsProbeService() {
85 NetworkChangeNotifier::RemoveIPAddressObserver(this); 76 NetworkChangeNotifier::RemoveDNSObserver(this);
86 } 77 }
87 78
88 void DnsProbeService::ProbeDns(const DnsProbeService::CallbackType& callback) { 79 void DnsProbeService::ProbeDns(const DnsProbeService::ProbeCallback& callback) {
89 callbacks_.push_back(callback); 80 pending_callbacks_.push_back(callback);
90 81
91 if (state_ == STATE_RESULTS_CACHED && ResultsExpired()) 82 if (state_ == STATE_RESULTS_CACHED && ResultsExpired())
92 ExpireResults(); 83 ExpireResult();
93 84
94 switch (state_) { 85 switch (state_) {
95 case STATE_NO_RESULTS: 86 case STATE_NO_RESULTS:
96 StartProbes(); 87 StartProbes();
97 break; 88 break;
98 case STATE_RESULTS_CACHED: 89 case STATE_RESULTS_CACHED:
99 CallCallbacks(); 90 CallCallbacks();
100 break; 91 break;
101 case STATE_PROBE_RUNNING: 92 case STATE_PROBE_RUNNING:
102 // do nothing; probe is already running, and will call the callback 93 // do nothing; probe is already running, and will call the callback
103 break; 94 break;
104 } 95 }
105 } 96 }
106 97
107 scoped_ptr<DnsProbeJob> DnsProbeService::CreateSystemProbeJob( 98 void DnsProbeService::OnDNSChanged() {
108 const DnsProbeJob::CallbackType& job_callback) { 99 ExpireResult();
109 DnsConfig system_config; 100 SetSystemClientToCurrentConfig();
110 GetSystemDnsConfig(&system_config);
111 return CreateProbeJob(system_config, job_callback);
112 } 101 }
113 102
114 scoped_ptr<DnsProbeJob> DnsProbeService::CreatePublicProbeJob( 103 void DnsProbeService::SetSystemClientForTesting(
115 const DnsProbeJob::CallbackType& job_callback) { 104 scoped_ptr<DnsClient> system_client) {
116 DnsConfig public_config; 105 SetSystemClient(system_client.Pass());
117 GetPublicDnsConfig(&public_config);
118 return CreateProbeJob(public_config, job_callback);
119 } 106 }
120 107
121 void DnsProbeService::OnIPAddressChanged() { 108 void DnsProbeService::SetPublicClientForTesting(
122 if (state_ == STATE_RESULTS_CACHED) 109 scoped_ptr<DnsClient> public_client) {
123 ExpireResults(); 110 SetPublicClient(public_client.Pass());
124 } 111 }
125 112
126 void DnsProbeService::ExpireResults() { 113 void DnsProbeService::ExpireResultForTesting() {
127 DCHECK_EQ(STATE_RESULTS_CACHED, state_); 114 ExpireResult();
115 }
128 116
129 state_ = STATE_NO_RESULTS; 117 void DnsProbeService::SetSystemClientToCurrentConfig() {
130 result_ = chrome_common_net::DNS_PROBE_UNKNOWN; 118 DnsConfig system_config;
119 NetworkChangeNotifier::GetDnsConfig(&system_config);
120 system_config.search.clear();
121 system_config.attempts = 1;
122 system_config.randomize_ports = false;
mmenke 2013/06/11 16:15:35 Think these two behaviors are worth mentioning in
Deprecated (see juliatuttle) 2013/06/13 14:37:04 Done.
123
124 scoped_ptr<DnsClient> system_client(DnsClient::CreateClient(NULL));
125 system_client->SetConfig(system_config);
126
127 SetSystemClient(system_client.Pass());
128 }
129
130 void DnsProbeService::SetPublicClientToGooglePublicDns() {
131 DnsConfig public_config;
132 public_config.nameservers.push_back(MakeDnsEndPoint(kGooglePublicDns1));
133 public_config.nameservers.push_back(MakeDnsEndPoint(kGooglePublicDns1));
mmenke 2013/06/11 16:15:35 kGooglePublicDns1 -> kGooglePublicDns2
Deprecated (see juliatuttle) 2013/06/13 14:37:04 Done.
134 public_config.attempts = 1;
135 public_config.randomize_ports = false;
136
137 scoped_ptr<DnsClient> public_client(DnsClient::CreateClient(NULL));
138 public_client->SetConfig(public_config);
139
140 SetPublicClient(public_client.Pass());
141 }
142
143 void DnsProbeService::SetSystemClient(scoped_ptr<DnsClient> system_client) {
144 system_runner_.set_client(system_client.Pass());
145 }
146
147 void DnsProbeService::SetPublicClient(scoped_ptr<DnsClient> public_client) {
148 public_runner_.set_client(public_client.Pass());
131 } 149 }
132 150
133 void DnsProbeService::StartProbes() { 151 void DnsProbeService::StartProbes() {
134 DCHECK_NE(STATE_PROBE_RUNNING, state_); 152 DCHECK_NE(STATE_PROBE_RUNNING, state_);
mmenke 2013/06/11 16:15:35 Think you can DCHECK_EQ(STATE_NO_RESULTS, state_);
Deprecated (see juliatuttle) 2013/06/13 14:37:04 Done.
135 DCHECK(!system_job_.get());
136 DCHECK(!public_job_.get());
137 153
138 DnsProbeJob::CallbackType job_callback = 154 state_ = STATE_PROBE_RUNNING;
139 base::Bind(&DnsProbeService::OnProbeJobComplete, 155 probe_start_time_ = base::Time::Now();
140 base::Unretained(this));
141 156
142 // TODO(ttuttle): Do we want to keep explicit flags for "job done"? 157 const base::Callback<void(ProbeType, DnsProbeRunner::Result)> callback =
143 // Or maybe DnsProbeJob should have a "finished" flag? 158 base::Bind(&DnsProbeService::OnProbeComplete, base::Unretained(this));
144 system_result_ = DnsProbeJob::SERVERS_UNKNOWN; 159 system_runner_.RunProbe(base::Bind(callback, SYSTEM));
145 public_result_ = DnsProbeJob::SERVERS_UNKNOWN; 160 public_runner_.RunProbe(base::Bind(callback, PUBLIC));
mmenke 2013/06/11 16:15:35 Suggest a comment that it's theoretically possible
Deprecated (see juliatuttle) 2013/06/13 14:37:04 Done.
161 }
146 162
147 system_job_ = CreateSystemProbeJob(job_callback); 163 void DnsProbeService::OnProbeComplete(
148 public_job_ = CreatePublicProbeJob(job_callback); 164 ProbeType type,
165 DnsProbeRunner::Result result) {
166 DCHECK_EQ(STATE_PROBE_RUNNING, state_);
149 167
150 // If we can't create one or both jobs, fail the probe immediately. 168 switch (type) {
151 if (!system_job_.get() || !public_job_.get()) { 169 case SYSTEM:
mmenke 2013/06/11 16:15:35 DCHECK(system_runner_.is_running())?
Deprecated (see juliatuttle) 2013/06/13 14:37:04 No; that returns false during the callback.
mmenke 2013/06/13 15:00:12 DCHECK(!system_runner_.is_running())? :)
152 system_job_.reset(); 170 system_result_ = result;
153 public_job_.reset(); 171 break;
154 state_ = STATE_RESULTS_CACHED; 172 case PUBLIC:
mmenke 2013/06/11 16:15:35 DCHECK(public_runner_.is_running());
Deprecated (see juliatuttle) 2013/06/13 14:37:04 Ditto.
mmenke 2013/06/13 15:00:12 DCHECK(!public_runner_.is_running())? :)
155 // TODO(ttuttle): Should this be BAD_CONFIG? Currently I think it only 173 public_result_ = result;
156 // happens when the system DnsConfig has no servers. 174 break;
157 result_ = chrome_common_net::DNS_PROBE_UNKNOWN; 175 default:
158 CallCallbacks(); 176 NOTREACHED();
159 return; 177 return;
160 } 178 }
161 179
162 state_ = STATE_PROBE_RUNNING; 180 if (system_runner_.is_running() || public_runner_.is_running())
163 probe_start_time_ = base::Time::Now(); 181 return;
164 }
165
166 void DnsProbeService::OnProbesComplete() {
167 DCHECK_EQ(STATE_PROBE_RUNNING, state_);
168 182
169 state_ = STATE_RESULTS_CACHED; 183 state_ = STATE_RESULTS_CACHED;
170 result_ = EvaluateResults(); 184 result_ = EvaluateResults();
171 185
172 HistogramProbes(); 186 HistogramProbes();
173 187
174 CallCallbacks(); 188 CallCallbacks();
175 } 189 }
176 190
191 DnsProbeStatus DnsProbeService::EvaluateResults() const {
192 DCHECK_NE(DnsProbeRunner::UNKNOWN, system_result_);
193 DCHECK_NE(DnsProbeRunner::UNKNOWN, public_result_);
194
195 // If the system DNS is working, assume the domain doesn't exist.
196 if (system_result_ == DnsProbeRunner::CORRECT)
197 return chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN;
198
199 // If the system DNS is not working but another public server is, assume the
200 // DNS config is bad (or perhaps the DNS servers are down or broken).
201 if (public_result_ == DnsProbeRunner::CORRECT)
202 return chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG;
203
204 // If the system DNS is not working and another public server is unreachable,
205 // assume the internet connection is down (note that system DNS may be a
206 // router on the LAN, so it may be reachable but returning errors.)
207 if (public_result_ == DnsProbeRunner::UNREACHABLE)
208 return chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET;
209
210 // Otherwise: the system DNS is not working and another public server is
211 // responding but with errors or incorrect results. This is an awkward case;
212 // an invasive captive portal or a restrictive firewall may be intercepting
213 // or rewriting DNS traffic, or the public server may itself be failing or
214 // down.
215 return chrome_common_net::DNS_PROBE_FINISHED_UNKNOWN;
216 }
217
218 // TODO(ttuttle): Make sure we're not changing result histogram mappings going
219 // from DnsProbeJob to DnsProbeRunner.
177 void DnsProbeService::HistogramProbes() const { 220 void DnsProbeService::HistogramProbes() const {
178 const DnsProbeResult kMaxResult = chrome_common_net::DNS_PROBE_MAX; 221 const DnsProbeStatus kMaxStatus = chrome_common_net::DNS_PROBE_MAX;
179 222
180 DCHECK_EQ(STATE_RESULTS_CACHED, state_); 223 DCHECK_EQ(STATE_RESULTS_CACHED, state_);
181 DCHECK_NE(kMaxResult, result_); 224 DCHECK(chrome_common_net::DnsProbeStatusIsFinished(result_));
182 225
183 base::TimeDelta elapsed = base::Time::Now() - probe_start_time_; 226 base::TimeDelta elapsed = base::Time::Now() - probe_start_time_;
184 227
185 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Probe.Result", result_, kMaxResult); 228 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Status", result_, kMaxStatus);
186 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.Elapsed", elapsed); 229 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed", elapsed);
187 230
188 if (NetworkChangeNotifier::IsOffline()) { 231 if (NetworkChangeNotifier::IsOffline()) {
mmenke 2013/06/12 19:17:12 Random comment that can be ignored for now: Long
189 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Probe.NcnOffline.Result", 232 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Status_NcnOffline",
190 result_, kMaxResult); 233 result_, kMaxStatus);
191 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.NcnOffline.Elapsed", elapsed); 234 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_NcnOffline", elapsed);
192 } else { 235 } else {
193 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Probe.NcnOnline.Result", 236 UMA_HISTOGRAM_ENUMERATION("DnsProbe.Status_NcnOnline",
194 result_, kMaxResult); 237 result_, kMaxStatus);
195 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.NcnOnline.Elapsed", elapsed); 238 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_NcnOnline", elapsed);
196 } 239 }
197 240
198 switch (result_) { 241 switch (result_) {
199 case chrome_common_net::DNS_PROBE_UNKNOWN: 242 case chrome_common_net::DNS_PROBE_FINISHED_UNKNOWN:
200 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.ResultUnknown.Elapsed", 243 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_Unknown",
201 elapsed); 244 elapsed);
202 break; 245 break;
203 case chrome_common_net::DNS_PROBE_NO_INTERNET: 246 case chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET:
204 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.ResultNoInternet.Elapsed", 247 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_NoInternet",
205 elapsed); 248 elapsed);
206 break; 249 break;
207 case chrome_common_net::DNS_PROBE_BAD_CONFIG: 250 case chrome_common_net::DNS_PROBE_FINISHED_BAD_CONFIG:
208 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Probe.ResultBadConfig.Elapsed", 251 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_BadConfig",
mmenke 2013/06/12 19:17:12 These should all pretty much represent the same th
Deprecated (see juliatuttle) 2013/06/13 14:37:04 Right.
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); 252 elapsed);
227 break; 253 break;
254 case chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN:
255 UMA_HISTOGRAM_MEDIUM_TIMES("DnsProbe.Elapsed_Nxdomain",
256 elapsed);
257 break;
258
259 // These aren't actually results.
260 case chrome_common_net::DNS_PROBE_POSSIBLE:
261 case chrome_common_net::DNS_PROBE_NOT_RUN:
262 case chrome_common_net::DNS_PROBE_STARTED:
228 case chrome_common_net::DNS_PROBE_MAX: 263 case chrome_common_net::DNS_PROBE_MAX:
229 NOTREACHED(); 264 NOTREACHED();
230 break; 265 break;
231 } 266 }
232 } 267 }
233 268
234 DnsProbeResult DnsProbeService::EvaluateResults() const {
235 DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, system_result_);
236 DCHECK_NE(DnsProbeJob::SERVERS_UNKNOWN, public_result_);
237
238 // If the system DNS is working, assume the domain doesn't exist.
239 if (system_result_ == DnsProbeJob::SERVERS_CORRECT)
240 return chrome_common_net::DNS_PROBE_NXDOMAIN;
241
242 // 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).
244 if (public_result_ == DnsProbeJob::SERVERS_CORRECT)
245 return chrome_common_net::DNS_PROBE_BAD_CONFIG;
246
247 // 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
249 // router on the LAN, so it may be reachable but returning errors.)
250 if (public_result_ == DnsProbeJob::SERVERS_UNREACHABLE)
251 return chrome_common_net::DNS_PROBE_NO_INTERNET;
252
253 // 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;
255 // 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
257 // down.
258 return chrome_common_net::DNS_PROBE_UNKNOWN;
259 }
260
261 void DnsProbeService::CallCallbacks() { 269 void DnsProbeService::CallCallbacks() {
262 DCHECK_EQ(STATE_RESULTS_CACHED, state_); 270 DCHECK_EQ(STATE_RESULTS_CACHED, state_);
263 DCHECK(!callbacks_.empty()); 271 DCHECK(chrome_common_net::DnsProbeStatusIsFinished(result_));
272 DCHECK(!pending_callbacks_.empty());
264 273
265 std::vector<CallbackType> callbacks = callbacks_; 274 std::vector<ProbeCallback> callbacks = pending_callbacks_;
266 callbacks_.clear(); 275 pending_callbacks_.clear();
267 276
268 for (std::vector<CallbackType>::const_iterator i = callbacks.begin(); 277 for (std::vector<ProbeCallback>::const_iterator i = callbacks.begin();
269 i != callbacks.end(); ++i) { 278 i != callbacks.end(); ++i) {
270 i->Run(result_); 279 i->Run(result_);
271 } 280 }
272 } 281 }
273 282
274 scoped_ptr<DnsProbeJob> DnsProbeService::CreateProbeJob( 283 void DnsProbeService::ExpireResult() {
275 const DnsConfig& dns_config, 284 if (state_ == STATE_RESULTS_CACHED) {
276 const DnsProbeJob::CallbackType& job_callback) { 285 state_ = STATE_NO_RESULTS;
277 if (!dns_config.IsValid()) 286 result_ = chrome_common_net::DNS_PROBE_MAX;
278 return scoped_ptr<DnsProbeJob>(NULL);
279
280 scoped_ptr<DnsClient> dns_client(DnsClient::CreateClient(NULL));
281 dns_client->SetConfig(dns_config);
282 return DnsProbeJob::CreateJob(dns_client.Pass(), job_callback, NULL);
283 }
284
285 void DnsProbeService::OnProbeJobComplete(DnsProbeJob* job,
286 DnsProbeJob::Result result) {
287 DCHECK_EQ(STATE_PROBE_RUNNING, state_);
288
289 if (job == system_job_.get()) {
290 system_result_ = result;
291 system_job_.reset();
292 } else if (job == public_job_.get()) {
293 public_result_ = result;
294 public_job_.reset();
295 } else {
296 NOTREACHED();
297 return;
298 } 287 }
299
300 if (system_result_ != DnsProbeJob::SERVERS_UNKNOWN &&
301 public_result_ != DnsProbeJob::SERVERS_UNKNOWN) {
302 OnProbesComplete();
303 }
304 }
305
306 void DnsProbeService::GetSystemDnsConfig(DnsConfig* config) {
307 NetworkChangeNotifier::GetDnsConfig(config);
308
309 // DNS probes don't need or want the suffix search list populated
310 config->search.clear();
311
312 if (dns_attempts_ != kAttemptsUseDefault)
313 config->attempts = dns_attempts_;
314
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.
322 config->randomize_ports = false;
323 }
324
325 void DnsProbeService::GetPublicDnsConfig(DnsConfig* config) {
326 *config = DnsConfig();
327
328 config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsPrimary));
329 config->nameservers.push_back(MakeDnsEndPoint(kPublicDnsSecondary));
330
331 if (dns_attempts_ != kAttemptsUseDefault)
332 config->attempts = dns_attempts_;
333
334 // Disable port randomization.
335 config->randomize_ports = false;
336 } 288 }
337 289
338 bool DnsProbeService::ResultsExpired() { 290 bool DnsProbeService::ResultsExpired() {
339 const base::TimeDelta kMaxResultAge = 291 const base::TimeDelta kMaxResultAge =
340 base::TimeDelta::FromMilliseconds(kMaxResultAgeMs); 292 base::TimeDelta::FromMilliseconds(kMaxResultAgeMs);
341 return base::Time::Now() - probe_start_time_ > kMaxResultAge; 293 return base::Time::Now() - probe_start_time_ > kMaxResultAge;
342 } 294 }
343 295
344 } // namespace chrome_browser_net 296 } // namespace chrome_browser_net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698