| 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 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 EXPECT_CALL(*stream4, OnCanWrite()); | 524 EXPECT_CALL(*stream4, OnCanWrite()); |
| 525 session_.OnCanWrite(); | 525 session_.OnCanWrite(); |
| 526 EXPECT_FALSE(session_.WillingAndAbleToWrite()); | 526 EXPECT_FALSE(session_.WillingAndAbleToWrite()); |
| 527 } | 527 } |
| 528 | 528 |
| 529 TEST_P(QuicSessionTest, OnCanWriteLimitsNumWritesIfFlowControlBlocked) { | 529 TEST_P(QuicSessionTest, OnCanWriteLimitsNumWritesIfFlowControlBlocked) { |
| 530 if (version() < QUIC_VERSION_19) { | 530 if (version() < QUIC_VERSION_19) { |
| 531 return; | 531 return; |
| 532 } | 532 } |
| 533 | 533 |
| 534 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, | |
| 535 true); | |
| 536 // Ensure connection level flow control blockage. | 534 // Ensure connection level flow control blockage. |
| 537 QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0); | 535 QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0); |
| 538 EXPECT_TRUE(session_.flow_controller()->IsBlocked()); | 536 EXPECT_TRUE(session_.flow_controller()->IsBlocked()); |
| 539 | 537 |
| 540 // Mark the crypto and headers streams as write blocked, we expect them to be | 538 // Mark the crypto and headers streams as write blocked, we expect them to be |
| 541 // allowed to write later. | 539 // allowed to write later. |
| 542 session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority); | 540 session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority); |
| 543 session_.MarkWriteBlocked(kHeadersStreamId, kHighestPriority); | 541 session_.MarkWriteBlocked(kHeadersStreamId, kHighestPriority); |
| 544 | 542 |
| 545 // Create a data stream, and although it is write blocked we never expect it | 543 // Create a data stream, and although it is write blocked we never expect it |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 EXPECT_CALL(*connection_, | 702 EXPECT_CALL(*connection_, |
| 705 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); | 703 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); |
| 706 session_.OnConfigNegotiated(); | 704 session_.OnConfigNegotiated(); |
| 707 } | 705 } |
| 708 | 706 |
| 709 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) { | 707 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) { |
| 710 if (version() < QUIC_VERSION_19) { | 708 if (version() < QUIC_VERSION_19) { |
| 711 return; | 709 return; |
| 712 } | 710 } |
| 713 | 711 |
| 714 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, | |
| 715 true); | |
| 716 // Test that when we receive an out of order stream RST we correctly adjust | 712 // Test that when we receive an out of order stream RST we correctly adjust |
| 717 // our connection level flow control receive window. | 713 // our connection level flow control receive window. |
| 718 // On close, the stream should mark as consumed all bytes between the highest | 714 // On close, the stream should mark as consumed all bytes between the highest |
| 719 // byte consumed so far and the final byte offset from the RST frame. | 715 // byte consumed so far and the final byte offset from the RST frame. |
| 720 TestStream* stream = session_.CreateOutgoingDataStream(); | 716 TestStream* stream = session_.CreateOutgoingDataStream(); |
| 721 | 717 |
| 722 const QuicStreamOffset kByteOffset = | 718 const QuicStreamOffset kByteOffset = |
| 723 1 + kInitialSessionFlowControlWindowForTest / 2; | 719 1 + kInitialSessionFlowControlWindowForTest / 2; |
| 724 | 720 |
| 725 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. | 721 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. |
| 726 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); | 722 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); |
| 727 // We do expect a connection level WINDOW_UPDATE when the stream is reset. | 723 // We do expect a connection level WINDOW_UPDATE when the stream is reset. |
| 728 EXPECT_CALL(*connection_, | 724 EXPECT_CALL(*connection_, |
| 729 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + | 725 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + |
| 730 kByteOffset)).Times(1); | 726 kByteOffset)).Times(1); |
| 731 | 727 |
| 732 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 728 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
| 733 kByteOffset); | 729 kByteOffset); |
| 734 session_.OnRstStream(rst_frame); | 730 session_.OnRstStream(rst_frame); |
| 735 session_.PostProcessAfterData(); | 731 session_.PostProcessAfterData(); |
| 736 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); | 732 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); |
| 737 } | 733 } |
| 738 | 734 |
| 739 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAndLocalReset) { | 735 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAndLocalReset) { |
| 740 if (version() < QUIC_VERSION_19) { | 736 if (version() < QUIC_VERSION_19) { |
| 741 return; | 737 return; |
| 742 } | 738 } |
| 743 | 739 |
| 744 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, | |
| 745 true); | |
| 746 // Test the situation where we receive a FIN on a stream, and before we fully | 740 // Test the situation where we receive a FIN on a stream, and before we fully |
| 747 // consume all the data from the sequencer buffer we locally RST the stream. | 741 // consume all the data from the sequencer buffer we locally RST the stream. |
| 748 // The bytes between highest consumed byte, and the final byte offset that we | 742 // The bytes between highest consumed byte, and the final byte offset that we |
| 749 // determined when the FIN arrived, should be marked as consumed at the | 743 // determined when the FIN arrived, should be marked as consumed at the |
| 750 // connection level flow controller when the stream is reset. | 744 // connection level flow controller when the stream is reset. |
| 751 TestStream* stream = session_.CreateOutgoingDataStream(); | 745 TestStream* stream = session_.CreateOutgoingDataStream(); |
| 752 | 746 |
| 753 const QuicStreamOffset kByteOffset = | 747 const QuicStreamOffset kByteOffset = |
| 754 1 + kInitialSessionFlowControlWindowForTest / 2; | 748 1 + kInitialSessionFlowControlWindowForTest / 2; |
| 755 QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector()); | 749 QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector()); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 782 } | 776 } |
| 783 | 777 |
| 784 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) { | 778 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) { |
| 785 // Test that when we RST the stream (and tear down stream state), and then | 779 // Test that when we RST the stream (and tear down stream state), and then |
| 786 // receive a FIN from the peer, we correctly adjust our connection level flow | 780 // receive a FIN from the peer, we correctly adjust our connection level flow |
| 787 // control receive window. | 781 // control receive window. |
| 788 if (version() < QUIC_VERSION_19) { | 782 if (version() < QUIC_VERSION_19) { |
| 789 return; | 783 return; |
| 790 } | 784 } |
| 791 | 785 |
| 792 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, | |
| 793 true); | |
| 794 // Connection starts with some non-zero highest received byte offset, | 786 // Connection starts with some non-zero highest received byte offset, |
| 795 // due to other active streams. | 787 // due to other active streams. |
| 796 const uint64 kInitialConnectionBytesConsumed = 567; | 788 const uint64 kInitialConnectionBytesConsumed = 567; |
| 797 const uint64 kInitialConnectionHighestReceivedOffset = 1234; | 789 const uint64 kInitialConnectionHighestReceivedOffset = 1234; |
| 798 EXPECT_LT(kInitialConnectionBytesConsumed, | 790 EXPECT_LT(kInitialConnectionBytesConsumed, |
| 799 kInitialConnectionHighestReceivedOffset); | 791 kInitialConnectionHighestReceivedOffset); |
| 800 session_.flow_controller()->UpdateHighestReceivedOffset( | 792 session_.flow_controller()->UpdateHighestReceivedOffset( |
| 801 kInitialConnectionHighestReceivedOffset); | 793 kInitialConnectionHighestReceivedOffset); |
| 802 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); | 794 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); |
| 803 | 795 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 826 } | 818 } |
| 827 | 819 |
| 828 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstAfterRst) { | 820 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstAfterRst) { |
| 829 // Test that when we RST the stream (and tear down stream state), and then | 821 // Test that when we RST the stream (and tear down stream state), and then |
| 830 // receive a RST from the peer, we correctly adjust our connection level flow | 822 // receive a RST from the peer, we correctly adjust our connection level flow |
| 831 // control receive window. | 823 // control receive window. |
| 832 if (version() < QUIC_VERSION_19) { | 824 if (version() < QUIC_VERSION_19) { |
| 833 return; | 825 return; |
| 834 } | 826 } |
| 835 | 827 |
| 836 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, | |
| 837 true); | |
| 838 // Connection starts with some non-zero highest received byte offset, | 828 // Connection starts with some non-zero highest received byte offset, |
| 839 // due to other active streams. | 829 // due to other active streams. |
| 840 const uint64 kInitialConnectionBytesConsumed = 567; | 830 const uint64 kInitialConnectionBytesConsumed = 567; |
| 841 const uint64 kInitialConnectionHighestReceivedOffset = 1234; | 831 const uint64 kInitialConnectionHighestReceivedOffset = 1234; |
| 842 EXPECT_LT(kInitialConnectionBytesConsumed, | 832 EXPECT_LT(kInitialConnectionBytesConsumed, |
| 843 kInitialConnectionHighestReceivedOffset); | 833 kInitialConnectionHighestReceivedOffset); |
| 844 session_.flow_controller()->UpdateHighestReceivedOffset( | 834 session_.flow_controller()->UpdateHighestReceivedOffset( |
| 845 kInitialConnectionHighestReceivedOffset); | 835 kInitialConnectionHighestReceivedOffset); |
| 846 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); | 836 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); |
| 847 | 837 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 862 EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset, | 852 EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset, |
| 863 session_.flow_controller()->highest_received_byte_offset()); | 853 session_.flow_controller()->highest_received_byte_offset()); |
| 864 } | 854 } |
| 865 | 855 |
| 866 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { | 856 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { |
| 867 // Test that if we receive a stream RST with a highest byte offset that | 857 // Test that if we receive a stream RST with a highest byte offset that |
| 868 // violates flow control, that we close the connection. | 858 // violates flow control, that we close the connection. |
| 869 if (version() <= QUIC_VERSION_16) { | 859 if (version() <= QUIC_VERSION_16) { |
| 870 return; | 860 return; |
| 871 } | 861 } |
| 872 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, | |
| 873 true); | |
| 874 | 862 |
| 875 const uint64 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; | 863 const uint64 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; |
| 876 EXPECT_CALL(*connection_, | 864 EXPECT_CALL(*connection_, |
| 877 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)) | 865 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)) |
| 878 .Times(2); | 866 .Times(2); |
| 879 | 867 |
| 880 // Check that stream frame + FIN results in connection close. | 868 // Check that stream frame + FIN results in connection close. |
| 881 TestStream* stream = session_.CreateOutgoingDataStream(); | 869 TestStream* stream = session_.CreateOutgoingDataStream(); |
| 882 stream->Reset(QUIC_STREAM_CANCELLED); | 870 stream->Reset(QUIC_STREAM_CANCELLED); |
| 883 QuicStreamFrame frame(stream->id(), true, kLargeOffset, IOVector()); | 871 QuicStreamFrame frame(stream->id(), true, kLargeOffset, IOVector()); |
| 884 vector<QuicStreamFrame> frames; | 872 vector<QuicStreamFrame> frames; |
| 885 frames.push_back(frame); | 873 frames.push_back(frame); |
| 886 session_.OnStreamFrames(frames); | 874 session_.OnStreamFrames(frames); |
| 887 | 875 |
| 888 // Check that RST results in connection close. | 876 // Check that RST results in connection close. |
| 889 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 877 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
| 890 kLargeOffset); | 878 kLargeOffset); |
| 891 session_.OnRstStream(rst_frame); | 879 session_.OnRstStream(rst_frame); |
| 892 } | 880 } |
| 893 | 881 |
| 894 TEST_P(QuicSessionTest, VersionNegotiationDisablesFlowControl) { | 882 TEST_P(QuicSessionTest, VersionNegotiationDisablesFlowControl) { |
| 895 if (version() < QUIC_VERSION_19) { | 883 if (version() < QUIC_VERSION_19) { |
| 896 return; | 884 return; |
| 897 } | 885 } |
| 898 | 886 |
| 899 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, | |
| 900 true); | |
| 901 // Test that after successful version negotiation, flow control is disabled | 887 // Test that after successful version negotiation, flow control is disabled |
| 902 // appropriately at both the connection and stream level. | 888 // appropriately at both the connection and stream level. |
| 903 | 889 |
| 904 // Initially both stream and connection flow control are enabled. | 890 // Initially both stream and connection flow control are enabled. |
| 905 TestStream* stream = session_.CreateOutgoingDataStream(); | 891 TestStream* stream = session_.CreateOutgoingDataStream(); |
| 906 EXPECT_TRUE(stream->flow_controller()->IsEnabled()); | 892 EXPECT_TRUE(stream->flow_controller()->IsEnabled()); |
| 907 EXPECT_TRUE(session_.flow_controller()->IsEnabled()); | 893 EXPECT_TRUE(session_.flow_controller()->IsEnabled()); |
| 908 | 894 |
| 909 // Version 18 implies that stream flow control is enabled, but connection | 895 // Version 18 implies that stream flow control is enabled, but connection |
| 910 // level is disabled. | 896 // level is disabled. |
| 911 session_.OnSuccessfulVersionNegotiation(QUIC_VERSION_18); | 897 session_.OnSuccessfulVersionNegotiation(QUIC_VERSION_18); |
| 912 EXPECT_FALSE(session_.flow_controller()->IsEnabled()); | 898 EXPECT_FALSE(session_.flow_controller()->IsEnabled()); |
| 913 EXPECT_TRUE(stream->flow_controller()->IsEnabled()); | 899 EXPECT_TRUE(stream->flow_controller()->IsEnabled()); |
| 914 | 900 |
| 915 // Version 16 means all flow control is disabled. | 901 // Version 16 means all flow control is disabled. |
| 916 session_.OnSuccessfulVersionNegotiation(QUIC_VERSION_16); | 902 session_.OnSuccessfulVersionNegotiation(QUIC_VERSION_16); |
| 917 EXPECT_FALSE(session_.flow_controller()->IsEnabled()); | 903 EXPECT_FALSE(session_.flow_controller()->IsEnabled()); |
| 918 EXPECT_FALSE(stream->flow_controller()->IsEnabled()); | 904 EXPECT_FALSE(stream->flow_controller()->IsEnabled()); |
| 919 } | 905 } |
| 920 | 906 |
| 907 TEST_P(QuicSessionTest, TooManyUnfinishedStreamsCauseConnectionClose) { |
| 908 if (version() < QUIC_VERSION_18) { |
| 909 return; |
| 910 } |
| 911 // If a buggy/malicious peer creates too many streams that are not ended with |
| 912 // a FIN or RST then we send a connection close. |
| 913 ValueRestore<bool> old_flag(&FLAGS_close_quic_connection_unfinished_streams, |
| 914 true); |
| 915 |
| 916 EXPECT_CALL(*connection_, |
| 917 SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS)).Times(1); |
| 918 |
| 919 const int kMaxStreams = 5; |
| 920 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams); |
| 921 |
| 922 // Create kMaxStreams + 1 data streams, and close them all without receiving a |
| 923 // FIN or a RST from the client. |
| 924 const int kFirstStreamId = kClientDataStreamId1; |
| 925 const int kFinalStreamId = kClientDataStreamId1 + 2 * kMaxStreams + 1; |
| 926 for (int i = kFirstStreamId; i < kFinalStreamId; i += 2) { |
| 927 QuicStreamFrame data1(i, false, 0, MakeIOVector("HT")); |
| 928 vector<QuicStreamFrame> frames; |
| 929 frames.push_back(data1); |
| 930 session_.OnStreamFrames(frames); |
| 931 EXPECT_EQ(1u, session_.GetNumOpenStreams()); |
| 932 session_.CloseStream(i); |
| 933 } |
| 934 } |
| 935 |
| 921 } // namespace | 936 } // namespace |
| 922 } // namespace test | 937 } // namespace test |
| 923 } // namespace net | 938 } // namespace net |
| OLD | NEW |