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 |