| 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 |