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 |