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 |