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

Side by Side Diff: net/dns/dns_transaction.cc

Issue 9369045: [net] HostResolverImpl + DnsTransaction + DnsConfigService = Asynchronous DNS ready for experiments. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Denitted. Created 8 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « net/dns/dns_transaction.h ('k') | net/dns/dns_transaction_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
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_transaction.h" 5 #include "net/dns/dns_transaction.h"
6 6
7 #include <deque> 7 #include <deque>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 } 44 }
45 45
46 bool IsIPLiteral(const std::string& hostname) { 46 bool IsIPLiteral(const std::string& hostname) {
47 IPAddressNumber ip; 47 IPAddressNumber ip;
48 return ParseIPLiteralToNumber(hostname, &ip); 48 return ParseIPLiteralToNumber(hostname, &ip);
49 } 49 }
50 50
51 class StartParameters : public NetLog::EventParameters { 51 class StartParameters : public NetLog::EventParameters {
52 public: 52 public:
53 StartParameters(const std::string& hostname, 53 StartParameters(const std::string& hostname,
54 uint16 qtype, 54 uint16 qtype)
55 const NetLog::Source& source) 55 : hostname_(hostname), qtype_(qtype) {}
56 : hostname_(hostname), qtype_(qtype), source_(source) {}
57 56
58 virtual Value* ToValue() const OVERRIDE { 57 virtual Value* ToValue() const OVERRIDE {
59 DictionaryValue* dict = new DictionaryValue(); 58 DictionaryValue* dict = new DictionaryValue();
60 dict->SetString("hostname", hostname_); 59 dict->SetString("hostname", hostname_);
61 dict->SetInteger("query_type", qtype_); 60 dict->SetInteger("query_type", qtype_);
62 dict->Set("source_dependency", source_.ToValue());
63 return dict; 61 return dict;
64 } 62 }
65 63
66 private: 64 private:
67 const std::string hostname_; 65 const std::string hostname_;
68 const uint16 qtype_; 66 const uint16 qtype_;
69 const NetLog::Source source_;
70 }; 67 };
71 68
72 class ResponseParameters : public NetLog::EventParameters { 69 class ResponseParameters : public NetLog::EventParameters {
73 public: 70 public:
74 ResponseParameters(int rcode, int answer_count, const NetLog::Source& source) 71 ResponseParameters(int rcode, int answer_count, const NetLog::Source& source)
75 : rcode_(rcode), answer_count_(answer_count), source_(source) {} 72 : rcode_(rcode), answer_count_(answer_count), source_(source) {}
76 73
77 virtual Value* ToValue() const OVERRIDE { 74 virtual Value* ToValue() const OVERRIDE {
78 DictionaryValue* dict = new DictionaryValue(); 75 DictionaryValue* dict = new DictionaryValue();
79 dict->SetInteger("rcode", rcode_); 76 dict->SetInteger("rcode", rcode_);
80 dict->SetInteger("answer_count", answer_count_); 77 dict->SetInteger("answer_count", answer_count_);
81 dict->Set("socket_source", source_.ToValue()); 78 dict->Set("source_dependency", source_.ToValue());
82 return dict; 79 return dict;
83 } 80 }
84 81
85 private: 82 private:
86 const int rcode_; 83 const int rcode_;
87 const int answer_count_; 84 const int answer_count_;
88 const NetLog::Source source_; 85 const NetLog::Source source_;
89 }; 86 };
90 87
91 // ---------------------------------------------------------------------------- 88 // ----------------------------------------------------------------------------
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 base::Bind(&DnsUDPAttempt::OnIOComplete, 201 base::Bind(&DnsUDPAttempt::OnIOComplete,
205 base::Unretained(this))); 202 base::Unretained(this)));
206 } 203 }
207 204
208 int DoReadResponseComplete(int rv) { 205 int DoReadResponseComplete(int rv) {
209 DCHECK_NE(ERR_IO_PENDING, rv); 206 DCHECK_NE(ERR_IO_PENDING, rv);
210 if (rv < 0) 207 if (rv < 0)
211 return rv; 208 return rv;
212 209
213 DCHECK(rv); 210 DCHECK(rv);
214 if (!response_->InitParse(rv, *query_)) 211 if (!response_->InitParse(rv, *query_)) {
212 // TODO(szym): Consider making this reaction less aggressive.
213 // Other implementations simply ignore mismatched responses. Since each
214 // DnsUDPAttempt binds to a different port, we might find that responses
215 // to previously timed out queries lead to failures in the future.
216 // http://crbug.com/107413
215 return ERR_DNS_MALFORMED_RESPONSE; 217 return ERR_DNS_MALFORMED_RESPONSE;
218 }
216 if (response_->flags() & dns_protocol::kFlagTC) 219 if (response_->flags() & dns_protocol::kFlagTC)
217 return ERR_DNS_SERVER_REQUIRES_TCP; 220 return ERR_DNS_SERVER_REQUIRES_TCP;
218 if (response_->rcode() != dns_protocol::kRcodeNOERROR && 221 if (response_->rcode() != dns_protocol::kRcodeNOERROR &&
219 response_->rcode() != dns_protocol::kRcodeNXDOMAIN) { 222 response_->rcode() != dns_protocol::kRcodeNXDOMAIN) {
220 return ERR_DNS_SERVER_FAILED; 223 return ERR_DNS_SERVER_FAILED;
221 } 224 }
222 if (response_->answer_count() == 0) 225 if (response_->answer_count() == 0)
223 return ERR_NAME_NOT_RESOLVED; 226 return ERR_NAME_NOT_RESOLVED;
224 227
225 return OK; 228 return OK;
(...skipping 25 matching lines...) Expand all
251 // The timeout for each DnsUDPAttempt is given by DnsSession::NextTimeout. 254 // The timeout for each DnsUDPAttempt is given by DnsSession::NextTimeout.
252 // The first server to attempt on each query is given by 255 // The first server to attempt on each query is given by
253 // DnsSession::NextFirstServerIndex, and the order is round-robin afterwards. 256 // DnsSession::NextFirstServerIndex, and the order is round-robin afterwards.
254 // Each server is attempted DnsConfig::attempts times. 257 // Each server is attempted DnsConfig::attempts times.
255 class DnsTransactionImpl : public DnsTransaction, public base::NonThreadSafe { 258 class DnsTransactionImpl : public DnsTransaction, public base::NonThreadSafe {
256 public: 259 public:
257 DnsTransactionImpl(DnsSession* session, 260 DnsTransactionImpl(DnsSession* session,
258 const std::string& hostname, 261 const std::string& hostname,
259 uint16 qtype, 262 uint16 qtype,
260 const DnsTransactionFactory::CallbackType& callback, 263 const DnsTransactionFactory::CallbackType& callback,
261 const BoundNetLog& source_net_log) 264 const BoundNetLog& net_log)
262 : session_(session), 265 : session_(session),
263 hostname_(hostname), 266 hostname_(hostname),
264 qtype_(qtype), 267 qtype_(qtype),
265 callback_(callback), 268 callback_(callback),
266 net_log_(BoundNetLog::Make(session->net_log(), 269 net_log_(net_log),
267 NetLog::SOURCE_DNS_TRANSACTION)),
268 first_server_index_(0) { 270 first_server_index_(0) {
269 DCHECK(session_); 271 DCHECK(session_);
270 DCHECK(!hostname_.empty()); 272 DCHECK(!hostname_.empty());
271 DCHECK(!callback_.is_null()); 273 DCHECK(!callback_.is_null());
272 274
273 DCHECK(!IsIPLiteral(hostname_)); 275 DCHECK(!IsIPLiteral(hostname_));
274 276
275 net_log_.BeginEvent(NetLog::TYPE_DNS_TRANSACTION, make_scoped_refptr( 277 net_log_.BeginEvent(NetLog::TYPE_DNS_TRANSACTION, make_scoped_refptr(
276 new StartParameters(hostname_, qtype_, source_net_log.source()))); 278 new StartParameters(hostname_, qtype_)));
277 } 279 }
278 280
279 virtual ~DnsTransactionImpl() { 281 virtual ~DnsTransactionImpl() {
280 STLDeleteElements(&attempts_); 282 STLDeleteElements(&attempts_);
281 if (!callback_.is_null()) { 283 if (!callback_.is_null()) {
282 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); 284 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL);
283 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION, 285 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION,
284 ERR_ABORTED); 286 ERR_ABORTED);
285 } 287 }
286 } 288 }
287 289
288 virtual const std::string& GetHostname() const OVERRIDE { 290 virtual const std::string& GetHostname() const OVERRIDE {
289 DCHECK(CalledOnValidThread()); 291 DCHECK(CalledOnValidThread());
290 return hostname_; 292 return hostname_;
291 } 293 }
292 294
293 virtual uint16 GetType() const OVERRIDE { 295 virtual uint16 GetType() const OVERRIDE {
294 DCHECK(CalledOnValidThread()); 296 DCHECK(CalledOnValidThread());
295 return qtype_; 297 return qtype_;
296 } 298 }
297 299
298 virtual int Start() OVERRIDE { 300 virtual int Start() OVERRIDE {
299 int rv = PrepareSearch(); 301 int rv = PrepareSearch();
300 if (rv == OK) 302 if (rv == OK)
301 rv = StartQuery(); 303 rv = StartQuery();
302 DCHECK_NE(OK, rv); 304 if (rv == OK) {
305 // In the very unlikely case that we immediately received the response, we
306 // cannot simply return OK nor run the callback, but instead complete
307 // asynchronously.
308 // TODO(szym): replace Unretained with WeakPtr factory.
309 MessageLoop::current()->PostTask(
310 FROM_HERE,
311 base::Bind(&DnsTransactionImpl::DoCallback,
312 base::Unretained(this),
313 OK,
314 attempts_.back()));
315 return ERR_IO_PENDING;
316 }
303 return rv; 317 return rv;
304 } 318 }
305 319
306 private: 320 private:
307 // Prepares |qnames_| according to the DnsConfig. 321 // Prepares |qnames_| according to the DnsConfig.
308 int PrepareSearch() { 322 int PrepareSearch() {
309 const DnsConfig& config = session_->config(); 323 const DnsConfig& config = session_->config();
310 324
311 std::string labeled_hostname; 325 std::string labeled_hostname;
312 if (!DNSDomainFromDot(hostname_, &labeled_hostname)) 326 if (!DNSDomainFromDot(hostname_, &labeled_hostname))
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 394
381 uint16 id = session_->NextQueryId(); 395 uint16 id = session_->NextQueryId();
382 scoped_ptr<DnsQuery> query; 396 scoped_ptr<DnsQuery> query;
383 if (attempts_.empty()) { 397 if (attempts_.empty()) {
384 query.reset(new DnsQuery(id, qnames_.front(), qtype_)); 398 query.reset(new DnsQuery(id, qnames_.front(), qtype_));
385 } else { 399 } else {
386 query.reset(attempts_[0]->query()->CloneWithNewId(id)); 400 query.reset(attempts_[0]->query()->CloneWithNewId(id));
387 } 401 }
388 402
389 net_log_.AddEvent(NetLog::TYPE_DNS_TRANSACTION_ATTEMPT, make_scoped_refptr( 403 net_log_.AddEvent(NetLog::TYPE_DNS_TRANSACTION_ATTEMPT, make_scoped_refptr(
390 new NetLogSourceParameter("socket_source", socket->NetLog().source()))); 404 new NetLogSourceParameter("source_dependency",
405 socket->NetLog().source())));
391 406
392 const DnsConfig& config = session_->config(); 407 const DnsConfig& config = session_->config();
393 408
394 unsigned server_index = first_server_index_ + 409 unsigned server_index = first_server_index_ +
395 (attempt_number % config.nameservers.size()); 410 (attempt_number % config.nameservers.size());
396 411
397 DnsUDPAttempt* attempt = new DnsUDPAttempt( 412 DnsUDPAttempt* attempt = new DnsUDPAttempt(
398 socket.Pass(), 413 socket.Pass(),
399 config.nameservers[server_index], 414 config.nameservers[server_index],
400 query.Pass(), 415 query.Pass(),
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 qnames_.pop_front(); 459 qnames_.pop_front();
445 if (qnames_.empty()) 460 if (qnames_.empty())
446 rv = ERR_NAME_NOT_RESOLVED; 461 rv = ERR_NAME_NOT_RESOLVED;
447 else 462 else
448 rv = StartQuery(); 463 rv = StartQuery();
449 break; 464 break;
450 case OK: 465 case OK:
451 DoCallback(rv, attempt); 466 DoCallback(rv, attempt);
452 return; 467 return;
453 default: 468 default:
454 // TODO(szym): Some nameservers could fail so try the next one. 469 // Some nameservers could fail so try the next one.
455 const DnsConfig& config = session_->config(); 470 const DnsConfig& config = session_->config();
456 if (attempts_.size() < config.attempts * config.nameservers.size()) { 471 if (attempts_.size() < config.attempts * config.nameservers.size()) {
457 rv = MakeAttempt(); 472 rv = MakeAttempt();
458 } else { 473 } else {
459 // TODO(szym): Should this be different than the timeout case? 474 // TODO(szym): Should this be different than the timeout case?
460 rv = ERR_DNS_SERVER_FAILED; 475 rv = ERR_DNS_SERVER_FAILED;
461 } 476 }
462 break; 477 break;
463 } 478 }
464 if (rv != ERR_IO_PENDING) 479 if (rv != ERR_IO_PENDING)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 class DnsTransactionFactoryImpl : public DnsTransactionFactory { 520 class DnsTransactionFactoryImpl : public DnsTransactionFactory {
506 public: 521 public:
507 explicit DnsTransactionFactoryImpl(DnsSession* session) { 522 explicit DnsTransactionFactoryImpl(DnsSession* session) {
508 session_ = session; 523 session_ = session;
509 } 524 }
510 525
511 virtual scoped_ptr<DnsTransaction> CreateTransaction( 526 virtual scoped_ptr<DnsTransaction> CreateTransaction(
512 const std::string& hostname, 527 const std::string& hostname,
513 uint16 qtype, 528 uint16 qtype,
514 const CallbackType& callback, 529 const CallbackType& callback,
515 const BoundNetLog& source_net_log) OVERRIDE { 530 const BoundNetLog& net_log) OVERRIDE {
516 return scoped_ptr<DnsTransaction>(new DnsTransactionImpl(session_, 531 return scoped_ptr<DnsTransaction>(new DnsTransactionImpl(session_,
517 hostname, 532 hostname,
518 qtype, 533 qtype,
519 callback, 534 callback,
520 source_net_log)); 535 net_log));
521 } 536 }
522 537
523 private: 538 private:
524 scoped_refptr<DnsSession> session_; 539 scoped_refptr<DnsSession> session_;
525 }; 540 };
526 541
527 } // namespace 542 } // namespace
528 543
529 // static 544 // static
530 scoped_ptr<DnsTransactionFactory> DnsTransactionFactory::CreateFactory( 545 scoped_ptr<DnsTransactionFactory> DnsTransactionFactory::CreateFactory(
531 DnsSession* session) { 546 DnsSession* session) {
532 return scoped_ptr<DnsTransactionFactory>( 547 return scoped_ptr<DnsTransactionFactory>(
533 new DnsTransactionFactoryImpl(session)); 548 new DnsTransactionFactoryImpl(session));
534 } 549 }
535 550
536 } // namespace net 551 } // namespace net
537 552
OLDNEW
« no previous file with comments | « net/dns/dns_transaction.h ('k') | net/dns/dns_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698