| 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/quic/quic_chromium_client_session.h" | 5 #include "net/quic/quic_chromium_client_session.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 | 35 |
| 36 namespace { | 36 namespace { |
| 37 | 37 |
| 38 // The length of time to wait for a 0-RTT handshake to complete | 38 // The length of time to wait for a 0-RTT handshake to complete |
| 39 // before allowing the requests to possibly proceed over TCP. | 39 // before allowing the requests to possibly proceed over TCP. |
| 40 const int k0RttHandshakeTimeoutMs = 300; | 40 const int k0RttHandshakeTimeoutMs = 300; |
| 41 | 41 |
| 42 // IPv6 packets have an additional 20 bytes of overhead than IPv4 packets. | 42 // IPv6 packets have an additional 20 bytes of overhead than IPv4 packets. |
| 43 const size_t kAdditionalOverheadForIPv6 = 20; | 43 const size_t kAdditionalOverheadForIPv6 = 20; |
| 44 | 44 |
| 45 // Maximum number of Readers that are created for any session due to |
| 46 // connection migration. A new Reader is created every time this endpoint's |
| 47 // IP address changes. |
| 48 const size_t kMaxReadersPerQuicSession = 5; |
| 49 |
| 45 // Histograms for tracking down the crashes from http://crbug.com/354669 | 50 // Histograms for tracking down the crashes from http://crbug.com/354669 |
| 46 // Note: these values must be kept in sync with the corresponding values in: | 51 // Note: these values must be kept in sync with the corresponding values in: |
| 47 // tools/metrics/histograms/histograms.xml | 52 // tools/metrics/histograms/histograms.xml |
| 48 enum Location { | 53 enum Location { |
| 49 DESTRUCTOR = 0, | 54 DESTRUCTOR = 0, |
| 50 ADD_OBSERVER = 1, | 55 ADD_OBSERVER = 1, |
| 51 TRY_CREATE_STREAM = 2, | 56 TRY_CREATE_STREAM = 2, |
| 52 CREATE_OUTGOING_RELIABLE_STREAM = 3, | 57 CREATE_OUTGOING_RELIABLE_STREAM = 3, |
| 53 NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER = 4, | 58 NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER = 4, |
| 54 NOTIFY_FACTORY_OF_SESSION_CLOSED = 5, | 59 NOTIFY_FACTORY_OF_SESSION_CLOSED = 5, |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 QuicCryptoClientConfig* crypto_config, | 178 QuicCryptoClientConfig* crypto_config, |
| 174 const char* const connection_description, | 179 const char* const connection_description, |
| 175 base::TimeTicks dns_resolution_end_time, | 180 base::TimeTicks dns_resolution_end_time, |
| 176 base::TaskRunner* task_runner, | 181 base::TaskRunner* task_runner, |
| 177 scoped_ptr<SocketPerformanceWatcher> socket_performance_watcher, | 182 scoped_ptr<SocketPerformanceWatcher> socket_performance_watcher, |
| 178 NetLog* net_log) | 183 NetLog* net_log) |
| 179 : QuicClientSessionBase(connection, config), | 184 : QuicClientSessionBase(connection, config), |
| 180 server_id_(server_id), | 185 server_id_(server_id), |
| 181 require_confirmation_(false), | 186 require_confirmation_(false), |
| 182 stream_factory_(stream_factory), | 187 stream_factory_(stream_factory), |
| 183 socket_(std::move(socket)), | |
| 184 transport_security_state_(transport_security_state), | 188 transport_security_state_(transport_security_state), |
| 185 server_info_(std::move(server_info)), | 189 server_info_(std::move(server_info)), |
| 186 num_total_streams_(0), | 190 num_total_streams_(0), |
| 187 task_runner_(task_runner), | 191 task_runner_(task_runner), |
| 188 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_QUIC_SESSION)), | 192 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_QUIC_SESSION)), |
| 189 packet_reader_(socket_.get(), | |
| 190 clock, | |
| 191 this, | |
| 192 yield_after_packets, | |
| 193 yield_after_duration, | |
| 194 net_log_), | |
| 195 dns_resolution_end_time_(dns_resolution_end_time), | 193 dns_resolution_end_time_(dns_resolution_end_time), |
| 196 logger_(new QuicConnectionLogger(this, | 194 logger_(new QuicConnectionLogger(this, |
| 197 connection_description, | 195 connection_description, |
| 198 std::move(socket_performance_watcher), | 196 std::move(socket_performance_watcher), |
| 199 net_log_)), | 197 net_log_)), |
| 200 going_away_(false), | 198 going_away_(false), |
| 201 disabled_reason_(QUIC_DISABLED_NOT), | 199 disabled_reason_(QUIC_DISABLED_NOT), |
| 202 weak_factory_(this) { | 200 weak_factory_(this) { |
| 201 sockets_.push_back(std::move(socket)); |
| 202 packet_readers_.push_back(make_scoped_ptr(new QuicPacketReader( |
| 203 sockets_.back().get(), clock, this, yield_after_packets, |
| 204 yield_after_duration, net_log_))); |
| 203 crypto_stream_.reset( | 205 crypto_stream_.reset( |
| 204 crypto_client_stream_factory->CreateQuicCryptoClientStream( | 206 crypto_client_stream_factory->CreateQuicCryptoClientStream( |
| 205 server_id, this, make_scoped_ptr(new ProofVerifyContextChromium( | 207 server_id, this, make_scoped_ptr(new ProofVerifyContextChromium( |
| 206 cert_verify_flags, net_log_)), | 208 cert_verify_flags, net_log_)), |
| 207 crypto_config)); | 209 crypto_config)); |
| 208 connection->set_debug_visitor(logger_.get()); | 210 connection->set_debug_visitor(logger_.get()); |
| 209 net_log_.BeginEvent(NetLog::TYPE_QUIC_SESSION, | 211 net_log_.BeginEvent(NetLog::TYPE_QUIC_SESSION, |
| 210 base::Bind(NetLogQuicClientSessionCallback, &server_id, | 212 base::Bind(NetLogQuicClientSessionCallback, &server_id, |
| 211 cert_verify_flags, require_confirmation_)); | 213 cert_verify_flags, require_confirmation_)); |
| 212 IPEndPoint address; | 214 IPEndPoint address; |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 } else if (error == QUIC_PUBLIC_RESET) { | 768 } else if (error == QUIC_PUBLIC_RESET) { |
| 767 disabled_reason_ = QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE; | 769 disabled_reason_ = QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE; |
| 768 } | 770 } |
| 769 | 771 |
| 770 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.QuicVersion", | 772 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.QuicVersion", |
| 771 connection()->version()); | 773 connection()->version()); |
| 772 NotifyFactoryOfSessionGoingAway(); | 774 NotifyFactoryOfSessionGoingAway(); |
| 773 if (!callback_.is_null()) { | 775 if (!callback_.is_null()) { |
| 774 base::ResetAndReturn(&callback_).Run(ERR_QUIC_PROTOCOL_ERROR); | 776 base::ResetAndReturn(&callback_).Run(ERR_QUIC_PROTOCOL_ERROR); |
| 775 } | 777 } |
| 776 socket_->Close(); | 778 |
| 779 for (auto& socket : sockets_) { |
| 780 socket->Close(); |
| 781 } |
| 777 QuicSession::OnConnectionClosed(error, from_peer); | 782 QuicSession::OnConnectionClosed(error, from_peer); |
| 778 DCHECK(dynamic_streams().empty()); | 783 DCHECK(dynamic_streams().empty()); |
| 779 CloseAllStreams(ERR_UNEXPECTED); | 784 CloseAllStreams(ERR_UNEXPECTED); |
| 780 CloseAllObservers(ERR_UNEXPECTED); | 785 CloseAllObservers(ERR_UNEXPECTED); |
| 781 NotifyFactoryOfSessionClosedLater(); | 786 NotifyFactoryOfSessionClosedLater(); |
| 782 } | 787 } |
| 783 | 788 |
| 784 void QuicChromiumClientSession::OnSuccessfulVersionNegotiation( | 789 void QuicChromiumClientSession::OnSuccessfulVersionNegotiation( |
| 785 const QuicVersion& version) { | 790 const QuicVersion& version) { |
| 786 logger_->OnSuccessfulVersionNegotiation(version); | 791 logger_->OnSuccessfulVersionNegotiation(version); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 812 cert_verify_result_.reset(new CertVerifyResult); | 817 cert_verify_result_.reset(new CertVerifyResult); |
| 813 cert_verify_result_->CopyFrom(verify_details_chromium->cert_verify_result); | 818 cert_verify_result_->CopyFrom(verify_details_chromium->cert_verify_result); |
| 814 pinning_failure_log_ = verify_details_chromium->pinning_failure_log; | 819 pinning_failure_log_ = verify_details_chromium->pinning_failure_log; |
| 815 scoped_ptr<ct::CTVerifyResult> ct_verify_result_copy( | 820 scoped_ptr<ct::CTVerifyResult> ct_verify_result_copy( |
| 816 new ct::CTVerifyResult(verify_details_chromium->ct_verify_result)); | 821 new ct::CTVerifyResult(verify_details_chromium->ct_verify_result)); |
| 817 ct_verify_result_ = std::move(ct_verify_result_copy); | 822 ct_verify_result_ = std::move(ct_verify_result_copy); |
| 818 logger_->OnCertificateVerified(*cert_verify_result_); | 823 logger_->OnCertificateVerified(*cert_verify_result_); |
| 819 } | 824 } |
| 820 | 825 |
| 821 void QuicChromiumClientSession::StartReading() { | 826 void QuicChromiumClientSession::StartReading() { |
| 822 packet_reader_.StartReading(); | 827 for (auto& packet_reader : packet_readers_) { |
| 828 packet_reader->StartReading(); |
| 829 } |
| 823 } | 830 } |
| 824 | 831 |
| 825 void QuicChromiumClientSession::CloseSessionOnError(int error, | 832 void QuicChromiumClientSession::CloseSessionOnError(int error, |
| 826 QuicErrorCode quic_error) { | 833 QuicErrorCode quic_error) { |
| 827 RecordAndCloseSessionOnError(error, quic_error); | 834 RecordAndCloseSessionOnError(error, quic_error); |
| 828 NotifyFactoryOfSessionClosed(); | 835 NotifyFactoryOfSessionClosed(); |
| 829 } | 836 } |
| 830 | 837 |
| 831 void QuicChromiumClientSession::CloseSessionOnErrorAndNotifyFactoryLater( | 838 void QuicChromiumClientSession::CloseSessionOnErrorAndNotifyFactoryLater( |
| 832 int error, | 839 int error, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 } | 918 } |
| 912 | 919 |
| 913 base::WeakPtr<QuicChromiumClientSession> | 920 base::WeakPtr<QuicChromiumClientSession> |
| 914 QuicChromiumClientSession::GetWeakPtr() { | 921 QuicChromiumClientSession::GetWeakPtr() { |
| 915 return weak_factory_.GetWeakPtr(); | 922 return weak_factory_.GetWeakPtr(); |
| 916 } | 923 } |
| 917 | 924 |
| 918 void QuicChromiumClientSession::OnReadError( | 925 void QuicChromiumClientSession::OnReadError( |
| 919 int result, | 926 int result, |
| 920 const DatagramClientSocket* socket) { | 927 const DatagramClientSocket* socket) { |
| 928 DCHECK(socket != nullptr); |
| 929 if (socket != GetDefaultSocket()) { |
| 930 // Ignore read errors from old sockets that are no longer active. |
| 931 // TODO(jri): Maybe clean up old sockets on error. |
| 932 return; |
| 933 } |
| 921 DVLOG(1) << "Closing session on read error: " << result; | 934 DVLOG(1) << "Closing session on read error: " << result; |
| 922 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.ReadError", -result); | 935 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.ReadError", -result); |
| 923 NotifyFactoryOfSessionGoingAway(); | 936 NotifyFactoryOfSessionGoingAway(); |
| 924 CloseSessionOnErrorInner(result, QUIC_PACKET_READ_ERROR); | 937 CloseSessionOnErrorInner(result, QUIC_PACKET_READ_ERROR); |
| 925 NotifyFactoryOfSessionClosedLater(); | 938 NotifyFactoryOfSessionClosedLater(); |
| 926 } | 939 } |
| 927 | 940 |
| 928 bool QuicChromiumClientSession::OnPacket(const QuicEncryptedPacket& packet, | 941 bool QuicChromiumClientSession::OnPacket(const QuicEncryptedPacket& packet, |
| 929 IPEndPoint local_address, | 942 IPEndPoint local_address, |
| 930 IPEndPoint peer_address) { | 943 IPEndPoint peer_address) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 979 if (IsCryptoHandshakeConfirmed()) | 992 if (IsCryptoHandshakeConfirmed()) |
| 980 return; | 993 return; |
| 981 | 994 |
| 982 // TODO(rch): re-enable this code once beta is cut. | 995 // TODO(rch): re-enable this code once beta is cut. |
| 983 // if (stream_factory_) | 996 // if (stream_factory_) |
| 984 // stream_factory_->OnSessionConnectTimeout(this); | 997 // stream_factory_->OnSessionConnectTimeout(this); |
| 985 // CloseAllStreams(ERR_QUIC_HANDSHAKE_FAILED); | 998 // CloseAllStreams(ERR_QUIC_HANDSHAKE_FAILED); |
| 986 // DCHECK_EQ(0u, GetNumOpenOutgoingStreams()); | 999 // DCHECK_EQ(0u, GetNumOpenOutgoingStreams()); |
| 987 } | 1000 } |
| 988 | 1001 |
| 1002 bool QuicChromiumClientSession::MigrateToSocket( |
| 1003 scoped_ptr<DatagramClientSocket> socket, |
| 1004 scoped_ptr<QuicPacketReader> reader, |
| 1005 scoped_ptr<QuicPacketWriter> writer) { |
| 1006 DCHECK_EQ(sockets_.size(), packet_readers_.size()); |
| 1007 if (sockets_.size() >= kMaxReadersPerQuicSession) { |
| 1008 return false; |
| 1009 } |
| 1010 // TODO(jri): Make SetQuicPacketWriter take a scoped_ptr. |
| 1011 connection()->SetQuicPacketWriter(writer.release(), /*owns_writer=*/true); |
| 1012 packet_readers_.push_back(std::move(reader)); |
| 1013 sockets_.push_back(std::move(socket)); |
| 1014 StartReading(); |
| 1015 connection()->SendPing(/*force=*/true); |
| 1016 return true; |
| 1017 } |
| 1018 |
| 1019 const DatagramClientSocket* QuicChromiumClientSession::GetDefaultSocket() |
| 1020 const { |
| 1021 DCHECK(sockets_.back().get() != nullptr); |
| 1022 // The most recently added socket is the currently active one. |
| 1023 return sockets_.back().get(); |
| 1024 } |
| 1025 |
| 989 } // namespace net | 1026 } // namespace net |
| OLD | NEW |