Index: net/quic/quic_session.cc |
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc |
index 6d5496eeafd66803e7c60dcf090ccc20555a6d15..48ea0072df7b822e0d3f4145dd6a45930c031a49 100644 |
--- a/net/quic/quic_session.cc |
+++ b/net/quic/quic_session.cc |
@@ -33,7 +33,8 @@ namespace net { |
QuicSession::QuicSession(QuicConnection* connection, const QuicConfig& config) |
: connection_(connection), |
config_(config), |
- max_open_streams_(config_.MaxStreamsPerConnection()), |
+ max_open_outgoing_streams_(config_.MaxStreamsPerConnection()), |
+ max_open_incoming_streams_(config_.MaxStreamsPerConnection()), |
next_outgoing_stream_id_(perspective() == Perspective::IS_SERVER ? 2 : 3), |
largest_peer_created_stream_id_( |
perspective() == Perspective::IS_SERVER ? 1 : 0), |
@@ -62,12 +63,12 @@ QuicSession::~QuicSession() { |
STLDeleteValues(&dynamic_stream_map_); |
DLOG_IF(WARNING, num_locally_closed_incoming_streams_highest_offset() > |
- max_open_streams_) |
+ max_open_incoming_streams_) |
<< "Surprisingly high number of locally closed peer initiated streams" |
"still waiting for final byte offset: " |
<< num_locally_closed_incoming_streams_highest_offset(); |
- DLOG_IF(WARNING, |
- GetNumLocallyClosedOutgoingStreamsHighestOffset() > max_open_streams_) |
+ DLOG_IF(WARNING, GetNumLocallyClosedOutgoingStreamsHighestOffset() > |
+ max_open_outgoing_streams_) |
<< "Surprisingly high number of locally closed self initiated streams" |
"still waiting for final byte offset: " |
<< GetNumLocallyClosedOutgoingStreamsHighestOffset(); |
@@ -371,14 +372,11 @@ void QuicSession::OnConfigNegotiated() { |
uint32_t max_streams = config_.MaxStreamsPerConnection(); |
if (perspective() == Perspective::IS_SERVER) { |
- // 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. |
- // Use a minimum number of additional streams, or a percentage increase, |
- // whichever is larger. |
- max_streams = |
- max(max_streams + kMaxStreamsMinimumIncrement, |
- static_cast<uint32_t>(max_streams * kMaxStreamsMultiplier)); |
+ if (!FLAGS_quic_different_max_num_open_streams) { |
+ max_streams = |
+ max(max_streams + kMaxStreamsMinimumIncrement, |
+ static_cast<uint32_t>(max_streams * kMaxStreamsMultiplier)); |
+ } |
if (config_.HasReceivedConnectionOptions()) { |
if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kAFCW)) { |
@@ -397,7 +395,21 @@ void QuicSession::OnConfigNegotiated() { |
} |
} |
} |
- set_max_open_streams(max_streams); |
+ |
+ set_max_open_outgoing_streams(max_streams); |
+ |
+ uint32_t max_incoming_streams = max_streams; |
+ if (FLAGS_quic_different_max_num_open_streams) { |
+ // A small number of additional incoming streams beyond the limit should be |
+ // allowed. This helps avoid early connection termination when FIN/RSTs for |
+ // old streams are lost or arrive out of order. |
+ // Use a minimum number of additional streams, or a percentage increase, |
+ // whichever is larger. |
+ max_incoming_streams = |
+ max(max_streams + kMaxStreamsMinimumIncrement, |
+ static_cast<uint32_t>(max_streams * kMaxStreamsMultiplier)); |
+ } |
+ set_max_open_incoming_streams(max_incoming_streams); |
if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) { |
// Streams which were created before the SHLO was received (0-RTT |
@@ -609,14 +621,14 @@ bool QuicSession::MaybeIncreaseLargestPeerStreamId( |
(stream_id - largest_peer_created_stream_id_) / 2 - 1; |
size_t new_num_available_streams = |
GetNumAvailableStreams() + additional_available_streams; |
- if (new_num_available_streams > get_max_available_streams()) { |
+ if (new_num_available_streams > MaxAvailableStreams()) { |
DVLOG(1) << "Failed to create a new incoming stream with id:" << stream_id |
<< ". There are already " << GetNumAvailableStreams() |
<< " streams available, which would become " |
<< new_num_available_streams << ", which exceeds the limit " |
- << get_max_available_streams() << "."; |
+ << MaxAvailableStreams() << "."; |
string details = IntToString(new_num_available_streams) + " above " + |
- IntToString(get_max_available_streams()); |
+ IntToString(MaxAvailableStreams()); |
CloseConnectionWithDetails(QUIC_TOO_MANY_AVAILABLE_STREAMS, |
details.c_str()); |
return false; |
@@ -666,12 +678,12 @@ ReliableQuicStream* QuicSession::GetOrCreateDynamicStream( |
} |
// Check if the new number of open streams would cause the number of |
// open streams to exceed the limit. |
- size_t num_current_open_streams = |
+ size_t num_open_incoming_streams = |
FLAGS_quic_distinguish_incoming_outgoing_streams |
? GetNumOpenIncomingStreams() |
: dynamic_stream_map_.size() - draining_streams_.size() + |
locally_closed_streams_highest_offset_.size(); |
- if (num_current_open_streams >= get_max_open_streams()) { |
+ if (num_open_incoming_streams >= max_open_incoming_streams()) { |
if (connection()->version() <= QUIC_VERSION_27) { |
CloseConnectionWithDetails(QUIC_TOO_MANY_OPEN_STREAMS, |
"Old style stream rejection"); |
@@ -690,11 +702,19 @@ ReliableQuicStream* QuicSession::GetOrCreateDynamicStream( |
return stream; |
} |
-void QuicSession::set_max_open_streams(size_t max_open_streams) { |
- DVLOG(1) << "Setting max_open_streams_ to " << max_open_streams; |
- DVLOG(1) << "Setting get_max_available_streams() to " |
- << get_max_available_streams(); |
- max_open_streams_ = max_open_streams; |
+void QuicSession::set_max_open_incoming_streams( |
+ size_t max_open_incoming_streams) { |
+ DVLOG(1) << "Setting max_open_incoming_streams_ to " |
+ << max_open_incoming_streams; |
+ max_open_incoming_streams_ = max_open_incoming_streams; |
+ DVLOG(1) << "MaxAvailableStreams() became " << MaxAvailableStreams(); |
+} |
+ |
+void QuicSession::set_max_open_outgoing_streams( |
+ size_t max_open_outgoing_streams) { |
+ DVLOG(1) << "Setting max_open_outgoing_streams_ to " |
+ << max_open_outgoing_streams; |
+ max_open_outgoing_streams_ = max_open_outgoing_streams; |
} |
bool QuicSession::goaway_sent() const { |
@@ -808,6 +828,10 @@ bool QuicSession::IsStreamFlowControlBlocked() { |
return false; |
} |
+size_t QuicSession::MaxAvailableStreams() const { |
+ return max_open_incoming_streams_ * kMaxAvailableStreamsMultiplier; |
+} |
+ |
bool QuicSession::IsIncomingStream(QuicStreamId id) const { |
return id % 2 != next_outgoing_stream_id_ % 2; |
} |