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_client_session.h" | 5 #include "net/quic/quic_client_session.h" |
6 | 6 |
7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
8 #include "base/location.h" | 8 #include "base/location.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/metrics/sparse_histogram.h" | 10 #include "base/metrics/sparse_histogram.h" |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 require_confirmation_)); | 196 require_confirmation_)); |
197 IPEndPoint address; | 197 IPEndPoint address; |
198 if (socket && socket->GetLocalAddress(&address) == OK && | 198 if (socket && socket->GetLocalAddress(&address) == OK && |
199 address.GetFamily() == ADDRESS_FAMILY_IPV6) { | 199 address.GetFamily() == ADDRESS_FAMILY_IPV6) { |
200 connection->set_max_packet_length(connection->max_packet_length() - | 200 connection->set_max_packet_length(connection->max_packet_length() - |
201 kAdditionalOverheadForIPv6); | 201 kAdditionalOverheadForIPv6); |
202 } | 202 } |
203 } | 203 } |
204 | 204 |
205 QuicClientSession::~QuicClientSession() { | 205 QuicClientSession::~QuicClientSession() { |
206 if (!streams()->empty()) | 206 if (!dynamic_streams().empty()) |
207 RecordUnexpectedOpenStreams(DESTRUCTOR); | 207 RecordUnexpectedOpenStreams(DESTRUCTOR); |
208 if (!observers_.empty()) | 208 if (!observers_.empty()) |
209 RecordUnexpectedObservers(DESTRUCTOR); | 209 RecordUnexpectedObservers(DESTRUCTOR); |
210 if (!going_away_) | 210 if (!going_away_) |
211 RecordUnexpectedNotGoingAway(DESTRUCTOR); | 211 RecordUnexpectedNotGoingAway(DESTRUCTOR); |
212 | 212 |
213 while (!streams()->empty() || | 213 while (!dynamic_streams().empty() || !observers_.empty() || |
214 !observers_.empty() || | |
215 !stream_requests_.empty()) { | 214 !stream_requests_.empty()) { |
216 // The session must be closed before it is destroyed. | 215 // The session must be closed before it is destroyed. |
217 DCHECK(streams()->empty()); | 216 DCHECK(dynamic_streams().empty()); |
218 CloseAllStreams(ERR_UNEXPECTED); | 217 CloseAllStreams(ERR_UNEXPECTED); |
219 DCHECK(observers_.empty()); | 218 DCHECK(observers_.empty()); |
220 CloseAllObservers(ERR_UNEXPECTED); | 219 CloseAllObservers(ERR_UNEXPECTED); |
221 | 220 |
222 connection()->set_debug_visitor(nullptr); | 221 connection()->set_debug_visitor(nullptr); |
223 net_log_.EndEvent(NetLog::TYPE_QUIC_SESSION); | 222 net_log_.EndEvent(NetLog::TYPE_QUIC_SESSION); |
224 | 223 |
225 while (!stream_requests_.empty()) { | 224 while (!stream_requests_.empty()) { |
226 StreamRequest* request = stream_requests_.front(); | 225 StreamRequest* request = stream_requests_.front(); |
227 stream_requests_.pop_front(); | 226 stream_requests_.pop_front(); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 void QuicClientSession::CancelRequest(StreamRequest* request) { | 392 void QuicClientSession::CancelRequest(StreamRequest* request) { |
394 // Remove |request| from the queue while preserving the order of the | 393 // Remove |request| from the queue while preserving the order of the |
395 // other elements. | 394 // other elements. |
396 StreamRequestQueue::iterator it = | 395 StreamRequestQueue::iterator it = |
397 std::find(stream_requests_.begin(), stream_requests_.end(), request); | 396 std::find(stream_requests_.begin(), stream_requests_.end(), request); |
398 if (it != stream_requests_.end()) { | 397 if (it != stream_requests_.end()) { |
399 it = stream_requests_.erase(it); | 398 it = stream_requests_.erase(it); |
400 } | 399 } |
401 } | 400 } |
402 | 401 |
403 QuicReliableClientStream* QuicClientSession::CreateOutgoingDataStream() { | 402 QuicReliableClientStream* QuicClientSession::CreateOutgoingDynamicStream() { |
404 if (!crypto_stream_->encryption_established()) { | 403 if (!crypto_stream_->encryption_established()) { |
405 DVLOG(1) << "Encryption not active so no outgoing stream created."; | 404 DVLOG(1) << "Encryption not active so no outgoing stream created."; |
406 return nullptr; | 405 return nullptr; |
407 } | 406 } |
408 if (GetNumOpenStreams() >= get_max_open_streams()) { | 407 if (GetNumOpenStreams() >= get_max_open_streams()) { |
409 DVLOG(1) << "Failed to create a new outgoing stream. " | 408 DVLOG(1) << "Failed to create a new outgoing stream. " |
410 << "Already " << GetNumOpenStreams() << " open."; | 409 << "Already " << GetNumOpenStreams() << " open."; |
411 return nullptr; | 410 return nullptr; |
412 } | 411 } |
413 if (goaway_received()) { | 412 if (goaway_received()) { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 SSLInfo ssl_info; | 544 SSLInfo ssl_info; |
546 if (!GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) { | 545 if (!GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) { |
547 // We can always pool with insecure QUIC sessions. | 546 // We can always pool with insecure QUIC sessions. |
548 return true; | 547 return true; |
549 } | 548 } |
550 | 549 |
551 return SpdySession::CanPool(transport_security_state_, ssl_info, | 550 return SpdySession::CanPool(transport_security_state_, ssl_info, |
552 server_id_.host(), hostname); | 551 server_id_.host(), hostname); |
553 } | 552 } |
554 | 553 |
555 QuicDataStream* QuicClientSession::CreateIncomingDataStream( | 554 QuicDataStream* QuicClientSession::CreateIncomingDynamicStream( |
556 QuicStreamId id) { | 555 QuicStreamId id) { |
557 DLOG(ERROR) << "Server push not supported"; | 556 DLOG(ERROR) << "Server push not supported"; |
558 return nullptr; | 557 return nullptr; |
559 } | 558 } |
560 | 559 |
561 void QuicClientSession::CloseStream(QuicStreamId stream_id) { | 560 void QuicClientSession::CloseStream(QuicStreamId stream_id) { |
562 ReliableQuicStream* stream = GetStream(stream_id); | 561 ReliableQuicStream* stream = GetStream(stream_id); |
563 if (stream) { | 562 if (stream) { |
564 logger_->UpdateReceivedFrameCounts( | 563 logger_->UpdateReceivedFrameCounts( |
565 stream_id, stream->num_frames_received(), | 564 stream_id, stream->num_frames_received(), |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 } | 722 } |
724 | 723 |
725 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.QuicVersion", | 724 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.QuicVersion", |
726 connection()->version()); | 725 connection()->version()); |
727 NotifyFactoryOfSessionGoingAway(); | 726 NotifyFactoryOfSessionGoingAway(); |
728 if (!callback_.is_null()) { | 727 if (!callback_.is_null()) { |
729 base::ResetAndReturn(&callback_).Run(ERR_QUIC_PROTOCOL_ERROR); | 728 base::ResetAndReturn(&callback_).Run(ERR_QUIC_PROTOCOL_ERROR); |
730 } | 729 } |
731 socket_->Close(); | 730 socket_->Close(); |
732 QuicSession::OnConnectionClosed(error, from_peer); | 731 QuicSession::OnConnectionClosed(error, from_peer); |
733 DCHECK(streams()->empty()); | 732 DCHECK(dynamic_streams().empty()); |
734 CloseAllStreams(ERR_UNEXPECTED); | 733 CloseAllStreams(ERR_UNEXPECTED); |
735 CloseAllObservers(ERR_UNEXPECTED); | 734 CloseAllObservers(ERR_UNEXPECTED); |
736 NotifyFactoryOfSessionClosedLater(); | 735 NotifyFactoryOfSessionClosedLater(); |
737 } | 736 } |
738 | 737 |
739 void QuicClientSession::OnSuccessfulVersionNegotiation( | 738 void QuicClientSession::OnSuccessfulVersionNegotiation( |
740 const QuicVersion& version) { | 739 const QuicVersion& version) { |
741 logger_->OnSuccessfulVersionNegotiation(version); | 740 logger_->OnSuccessfulVersionNegotiation(version); |
742 QuicSession::OnSuccessfulVersionNegotiation(version); | 741 QuicSession::OnSuccessfulVersionNegotiation(version); |
743 } | 742 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 net_log_.AddEvent( | 803 net_log_.AddEvent( |
805 NetLog::TYPE_QUIC_SESSION_CLOSE_ON_ERROR, | 804 NetLog::TYPE_QUIC_SESSION_CLOSE_ON_ERROR, |
806 NetLog::IntegerCallback("net_error", net_error)); | 805 NetLog::IntegerCallback("net_error", net_error)); |
807 | 806 |
808 if (connection()->connected()) | 807 if (connection()->connected()) |
809 connection()->CloseConnection(quic_error, false); | 808 connection()->CloseConnection(quic_error, false); |
810 DCHECK(!connection()->connected()); | 809 DCHECK(!connection()->connected()); |
811 } | 810 } |
812 | 811 |
813 void QuicClientSession::CloseAllStreams(int net_error) { | 812 void QuicClientSession::CloseAllStreams(int net_error) { |
814 while (!streams()->empty()) { | 813 while (!dynamic_streams().empty()) { |
815 ReliableQuicStream* stream = streams()->begin()->second; | 814 ReliableQuicStream* stream = dynamic_streams().begin()->second; |
816 QuicStreamId id = stream->id(); | 815 QuicStreamId id = stream->id(); |
817 static_cast<QuicReliableClientStream*>(stream)->OnError(net_error); | 816 static_cast<QuicReliableClientStream*>(stream)->OnError(net_error); |
818 CloseStream(id); | 817 CloseStream(id); |
819 } | 818 } |
820 } | 819 } |
821 | 820 |
822 void QuicClientSession::CloseAllObservers(int net_error) { | 821 void QuicClientSession::CloseAllObservers(int net_error) { |
823 while (!observers_.empty()) { | 822 while (!observers_.empty()) { |
824 Observer* observer = *observers_.begin(); | 823 Observer* observer = *observers_.begin(); |
825 observers_.erase(observer); | 824 observers_.erase(observer); |
826 observer->OnSessionClosed(net_error); | 825 observer->OnSessionClosed(net_error); |
827 } | 826 } |
828 } | 827 } |
829 | 828 |
830 scoped_ptr<base::Value> QuicClientSession::GetInfoAsValue( | 829 scoped_ptr<base::Value> QuicClientSession::GetInfoAsValue( |
831 const std::set<HostPortPair>& aliases) { | 830 const std::set<HostPortPair>& aliases) { |
832 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 831 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
833 dict->SetString("version", QuicVersionToString(connection()->version())); | 832 dict->SetString("version", QuicVersionToString(connection()->version())); |
834 dict->SetInteger("open_streams", GetNumOpenStreams()); | 833 dict->SetInteger("open_streams", GetNumOpenStreams()); |
835 scoped_ptr<base::ListValue> stream_list(new base::ListValue()); | 834 scoped_ptr<base::ListValue> stream_list(new base::ListValue()); |
836 for (base::hash_map<QuicStreamId, QuicDataStream*>::const_iterator it | 835 for (base::hash_map<QuicStreamId, ReliableQuicStream*>::const_iterator it = |
837 = streams()->begin(); | 836 dynamic_streams().begin(); |
838 it != streams()->end(); | 837 it != dynamic_streams().end(); ++it) { |
839 ++it) { | |
840 stream_list->Append(new base::StringValue( | 838 stream_list->Append(new base::StringValue( |
841 base::Uint64ToString(it->second->id()))); | 839 base::Uint64ToString(it->second->id()))); |
842 } | 840 } |
843 dict->Set("active_streams", stream_list.Pass()); | 841 dict->Set("active_streams", stream_list.Pass()); |
844 | 842 |
845 dict->SetInteger("total_streams", num_total_streams_); | 843 dict->SetInteger("total_streams", num_total_streams_); |
846 dict->SetString("peer_address", peer_address().ToString()); | 844 dict->SetString("peer_address", peer_address().ToString()); |
847 dict->SetString("connection_id", base::Uint64ToString(connection_id())); | 845 dict->SetString("connection_id", base::Uint64ToString(connection_id())); |
848 dict->SetBoolean("connected", connection()->connected()); | 846 dict->SetBoolean("connected", connection()->connected()); |
849 const QuicConnectionStats& stats = connection()->GetStats(); | 847 const QuicConnectionStats& stats = connection()->GetStats(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 return true; | 884 return true; |
887 } | 885 } |
888 | 886 |
889 void QuicClientSession::NotifyFactoryOfSessionGoingAway() { | 887 void QuicClientSession::NotifyFactoryOfSessionGoingAway() { |
890 going_away_ = true; | 888 going_away_ = true; |
891 if (stream_factory_) | 889 if (stream_factory_) |
892 stream_factory_->OnSessionGoingAway(this); | 890 stream_factory_->OnSessionGoingAway(this); |
893 } | 891 } |
894 | 892 |
895 void QuicClientSession::NotifyFactoryOfSessionClosedLater() { | 893 void QuicClientSession::NotifyFactoryOfSessionClosedLater() { |
896 if (!streams()->empty()) | 894 if (!dynamic_streams().empty()) |
897 RecordUnexpectedOpenStreams(NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER); | 895 RecordUnexpectedOpenStreams(NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER); |
898 | 896 |
899 if (!going_away_) | 897 if (!going_away_) |
900 RecordUnexpectedNotGoingAway(NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER); | 898 RecordUnexpectedNotGoingAway(NOTIFY_FACTORY_OF_SESSION_CLOSED_LATER); |
901 | 899 |
902 going_away_ = true; | 900 going_away_ = true; |
903 DCHECK_EQ(0u, GetNumOpenStreams()); | 901 DCHECK_EQ(0u, GetNumOpenStreams()); |
904 DCHECK(!connection()->connected()); | 902 DCHECK(!connection()->connected()); |
905 base::ThreadTaskRunnerHandle::Get()->PostTask( | 903 base::ThreadTaskRunnerHandle::Get()->PostTask( |
906 FROM_HERE, base::Bind(&QuicClientSession::NotifyFactoryOfSessionClosed, | 904 FROM_HERE, base::Bind(&QuicClientSession::NotifyFactoryOfSessionClosed, |
907 weak_factory_.GetWeakPtr())); | 905 weak_factory_.GetWeakPtr())); |
908 } | 906 } |
909 | 907 |
910 void QuicClientSession::NotifyFactoryOfSessionClosed() { | 908 void QuicClientSession::NotifyFactoryOfSessionClosed() { |
911 if (!streams()->empty()) | 909 if (!dynamic_streams().empty()) |
912 RecordUnexpectedOpenStreams(NOTIFY_FACTORY_OF_SESSION_CLOSED); | 910 RecordUnexpectedOpenStreams(NOTIFY_FACTORY_OF_SESSION_CLOSED); |
913 | 911 |
914 if (!going_away_) | 912 if (!going_away_) |
915 RecordUnexpectedNotGoingAway(NOTIFY_FACTORY_OF_SESSION_CLOSED); | 913 RecordUnexpectedNotGoingAway(NOTIFY_FACTORY_OF_SESSION_CLOSED); |
916 | 914 |
917 going_away_ = true; | 915 going_away_ = true; |
918 DCHECK_EQ(0u, GetNumOpenStreams()); | 916 DCHECK_EQ(0u, GetNumOpenStreams()); |
919 // Will delete |this|. | 917 // Will delete |this|. |
920 if (stream_factory_) | 918 if (stream_factory_) |
921 stream_factory_->OnSessionClosed(this); | 919 stream_factory_->OnSessionClosed(this); |
922 } | 920 } |
923 | 921 |
924 void QuicClientSession::OnConnectTimeout() { | 922 void QuicClientSession::OnConnectTimeout() { |
925 DCHECK(callback_.is_null()); | 923 DCHECK(callback_.is_null()); |
926 DCHECK(IsEncryptionEstablished()); | 924 DCHECK(IsEncryptionEstablished()); |
927 | 925 |
928 if (IsCryptoHandshakeConfirmed()) | 926 if (IsCryptoHandshakeConfirmed()) |
929 return; | 927 return; |
930 | 928 |
931 // TODO(rch): re-enable this code once beta is cut. | 929 // TODO(rch): re-enable this code once beta is cut. |
932 // if (stream_factory_) | 930 // if (stream_factory_) |
933 // stream_factory_->OnSessionConnectTimeout(this); | 931 // stream_factory_->OnSessionConnectTimeout(this); |
934 // CloseAllStreams(ERR_QUIC_HANDSHAKE_FAILED); | 932 // CloseAllStreams(ERR_QUIC_HANDSHAKE_FAILED); |
935 // DCHECK_EQ(0u, GetNumOpenStreams()); | 933 // DCHECK_EQ(0u, GetNumOpenStreams()); |
936 } | 934 } |
937 | 935 |
938 } // namespace net | 936 } // namespace net |
OLD | NEW |