| 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 "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
| 9 #include "net/quic/crypto/proof_verifier.h" | 9 #include "net/quic/crypto/proof_verifier.h" |
| 10 #include "net/quic/quic_bug_tracker.h" | 10 #include "net/quic/quic_bug_tracker.h" |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 | 163 |
| 164 void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { | 164 void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { |
| 165 if (ContainsKey(static_stream_map_, frame.stream_id)) { | 165 if (ContainsKey(static_stream_map_, frame.stream_id)) { |
| 166 connection()->SendConnectionCloseWithDetails( | 166 connection()->SendConnectionCloseWithDetails( |
| 167 QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream"); | 167 QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream"); |
| 168 return; | 168 return; |
| 169 } | 169 } |
| 170 | 170 |
| 171 ReliableQuicStream* stream = GetOrCreateDynamicStream(frame.stream_id); | 171 ReliableQuicStream* stream = GetOrCreateDynamicStream(frame.stream_id); |
| 172 if (!stream) { | 172 if (!stream) { |
| 173 // The RST frame contains the final byte offset for the stream: we can now | 173 HandleRstOnValidNonexistentStream(frame); |
| 174 // update the connection level flow controller if needed. | |
| 175 UpdateFlowControlOnFinalReceivedByteOffset(frame.stream_id, | |
| 176 frame.byte_offset); | |
| 177 return; // Errors are handled by GetStream. | 174 return; // Errors are handled by GetStream. |
| 178 } | 175 } |
| 179 | 176 |
| 180 stream->OnStreamReset(frame); | 177 stream->OnStreamReset(frame); |
| 181 } | 178 } |
| 182 | 179 |
| 183 void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) { | 180 void QuicSession::OnGoAway(const QuicGoAwayFrame& frame) { |
| 184 DCHECK(frame.last_good_stream_id < next_outgoing_stream_id_); | 181 DCHECK(frame.last_good_stream_id < next_outgoing_stream_id_); |
| 185 } | 182 } |
| 186 | 183 |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 flow_controller_.UpdateReceiveWindowSize(session_window); | 501 flow_controller_.UpdateReceiveWindowSize(session_window); |
| 505 // Inform all existing streams about the new window. | 502 // Inform all existing streams about the new window. |
| 506 for (auto const& kv : static_stream_map_) { | 503 for (auto const& kv : static_stream_map_) { |
| 507 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); | 504 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); |
| 508 } | 505 } |
| 509 for (auto const& kv : dynamic_stream_map_) { | 506 for (auto const& kv : dynamic_stream_map_) { |
| 510 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); | 507 kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); |
| 511 } | 508 } |
| 512 } | 509 } |
| 513 | 510 |
| 511 void QuicSession::HandleFrameOnNonexistentOutgoingStream( |
| 512 QuicStreamId stream_id) { |
| 513 DCHECK(!IsClosedStream(stream_id)); |
| 514 // Received a frame for a locally-created stream that is not currently |
| 515 // active. This is an error. |
| 516 CloseConnectionWithDetails(QUIC_INVALID_STREAM_ID, |
| 517 "Data for nonexistent stream"); |
| 518 } |
| 519 |
| 520 void QuicSession::HandleRstOnValidNonexistentStream( |
| 521 const QuicRstStreamFrame& frame) { |
| 522 // If the stream is neither originally in active streams nor created in |
| 523 // GetOrCreateDynamicStream(), it could be a closed stream in which case its |
| 524 // final received byte offset need to be updated. |
| 525 if (IsClosedStream(frame.stream_id)) { |
| 526 // The RST frame contains the final byte offset for the stream: we can now |
| 527 // update the connection level flow controller if needed. |
| 528 UpdateFlowControlOnFinalReceivedByteOffset(frame.stream_id, |
| 529 frame.byte_offset); |
| 530 } |
| 531 } |
| 532 |
| 514 void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) { | 533 void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) { |
| 515 if (new_window < kMinimumFlowControlSendWindow) { | 534 if (new_window < kMinimumFlowControlSendWindow) { |
| 516 LOG(ERROR) << "Peer sent us an invalid stream flow control send window: " | 535 LOG(ERROR) << "Peer sent us an invalid stream flow control send window: " |
| 517 << new_window | 536 << new_window |
| 518 << ", below default: " << kMinimumFlowControlSendWindow; | 537 << ", below default: " << kMinimumFlowControlSendWindow; |
| 519 if (connection_->connected()) { | 538 if (connection_->connected()) { |
| 520 connection_->SendConnectionCloseWithDetails( | 539 connection_->SendConnectionCloseWithDetails( |
| 521 QUIC_FLOW_CONTROL_INVALID_WINDOW, "New stream window too low"); | 540 QUIC_FLOW_CONTROL_INVALID_WINDOW, "New stream window too low"); |
| 522 } | 541 } |
| 523 return; | 542 return; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 StreamMap::iterator it = dynamic_stream_map_.find(stream_id); | 665 StreamMap::iterator it = dynamic_stream_map_.find(stream_id); |
| 647 if (it != dynamic_stream_map_.end()) { | 666 if (it != dynamic_stream_map_.end()) { |
| 648 return it->second; | 667 return it->second; |
| 649 } | 668 } |
| 650 | 669 |
| 651 if (IsClosedStream(stream_id)) { | 670 if (IsClosedStream(stream_id)) { |
| 652 return nullptr; | 671 return nullptr; |
| 653 } | 672 } |
| 654 | 673 |
| 655 if (!IsIncomingStream(stream_id)) { | 674 if (!IsIncomingStream(stream_id)) { |
| 656 // Received a frame for a locally-created stream that is not currently | 675 HandleFrameOnNonexistentOutgoingStream(stream_id); |
| 657 // active. This is an error. | |
| 658 CloseConnectionWithDetails(QUIC_INVALID_STREAM_ID, | |
| 659 "Data for nonexistent stream"); | |
| 660 return nullptr; | 676 return nullptr; |
| 661 } | 677 } |
| 662 | 678 |
| 663 available_streams_.erase(stream_id); | 679 available_streams_.erase(stream_id); |
| 664 | 680 |
| 665 if (stream_id > largest_peer_created_stream_id_) { | 681 if (stream_id > largest_peer_created_stream_id_) { |
| 666 // Check if the new number of available streams would cause the number of | 682 // Check if the new number of available streams would cause the number of |
| 667 // available streams to exceed the limit. Note that the peer can create | 683 // available streams to exceed the limit. Note that the peer can create |
| 668 // only alternately-numbered streams. | 684 // only alternately-numbered streams. |
| 669 size_t additional_available_streams = | 685 size_t additional_available_streams = |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 } | 839 } |
| 824 } | 840 } |
| 825 return false; | 841 return false; |
| 826 } | 842 } |
| 827 | 843 |
| 828 bool QuicSession::IsIncomingStream(QuicStreamId id) const { | 844 bool QuicSession::IsIncomingStream(QuicStreamId id) const { |
| 829 return id % 2 != next_outgoing_stream_id_ % 2; | 845 return id % 2 != next_outgoing_stream_id_ % 2; |
| 830 } | 846 } |
| 831 | 847 |
| 832 } // namespace net | 848 } // namespace net |
| OLD | NEW |