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 <memory> | 8 #include <memory> |
9 #include <string> | 9 #include <string> |
10 #include <utility> | 10 #include <utility> |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "net/base/io_buffer.h" | 31 #include "net/base/io_buffer.h" |
32 #include "net/base/ip_address.h" | 32 #include "net/base/ip_address.h" |
33 #include "net/base/ip_endpoint.h" | 33 #include "net/base/ip_endpoint.h" |
34 #include "net/base/net_errors.h" | 34 #include "net/base/net_errors.h" |
35 #include "net/dns/dns_protocol.h" | 35 #include "net/dns/dns_protocol.h" |
36 #include "net/dns/dns_query.h" | 36 #include "net/dns/dns_query.h" |
37 #include "net/dns/dns_response.h" | 37 #include "net/dns/dns_response.h" |
38 #include "net/dns/dns_session.h" | 38 #include "net/dns/dns_session.h" |
39 #include "net/dns/dns_util.h" | 39 #include "net/dns/dns_util.h" |
40 #include "net/log/net_log.h" | 40 #include "net/log/net_log.h" |
| 41 #include "net/log/net_log_event_type.h" |
41 #include "net/socket/stream_socket.h" | 42 #include "net/socket/stream_socket.h" |
42 #include "net/udp/datagram_client_socket.h" | 43 #include "net/udp/datagram_client_socket.h" |
43 | 44 |
44 namespace net { | 45 namespace net { |
45 | 46 |
46 namespace { | 47 namespace { |
47 | 48 |
48 // Provide a common macro to simplify code and readability. We must use a | 49 // Provide a common macro to simplify code and readability. We must use a |
49 // macro as the underlying HISTOGRAM macro creates static variables. | 50 // macro as the underlying HISTOGRAM macro creates static variables. |
50 #define DNS_HISTOGRAM(name, time) UMA_HISTOGRAM_CUSTOM_TIMES(name, time, \ | 51 #define DNS_HISTOGRAM(name, time) UMA_HISTOGRAM_CUSTOM_TIMES(name, time, \ |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 had_tcp_attempt_(false), | 574 had_tcp_attempt_(false), |
574 first_server_index_(0) { | 575 first_server_index_(0) { |
575 DCHECK(session_.get()); | 576 DCHECK(session_.get()); |
576 DCHECK(!hostname_.empty()); | 577 DCHECK(!hostname_.empty()); |
577 DCHECK(!callback_.is_null()); | 578 DCHECK(!callback_.is_null()); |
578 DCHECK(!IsIPLiteral(hostname_)); | 579 DCHECK(!IsIPLiteral(hostname_)); |
579 } | 580 } |
580 | 581 |
581 ~DnsTransactionImpl() override { | 582 ~DnsTransactionImpl() override { |
582 if (!callback_.is_null()) { | 583 if (!callback_.is_null()) { |
583 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION, | 584 net_log_.EndEventWithNetErrorCode(NetLogEventType::DNS_TRANSACTION, |
584 ERR_ABORTED); | 585 ERR_ABORTED); |
585 } // otherwise logged in DoCallback or Start | 586 } // otherwise logged in DoCallback or Start |
586 } | 587 } |
587 | 588 |
588 const std::string& GetHostname() const override { | 589 const std::string& GetHostname() const override { |
589 DCHECK(CalledOnValidThread()); | 590 DCHECK(CalledOnValidThread()); |
590 return hostname_; | 591 return hostname_; |
591 } | 592 } |
592 | 593 |
593 uint16_t GetType() const override { | 594 uint16_t GetType() const override { |
594 DCHECK(CalledOnValidThread()); | 595 DCHECK(CalledOnValidThread()); |
595 return qtype_; | 596 return qtype_; |
596 } | 597 } |
597 | 598 |
598 void Start() override { | 599 void Start() override { |
599 DCHECK(!callback_.is_null()); | 600 DCHECK(!callback_.is_null()); |
600 DCHECK(attempts_.empty()); | 601 DCHECK(attempts_.empty()); |
601 net_log_.BeginEvent(NetLog::TYPE_DNS_TRANSACTION, | 602 net_log_.BeginEvent(NetLogEventType::DNS_TRANSACTION, |
602 base::Bind(&NetLogStartCallback, &hostname_, qtype_)); | 603 base::Bind(&NetLogStartCallback, &hostname_, qtype_)); |
603 AttemptResult result(PrepareSearch(), NULL); | 604 AttemptResult result(PrepareSearch(), NULL); |
604 if (result.rv == OK) { | 605 if (result.rv == OK) { |
605 qnames_initial_size_ = qnames_.size(); | 606 qnames_initial_size_ = qnames_.size(); |
606 if (qtype_ == dns_protocol::kTypeA) | 607 if (qtype_ == dns_protocol::kTypeA) |
607 UMA_HISTOGRAM_COUNTS("AsyncDNS.SuffixSearchStart", qnames_.size()); | 608 UMA_HISTOGRAM_COUNTS("AsyncDNS.SuffixSearchStart", qnames_.size()); |
608 result = ProcessAttemptResult(StartQuery()); | 609 result = ProcessAttemptResult(StartQuery()); |
609 } | 610 } |
610 | 611 |
611 // Must always return result asynchronously, to avoid reentrancy. | 612 // Must always return result asynchronously, to avoid reentrancy. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 | 691 |
691 if (response && qtype_ == dns_protocol::kTypeA) { | 692 if (response && qtype_ == dns_protocol::kTypeA) { |
692 UMA_HISTOGRAM_COUNTS("AsyncDNS.SuffixSearchRemain", qnames_.size()); | 693 UMA_HISTOGRAM_COUNTS("AsyncDNS.SuffixSearchRemain", qnames_.size()); |
693 UMA_HISTOGRAM_COUNTS("AsyncDNS.SuffixSearchDone", | 694 UMA_HISTOGRAM_COUNTS("AsyncDNS.SuffixSearchDone", |
694 qnames_initial_size_ - qnames_.size()); | 695 qnames_initial_size_ - qnames_.size()); |
695 } | 696 } |
696 | 697 |
697 DnsTransactionFactory::CallbackType callback = callback_; | 698 DnsTransactionFactory::CallbackType callback = callback_; |
698 callback_.Reset(); | 699 callback_.Reset(); |
699 | 700 |
700 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION, result.rv); | 701 net_log_.EndEventWithNetErrorCode(NetLogEventType::DNS_TRANSACTION, |
| 702 result.rv); |
701 callback.Run(this, result.rv, response); | 703 callback.Run(this, result.rv, response); |
702 } | 704 } |
703 | 705 |
704 // Makes another attempt at the current name, |qnames_.front()|, using the | 706 // Makes another attempt at the current name, |qnames_.front()|, using the |
705 // next nameserver. | 707 // next nameserver. |
706 AttemptResult MakeAttempt() { | 708 AttemptResult MakeAttempt() { |
707 unsigned attempt_number = attempts_.size(); | 709 unsigned attempt_number = attempts_.size(); |
708 | 710 |
709 uint16_t id = session_->NextQueryId(); | 711 uint16_t id = session_->NextQueryId(); |
710 std::unique_ptr<DnsQuery> query; | 712 std::unique_ptr<DnsQuery> query; |
(...skipping 18 matching lines...) Expand all Loading... |
729 DnsUDPAttempt* attempt = | 731 DnsUDPAttempt* attempt = |
730 new DnsUDPAttempt(server_index, std::move(lease), std::move(query)); | 732 new DnsUDPAttempt(server_index, std::move(lease), std::move(query)); |
731 | 733 |
732 attempts_.push_back(base::WrapUnique(attempt)); | 734 attempts_.push_back(base::WrapUnique(attempt)); |
733 ++attempts_count_; | 735 ++attempts_count_; |
734 | 736 |
735 if (!got_socket) | 737 if (!got_socket) |
736 return AttemptResult(ERR_CONNECTION_REFUSED, NULL); | 738 return AttemptResult(ERR_CONNECTION_REFUSED, NULL); |
737 | 739 |
738 net_log_.AddEvent( | 740 net_log_.AddEvent( |
739 NetLog::TYPE_DNS_TRANSACTION_ATTEMPT, | 741 NetLogEventType::DNS_TRANSACTION_ATTEMPT, |
740 attempt->GetSocketNetLog().source().ToEventParametersCallback()); | 742 attempt->GetSocketNetLog().source().ToEventParametersCallback()); |
741 | 743 |
742 int rv = attempt->Start( | 744 int rv = attempt->Start( |
743 base::Bind(&DnsTransactionImpl::OnUdpAttemptComplete, | 745 base::Bind(&DnsTransactionImpl::OnUdpAttemptComplete, |
744 base::Unretained(this), attempt_number, | 746 base::Unretained(this), attempt_number, |
745 base::TimeTicks::Now())); | 747 base::TimeTicks::Now())); |
746 if (rv == ERR_IO_PENDING) { | 748 if (rv == ERR_IO_PENDING) { |
747 base::TimeDelta timeout = session_->NextTimeout(server_index, | 749 base::TimeDelta timeout = session_->NextTimeout(server_index, |
748 attempt_number); | 750 attempt_number); |
749 timer_.Start(FROM_HERE, timeout, this, &DnsTransactionImpl::OnTimeout); | 751 timer_.Start(FROM_HERE, timeout, this, &DnsTransactionImpl::OnTimeout); |
(...skipping 22 matching lines...) Expand all Loading... |
772 unsigned attempt_number = attempts_.size(); | 774 unsigned attempt_number = attempts_.size(); |
773 | 775 |
774 DnsTCPAttempt* attempt = | 776 DnsTCPAttempt* attempt = |
775 new DnsTCPAttempt(server_index, std::move(socket), std::move(query)); | 777 new DnsTCPAttempt(server_index, std::move(socket), std::move(query)); |
776 | 778 |
777 attempts_.push_back(base::WrapUnique(attempt)); | 779 attempts_.push_back(base::WrapUnique(attempt)); |
778 ++attempts_count_; | 780 ++attempts_count_; |
779 had_tcp_attempt_ = true; | 781 had_tcp_attempt_ = true; |
780 | 782 |
781 net_log_.AddEvent( | 783 net_log_.AddEvent( |
782 NetLog::TYPE_DNS_TRANSACTION_TCP_ATTEMPT, | 784 NetLogEventType::DNS_TRANSACTION_TCP_ATTEMPT, |
783 attempt->GetSocketNetLog().source().ToEventParametersCallback()); | 785 attempt->GetSocketNetLog().source().ToEventParametersCallback()); |
784 | 786 |
785 int rv = attempt->Start(base::Bind(&DnsTransactionImpl::OnAttemptComplete, | 787 int rv = attempt->Start(base::Bind(&DnsTransactionImpl::OnAttemptComplete, |
786 base::Unretained(this), | 788 base::Unretained(this), |
787 attempt_number)); | 789 attempt_number)); |
788 if (rv == ERR_IO_PENDING) { | 790 if (rv == ERR_IO_PENDING) { |
789 // Custom timeout for TCP attempt. | 791 // Custom timeout for TCP attempt. |
790 base::TimeDelta timeout = timer_.GetCurrentDelay() * 2; | 792 base::TimeDelta timeout = timer_.GetCurrentDelay() * 2; |
791 timer_.Start(FROM_HERE, timeout, this, &DnsTransactionImpl::OnTimeout); | 793 timer_.Start(FROM_HERE, timeout, this, &DnsTransactionImpl::OnTimeout); |
792 } | 794 } |
793 return AttemptResult(rv, attempt); | 795 return AttemptResult(rv, attempt); |
794 } | 796 } |
795 | 797 |
796 // Begins query for the current name. Makes the first attempt. | 798 // Begins query for the current name. Makes the first attempt. |
797 AttemptResult StartQuery() { | 799 AttemptResult StartQuery() { |
798 std::string dotted_qname = DNSDomainToString(qnames_.front()); | 800 std::string dotted_qname = DNSDomainToString(qnames_.front()); |
799 net_log_.BeginEvent(NetLog::TYPE_DNS_TRANSACTION_QUERY, | 801 net_log_.BeginEvent(NetLogEventType::DNS_TRANSACTION_QUERY, |
800 NetLog::StringCallback("qname", &dotted_qname)); | 802 NetLog::StringCallback("qname", &dotted_qname)); |
801 | 803 |
802 first_server_index_ = session_->NextFirstServerIndex(); | 804 first_server_index_ = session_->NextFirstServerIndex(); |
803 RecordLostPacketsIfAny(); | 805 RecordLostPacketsIfAny(); |
804 attempts_.clear(); | 806 attempts_.clear(); |
805 had_tcp_attempt_ = false; | 807 had_tcp_attempt_ = false; |
806 return MakeAttempt(); | 808 return MakeAttempt(); |
807 } | 809 } |
808 | 810 |
809 void OnUdpAttemptComplete(unsigned attempt_number, | 811 void OnUdpAttemptComplete(unsigned attempt_number, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 int server_attempt = server_attempts[server_index]++; | 851 int server_attempt = server_attempts[server_index]++; |
850 // Don't record lost packet unless attempt is in pending state. | 852 // Don't record lost packet unless attempt is in pending state. |
851 if (!attempts_[i]->is_pending()) | 853 if (!attempts_[i]->is_pending()) |
852 continue; | 854 continue; |
853 session_->RecordLostPacket(server_index, server_attempt); | 855 session_->RecordLostPacket(server_index, server_attempt); |
854 } | 856 } |
855 } | 857 } |
856 | 858 |
857 void LogResponse(const DnsAttempt* attempt) { | 859 void LogResponse(const DnsAttempt* attempt) { |
858 if (attempt && attempt->GetResponse()) { | 860 if (attempt && attempt->GetResponse()) { |
859 net_log_.AddEvent( | 861 net_log_.AddEvent(NetLogEventType::DNS_TRANSACTION_RESPONSE, |
860 NetLog::TYPE_DNS_TRANSACTION_RESPONSE, | 862 base::Bind(&DnsAttempt::NetLogResponseCallback, |
861 base::Bind(&DnsAttempt::NetLogResponseCallback, | 863 base::Unretained(attempt))); |
862 base::Unretained(attempt))); | |
863 } | 864 } |
864 } | 865 } |
865 | 866 |
866 bool MoreAttemptsAllowed() const { | 867 bool MoreAttemptsAllowed() const { |
867 if (had_tcp_attempt_) | 868 if (had_tcp_attempt_) |
868 return false; | 869 return false; |
869 const DnsConfig& config = session_->config(); | 870 const DnsConfig& config = session_->config(); |
870 return attempts_.size() < config.attempts * config.nameservers.size(); | 871 return attempts_.size() < config.attempts * config.nameservers.size(); |
871 } | 872 } |
872 | 873 |
873 // Resolves the result of a DnsAttempt until a terminal result is reached | 874 // Resolves the result of a DnsAttempt until a terminal result is reached |
874 // or it will complete asynchronously (ERR_IO_PENDING). | 875 // or it will complete asynchronously (ERR_IO_PENDING). |
875 AttemptResult ProcessAttemptResult(AttemptResult result) { | 876 AttemptResult ProcessAttemptResult(AttemptResult result) { |
876 while (result.rv != ERR_IO_PENDING) { | 877 while (result.rv != ERR_IO_PENDING) { |
877 LogResponse(result.attempt); | 878 LogResponse(result.attempt); |
878 | 879 |
879 switch (result.rv) { | 880 switch (result.rv) { |
880 case OK: | 881 case OK: |
881 session_->RecordServerSuccess(result.attempt->server_index()); | 882 session_->RecordServerSuccess(result.attempt->server_index()); |
882 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION_QUERY, | 883 net_log_.EndEventWithNetErrorCode( |
883 result.rv); | 884 NetLogEventType::DNS_TRANSACTION_QUERY, result.rv); |
884 DCHECK(result.attempt); | 885 DCHECK(result.attempt); |
885 DCHECK(result.attempt->GetResponse()); | 886 DCHECK(result.attempt->GetResponse()); |
886 return result; | 887 return result; |
887 case ERR_NAME_NOT_RESOLVED: | 888 case ERR_NAME_NOT_RESOLVED: |
888 session_->RecordServerSuccess(result.attempt->server_index()); | 889 session_->RecordServerSuccess(result.attempt->server_index()); |
889 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_DNS_TRANSACTION_QUERY, | 890 net_log_.EndEventWithNetErrorCode( |
890 result.rv); | 891 NetLogEventType::DNS_TRANSACTION_QUERY, result.rv); |
891 // Try next suffix. | 892 // Try next suffix. |
892 qnames_.pop_front(); | 893 qnames_.pop_front(); |
893 if (qnames_.empty()) { | 894 if (qnames_.empty()) { |
894 return AttemptResult(ERR_NAME_NOT_RESOLVED, NULL); | 895 return AttemptResult(ERR_NAME_NOT_RESOLVED, NULL); |
895 } else { | 896 } else { |
896 result = StartQuery(); | 897 result = StartQuery(); |
897 } | 898 } |
898 break; | 899 break; |
899 case ERR_CONNECTION_REFUSED: | 900 case ERR_CONNECTION_REFUSED: |
900 case ERR_DNS_TIMED_OUT: | 901 case ERR_DNS_TIMED_OUT: |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
995 } // namespace | 996 } // namespace |
996 | 997 |
997 // static | 998 // static |
998 std::unique_ptr<DnsTransactionFactory> DnsTransactionFactory::CreateFactory( | 999 std::unique_ptr<DnsTransactionFactory> DnsTransactionFactory::CreateFactory( |
999 DnsSession* session) { | 1000 DnsSession* session) { |
1000 return std::unique_ptr<DnsTransactionFactory>( | 1001 return std::unique_ptr<DnsTransactionFactory>( |
1001 new DnsTransactionFactoryImpl(session)); | 1002 new DnsTransactionFactoryImpl(session)); |
1002 } | 1003 } |
1003 | 1004 |
1004 } // namespace net | 1005 } // namespace net |
OLD | NEW |