Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / net / quic / quic_session.cc
index f227727..0f5be9c 100644 (file)
@@ -64,6 +64,10 @@ class VisitorShim : public QuicConnectionVisitorInterface {
     session_->PostProcessAfterData();
   }
 
+  virtual void OnCongestionWindowChange(QuicTime now) OVERRIDE {
+    session_->OnCongestionWindowChange(now);
+  }
+
   virtual void OnSuccessfulVersionNegotiation(
       const QuicVersion& version) OVERRIDE {
     session_->OnSuccessfulVersionNegotiation(version);
@@ -100,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),
@@ -127,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() {
@@ -268,7 +266,7 @@ void QuicSession::OnWindowUpdateFrames(
       continue;
     }
 
-    if (connection_->version() <= QUIC_VERSION_20 &&
+    if (connection_->version() < QUIC_VERSION_21 &&
         (stream_id == kCryptoStreamId || stream_id == kHeadersStreamId)) {
       DLOG(DFATAL) << "WindowUpdate for stream " << stream_id << " in version "
                    << QuicVersionToString(connection_->version());
@@ -430,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);
@@ -478,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;
   }
@@ -496,7 +497,7 @@ void QuicSession::OnConfigNegotiated() {
     return;
   }
 
-  // QUIC_VERSION_20 and higher can have independent stream and session flow
+  // QUIC_VERSION_21 and higher can have independent stream and session flow
   // control windows.
   if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) {
     // Streams which were created before the SHLO was received (0-RTT
@@ -522,7 +523,7 @@ void QuicSession::OnNewStreamFlowControlWindow(uint32 new_window) {
   }
 
   // Inform all existing streams about the new window.
-  if (connection_->version() > QUIC_VERSION_20) {
+  if (connection_->version() >= QUIC_VERSION_21) {
     GetCryptoStream()->flow_controller()->UpdateSendWindowOffset(new_window);
     headers_stream_->flow_controller()->UpdateSendWindowOffset(new_window);
   }
@@ -556,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:
@@ -566,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:
@@ -681,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) {
@@ -746,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) {
@@ -755,7 +770,7 @@ void QuicSession::OnSuccessfulVersionNegotiation(const QuicVersion& version) {
 
   // Disable stream level flow control based on negotiated version. Streams may
   // have been created with a different version.
-  if (version <= QUIC_VERSION_20) {
+  if (version < QUIC_VERSION_21) {
     GetCryptoStream()->flow_controller()->Disable();
     headers_stream_->flow_controller()->Disable();
   }