OLD | NEW |
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 |
11 #include "base/big_endian.h" | 11 #include "base/big_endian.h" |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/macros.h" |
14 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
15 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
16 #include "base/memory/weak_ptr.h" | 17 #include "base/memory/weak_ptr.h" |
17 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
18 #include "base/profiler/scoped_tracker.h" | 19 #include "base/profiler/scoped_tracker.h" |
19 #include "base/rand_util.h" | 20 #include "base/rand_util.h" |
20 #include "base/single_thread_task_runner.h" | 21 #include "base/single_thread_task_runner.h" |
21 #include "base/stl_util.h" | 22 #include "base/stl_util.h" |
22 #include "base/strings/string_piece.h" | 23 #include "base/strings/string_piece.h" |
23 #include "base/thread_task_runner_handle.h" | 24 #include "base/thread_task_runner_handle.h" |
(...skipping 30 matching lines...) Expand all Loading... |
54 return count; | 55 return count; |
55 } | 56 } |
56 | 57 |
57 bool IsIPLiteral(const std::string& hostname) { | 58 bool IsIPLiteral(const std::string& hostname) { |
58 IPAddressNumber ip; | 59 IPAddressNumber ip; |
59 return ParseIPLiteralToNumber(hostname, &ip); | 60 return ParseIPLiteralToNumber(hostname, &ip); |
60 } | 61 } |
61 | 62 |
62 scoped_ptr<base::Value> NetLogStartCallback( | 63 scoped_ptr<base::Value> NetLogStartCallback( |
63 const std::string* hostname, | 64 const std::string* hostname, |
64 uint16 qtype, | 65 uint16_t qtype, |
65 NetLogCaptureMode /* capture_mode */) { | 66 NetLogCaptureMode /* capture_mode */) { |
66 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 67 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
67 dict->SetString("hostname", *hostname); | 68 dict->SetString("hostname", *hostname); |
68 dict->SetInteger("query_type", qtype); | 69 dict->SetInteger("query_type", qtype); |
69 return dict.Pass(); | 70 return dict.Pass(); |
70 }; | 71 }; |
71 | 72 |
72 // ---------------------------------------------------------------------------- | 73 // ---------------------------------------------------------------------------- |
73 | 74 |
74 // A single asynchronous DNS exchange, which consists of sending out a | 75 // A single asynchronous DNS exchange, which consists of sending out a |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 | 298 |
298 class DnsTCPAttempt : public DnsAttempt { | 299 class DnsTCPAttempt : public DnsAttempt { |
299 public: | 300 public: |
300 DnsTCPAttempt(unsigned server_index, | 301 DnsTCPAttempt(unsigned server_index, |
301 scoped_ptr<StreamSocket> socket, | 302 scoped_ptr<StreamSocket> socket, |
302 scoped_ptr<DnsQuery> query) | 303 scoped_ptr<DnsQuery> query) |
303 : DnsAttempt(server_index), | 304 : DnsAttempt(server_index), |
304 next_state_(STATE_NONE), | 305 next_state_(STATE_NONE), |
305 socket_(socket.Pass()), | 306 socket_(socket.Pass()), |
306 query_(query.Pass()), | 307 query_(query.Pass()), |
307 length_buffer_(new IOBufferWithSize(sizeof(uint16))), | 308 length_buffer_(new IOBufferWithSize(sizeof(uint16_t))), |
308 response_length_(0) {} | 309 response_length_(0) {} |
309 | 310 |
310 // DnsAttempt: | 311 // DnsAttempt: |
311 int Start(const CompletionCallback& callback) override { | 312 int Start(const CompletionCallback& callback) override { |
312 DCHECK_EQ(STATE_NONE, next_state_); | 313 DCHECK_EQ(STATE_NONE, next_state_); |
313 callback_ = callback; | 314 callback_ = callback; |
314 start_time_ = base::TimeTicks::Now(); | 315 start_time_ = base::TimeTicks::Now(); |
315 next_state_ = STATE_CONNECT_COMPLETE; | 316 next_state_ = STATE_CONNECT_COMPLETE; |
316 int rv = socket_->Connect(base::Bind(&DnsTCPAttempt::OnIOComplete, | 317 int rv = socket_->Connect(base::Bind(&DnsTCPAttempt::OnIOComplete, |
317 base::Unretained(this))); | 318 base::Unretained(this))); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 int DoConnectComplete(int rv) { | 395 int DoConnectComplete(int rv) { |
395 // TODO(rvargas): Remove ScopedTracker below once crbug.com/462784 is fixed. | 396 // TODO(rvargas): Remove ScopedTracker below once crbug.com/462784 is fixed. |
396 tracked_objects::ScopedTracker tracking_profile( | 397 tracked_objects::ScopedTracker tracking_profile( |
397 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 398 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
398 "462784 DnsTCPAttempt::DoConnectComplete")); | 399 "462784 DnsTCPAttempt::DoConnectComplete")); |
399 | 400 |
400 DCHECK_NE(ERR_IO_PENDING, rv); | 401 DCHECK_NE(ERR_IO_PENDING, rv); |
401 if (rv < 0) | 402 if (rv < 0) |
402 return rv; | 403 return rv; |
403 | 404 |
404 uint16 query_size = static_cast<uint16>(query_->io_buffer()->size()); | 405 uint16_t query_size = static_cast<uint16_t>(query_->io_buffer()->size()); |
405 if (static_cast<int>(query_size) != query_->io_buffer()->size()) | 406 if (static_cast<int>(query_size) != query_->io_buffer()->size()) |
406 return ERR_FAILED; | 407 return ERR_FAILED; |
407 base::WriteBigEndian<uint16>(length_buffer_->data(), query_size); | 408 base::WriteBigEndian<uint16_t>(length_buffer_->data(), query_size); |
408 buffer_ = | 409 buffer_ = |
409 new DrainableIOBuffer(length_buffer_.get(), length_buffer_->size()); | 410 new DrainableIOBuffer(length_buffer_.get(), length_buffer_->size()); |
410 next_state_ = STATE_SEND_LENGTH; | 411 next_state_ = STATE_SEND_LENGTH; |
411 return OK; | 412 return OK; |
412 } | 413 } |
413 | 414 |
414 int DoSendLength(int rv) { | 415 int DoSendLength(int rv) { |
415 DCHECK_NE(ERR_IO_PENDING, rv); | 416 DCHECK_NE(ERR_IO_PENDING, rv); |
416 if (rv < 0) | 417 if (rv < 0) |
417 return rv; | 418 return rv; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 return rv; | 463 return rv; |
463 if (rv == 0) | 464 if (rv == 0) |
464 return ERR_CONNECTION_CLOSED; | 465 return ERR_CONNECTION_CLOSED; |
465 | 466 |
466 buffer_->DidConsume(rv); | 467 buffer_->DidConsume(rv); |
467 if (buffer_->BytesRemaining() > 0) { | 468 if (buffer_->BytesRemaining() > 0) { |
468 next_state_ = STATE_READ_LENGTH; | 469 next_state_ = STATE_READ_LENGTH; |
469 return OK; | 470 return OK; |
470 } | 471 } |
471 | 472 |
472 base::ReadBigEndian<uint16>(length_buffer_->data(), &response_length_); | 473 base::ReadBigEndian<uint16_t>(length_buffer_->data(), &response_length_); |
473 // Check if advertised response is too short. (Optimization only.) | 474 // Check if advertised response is too short. (Optimization only.) |
474 if (response_length_ < query_->io_buffer()->size()) | 475 if (response_length_ < query_->io_buffer()->size()) |
475 return ERR_DNS_MALFORMED_RESPONSE; | 476 return ERR_DNS_MALFORMED_RESPONSE; |
476 // Allocate more space so that DnsResponse::InitParse sanity check passes. | 477 // Allocate more space so that DnsResponse::InitParse sanity check passes. |
477 response_.reset(new DnsResponse(response_length_ + 1)); | 478 response_.reset(new DnsResponse(response_length_ + 1)); |
478 buffer_ = new DrainableIOBuffer(response_->io_buffer(), response_length_); | 479 buffer_ = new DrainableIOBuffer(response_->io_buffer(), response_length_); |
479 next_state_ = STATE_READ_RESPONSE; | 480 next_state_ = STATE_READ_RESPONSE; |
480 return OK; | 481 return OK; |
481 } | 482 } |
482 | 483 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 } | 528 } |
528 | 529 |
529 State next_state_; | 530 State next_state_; |
530 base::TimeTicks start_time_; | 531 base::TimeTicks start_time_; |
531 | 532 |
532 scoped_ptr<StreamSocket> socket_; | 533 scoped_ptr<StreamSocket> socket_; |
533 scoped_ptr<DnsQuery> query_; | 534 scoped_ptr<DnsQuery> query_; |
534 scoped_refptr<IOBufferWithSize> length_buffer_; | 535 scoped_refptr<IOBufferWithSize> length_buffer_; |
535 scoped_refptr<DrainableIOBuffer> buffer_; | 536 scoped_refptr<DrainableIOBuffer> buffer_; |
536 | 537 |
537 uint16 response_length_; | 538 uint16_t response_length_; |
538 scoped_ptr<DnsResponse> response_; | 539 scoped_ptr<DnsResponse> response_; |
539 | 540 |
540 CompletionCallback callback_; | 541 CompletionCallback callback_; |
541 | 542 |
542 DISALLOW_COPY_AND_ASSIGN(DnsTCPAttempt); | 543 DISALLOW_COPY_AND_ASSIGN(DnsTCPAttempt); |
543 }; | 544 }; |
544 | 545 |
545 // ---------------------------------------------------------------------------- | 546 // ---------------------------------------------------------------------------- |
546 | 547 |
547 // Implements DnsTransaction. Configuration is supplied by DnsSession. | 548 // Implements DnsTransaction. Configuration is supplied by DnsSession. |
548 // The suffix list is built according to the DnsConfig from the session. | 549 // The suffix list is built according to the DnsConfig from the session. |
549 // The timeout for each DnsUDPAttempt is given by DnsSession::NextTimeout. | 550 // The timeout for each DnsUDPAttempt is given by DnsSession::NextTimeout. |
550 // The first server to attempt on each query is given by | 551 // The first server to attempt on each query is given by |
551 // DnsSession::NextFirstServerIndex, and the order is round-robin afterwards. | 552 // DnsSession::NextFirstServerIndex, and the order is round-robin afterwards. |
552 // Each server is attempted DnsConfig::attempts times. | 553 // Each server is attempted DnsConfig::attempts times. |
553 class DnsTransactionImpl : public DnsTransaction, | 554 class DnsTransactionImpl : public DnsTransaction, |
554 public base::NonThreadSafe, | 555 public base::NonThreadSafe, |
555 public base::SupportsWeakPtr<DnsTransactionImpl> { | 556 public base::SupportsWeakPtr<DnsTransactionImpl> { |
556 public: | 557 public: |
557 DnsTransactionImpl(DnsSession* session, | 558 DnsTransactionImpl(DnsSession* session, |
558 const std::string& hostname, | 559 const std::string& hostname, |
559 uint16 qtype, | 560 uint16_t qtype, |
560 const DnsTransactionFactory::CallbackType& callback, | 561 const DnsTransactionFactory::CallbackType& callback, |
561 const BoundNetLog& net_log) | 562 const BoundNetLog& net_log) |
562 : session_(session), | 563 : session_(session), |
563 hostname_(hostname), | 564 hostname_(hostname), |
564 qtype_(qtype), | 565 qtype_(qtype), |
565 callback_(callback), | 566 callback_(callback), |
566 net_log_(net_log), | 567 net_log_(net_log), |
567 qnames_initial_size_(0), | 568 qnames_initial_size_(0), |
568 attempts_count_(0), | 569 attempts_count_(0), |
569 had_tcp_attempt_(false), | 570 had_tcp_attempt_(false), |
570 first_server_index_(0) { | 571 first_server_index_(0) { |
571 DCHECK(session_.get()); | 572 DCHECK(session_.get()); |
572 DCHECK(!hostname_.empty()); | 573 DCHECK(!hostname_.empty()); |
573 DCHECK(!callback_.is_null()); | 574 DCHECK(!callback_.is_null()); |
574 DCHECK(!IsIPLiteral(hostname_)); | 575 DCHECK(!IsIPLiteral(hostname_)); |
575 } | 576 } |
576 | 577 |
577 ~DnsTransactionImpl() override { | 578 ~DnsTransactionImpl() override { |
578 if (!callback_.is_null()) { | 579 if (!callback_.is_null()) { |
579 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION, | 580 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION, |
580 ERR_ABORTED); | 581 ERR_ABORTED); |
581 } // otherwise logged in DoCallback or Start | 582 } // otherwise logged in DoCallback or Start |
582 } | 583 } |
583 | 584 |
584 const std::string& GetHostname() const override { | 585 const std::string& GetHostname() const override { |
585 DCHECK(CalledOnValidThread()); | 586 DCHECK(CalledOnValidThread()); |
586 return hostname_; | 587 return hostname_; |
587 } | 588 } |
588 | 589 |
589 uint16 GetType() const override { | 590 uint16_t GetType() const override { |
590 DCHECK(CalledOnValidThread()); | 591 DCHECK(CalledOnValidThread()); |
591 return qtype_; | 592 return qtype_; |
592 } | 593 } |
593 | 594 |
594 void Start() override { | 595 void Start() override { |
595 DCHECK(!callback_.is_null()); | 596 DCHECK(!callback_.is_null()); |
596 DCHECK(attempts_.empty()); | 597 DCHECK(attempts_.empty()); |
597 net_log_.BeginEvent(NetLog::TYPE_DNS_TRANSACTION, | 598 net_log_.BeginEvent(NetLog::TYPE_DNS_TRANSACTION, |
598 base::Bind(&NetLogStartCallback, &hostname_, qtype_)); | 599 base::Bind(&NetLogStartCallback, &hostname_, qtype_)); |
599 AttemptResult result(PrepareSearch(), NULL); | 600 AttemptResult result(PrepareSearch(), NULL); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 | 696 |
696 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION, result.rv); | 697 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION, result.rv); |
697 callback.Run(this, result.rv, response); | 698 callback.Run(this, result.rv, response); |
698 } | 699 } |
699 | 700 |
700 // Makes another attempt at the current name, |qnames_.front()|, using the | 701 // Makes another attempt at the current name, |qnames_.front()|, using the |
701 // next nameserver. | 702 // next nameserver. |
702 AttemptResult MakeAttempt() { | 703 AttemptResult MakeAttempt() { |
703 unsigned attempt_number = attempts_.size(); | 704 unsigned attempt_number = attempts_.size(); |
704 | 705 |
705 uint16 id = session_->NextQueryId(); | 706 uint16_t id = session_->NextQueryId(); |
706 scoped_ptr<DnsQuery> query; | 707 scoped_ptr<DnsQuery> query; |
707 if (attempts_.empty()) { | 708 if (attempts_.empty()) { |
708 query.reset(new DnsQuery(id, qnames_.front(), qtype_)); | 709 query.reset(new DnsQuery(id, qnames_.front(), qtype_)); |
709 } else { | 710 } else { |
710 query = attempts_[0]->GetQuery()->CloneWithNewId(id); | 711 query = attempts_[0]->GetQuery()->CloneWithNewId(id); |
711 } | 712 } |
712 | 713 |
713 const DnsConfig& config = session_->config(); | 714 const DnsConfig& config = session_->config(); |
714 | 715 |
715 unsigned server_index = | 716 unsigned server_index = |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 AttemptResult MakeTCPAttempt(const DnsAttempt* previous_attempt) { | 751 AttemptResult MakeTCPAttempt(const DnsAttempt* previous_attempt) { |
751 DCHECK(previous_attempt); | 752 DCHECK(previous_attempt); |
752 DCHECK(!had_tcp_attempt_); | 753 DCHECK(!had_tcp_attempt_); |
753 | 754 |
754 unsigned server_index = previous_attempt->server_index(); | 755 unsigned server_index = previous_attempt->server_index(); |
755 | 756 |
756 scoped_ptr<StreamSocket> socket( | 757 scoped_ptr<StreamSocket> socket( |
757 session_->CreateTCPSocket(server_index, net_log_.source())); | 758 session_->CreateTCPSocket(server_index, net_log_.source())); |
758 | 759 |
759 // TODO(szym): Reuse the same id to help the server? | 760 // TODO(szym): Reuse the same id to help the server? |
760 uint16 id = session_->NextQueryId(); | 761 uint16_t id = session_->NextQueryId(); |
761 scoped_ptr<DnsQuery> query = | 762 scoped_ptr<DnsQuery> query = |
762 previous_attempt->GetQuery()->CloneWithNewId(id); | 763 previous_attempt->GetQuery()->CloneWithNewId(id); |
763 | 764 |
764 RecordLostPacketsIfAny(); | 765 RecordLostPacketsIfAny(); |
765 // Cancel all other attempts, no point waiting on them. | 766 // Cancel all other attempts, no point waiting on them. |
766 attempts_.clear(); | 767 attempts_.clear(); |
767 | 768 |
768 unsigned attempt_number = attempts_.size(); | 769 unsigned attempt_number = attempts_.size(); |
769 | 770 |
770 DnsTCPAttempt* attempt = new DnsTCPAttempt(server_index, socket.Pass(), | 771 DnsTCPAttempt* attempt = new DnsTCPAttempt(server_index, socket.Pass(), |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 return; | 935 return; |
935 DCHECK(!attempts_.empty()); | 936 DCHECK(!attempts_.empty()); |
936 AttemptResult result = ProcessAttemptResult( | 937 AttemptResult result = ProcessAttemptResult( |
937 AttemptResult(ERR_DNS_TIMED_OUT, attempts_.back().get())); | 938 AttemptResult(ERR_DNS_TIMED_OUT, attempts_.back().get())); |
938 if (result.rv != ERR_IO_PENDING) | 939 if (result.rv != ERR_IO_PENDING) |
939 DoCallback(result); | 940 DoCallback(result); |
940 } | 941 } |
941 | 942 |
942 scoped_refptr<DnsSession> session_; | 943 scoped_refptr<DnsSession> session_; |
943 std::string hostname_; | 944 std::string hostname_; |
944 uint16 qtype_; | 945 uint16_t qtype_; |
945 // Cleared in DoCallback. | 946 // Cleared in DoCallback. |
946 DnsTransactionFactory::CallbackType callback_; | 947 DnsTransactionFactory::CallbackType callback_; |
947 | 948 |
948 BoundNetLog net_log_; | 949 BoundNetLog net_log_; |
949 | 950 |
950 // Search list of fully-qualified DNS names to query next (in DNS format). | 951 // Search list of fully-qualified DNS names to query next (in DNS format). |
951 std::deque<std::string> qnames_; | 952 std::deque<std::string> qnames_; |
952 size_t qnames_initial_size_; | 953 size_t qnames_initial_size_; |
953 | 954 |
954 // List of attempts for the current name. | 955 // List of attempts for the current name. |
(...skipping 15 matching lines...) Expand all Loading... |
970 // Implementation of DnsTransactionFactory that returns instances of | 971 // Implementation of DnsTransactionFactory that returns instances of |
971 // DnsTransactionImpl. | 972 // DnsTransactionImpl. |
972 class DnsTransactionFactoryImpl : public DnsTransactionFactory { | 973 class DnsTransactionFactoryImpl : public DnsTransactionFactory { |
973 public: | 974 public: |
974 explicit DnsTransactionFactoryImpl(DnsSession* session) { | 975 explicit DnsTransactionFactoryImpl(DnsSession* session) { |
975 session_ = session; | 976 session_ = session; |
976 } | 977 } |
977 | 978 |
978 scoped_ptr<DnsTransaction> CreateTransaction( | 979 scoped_ptr<DnsTransaction> CreateTransaction( |
979 const std::string& hostname, | 980 const std::string& hostname, |
980 uint16 qtype, | 981 uint16_t qtype, |
981 const CallbackType& callback, | 982 const CallbackType& callback, |
982 const BoundNetLog& net_log) override { | 983 const BoundNetLog& net_log) override { |
983 return scoped_ptr<DnsTransaction>(new DnsTransactionImpl( | 984 return scoped_ptr<DnsTransaction>(new DnsTransactionImpl( |
984 session_.get(), hostname, qtype, callback, net_log)); | 985 session_.get(), hostname, qtype, callback, net_log)); |
985 } | 986 } |
986 | 987 |
987 private: | 988 private: |
988 scoped_refptr<DnsSession> session_; | 989 scoped_refptr<DnsSession> session_; |
989 }; | 990 }; |
990 | 991 |
991 } // namespace | 992 } // namespace |
992 | 993 |
993 // static | 994 // static |
994 scoped_ptr<DnsTransactionFactory> DnsTransactionFactory::CreateFactory( | 995 scoped_ptr<DnsTransactionFactory> DnsTransactionFactory::CreateFactory( |
995 DnsSession* session) { | 996 DnsSession* session) { |
996 return scoped_ptr<DnsTransactionFactory>( | 997 return scoped_ptr<DnsTransactionFactory>( |
997 new DnsTransactionFactoryImpl(session)); | 998 new DnsTransactionFactoryImpl(session)); |
998 } | 999 } |
999 | 1000 |
1000 } // namespace net | 1001 } // namespace net |
OLD | NEW |