| 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 <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/containers/hash_tables.h" | 10 #include "base/containers/hash_tables.h" |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 return QuicSession::WritevData(id, data, offset, fin, fec_protection, | 164 return QuicSession::WritevData(id, data, offset, fin, fec_protection, |
| 165 ack_notifier_delegate); | 165 ack_notifier_delegate); |
| 166 } | 166 } |
| 167 } | 167 } |
| 168 | 168 |
| 169 void set_writev_consumes_all_data(bool val) { | 169 void set_writev_consumes_all_data(bool val) { |
| 170 writev_consumes_all_data_ = val; | 170 writev_consumes_all_data_ = val; |
| 171 } | 171 } |
| 172 | 172 |
| 173 QuicConsumedData SendStreamData(QuicStreamId id) { | 173 QuicConsumedData SendStreamData(QuicStreamId id) { |
| 174 return WritevData(id, IOVector(), 0, true, MAY_FEC_PROTECT, nullptr); | 174 return WritevData(id, MakeIOVector("not empty"), 0, true, MAY_FEC_PROTECT, |
| 175 nullptr); |
| 175 } | 176 } |
| 176 | 177 |
| 177 using QuicSession::PostProcessAfterData; | 178 using QuicSession::PostProcessAfterData; |
| 178 | 179 |
| 179 private: | 180 private: |
| 180 StrictMock<TestCryptoStream> crypto_stream_; | 181 StrictMock<TestCryptoStream> crypto_stream_; |
| 181 | 182 |
| 182 bool writev_consumes_all_data_; | 183 bool writev_consumes_all_data_; |
| 183 }; | 184 }; |
| 184 | 185 |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedStream) { | 630 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedStream) { |
| 630 // Test that if a stream is flow control blocked, then on receipt of the SHLO | 631 // Test that if a stream is flow control blocked, then on receipt of the SHLO |
| 631 // containing a suitable send window offset, the stream becomes unblocked. | 632 // containing a suitable send window offset, the stream becomes unblocked. |
| 632 | 633 |
| 633 // Ensure that Writev consumes all the data it is given (simulate no socket | 634 // Ensure that Writev consumes all the data it is given (simulate no socket |
| 634 // blocking). | 635 // blocking). |
| 635 session_.set_writev_consumes_all_data(true); | 636 session_.set_writev_consumes_all_data(true); |
| 636 | 637 |
| 637 // Create a stream, and send enough data to make it flow control blocked. | 638 // Create a stream, and send enough data to make it flow control blocked. |
| 638 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 639 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
| 639 string body(kDefaultFlowControlSendWindow, '.'); | 640 string body(kMinimumFlowControlSendWindow, '.'); |
| 640 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); | 641 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); |
| 641 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 642 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 642 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 643 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 643 stream2->SendBody(body, false); | 644 stream2->SendBody(body, false); |
| 644 EXPECT_TRUE(stream2->flow_controller()->IsBlocked()); | 645 EXPECT_TRUE(stream2->flow_controller()->IsBlocked()); |
| 645 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); | 646 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); |
| 646 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); | 647 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); |
| 647 | 648 |
| 648 // The handshake message will call OnCanWrite, so the stream can resume | 649 // The handshake message will call OnCanWrite, so the stream can resume |
| 649 // writing. | 650 // writing. |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 } | 760 } |
| 760 | 761 |
| 761 TEST_P(QuicSessionTest, InvalidFlowControlWindowInHandshake) { | 762 TEST_P(QuicSessionTest, InvalidFlowControlWindowInHandshake) { |
| 762 // TODO(rjshade): Remove this test when removing QUIC_VERSION_19. | 763 // TODO(rjshade): Remove this test when removing QUIC_VERSION_19. |
| 763 // Test that receipt of an invalid (< default) flow control window from | 764 // Test that receipt of an invalid (< default) flow control window from |
| 764 // the peer results in the connection being torn down. | 765 // the peer results in the connection being torn down. |
| 765 if (version() > QUIC_VERSION_19) { | 766 if (version() > QUIC_VERSION_19) { |
| 766 return; | 767 return; |
| 767 } | 768 } |
| 768 | 769 |
| 769 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; | 770 uint32 kInvalidWindow = kMinimumFlowControlSendWindow - 1; |
| 770 QuicConfigPeer::SetReceivedInitialFlowControlWindow(session_.config(), | 771 QuicConfigPeer::SetReceivedInitialFlowControlWindow(session_.config(), |
| 771 kInvalidWindow); | 772 kInvalidWindow); |
| 772 | 773 |
| 773 EXPECT_CALL(*connection_, | 774 EXPECT_CALL(*connection_, |
| 774 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)).Times(2); | 775 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)).Times(2); |
| 775 session_.OnConfigNegotiated(); | 776 session_.OnConfigNegotiated(); |
| 776 } | 777 } |
| 777 | 778 |
| 778 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) { | 779 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) { |
| 779 // Test that when we receive an out of order stream RST we correctly adjust | 780 // Test that when we receive an out of order stream RST we correctly adjust |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 910 session_.flow_controller()->highest_received_byte_offset()); | 911 session_.flow_controller()->highest_received_byte_offset()); |
| 911 } | 912 } |
| 912 | 913 |
| 913 TEST_P(QuicSessionTest, InvalidStreamFlowControlWindowInHandshake) { | 914 TEST_P(QuicSessionTest, InvalidStreamFlowControlWindowInHandshake) { |
| 914 // Test that receipt of an invalid (< default) stream flow control window from | 915 // Test that receipt of an invalid (< default) stream flow control window from |
| 915 // the peer results in the connection being torn down. | 916 // the peer results in the connection being torn down. |
| 916 if (version() <= QUIC_VERSION_19) { | 917 if (version() <= QUIC_VERSION_19) { |
| 917 return; | 918 return; |
| 918 } | 919 } |
| 919 | 920 |
| 920 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; | 921 uint32 kInvalidWindow = kMinimumFlowControlSendWindow - 1; |
| 921 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(), | 922 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(), |
| 922 kInvalidWindow); | 923 kInvalidWindow); |
| 923 | 924 |
| 924 EXPECT_CALL(*connection_, | 925 EXPECT_CALL(*connection_, |
| 925 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); | 926 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); |
| 926 session_.OnConfigNegotiated(); | 927 session_.OnConfigNegotiated(); |
| 927 } | 928 } |
| 928 | 929 |
| 929 TEST_P(QuicSessionTest, InvalidSessionFlowControlWindowInHandshake) { | 930 TEST_P(QuicSessionTest, InvalidSessionFlowControlWindowInHandshake) { |
| 930 // Test that receipt of an invalid (< default) session flow control window | 931 // Test that receipt of an invalid (< default) session flow control window |
| 931 // from the peer results in the connection being torn down. | 932 // from the peer results in the connection being torn down. |
| 932 if (version() == QUIC_VERSION_19) { | 933 if (version() == QUIC_VERSION_19) { |
| 933 return; | 934 return; |
| 934 } | 935 } |
| 935 | 936 |
| 936 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; | 937 uint32 kInvalidWindow = kMinimumFlowControlSendWindow - 1; |
| 937 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(), | 938 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(), |
| 938 kInvalidWindow); | 939 kInvalidWindow); |
| 939 | 940 |
| 940 EXPECT_CALL(*connection_, | 941 EXPECT_CALL(*connection_, |
| 941 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); | 942 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); |
| 942 session_.OnConfigNegotiated(); | 943 session_.OnConfigNegotiated(); |
| 943 } | 944 } |
| 944 | 945 |
| 945 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { | 946 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { |
| 946 // Test that if we receive a stream RST with a highest byte offset that | 947 // Test that if we receive a stream RST with a highest byte offset that |
| (...skipping 28 matching lines...) Expand all Loading... |
| 975 QuicHeadersStream* headers_stream = | 976 QuicHeadersStream* headers_stream = |
| 976 QuicSessionPeer::GetHeadersStream(&session_); | 977 QuicSessionPeer::GetHeadersStream(&session_); |
| 977 QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(), | 978 QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(), |
| 978 0); | 979 0); |
| 979 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); | 980 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); |
| 980 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 981 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 981 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); | 982 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); |
| 982 | 983 |
| 983 // Unblock the headers stream by supplying a WINDOW_UPDATE. | 984 // Unblock the headers stream by supplying a WINDOW_UPDATE. |
| 984 QuicWindowUpdateFrame window_update_frame(headers_stream->id(), | 985 QuicWindowUpdateFrame window_update_frame(headers_stream->id(), |
| 985 2 * kDefaultFlowControlSendWindow); | 986 2 * kMinimumFlowControlSendWindow); |
| 986 vector<QuicWindowUpdateFrame> frames; | 987 vector<QuicWindowUpdateFrame> frames; |
| 987 frames.push_back(window_update_frame); | 988 frames.push_back(window_update_frame); |
| 988 session_.OnWindowUpdateFrames(frames); | 989 session_.OnWindowUpdateFrames(frames); |
| 989 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); | 990 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
| 990 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 991 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 991 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 992 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 992 } | 993 } |
| 993 | 994 |
| 994 TEST_P(QuicSessionTest, TooManyUnfinishedStreamsCauseConnectionClose) { | 995 TEST_P(QuicSessionTest, TooManyUnfinishedStreamsCauseConnectionClose) { |
| 995 // If a buggy/malicious peer creates too many streams that are not ended with | 996 // If a buggy/malicious peer creates too many streams that are not ended with |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1014 } | 1015 } |
| 1015 | 1016 |
| 1016 // Called after any new data is received by the session, and triggers the call | 1017 // Called after any new data is received by the session, and triggers the call |
| 1017 // to close the connection. | 1018 // to close the connection. |
| 1018 session_.PostProcessAfterData(); | 1019 session_.PostProcessAfterData(); |
| 1019 } | 1020 } |
| 1020 | 1021 |
| 1021 } // namespace | 1022 } // namespace |
| 1022 } // namespace test | 1023 } // namespace test |
| 1023 } // namespace net | 1024 } // namespace net |
| OLD | NEW |