| 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/core/quic_session.h" | 5 #include "net/quic/core/quic_session.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "net/quic/core/crypto/proof_verifier.h" | 10 #include "net/quic/core/crypto/proof_verifier.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 | 48 |
| 49 void QuicSession::Initialize() { | 49 void QuicSession::Initialize() { |
| 50 connection_->set_visitor(this); | 50 connection_->set_visitor(this); |
| 51 connection_->SetFromConfig(config_); | 51 connection_->SetFromConfig(config_); |
| 52 | 52 |
| 53 DCHECK_EQ(kCryptoStreamId, GetCryptoStream()->id()); | 53 DCHECK_EQ(kCryptoStreamId, GetCryptoStream()->id()); |
| 54 static_stream_map_[kCryptoStreamId] = GetCryptoStream(); | 54 static_stream_map_[kCryptoStreamId] = GetCryptoStream(); |
| 55 } | 55 } |
| 56 | 56 |
| 57 QuicSession::~QuicSession() { | 57 QuicSession::~QuicSession() { |
| 58 DLOG_IF(WARNING, num_locally_closed_incoming_streams_highest_offset() > | 58 DLOG_IF(WARNING, |
| 59 max_open_incoming_streams_) | 59 num_locally_closed_incoming_streams_highest_offset() > |
| 60 max_open_incoming_streams_) |
| 60 << "Surprisingly high number of locally closed peer initiated streams" | 61 << "Surprisingly high number of locally closed peer initiated streams" |
| 61 "still waiting for final byte offset: " | 62 "still waiting for final byte offset: " |
| 62 << num_locally_closed_incoming_streams_highest_offset(); | 63 << num_locally_closed_incoming_streams_highest_offset(); |
| 63 DLOG_IF(WARNING, GetNumLocallyClosedOutgoingStreamsHighestOffset() > | 64 DLOG_IF(WARNING, |
| 64 max_open_outgoing_streams_) | 65 GetNumLocallyClosedOutgoingStreamsHighestOffset() > |
| 66 max_open_outgoing_streams_) |
| 65 << "Surprisingly high number of locally closed self initiated streams" | 67 << "Surprisingly high number of locally closed self initiated streams" |
| 66 "still waiting for final byte offset: " | 68 "still waiting for final byte offset: " |
| 67 << GetNumLocallyClosedOutgoingStreamsHighestOffset(); | 69 << GetNumLocallyClosedOutgoingStreamsHighestOffset(); |
| 68 } | 70 } |
| 69 | 71 |
| 70 void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) { | 72 void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) { |
| 71 // TODO(rch) deal with the error case of stream id 0. | 73 // TODO(rch) deal with the error case of stream id 0. |
| 72 QuicStreamId stream_id = frame.stream_id; | 74 QuicStreamId stream_id = frame.stream_id; |
| 73 QuicStream* stream = GetOrCreateStream(stream_id); | 75 QuicStream* stream = GetOrCreateStream(stream_id); |
| 74 if (!stream) { | 76 if (!stream) { |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 | 434 |
| 433 const QuicVersion version = connection()->version(); | 435 const QuicVersion version = connection()->version(); |
| 434 uint32_t max_streams = 0; | 436 uint32_t max_streams = 0; |
| 435 if (version > QUIC_VERSION_34 && | 437 if (version > QUIC_VERSION_34 && |
| 436 config_.HasReceivedMaxIncomingDynamicStreams()) { | 438 config_.HasReceivedMaxIncomingDynamicStreams()) { |
| 437 max_streams = config_.ReceivedMaxIncomingDynamicStreams(); | 439 max_streams = config_.ReceivedMaxIncomingDynamicStreams(); |
| 438 } else { | 440 } else { |
| 439 max_streams = config_.MaxStreamsPerConnection(); | 441 max_streams = config_.MaxStreamsPerConnection(); |
| 440 } | 442 } |
| 441 set_max_open_outgoing_streams(max_streams); | 443 set_max_open_outgoing_streams(max_streams); |
| 444 if (FLAGS_quic_large_ifw_options && |
| 445 perspective() == Perspective::IS_SERVER) { |
| 446 if (config_.HasReceivedConnectionOptions()) { |
| 447 // The following variations change the initial receive flow control |
| 448 // window sizes. |
| 449 if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW6)) { |
| 450 AdjustInitialFlowControlWindows(64 * 1024); |
| 451 } |
| 452 if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW7)) { |
| 453 AdjustInitialFlowControlWindows(128 * 1024); |
| 454 } |
| 455 if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW8)) { |
| 456 AdjustInitialFlowControlWindows(256 * 1024); |
| 457 } |
| 458 if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFW9)) { |
| 459 AdjustInitialFlowControlWindows(512 * 1024); |
| 460 } |
| 461 if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kIFWA)) { |
| 462 AdjustInitialFlowControlWindows(1024 * 1024); |
| 463 } |
| 464 } |
| 465 } |
| 442 | 466 |
| 443 if (version <= QUIC_VERSION_34) { | 467 if (version <= QUIC_VERSION_34) { |
| 444 // A small number of additional incoming streams beyond the limit should be | 468 // A small number of additional incoming streams beyond the limit should be |
| 445 // allowed. This helps avoid early connection termination when FIN/RSTs for | 469 // allowed. This helps avoid early connection termination when FIN/RSTs for |
| 446 // old streams are lost or arrive out of order. | 470 // old streams are lost or arrive out of order. |
| 447 // Use a minimum number of additional streams, or a percentage increase, | 471 // Use a minimum number of additional streams, or a percentage increase, |
| 448 // whichever is larger. | 472 // whichever is larger. |
| 449 uint32_t max_incoming_streams = | 473 uint32_t max_incoming_streams = |
| 450 std::max(max_streams + kMaxStreamsMinimumIncrement, | 474 std::max(max_streams + kMaxStreamsMinimumIncrement, |
| 451 static_cast<uint32_t>(max_streams * kMaxStreamsMultiplier)); | 475 static_cast<uint32_t>(max_streams * kMaxStreamsMultiplier)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 465 // requests) are now informed of the peer's initial flow control window. | 489 // requests) are now informed of the peer's initial flow control window. |
| 466 OnNewStreamFlowControlWindow( | 490 OnNewStreamFlowControlWindow( |
| 467 config_.ReceivedInitialStreamFlowControlWindowBytes()); | 491 config_.ReceivedInitialStreamFlowControlWindowBytes()); |
| 468 } | 492 } |
| 469 if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) { | 493 if (config_.HasReceivedInitialSessionFlowControlWindowBytes()) { |
| 470 OnNewSessionFlowControlWindow( | 494 OnNewSessionFlowControlWindow( |
| 471 config_.ReceivedInitialSessionFlowControlWindowBytes()); | 495 config_.ReceivedInitialSessionFlowControlWindowBytes()); |
| 472 } | 496 } |
| 473 } | 497 } |
| 474 | 498 |
| 499 void QuicSession::AdjustInitialFlowControlWindows(size_t stream_window) { |
| 500 const float session_window_multiplier = |
| 501 config_.GetInitialStreamFlowControlWindowToSend() |
| 502 ? static_cast<float>( |
| 503 config_.GetInitialSessionFlowControlWindowToSend()) / |
| 504 config_.GetInitialStreamFlowControlWindowToSend() |
| 505 : 1.5; |
| 506 |
| 507 DVLOG(1) << ENDPOINT << "Set stream receive window to " << stream_window; |
| 508 config_.SetInitialStreamFlowControlWindowToSend(stream_window); |
| 509 |
| 510 size_t session_window = session_window_multiplier * stream_window; |
| 511 DVLOG(1) << ENDPOINT << "Set session receive window to " << session_window; |
| 512 config_.SetInitialSessionFlowControlWindowToSend(session_window); |
| 513 flow_controller_.UpdateReceiveWindowSize(session_window); |
| 514 // Inform all existing streams about the new window. |
| 515 for (auto const& kv : static_stream_map_) { |
| 516 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); |
| 517 } |
| 518 for (auto const& kv : dynamic_stream_map_) { |
| 519 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); |
| 520 } |
| 521 } |
| 522 |
| 475 void QuicSession::HandleFrameOnNonexistentOutgoingStream( | 523 void QuicSession::HandleFrameOnNonexistentOutgoingStream( |
| 476 QuicStreamId stream_id) { | 524 QuicStreamId stream_id) { |
| 477 DCHECK(!IsClosedStream(stream_id)); | 525 DCHECK(!IsClosedStream(stream_id)); |
| 478 // Received a frame for a locally-created stream that is not currently | 526 // Received a frame for a locally-created stream that is not currently |
| 479 // active. This is an error. | 527 // active. This is an error. |
| 480 connection()->CloseConnection( | 528 connection()->CloseConnection( |
| 481 QUIC_INVALID_STREAM_ID, "Data for nonexistent stream", | 529 QUIC_INVALID_STREAM_ID, "Data for nonexistent stream", |
| 482 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 530 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 483 } | 531 } |
| 484 | 532 |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 | 862 |
| 815 size_t QuicSession::MaxAvailableStreams() const { | 863 size_t QuicSession::MaxAvailableStreams() const { |
| 816 return max_open_incoming_streams_ * kMaxAvailableStreamsMultiplier; | 864 return max_open_incoming_streams_ * kMaxAvailableStreamsMultiplier; |
| 817 } | 865 } |
| 818 | 866 |
| 819 bool QuicSession::IsIncomingStream(QuicStreamId id) const { | 867 bool QuicSession::IsIncomingStream(QuicStreamId id) const { |
| 820 return id % 2 != next_outgoing_stream_id_ % 2; | 868 return id % 2 != next_outgoing_stream_id_ % 2; |
| 821 } | 869 } |
| 822 | 870 |
| 823 } // namespace net | 871 } // namespace net |
| OLD | NEW |