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

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

Issue 13270005: Display DNS probe results. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix one last nit Created 7 years, 5 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
« no previous file with comments | « chrome/browser/net/dns_probe_job.h ('k') | chrome/browser/net/dns_probe_job_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/net/dns_probe_job.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop.h"
11 #include "base/time/time.h"
12 #include "net/base/address_list.h"
13 #include "net/base/net_errors.h"
14 #include "net/base/net_log.h"
15 #include "net/dns/dns_client.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::DnsResponse;
25 using net::DnsTransaction;
26 using net::NetLog;
27
28 namespace chrome_browser_net {
29
30 namespace {
31
32 // Returns true if the given net_error indicates that we received a response
33 // from the DNS server containing an error, or false if the given net_error
34 // indicates that we never received a response.
35 bool DidReceiveDnsResponse(int net_error) {
36 switch (net_error) {
37 case net::ERR_NAME_NOT_RESOLVED: // NXDOMAIN maps to this.
38 case net::ERR_DNS_MALFORMED_RESPONSE:
39 case net::ERR_DNS_SERVER_REQUIRES_TCP:
40 case net::ERR_DNS_SERVER_FAILED:
41 case net::ERR_DNS_SORT_ERROR: // Can only happen if the server responds.
42 return true;
43 default:
44 return false;
45 }
46 }
47
48 class DnsProbeJobImpl : public DnsProbeJob {
49 public:
50 DnsProbeJobImpl(scoped_ptr<DnsClient> dns_client,
51 const DnsProbeJob::CallbackType& callback,
52 NetLog* net_log);
53 virtual ~DnsProbeJobImpl();
54
55 private:
56 enum QueryResult {
57 QUERY_UNKNOWN,
58 QUERY_CORRECT,
59 QUERY_INCORRECT,
60 QUERY_DNS_ERROR,
61 QUERY_NET_ERROR,
62 };
63
64 void Start();
65
66 scoped_ptr<DnsTransaction> CreateTransaction(
67 const std::string& hostname);
68 void StartTransaction(DnsTransaction* transaction);
69 // Checks that |net_error| is OK, |response| parses, and has at least one
70 // address.
71 QueryResult EvaluateGoodResponse(int net_error, const DnsResponse* response);
72 // Checks that |net_error| is OK, |response| parses but has no addresses.
73 QueryResult EvaluateBadResponse(int net_error, const DnsResponse* response);
74 DnsProbeJob::Result EvaluateQueryResults();
75 void OnTransactionComplete(DnsTransaction* transaction,
76 int net_error,
77 const DnsResponse* response);
78
79 BoundNetLog bound_net_log_;
80 scoped_ptr<DnsClient> dns_client_;
81 const DnsProbeJob::CallbackType callback_;
82 scoped_ptr<DnsTransaction> good_transaction_;
83 scoped_ptr<DnsTransaction> bad_transaction_;
84 bool good_running_;
85 bool bad_running_;
86 QueryResult good_result_;
87 QueryResult bad_result_;
88 base::WeakPtrFactory<DnsProbeJobImpl> weak_factory_;
89
90 DISALLOW_COPY_AND_ASSIGN(DnsProbeJobImpl);
91 };
92
93 DnsProbeJobImpl::DnsProbeJobImpl(scoped_ptr<DnsClient> dns_client,
94 const DnsProbeJob::CallbackType& callback,
95 NetLog* net_log)
96 : bound_net_log_(
97 BoundNetLog::Make(net_log, NetLog::SOURCE_DNS_PROBER)),
98 dns_client_(dns_client.Pass()),
99 callback_(callback),
100 good_running_(false),
101 bad_running_(false),
102 good_result_(QUERY_UNKNOWN),
103 bad_result_(QUERY_UNKNOWN),
104 weak_factory_(this) {
105 DCHECK(dns_client_.get());
106 DCHECK(dns_client_->GetConfig());
107
108 base::MessageLoop::current()->PostTask(
109 FROM_HERE,
110 base::Bind(&DnsProbeJobImpl::Start,
111 weak_factory_.GetWeakPtr()));
112 }
113
114 DnsProbeJobImpl::~DnsProbeJobImpl() {
115 }
116
117 void DnsProbeJobImpl::Start() {
118 // TODO(ttuttle): Pick a good random hostname for the bad case.
119 // Consider running transactions in series?
120 good_transaction_ = CreateTransaction("google.com");
121 bad_transaction_ = CreateTransaction("thishostname.doesnotresolve");
122
123 // StartTransaction may call the callback synchrononously, so set these
124 // before we call it.
125 good_running_ = true;
126 bad_running_ = true;
127
128 // TODO(ttuttle): Log probe started.
129
130 StartTransaction(good_transaction_.get());
131 StartTransaction(bad_transaction_.get());
132 }
133
134 scoped_ptr<DnsTransaction> DnsProbeJobImpl::CreateTransaction(
135 const std::string& hostname) {
136 return dns_client_->GetTransactionFactory()->CreateTransaction(
137 hostname,
138 net::dns_protocol::kTypeA,
139 base::Bind(&DnsProbeJobImpl::OnTransactionComplete,
140 base::Unretained(this)),
141 bound_net_log_);
142 }
143
144 void DnsProbeJobImpl::StartTransaction(DnsTransaction* transaction) {
145 int rv = transaction->Start();
146 if (rv != net::ERR_IO_PENDING) {
147 // TODO(ttuttle): Make sure this counts as unreachable, not error.
148 OnTransactionComplete(transaction, rv, NULL);
149 }
150
151 // TODO(ttuttle): Log transaction started.
152 }
153
154 DnsProbeJobImpl::QueryResult DnsProbeJobImpl::EvaluateGoodResponse(
155 int net_error,
156 const DnsResponse* response) {
157 if (net_error != net::OK)
158 return DidReceiveDnsResponse(net_error) ? QUERY_DNS_ERROR : QUERY_NET_ERROR;
159
160 AddressList addr_list;
161 TimeDelta ttl;
162 DnsResponse::Result result = response->ParseToAddressList(&addr_list, &ttl);
163
164 if (result != DnsResponse::DNS_PARSE_OK)
165 return QUERY_DNS_ERROR;
166
167 if (addr_list.empty())
168 return QUERY_INCORRECT;
169
170 return QUERY_CORRECT;
171 }
172
173 DnsProbeJobImpl::QueryResult DnsProbeJobImpl::EvaluateBadResponse(
174 int net_error,
175 const DnsResponse* response) {
176 if (net_error == net::ERR_NAME_NOT_RESOLVED) // NXDOMAIN maps to this
177 return QUERY_CORRECT;
178
179 if (net_error != net::OK)
180 return DidReceiveDnsResponse(net_error) ? QUERY_DNS_ERROR : QUERY_NET_ERROR;
181
182 return QUERY_INCORRECT;
183 }
184
185 DnsProbeJob::Result DnsProbeJobImpl::EvaluateQueryResults() {
186 if (good_result_ == QUERY_NET_ERROR || bad_result_ == QUERY_NET_ERROR)
187 return SERVERS_UNREACHABLE;
188
189 if (good_result_ == QUERY_DNS_ERROR || bad_result_ == QUERY_DNS_ERROR)
190 return SERVERS_FAILING;
191
192 // Ignore incorrect responses to known-bad query to avoid flagging domain
193 // helpers.
194 if (good_result_ == QUERY_INCORRECT)
195 return SERVERS_INCORRECT;
196
197 return SERVERS_CORRECT;
198 }
199
200 void DnsProbeJobImpl::OnTransactionComplete(DnsTransaction* transaction,
201 int net_error,
202 const DnsResponse* response) {
203 if (transaction == good_transaction_.get()) {
204 DCHECK(good_running_);
205 DCHECK_EQ(QUERY_UNKNOWN, good_result_);
206 good_result_ = EvaluateGoodResponse(net_error, response);
207 good_running_ = false;
208 } else if (transaction == bad_transaction_.get()) {
209 DCHECK(bad_running_);
210 DCHECK_EQ(QUERY_UNKNOWN, bad_result_);
211 bad_result_ = EvaluateBadResponse(net_error, response);
212 bad_running_ = false;
213 } else {
214 NOTREACHED();
215 return;
216 }
217
218 if (good_running_ || bad_running_)
219 return;
220
221 callback_.Run(this, EvaluateQueryResults());
222
223 // TODO(ttuttle): Log probe finished.
224 }
225
226 } // namespace
227
228 scoped_ptr<DnsProbeJob> DnsProbeJob::CreateJob(
229 scoped_ptr<DnsClient> dns_client,
230 const CallbackType& callback,
231 NetLog* net_log) {
232 return scoped_ptr<DnsProbeJob>(
233 new DnsProbeJobImpl(dns_client.Pass(), callback, net_log));
234 }
235
236 } // namespace chrome_browser_net
OLDNEW
« no previous file with comments | « chrome/browser/net/dns_probe_job.h ('k') | chrome/browser/net/dns_probe_job_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698