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" |
11 #include "base/containers/hash_tables.h" | 11 #include "base/containers/hash_tables.h" |
12 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
| 13 #include "base/stl_util.h" |
13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
14 #include "net/quic/crypto/crypto_protocol.h" | 15 #include "net/quic/crypto/crypto_protocol.h" |
15 #include "net/quic/quic_crypto_stream.h" | 16 #include "net/quic/quic_crypto_stream.h" |
16 #include "net/quic/quic_flags.h" | 17 #include "net/quic/quic_flags.h" |
17 #include "net/quic/quic_protocol.h" | 18 #include "net/quic/quic_protocol.h" |
18 #include "net/quic/quic_utils.h" | 19 #include "net/quic/quic_utils.h" |
19 #include "net/quic/reliable_quic_stream.h" | 20 #include "net/quic/reliable_quic_stream.h" |
20 #include "net/quic/test_tools/quic_config_peer.h" | 21 #include "net/quic/test_tools/quic_config_peer.h" |
21 #include "net/quic/test_tools/quic_connection_peer.h" | 22 #include "net/quic/test_tools/quic_connection_peer.h" |
22 #include "net/quic/test_tools/quic_data_stream_peer.h" | 23 #include "net/quic/test_tools/quic_data_stream_peer.h" |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6" | 221 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6" |
221 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG" | 222 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG" |
222 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk" | 223 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk" |
223 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn" | 224 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn" |
224 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" | 225 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" |
225 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; | 226 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; |
226 } | 227 } |
227 | 228 |
228 void CheckClosedStreams() { | 229 void CheckClosedStreams() { |
229 for (int i = kCryptoStreamId; i < 100; i++) { | 230 for (int i = kCryptoStreamId; i < 100; i++) { |
230 if (closed_streams_.count(i) == 0) { | 231 if (!ContainsKey(closed_streams_, i)) { |
231 EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i; | 232 EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i; |
232 } else { | 233 } else { |
233 EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i; | 234 EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i; |
234 } | 235 } |
235 } | 236 } |
236 } | 237 } |
237 | 238 |
238 void CloseStream(QuicStreamId id) { | 239 void CloseStream(QuicStreamId id) { |
239 session_.CloseStream(id); | 240 session_.CloseStream(id); |
240 closed_streams_.insert(id); | 241 closed_streams_.insert(id); |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 CloseStream(stream6->id()); | 523 CloseStream(stream6->id()); |
523 | 524 |
524 InSequence s; | 525 InSequence s; |
525 EXPECT_CALL(*stream2, OnCanWrite()); | 526 EXPECT_CALL(*stream2, OnCanWrite()); |
526 EXPECT_CALL(*stream4, OnCanWrite()); | 527 EXPECT_CALL(*stream4, OnCanWrite()); |
527 session_.OnCanWrite(); | 528 session_.OnCanWrite(); |
528 EXPECT_FALSE(session_.WillingAndAbleToWrite()); | 529 EXPECT_FALSE(session_.WillingAndAbleToWrite()); |
529 } | 530 } |
530 | 531 |
531 TEST_P(QuicSessionTest, OnCanWriteLimitsNumWritesIfFlowControlBlocked) { | 532 TEST_P(QuicSessionTest, OnCanWriteLimitsNumWritesIfFlowControlBlocked) { |
532 if (version() < QUIC_VERSION_19) { | |
533 return; | |
534 } | |
535 | |
536 // Ensure connection level flow control blockage. | 533 // Ensure connection level flow control blockage. |
537 QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0); | 534 QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0); |
538 EXPECT_TRUE(session_.flow_controller()->IsBlocked()); | 535 EXPECT_TRUE(session_.flow_controller()->IsBlocked()); |
539 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); | 536 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); |
540 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 537 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
541 | 538 |
542 // Mark the crypto and headers streams as write blocked, we expect them to be | 539 // Mark the crypto and headers streams as write blocked, we expect them to be |
543 // allowed to write later. | 540 // allowed to write later. |
544 session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority); | 541 session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority); |
545 session_.MarkWriteBlocked(kHeadersStreamId, kHighestPriority); | 542 session_.MarkWriteBlocked(kHeadersStreamId, kHighestPriority); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); | 722 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
726 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 723 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
727 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 724 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
728 QuicHeadersStream* headers_stream = | 725 QuicHeadersStream* headers_stream = |
729 QuicSessionPeer::GetHeadersStream(&session_); | 726 QuicSessionPeer::GetHeadersStream(&session_); |
730 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); | 727 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
731 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 728 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
732 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 729 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
733 QuicStreamId stream_id = 5; | 730 QuicStreamId stream_id = 5; |
734 // Write until the header stream is flow control blocked. | 731 // Write until the header stream is flow control blocked. |
735 while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) { | 732 while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2010) { |
736 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 733 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
737 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 734 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
738 SpdyHeaderBlock headers; | 735 SpdyHeaderBlock headers; |
739 headers["header"] = base::Uint64ToString(base::RandUint64()) + | 736 headers["header"] = base::Uint64ToString(base::RandUint64()) + |
740 base::Uint64ToString(base::RandUint64()) + | 737 base::Uint64ToString(base::RandUint64()) + |
741 base::Uint64ToString(base::RandUint64()); | 738 base::Uint64ToString(base::RandUint64()); |
742 headers_stream->WriteHeaders(stream_id, headers, true, nullptr); | 739 headers_stream->WriteHeaders(stream_id, headers, true, nullptr); |
743 stream_id += 2; | 740 stream_id += 2; |
744 } | 741 } |
745 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); | 742 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); |
746 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); | 743 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
747 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 744 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
748 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); | 745 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); |
749 EXPECT_FALSE(session_.HasDataToWrite()); | 746 EXPECT_FALSE(session_.HasDataToWrite()); |
750 EXPECT_TRUE(headers_stream->HasBufferedData()); | 747 // TODO(rtenneti): crbug.com/423586 headers_stream->HasBufferedData is flaky. |
| 748 // EXPECT_TRUE(headers_stream->HasBufferedData()); |
751 | 749 |
752 // Now complete the crypto handshake, resulting in an increased flow control | 750 // Now complete the crypto handshake, resulting in an increased flow control |
753 // send window. | 751 // send window. |
754 CryptoHandshakeMessage msg; | 752 CryptoHandshakeMessage msg; |
755 session_.GetCryptoStream()->OnHandshakeMessage(msg); | 753 session_.GetCryptoStream()->OnHandshakeMessage(msg); |
756 | 754 |
757 // Stream is now unblocked and will no longer have buffered data. | 755 // Stream is now unblocked and will no longer have buffered data. |
758 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); | 756 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
759 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 757 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
760 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 758 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
(...skipping 10 matching lines...) Expand all Loading... |
771 | 769 |
772 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; | 770 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; |
773 QuicConfigPeer::SetReceivedInitialFlowControlWindow(session_.config(), | 771 QuicConfigPeer::SetReceivedInitialFlowControlWindow(session_.config(), |
774 kInvalidWindow); | 772 kInvalidWindow); |
775 | 773 |
776 EXPECT_CALL(*connection_, | 774 EXPECT_CALL(*connection_, |
777 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)).Times(2); | 775 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)).Times(2); |
778 session_.OnConfigNegotiated(); | 776 session_.OnConfigNegotiated(); |
779 } | 777 } |
780 | 778 |
781 TEST_P(QuicSessionTest, InvalidStreamFlowControlWindowInHandshake) { | |
782 // Test that receipt of an invalid (< default) stream flow control window from | |
783 // the peer results in the connection being torn down. | |
784 if (version() <= QUIC_VERSION_19) { | |
785 return; | |
786 } | |
787 | |
788 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; | |
789 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(), | |
790 kInvalidWindow); | |
791 | |
792 EXPECT_CALL(*connection_, | |
793 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); | |
794 session_.OnConfigNegotiated(); | |
795 } | |
796 | |
797 TEST_P(QuicSessionTest, InvalidSessionFlowControlWindowInHandshake) { | |
798 // Test that receipt of an invalid (< default) session flow control window | |
799 // from the peer results in the connection being torn down. | |
800 if (version() <= QUIC_VERSION_19) { | |
801 return; | |
802 } | |
803 | |
804 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; | |
805 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(), | |
806 kInvalidWindow); | |
807 | |
808 EXPECT_CALL(*connection_, | |
809 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); | |
810 session_.OnConfigNegotiated(); | |
811 } | |
812 | |
813 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) { | 779 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) { |
814 if (version() < QUIC_VERSION_19) { | |
815 return; | |
816 } | |
817 | |
818 // 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 |
819 // our connection level flow control receive window. | 781 // our connection level flow control receive window. |
820 // On close, the stream should mark as consumed all bytes between the highest | 782 // On close, the stream should mark as consumed all bytes between the highest |
821 // byte consumed so far and the final byte offset from the RST frame. | 783 // byte consumed so far and the final byte offset from the RST frame. |
822 TestStream* stream = session_.CreateOutgoingDataStream(); | 784 TestStream* stream = session_.CreateOutgoingDataStream(); |
823 | 785 |
824 const QuicStreamOffset kByteOffset = | 786 const QuicStreamOffset kByteOffset = |
825 1 + kInitialSessionFlowControlWindowForTest / 2; | 787 1 + kInitialSessionFlowControlWindowForTest / 2; |
826 | 788 |
827 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. | 789 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. |
828 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); | 790 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); |
829 // We do expect a connection level WINDOW_UPDATE when the stream is reset. | 791 // We do expect a connection level WINDOW_UPDATE when the stream is reset. |
830 EXPECT_CALL(*connection_, | 792 EXPECT_CALL(*connection_, |
831 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + | 793 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + |
832 kByteOffset)).Times(1); | 794 kByteOffset)).Times(1); |
833 | 795 |
834 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 796 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
835 kByteOffset); | 797 kByteOffset); |
836 session_.OnRstStream(rst_frame); | 798 session_.OnRstStream(rst_frame); |
837 session_.PostProcessAfterData(); | 799 session_.PostProcessAfterData(); |
838 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); | 800 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); |
839 } | 801 } |
840 | 802 |
841 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAndLocalReset) { | 803 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAndLocalReset) { |
842 if (version() < QUIC_VERSION_19) { | |
843 return; | |
844 } | |
845 | |
846 // Test the situation where we receive a FIN on a stream, and before we fully | 804 // Test the situation where we receive a FIN on a stream, and before we fully |
847 // consume all the data from the sequencer buffer we locally RST the stream. | 805 // consume all the data from the sequencer buffer we locally RST the stream. |
848 // The bytes between highest consumed byte, and the final byte offset that we | 806 // The bytes between highest consumed byte, and the final byte offset that we |
849 // determined when the FIN arrived, should be marked as consumed at the | 807 // determined when the FIN arrived, should be marked as consumed at the |
850 // connection level flow controller when the stream is reset. | 808 // connection level flow controller when the stream is reset. |
851 TestStream* stream = session_.CreateOutgoingDataStream(); | 809 TestStream* stream = session_.CreateOutgoingDataStream(); |
852 | 810 |
853 const QuicStreamOffset kByteOffset = | 811 const QuicStreamOffset kByteOffset = |
854 1 + kInitialSessionFlowControlWindowForTest / 2; | 812 1 + kInitialSessionFlowControlWindowForTest / 2; |
855 QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector()); | 813 QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector()); |
(...skipping 22 matching lines...) Expand all Loading... |
878 | 836 |
879 // Reset stream locally. | 837 // Reset stream locally. |
880 stream->Reset(QUIC_STREAM_CANCELLED); | 838 stream->Reset(QUIC_STREAM_CANCELLED); |
881 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); | 839 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); |
882 } | 840 } |
883 | 841 |
884 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) { | 842 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) { |
885 // Test that when we RST the stream (and tear down stream state), and then | 843 // Test that when we RST the stream (and tear down stream state), and then |
886 // receive a FIN from the peer, we correctly adjust our connection level flow | 844 // receive a FIN from the peer, we correctly adjust our connection level flow |
887 // control receive window. | 845 // control receive window. |
888 if (version() < QUIC_VERSION_19) { | |
889 return; | |
890 } | |
891 | 846 |
892 // Connection starts with some non-zero highest received byte offset, | 847 // Connection starts with some non-zero highest received byte offset, |
893 // due to other active streams. | 848 // due to other active streams. |
894 const uint64 kInitialConnectionBytesConsumed = 567; | 849 const uint64 kInitialConnectionBytesConsumed = 567; |
895 const uint64 kInitialConnectionHighestReceivedOffset = 1234; | 850 const uint64 kInitialConnectionHighestReceivedOffset = 1234; |
896 EXPECT_LT(kInitialConnectionBytesConsumed, | 851 EXPECT_LT(kInitialConnectionBytesConsumed, |
897 kInitialConnectionHighestReceivedOffset); | 852 kInitialConnectionHighestReceivedOffset); |
898 session_.flow_controller()->UpdateHighestReceivedOffset( | 853 session_.flow_controller()->UpdateHighestReceivedOffset( |
899 kInitialConnectionHighestReceivedOffset); | 854 kInitialConnectionHighestReceivedOffset); |
900 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); | 855 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); |
(...skipping 19 matching lines...) Expand all Loading... |
920 session_.flow_controller()->bytes_consumed()); | 875 session_.flow_controller()->bytes_consumed()); |
921 EXPECT_EQ( | 876 EXPECT_EQ( |
922 kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer, | 877 kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer, |
923 session_.flow_controller()->highest_received_byte_offset()); | 878 session_.flow_controller()->highest_received_byte_offset()); |
924 } | 879 } |
925 | 880 |
926 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstAfterRst) { | 881 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstAfterRst) { |
927 // Test that when we RST the stream (and tear down stream state), and then | 882 // Test that when we RST the stream (and tear down stream state), and then |
928 // receive a RST from the peer, we correctly adjust our connection level flow | 883 // receive a RST from the peer, we correctly adjust our connection level flow |
929 // control receive window. | 884 // control receive window. |
930 if (version() < QUIC_VERSION_19) { | |
931 return; | |
932 } | |
933 | 885 |
934 // Connection starts with some non-zero highest received byte offset, | 886 // Connection starts with some non-zero highest received byte offset, |
935 // due to other active streams. | 887 // due to other active streams. |
936 const uint64 kInitialConnectionBytesConsumed = 567; | 888 const uint64 kInitialConnectionBytesConsumed = 567; |
937 const uint64 kInitialConnectionHighestReceivedOffset = 1234; | 889 const uint64 kInitialConnectionHighestReceivedOffset = 1234; |
938 EXPECT_LT(kInitialConnectionBytesConsumed, | 890 EXPECT_LT(kInitialConnectionBytesConsumed, |
939 kInitialConnectionHighestReceivedOffset); | 891 kInitialConnectionHighestReceivedOffset); |
940 session_.flow_controller()->UpdateHighestReceivedOffset( | 892 session_.flow_controller()->UpdateHighestReceivedOffset( |
941 kInitialConnectionHighestReceivedOffset); | 893 kInitialConnectionHighestReceivedOffset); |
942 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); | 894 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); |
943 | 895 |
944 // Reset our stream: this results in the stream being closed locally. | 896 // Reset our stream: this results in the stream being closed locally. |
945 TestStream* stream = session_.CreateOutgoingDataStream(); | 897 TestStream* stream = session_.CreateOutgoingDataStream(); |
946 stream->Reset(QUIC_STREAM_CANCELLED); | 898 stream->Reset(QUIC_STREAM_CANCELLED); |
947 | 899 |
948 // Now receive a RST from the peer. We should handle this by adjusting the | 900 // Now receive a RST from the peer. We should handle this by adjusting the |
949 // connection level flow control receive window to take into account the total | 901 // connection level flow control receive window to take into account the total |
950 // number of bytes sent by the peer. | 902 // number of bytes sent by the peer. |
951 const QuicStreamOffset kByteOffset = 5678; | 903 const QuicStreamOffset kByteOffset = 5678; |
952 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 904 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
953 kByteOffset); | 905 kByteOffset); |
954 session_.OnRstStream(rst_frame); | 906 session_.OnRstStream(rst_frame); |
955 | 907 |
956 EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset, | 908 EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset, |
957 session_.flow_controller()->bytes_consumed()); | 909 session_.flow_controller()->bytes_consumed()); |
958 EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset, | 910 EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset, |
959 session_.flow_controller()->highest_received_byte_offset()); | 911 session_.flow_controller()->highest_received_byte_offset()); |
960 } | 912 } |
961 | 913 |
| 914 TEST_P(QuicSessionTest, InvalidStreamFlowControlWindowInHandshake) { |
| 915 // Test that receipt of an invalid (< default) stream flow control window from |
| 916 // the peer results in the connection being torn down. |
| 917 if (version() <= QUIC_VERSION_19) { |
| 918 return; |
| 919 } |
| 920 |
| 921 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; |
| 922 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(), |
| 923 kInvalidWindow); |
| 924 |
| 925 EXPECT_CALL(*connection_, |
| 926 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); |
| 927 session_.OnConfigNegotiated(); |
| 928 } |
| 929 |
| 930 TEST_P(QuicSessionTest, InvalidSessionFlowControlWindowInHandshake) { |
| 931 // Test that receipt of an invalid (< default) session flow control window |
| 932 // from the peer results in the connection being torn down. |
| 933 if (version() == QUIC_VERSION_19) { |
| 934 return; |
| 935 } |
| 936 |
| 937 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; |
| 938 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(), |
| 939 kInvalidWindow); |
| 940 |
| 941 EXPECT_CALL(*connection_, |
| 942 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); |
| 943 session_.OnConfigNegotiated(); |
| 944 } |
| 945 |
962 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { | 946 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { |
963 // 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 |
964 // violates flow control, that we close the connection. | 948 // violates flow control, that we close the connection. |
965 const uint64 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; | 949 const uint64 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; |
966 EXPECT_CALL(*connection_, | 950 EXPECT_CALL(*connection_, |
967 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)) | 951 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)) |
968 .Times(2); | 952 .Times(2); |
969 | 953 |
970 // Check that stream frame + FIN results in connection close. | 954 // Check that stream frame + FIN results in connection close. |
971 TestStream* stream = session_.CreateOutgoingDataStream(); | 955 TestStream* stream = session_.CreateOutgoingDataStream(); |
972 stream->Reset(QUIC_STREAM_CANCELLED); | 956 stream->Reset(QUIC_STREAM_CANCELLED); |
973 QuicStreamFrame frame(stream->id(), true, kLargeOffset, IOVector()); | 957 QuicStreamFrame frame(stream->id(), true, kLargeOffset, IOVector()); |
974 vector<QuicStreamFrame> frames; | 958 vector<QuicStreamFrame> frames; |
975 frames.push_back(frame); | 959 frames.push_back(frame); |
976 session_.OnStreamFrames(frames); | 960 session_.OnStreamFrames(frames); |
977 | 961 |
978 // Check that RST results in connection close. | 962 // Check that RST results in connection close. |
979 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 963 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
980 kLargeOffset); | 964 kLargeOffset); |
981 session_.OnRstStream(rst_frame); | 965 session_.OnRstStream(rst_frame); |
982 } | 966 } |
983 | 967 |
984 TEST_P(QuicSessionTest, VersionNegotiationDisablesFlowControl) { | |
985 if (version() < QUIC_VERSION_19) { | |
986 return; | |
987 } | |
988 | |
989 // Test that after successful version negotiation, flow control is disabled | |
990 // appropriately at both the connection and stream level. | |
991 | |
992 // Initially both stream and connection flow control are enabled. | |
993 TestStream* stream = session_.CreateOutgoingDataStream(); | |
994 EXPECT_TRUE(stream->flow_controller()->IsEnabled()); | |
995 EXPECT_TRUE(session_.flow_controller()->IsEnabled()); | |
996 | |
997 // Version 18 implies that stream flow control is enabled, but connection | |
998 // level is disabled. | |
999 session_.OnSuccessfulVersionNegotiation(QUIC_VERSION_18); | |
1000 EXPECT_FALSE(session_.flow_controller()->IsEnabled()); | |
1001 EXPECT_TRUE(stream->flow_controller()->IsEnabled()); | |
1002 } | |
1003 | |
1004 TEST_P(QuicSessionTest, WindowUpdateUnblocksHeadersStream) { | 968 TEST_P(QuicSessionTest, WindowUpdateUnblocksHeadersStream) { |
1005 // Test that a flow control blocked headers stream gets unblocked on recipt of | 969 // Test that a flow control blocked headers stream gets unblocked on recipt of |
1006 // a WINDOW_UPDATE frame. Regression test for b/17413860. | 970 // a WINDOW_UPDATE frame. Regression test for b/17413860. |
1007 if (version() < QUIC_VERSION_21) { | 971 if (version() < QUIC_VERSION_21) { |
1008 return; | 972 return; |
1009 } | 973 } |
1010 | 974 |
1011 // Set the headers stream to be flow control blocked. | 975 // Set the headers stream to be flow control blocked. |
1012 QuicHeadersStream* headers_stream = | 976 QuicHeadersStream* headers_stream = |
1013 QuicSessionPeer::GetHeadersStream(&session_); | 977 QuicSessionPeer::GetHeadersStream(&session_); |
1014 QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(), | 978 QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(), |
1015 0); | 979 0); |
1016 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); | 980 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); |
1017 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 981 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
1018 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); | 982 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); |
1019 | 983 |
1020 // Unblock the headers stream by supplying a WINDOW_UPDATE. | 984 // Unblock the headers stream by supplying a WINDOW_UPDATE. |
1021 QuicWindowUpdateFrame window_update_frame(headers_stream->id(), | 985 QuicWindowUpdateFrame window_update_frame(headers_stream->id(), |
1022 2 * kDefaultFlowControlSendWindow); | 986 2 * kDefaultFlowControlSendWindow); |
1023 vector<QuicWindowUpdateFrame> frames; | 987 vector<QuicWindowUpdateFrame> frames; |
1024 frames.push_back(window_update_frame); | 988 frames.push_back(window_update_frame); |
1025 session_.OnWindowUpdateFrames(frames); | 989 session_.OnWindowUpdateFrames(frames); |
1026 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); | 990 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
1027 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 991 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
1028 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 992 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
1029 } | 993 } |
1030 | 994 |
1031 TEST_P(QuicSessionTest, TooManyUnfinishedStreamsCauseConnectionClose) { | 995 TEST_P(QuicSessionTest, TooManyUnfinishedStreamsCauseConnectionClose) { |
1032 if (version() < QUIC_VERSION_18) { | |
1033 return; | |
1034 } | |
1035 // 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 |
1036 // a FIN or RST then we send a connection close. | 997 // a FIN or RST then we send a connection close. |
1037 ValueRestore<bool> old_flag(&FLAGS_close_quic_connection_unfinished_streams_2, | 998 ValueRestore<bool> old_flag(&FLAGS_close_quic_connection_unfinished_streams_2, |
1038 true); | 999 true); |
1039 | 1000 |
1040 EXPECT_CALL(*connection_, | 1001 EXPECT_CALL(*connection_, |
1041 SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS)).Times(1); | 1002 SendConnectionClose(QUIC_TOO_MANY_UNFINISHED_STREAMS)).Times(1); |
1042 | 1003 |
1043 const int kMaxStreams = 5; | 1004 const int kMaxStreams = 5; |
1044 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams); | 1005 QuicSessionPeer::SetMaxOpenStreams(&session_, kMaxStreams); |
(...skipping 12 matching lines...) Expand all Loading... |
1057 } | 1018 } |
1058 | 1019 |
1059 // Called after any new data is received by the session, and triggers the call | 1020 // Called after any new data is received by the session, and triggers the call |
1060 // to close the connection. | 1021 // to close the connection. |
1061 session_.PostProcessAfterData(); | 1022 session_.PostProcessAfterData(); |
1062 } | 1023 } |
1063 | 1024 |
1064 } // namespace | 1025 } // namespace |
1065 } // namespace test | 1026 } // namespace test |
1066 } // namespace net | 1027 } // namespace net |
OLD | NEW |