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_session.h" | 5 #include "net/quic/quic_session.h" |
6 | 6 |
7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
8 #include "net/quic/crypto/proof_verifier.h" | 8 #include "net/quic/crypto/proof_verifier.h" |
9 #include "net/quic/quic_connection.h" | 9 #include "net/quic/quic_connection.h" |
10 #include "net/quic/quic_flow_controller.h" | 10 #include "net/quic/quic_flow_controller.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 }; | 97 }; |
98 | 98 |
99 QuicSession::QuicSession(QuicConnection* connection, const QuicConfig& config) | 99 QuicSession::QuicSession(QuicConnection* connection, const QuicConfig& config) |
100 : connection_(connection), | 100 : connection_(connection), |
101 visitor_shim_(new VisitorShim(this)), | 101 visitor_shim_(new VisitorShim(this)), |
102 config_(config), | 102 config_(config), |
103 max_open_streams_(config_.MaxStreamsPerConnection()), | 103 max_open_streams_(config_.MaxStreamsPerConnection()), |
104 next_stream_id_(is_server() ? 2 : 5), | 104 next_stream_id_(is_server() ? 2 : 5), |
105 largest_peer_created_stream_id_(0), | 105 largest_peer_created_stream_id_(0), |
106 error_(QUIC_NO_ERROR), | 106 error_(QUIC_NO_ERROR), |
| 107 flow_controller_(new QuicFlowController( |
| 108 connection_.get(), |
| 109 0, |
| 110 is_server(), |
| 111 kMinimumFlowControlSendWindow, |
| 112 config_.GetInitialSessionFlowControlWindowToSend(), |
| 113 config_.GetInitialSessionFlowControlWindowToSend())), |
107 goaway_received_(false), | 114 goaway_received_(false), |
108 goaway_sent_(false), | 115 goaway_sent_(false), |
109 has_pending_handshake_(false) { | 116 has_pending_handshake_(false) { |
110 if (connection_->version() == QUIC_VERSION_19) { | |
111 flow_controller_.reset(new QuicFlowController( | |
112 connection_.get(), 0, is_server(), kMinimumFlowControlSendWindow, | |
113 config_.GetInitialFlowControlWindowToSend(), | |
114 config_.GetInitialFlowControlWindowToSend())); | |
115 } else { | |
116 flow_controller_.reset(new QuicFlowController( | |
117 connection_.get(), 0, is_server(), kMinimumFlowControlSendWindow, | |
118 config_.GetInitialSessionFlowControlWindowToSend(), | |
119 config_.GetInitialSessionFlowControlWindowToSend())); | |
120 } | |
121 } | 117 } |
122 | 118 |
123 void QuicSession::InitializeSession() { | 119 void QuicSession::InitializeSession() { |
124 connection_->set_visitor(visitor_shim_.get()); | 120 connection_->set_visitor(visitor_shim_.get()); |
125 connection_->SetFromConfig(config_); | 121 connection_->SetFromConfig(config_); |
126 headers_stream_.reset(new QuicHeadersStream(this)); | 122 headers_stream_.reset(new QuicHeadersStream(this)); |
127 } | 123 } |
128 | 124 |
129 QuicSession::~QuicSession() { | 125 QuicSession::~QuicSession() { |
130 STLDeleteElements(&closed_streams_); | 126 STLDeleteElements(&closed_streams_); |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 bool QuicSession::IsEncryptionEstablished() { | 453 bool QuicSession::IsEncryptionEstablished() { |
458 return GetCryptoStream()->encryption_established(); | 454 return GetCryptoStream()->encryption_established(); |
459 } | 455 } |
460 | 456 |
461 bool QuicSession::IsCryptoHandshakeConfirmed() { | 457 bool QuicSession::IsCryptoHandshakeConfirmed() { |
462 return GetCryptoStream()->handshake_confirmed(); | 458 return GetCryptoStream()->handshake_confirmed(); |
463 } | 459 } |
464 | 460 |
465 void QuicSession::OnConfigNegotiated() { | 461 void QuicSession::OnConfigNegotiated() { |
466 connection_->SetFromConfig(config_); | 462 connection_->SetFromConfig(config_); |
467 QuicVersion version = connection()->version(); | |
468 | 463 |
469 uint32 max_streams = config_.MaxStreamsPerConnection(); | 464 uint32 max_streams = config_.MaxStreamsPerConnection(); |
470 if (is_server()) { | 465 if (is_server()) { |
471 // A server should accept a small number of additional streams beyond the | 466 // A server should accept a small number of additional streams beyond the |
472 // limit sent to the client. This helps avoid early connection termination | 467 // limit sent to the client. This helps avoid early connection termination |
473 // when FIN/RSTs for old streams are lost or arrive out of order. | 468 // when FIN/RSTs for old streams are lost or arrive out of order. |
474 // Use a minimum number of additional streams, or a percentage increase, | 469 // Use a minimum number of additional streams, or a percentage increase, |
475 // whichever is larger. | 470 // whichever is larger. |
476 max_streams = | 471 max_streams = |
477 max(max_streams + kMaxStreamsMinimumIncrement, | 472 max(max_streams + kMaxStreamsMinimumIncrement, |
478 static_cast<uint32>(max_streams * kMaxStreamsMultiplier)); | 473 static_cast<uint32>(max_streams * kMaxStreamsMultiplier)); |
479 } | 474 } |
480 set_max_open_streams(max_streams); | 475 set_max_open_streams(max_streams); |
481 | 476 |
482 if (version == QUIC_VERSION_19) { | |
483 // QUIC_VERSION_19 doesn't support independent stream/session flow | |
484 // control windows. | |
485 if (config_.HasReceivedInitialFlowControlWindowBytes()) { | |
486 // Streams which were created before the SHLO was received (0-RTT | |
487 // requests) are now informed of the peer's initial flow control window. | |
488 QuicStreamOffset new_window = | |
489 config_.ReceivedInitialFlowControlWindowBytes(); | |
490 OnNewStreamFlowControlWindow(new_window); | |
491 OnNewSessionFlowControlWindow(new_window); | |
492 } | |
493 | |
494 return; | |
495 } | |
496 | |
497 // QUIC_VERSION_21 and higher can have independent stream and session flow | |
498 // control windows. | |
499 if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) { | 477 if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) { |
500 // Streams which were created before the SHLO was received (0-RTT | 478 // Streams which were created before the SHLO was received (0-RTT |
501 // requests) are now informed of the peer's initial flow control window. | 479 // requests) are now informed of the peer's initial flow control window. |
502 OnNewStreamFlowControlWindow( | 480 OnNewStreamFlowControlWindow( |
503 config_.ReceivedInitialStreamFlowControlWindowBytes()); | 481 config_.ReceivedInitialStreamFlowControlWindowBytes()); |
504 } | 482 } |
505 if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) { | 483 if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) { |
506 OnNewSessionFlowControlWindow( | 484 OnNewSessionFlowControlWindow( |
507 config_.ReceivedInitialSessionFlowControlWindowBytes()); | 485 config_.ReceivedInitialSessionFlowControlWindowBytes()); |
508 } | 486 } |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 connection_->HasQueuedData(); | 719 connection_->HasQueuedData(); |
742 } | 720 } |
743 | 721 |
744 bool QuicSession::GetSSLInfo(SSLInfo* ssl_info) const { | 722 bool QuicSession::GetSSLInfo(SSLInfo* ssl_info) const { |
745 NOTIMPLEMENTED(); | 723 NOTIMPLEMENTED(); |
746 return false; | 724 return false; |
747 } | 725 } |
748 | 726 |
749 void QuicSession::PostProcessAfterData() { | 727 void QuicSession::PostProcessAfterData() { |
750 STLDeleteElements(&closed_streams_); | 728 STLDeleteElements(&closed_streams_); |
751 closed_streams_.clear(); | |
752 | 729 |
753 if (connection()->connected() && | 730 if (connection()->connected() && |
754 locally_closed_streams_highest_offset_.size() > max_open_streams_) { | 731 locally_closed_streams_highest_offset_.size() > max_open_streams_) { |
755 // A buggy client may fail to send FIN/RSTs. Don't tolerate this. | 732 // A buggy client may fail to send FIN/RSTs. Don't tolerate this. |
756 connection_->SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS); | 733 connection_->SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS); |
757 } | 734 } |
758 } | 735 } |
759 | 736 |
760 void QuicSession::OnSuccessfulVersionNegotiation(const QuicVersion& version) { | |
761 // Disable stream level flow control based on negotiated version. Streams may | |
762 // have been created with a different version. | |
763 if (version < QUIC_VERSION_21) { | |
764 GetCryptoStream()->flow_controller()->Disable(); | |
765 headers_stream_->flow_controller()->Disable(); | |
766 } | |
767 } | |
768 | |
769 bool QuicSession::IsConnectionFlowControlBlocked() const { | 737 bool QuicSession::IsConnectionFlowControlBlocked() const { |
770 return flow_controller_->IsBlocked(); | 738 return flow_controller_->IsBlocked(); |
771 } | 739 } |
772 | 740 |
773 bool QuicSession::IsStreamFlowControlBlocked() { | 741 bool QuicSession::IsStreamFlowControlBlocked() { |
774 if (headers_stream_->flow_controller()->IsBlocked() || | 742 if (headers_stream_->flow_controller()->IsBlocked() || |
775 GetCryptoStream()->flow_controller()->IsBlocked()) { | 743 GetCryptoStream()->flow_controller()->IsBlocked()) { |
776 return true; | 744 return true; |
777 } | 745 } |
778 for (DataStreamMap::iterator it = stream_map_.begin(); | 746 for (DataStreamMap::iterator it = stream_map_.begin(); |
779 it != stream_map_.end(); ++it) { | 747 it != stream_map_.end(); ++it) { |
780 if (it->second->flow_controller()->IsBlocked()) { | 748 if (it->second->flow_controller()->IsBlocked()) { |
781 return true; | 749 return true; |
782 } | 750 } |
783 } | 751 } |
784 return false; | 752 return false; |
785 } | 753 } |
786 | 754 |
787 } // namespace net | 755 } // namespace net |
OLD | NEW |