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

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

Issue 13270005: Display DNS probe results. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: ...actually add the unittests 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
(Empty)
1 // Copyright (c) 2013 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 "chrome/browser/net/dns_probe_runner.h"
6
7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "net/base/ip_endpoint.h"
10 #include "net/base/net_errors.h"
11 #include "net/base/net_log.h"
12 #include "net/base/net_util.h"
13 #include "net/base/network_change_notifier.h"
14 #include "net/dns/dns_client.h"
15 #include "net/dns/dns_config_service.h"
16 #include "net/dns/dns_protocol.h"
17 #include "net/dns/dns_response.h"
18 #include "net/dns/dns_transaction.h"
19
20 using base::TimeDelta;
21 using net::AddressList;
22 using net::BoundNetLog;
23 using net::DnsClient;
24 using net::DnsConfig;
25 using net::DnsResponse;
26 using net::DnsTransaction;
27 using net::IPAddressNumber;
28 using net::IPEndPoint;
29 using net::NetLog;
30 using net::NetworkChangeNotifier;
31 using net::ParseIPLiteralToNumber;
32
33 namespace {
34
35 // The public DNS servers used by the DnsProbeService to verify internet
36 // connectivity.
37 const char kPublicDnsPrimary[] = "8.8.8.8";
38 const char kPublicDnsSecondary[] = "8.8.4.4";
39
40 IPEndPoint MakeDnsEndPoint(const std::string& dns_ip_literal) {
41 IPAddressNumber dns_ip_number;
42 bool rv = ParseIPLiteralToNumber(dns_ip_literal, &dns_ip_number);
43 DCHECK(rv);
44 return IPEndPoint(dns_ip_number, net::dns_protocol::kDefaultPort);
45 }
46
47 // Returns true if the given net_error indicates that we received a response
48 // from the DNS server containing an error, or false if the given net_error
49 // indicates that we never received a response.
50 bool DidReceiveDnsResponse(int net_error) {
51 switch (net_error) {
52 case net::ERR_NAME_NOT_RESOLVED: // NXDOMAIN maps to this.
53 case net::ERR_DNS_MALFORMED_RESPONSE:
54 case net::ERR_DNS_SERVER_REQUIRES_TCP:
55 case net::ERR_DNS_SERVER_FAILED:
56 case net::ERR_DNS_SORT_ERROR: // Can only happen if the server responds.
57 return true;
58 default:
59 return false;
60 }
61 }
62
63 } // namespace
64
65 DnsProbeRunner::ProbeInfo::ProbeInfo(
66 DnsProbeRunner::Type type,
67 const DnsProbeRunner::ProbeCallback& callback)
68 : type(type),
69 callback(callback) {}
70
71 DnsProbeRunner::ProbeInfo::~ProbeInfo() {}
72
73 DnsProbeRunner::DnsProbeRunner()
74 : weak_factory_(this),
75 bound_net_log_(BoundNetLog::Make(NULL, NetLog::SOURCE_DNS_PROBER)),
76 mock_mode_(DnsProbeRunner::NO_MOCK) {
77 NetworkChangeNotifier::AddDNSObserver(this);
78 InitializeSystemClient();
79 InitializePublicClient();
80 }
81
82 DnsProbeRunner::~DnsProbeRunner() {
83 NetworkChangeNotifier::RemoveDNSObserver(this);
84 for (TransactionMap::iterator it = pending_transactions_.begin();
85 it != pending_transactions_.end(); ++it) {
86 delete it->first;
87 }
88 }
89
90 void DnsProbeRunner::OnDNSChanged() {
91 InitializeSystemClient();
szym 2013/06/07 19:31:28 Note that this does not affect any pending transac
Deprecated (see juliatuttle) 2013/06/11 01:07:34 That's okay; error pages can be obsolete for other
92 }
93
94 void DnsProbeRunner::RunProbe(Type type,
95 const ProbeCallback& callback) {
96 if (mock_mode_ == MOCK_RESULTS) {
97 callback.Run(type, GetMockResult(type));
98 return;
99 }
100
101 DnsTransaction* transaction =
102 GetClient(type)->GetTransactionFactory()->CreateTransaction(
103 "google.com",
104 net::dns_protocol::kTypeA,
105 base::Bind(&DnsProbeRunner::OnTransactionComplete,
106 weak_factory_.GetWeakPtr(),
107 true /* async */),
108 bound_net_log_).release();
109
110 pending_transactions_.insert(std::pair<DnsTransaction*,ProbeInfo>(
111 transaction,
112 ProbeInfo(type, callback)));
szym 2013/06/07 19:31:28 Instead bind ProbeInfo as an argument to OnTransac
Deprecated (see juliatuttle) 2013/06/11 01:07:34 Obsolete.
113
114 int rv = transaction->Start();
115 if (rv != net::ERR_IO_PENDING) {
116 OnTransactionComplete(false /* not async */,
117 transaction,
118 rv,
119 NULL);
120 }
121 }
122
123 void DnsProbeRunner::SetClientsForTesting(
124 scoped_ptr<DnsClient> mock_system_client,
125 scoped_ptr<DnsClient> mock_public_client) {
126 DCHECK_EQ(NO_MOCK, mock_mode_);
127 DCHECK(mock_system_client.get());
128 DCHECK(mock_public_client.get());
129
130 mock_mode_ = MOCK_CLIENTS;
131 mock_system_client_ = mock_system_client.Pass();
132 mock_public_client_ = mock_public_client.Pass();
133 }
134
135 void DnsProbeRunner::SetResultsForTesting(
136 Result system_result,
137 Result public_result) {
138 mock_mode_ = MOCK_RESULTS;
139 mock_system_result_ = system_result;
140 mock_public_result_ = public_result;
141 mock_system_client_.reset();
142 mock_public_client_.reset();
143 }
144
145 void DnsProbeRunner::InitializeSystemClient() {
146 DnsConfig config;
147 NetworkChangeNotifier::GetDnsConfig(&config);
148 config.search.clear();
149 config.attempts = 1;
150 config.randomize_ports = false;
151
152 scoped_ptr<DnsClient> client = DnsClient::CreateClient(NULL);
153 client->SetConfig(config);
154
155 system_client_ = client.Pass();
156 }
157
158 void DnsProbeRunner::InitializePublicClient() {
159 DnsConfig config;
160 config.nameservers.push_back(MakeDnsEndPoint(kPublicDnsPrimary));
161 config.nameservers.push_back(MakeDnsEndPoint(kPublicDnsSecondary));
162 config.search.clear();
163 config.attempts = 1;
164 config.randomize_ports = false;
165
166 scoped_ptr<DnsClient> client = DnsClient::CreateClient(NULL);
167 client->SetConfig(config);
168
169 public_client_ = client.Pass();
170 }
171
172 DnsProbeRunner::Result DnsProbeRunner::GetMockResult(Type type) {
173 DCHECK_EQ(MOCK_RESULTS, mock_mode_);
174
175 switch (type) {
176 case SYSTEM:
177 return mock_system_result_;
178 case PUBLIC:
179 return mock_public_result_;
180 }
181
182 NOTREACHED();
183 return UNKNOWN;
184 }
185
186 DnsClient* DnsProbeRunner::GetClient(Type type) {
187 DCHECK_NE(MOCK_RESULTS, mock_mode_);
188
189 switch (mock_mode_) {
190 case NO_MOCK:
191 switch (type) {
192 case SYSTEM:
193 return system_client_.get();
194 case PUBLIC:
195 return public_client_.get();
196 }
197 case MOCK_CLIENTS:
198 switch (type) {
199 case SYSTEM:
200 return mock_system_client_.get();
201 case PUBLIC:
202 return mock_public_client_.get();
203 }
204 case MOCK_RESULTS:
205 NOTREACHED();
206 return NULL;
207 }
208
209 NOTREACHED();
210 return NULL;
211 }
212
213 void DnsProbeRunner::OnTransactionComplete(
214 bool async,
215 DnsTransaction* transaction,
216 int net_error,
217 const DnsResponse* response) {
218 TransactionMap::iterator it = pending_transactions_.find(transaction);
219 // I'd use DCHECK_NE, but it doesn't know how to print iterators.
220 DCHECK(it != pending_transactions_.end());
221
222 const ProbeInfo& info = it->second;
223 const Result result = EvaluateResponse(async, net_error, response);
224 info.callback.Run(info.type, result);
225
226 pending_transactions_.erase(it);
227 }
228
229 DnsProbeRunner::Result DnsProbeRunner::EvaluateResponse(
230 bool async,
231 int net_error,
232 const DnsResponse* response) {
233 if (!async) {
szym 2013/06/07 19:31:28 I'm not sure you need this. The net_error returned
Deprecated (see juliatuttle) 2013/06/11 01:07:34 I don't *need* it, but I want to be explicit about
234 return UNREACHABLE;
235 }
236
237 if (net_error != net::OK) {
238 if (DidReceiveDnsResponse(net_error)) {
239 return FAILING;
240 } else {
241 return UNREACHABLE;
242 }
243 }
244
245 AddressList addr_list;
246 TimeDelta ttl;
247 DnsResponse::Result result = response->ParseToAddressList(&addr_list, &ttl);
248
249 if (result != DnsResponse::DNS_PARSE_OK) {
250 return FAILING;
251 }
252
253 if (addr_list.empty()) {
254 return INCORRECT;
255 }
256
257 return CORRECT;
258 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698