Index: net/quic/quic_session.cc |
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc |
index d264cc1de6630e126c4eb2c29ac375aae1e88754..0f5be9c9dffd3b3f625dc6ee06dd45acbf6b70e7 100644 |
--- a/net/quic/quic_session.cc |
+++ b/net/quic/quic_session.cc |
@@ -104,7 +104,7 @@ QuicSession::QuicSession(QuicConnection* connection, const QuicConfig& config) |
visitor_shim_(new VisitorShim(this)), |
config_(config), |
max_open_streams_(config_.max_streams_per_connection()), |
- next_stream_id_(is_server() ? 2 : 3), |
+ next_stream_id_(is_server() ? 2 : 5), |
largest_peer_created_stream_id_(0), |
error_(QUIC_NO_ERROR), |
goaway_received_(false), |
@@ -131,12 +131,6 @@ void QuicSession::InitializeSession() { |
config_.max_time_before_crypto_handshake()); |
} |
headers_stream_.reset(new QuicHeadersStream(this)); |
- if (!is_server()) { |
- // For version above QUIC v12, the headers stream is stream 3, so the |
- // next available local stream ID should be 5. |
- DCHECK_EQ(kHeadersStreamId, next_stream_id_); |
- next_stream_id_ += 2; |
- } |
} |
QuicSession::~QuicSession() { |
@@ -434,12 +428,6 @@ void QuicSession::CloseStreamInner(QuicStreamId stream_id, |
stream->flow_controller()->IsEnabled()) { |
locally_closed_streams_highest_offset_[stream_id] = |
stream->flow_controller()->highest_received_byte_offset(); |
- if (FLAGS_close_quic_connection_unfinished_streams && |
- connection()->connected() && |
- locally_closed_streams_highest_offset_.size() > max_open_streams_) { |
- // A buggy client may fail to send FIN/RSTs. Don't tolerate this. |
- connection_->SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS); |
- } |
} |
stream_map_.erase(it); |
@@ -482,6 +470,15 @@ bool QuicSession::IsCryptoHandshakeConfirmed() { |
void QuicSession::OnConfigNegotiated() { |
connection_->SetFromConfig(config_); |
QuicVersion version = connection()->version(); |
+ |
+ // A server should accept a small number of additional streams beyond the |
+ // limit sent to the client. This helps avoid early connection termination |
+ // when FIN/RSTs for old streams are lost or arrive out of order. |
+ if (FLAGS_quic_allow_more_open_streams) { |
+ set_max_open_streams((is_server() ? kMaxStreamsMultiplier : 1.0) * |
+ config_.max_streams_per_connection()); |
+ } |
+ |
if (version <= QUIC_VERSION_16) { |
return; |
} |
@@ -560,7 +557,7 @@ void QuicSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) { |
case ENCRYPTION_REESTABLISHED: |
// Retransmit originally packets that were sent, since they can't be |
// decrypted by the peer. |
- connection_->RetransmitUnackedPackets(INITIAL_ENCRYPTION_ONLY); |
+ connection_->RetransmitUnackedPackets(ALL_INITIAL_RETRANSMISSION); |
break; |
case HANDSHAKE_CONFIRMED: |
@@ -570,7 +567,9 @@ void QuicSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) { |
// the peer. |
connection_->NeuterUnencryptedPackets(); |
connection_->SetOverallConnectionTimeout(QuicTime::Delta::Infinite()); |
- max_open_streams_ = config_.max_streams_per_connection(); |
+ if (!FLAGS_quic_allow_more_open_streams) { |
+ max_open_streams_ = config_.max_streams_per_connection(); |
+ } |
break; |
default: |
@@ -685,6 +684,11 @@ QuicDataStream* QuicSession::GetIncomingDataStream(QuicStreamId stream_id) { |
return stream; |
} |
+void QuicSession::set_max_open_streams(size_t max_open_streams) { |
+ DVLOG(1) << "Setting max_open_streams_ to " << max_open_streams; |
+ max_open_streams_ = max_open_streams; |
+} |
+ |
bool QuicSession::IsClosedStream(QuicStreamId id) { |
DCHECK_NE(0u, id); |
if (id == kCryptoStreamId) { |
@@ -750,6 +754,13 @@ bool QuicSession::GetSSLInfo(SSLInfo* ssl_info) const { |
void QuicSession::PostProcessAfterData() { |
STLDeleteElements(&closed_streams_); |
closed_streams_.clear(); |
+ |
+ if (FLAGS_close_quic_connection_unfinished_streams_2 && |
+ connection()->connected() && |
+ locally_closed_streams_highest_offset_.size() > max_open_streams_) { |
+ // A buggy client may fail to send FIN/RSTs. Don't tolerate this. |
+ connection_->SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS); |
+ } |
} |
void QuicSession::OnSuccessfulVersionNegotiation(const QuicVersion& version) { |