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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 public: | 52 public: |
53 explicit TestCryptoStream(QuicSession* session) | 53 explicit TestCryptoStream(QuicSession* session) |
54 : QuicCryptoStream(session) { | 54 : QuicCryptoStream(session) { |
55 } | 55 } |
56 | 56 |
57 void OnHandshakeMessage(const CryptoHandshakeMessage& message) override { | 57 void OnHandshakeMessage(const CryptoHandshakeMessage& message) override { |
58 encryption_established_ = true; | 58 encryption_established_ = true; |
59 handshake_confirmed_ = true; | 59 handshake_confirmed_ = true; |
60 CryptoHandshakeMessage msg; | 60 CryptoHandshakeMessage msg; |
61 string error_details; | 61 string error_details; |
62 session()->config()->SetInitialFlowControlWindowToSend( | |
63 kInitialSessionFlowControlWindowForTest); | |
64 session()->config()->SetInitialStreamFlowControlWindowToSend( | 62 session()->config()->SetInitialStreamFlowControlWindowToSend( |
65 kInitialStreamFlowControlWindowForTest); | 63 kInitialStreamFlowControlWindowForTest); |
66 session()->config()->SetInitialSessionFlowControlWindowToSend( | 64 session()->config()->SetInitialSessionFlowControlWindowToSend( |
67 kInitialSessionFlowControlWindowForTest); | 65 kInitialSessionFlowControlWindowForTest); |
68 session()->config()->ToHandshakeMessage(&msg); | 66 session()->config()->ToHandshakeMessage(&msg); |
69 const QuicErrorCode error = session()->config()->ProcessPeerHello( | 67 const QuicErrorCode error = session()->config()->ProcessPeerHello( |
70 msg, CLIENT, &error_details); | 68 msg, CLIENT, &error_details); |
71 EXPECT_EQ(QUIC_NO_ERROR, error); | 69 EXPECT_EQ(QUIC_NO_ERROR, error); |
72 session()->OnConfigNegotiated(); | 70 session()->OnConfigNegotiated(); |
73 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); | 71 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 StrictMock<TestCryptoStream> crypto_stream_; | 179 StrictMock<TestCryptoStream> crypto_stream_; |
182 | 180 |
183 bool writev_consumes_all_data_; | 181 bool writev_consumes_all_data_; |
184 }; | 182 }; |
185 | 183 |
186 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> { | 184 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> { |
187 protected: | 185 protected: |
188 QuicSessionTest() | 186 QuicSessionTest() |
189 : connection_(new MockConnection(true, SupportedVersions(GetParam()))), | 187 : connection_(new MockConnection(true, SupportedVersions(GetParam()))), |
190 session_(connection_) { | 188 session_(connection_) { |
191 session_.config()->SetInitialFlowControlWindowToSend( | |
192 kInitialSessionFlowControlWindowForTest); | |
193 session_.config()->SetInitialStreamFlowControlWindowToSend( | 189 session_.config()->SetInitialStreamFlowControlWindowToSend( |
194 kInitialStreamFlowControlWindowForTest); | 190 kInitialStreamFlowControlWindowForTest); |
195 session_.config()->SetInitialSessionFlowControlWindowToSend( | 191 session_.config()->SetInitialSessionFlowControlWindowToSend( |
196 kInitialSessionFlowControlWindowForTest); | 192 kInitialSessionFlowControlWindowForTest); |
197 headers_[":host"] = "www.google.com"; | 193 headers_[":host"] = "www.google.com"; |
198 headers_[":path"] = "/index.hml"; | 194 headers_[":path"] = "/index.hml"; |
199 headers_[":scheme"] = "http"; | 195 headers_[":scheme"] = "http"; |
200 headers_["cookie"] = | 196 headers_["cookie"] = |
201 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " | 197 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " |
202 "__utmc=160408618; " | 198 "__utmc=160408618; " |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 CryptoHandshakeMessage msg; | 650 CryptoHandshakeMessage msg; |
655 session_.GetCryptoStream()->OnHandshakeMessage(msg); | 651 session_.GetCryptoStream()->OnHandshakeMessage(msg); |
656 | 652 |
657 // Stream is now unblocked. | 653 // Stream is now unblocked. |
658 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); | 654 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); |
659 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 655 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
660 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 656 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
661 } | 657 } |
662 | 658 |
663 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedCryptoStream) { | 659 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedCryptoStream) { |
664 if (version() <= QUIC_VERSION_19) { | |
665 return; | |
666 } | |
667 // Test that if the crypto stream is flow control blocked, then if the SHLO | 660 // Test that if the crypto stream is flow control blocked, then if the SHLO |
668 // contains a larger send window offset, the stream becomes unblocked. | 661 // contains a larger send window offset, the stream becomes unblocked. |
669 session_.set_writev_consumes_all_data(true); | 662 session_.set_writev_consumes_all_data(true); |
670 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); | 663 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); |
671 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); | 664 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
672 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 665 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
673 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 666 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
674 QuicHeadersStream* headers_stream = | 667 QuicHeadersStream* headers_stream = |
675 QuicSessionPeer::GetHeadersStream(&session_); | 668 QuicSessionPeer::GetHeadersStream(&session_); |
676 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); | 669 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
(...skipping 25 matching lines...) Expand all Loading... |
702 CryptoHandshakeMessage msg; | 695 CryptoHandshakeMessage msg; |
703 session_.GetCryptoStream()->OnHandshakeMessage(msg); | 696 session_.GetCryptoStream()->OnHandshakeMessage(msg); |
704 | 697 |
705 // Stream is now unblocked and will no longer have buffered data. | 698 // Stream is now unblocked and will no longer have buffered data. |
706 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); | 699 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
707 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 700 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
708 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 701 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
709 } | 702 } |
710 | 703 |
711 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedHeadersStream) { | 704 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedHeadersStream) { |
712 if (version() <= QUIC_VERSION_19) { | |
713 return; | |
714 } | |
715 // Test that if the header stream is flow control blocked, then if the SHLO | 705 // Test that if the header stream is flow control blocked, then if the SHLO |
716 // contains a larger send window offset, the stream becomes unblocked. | 706 // contains a larger send window offset, the stream becomes unblocked. |
717 session_.set_writev_consumes_all_data(true); | 707 session_.set_writev_consumes_all_data(true); |
718 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); | 708 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); |
719 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); | 709 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
720 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 710 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
721 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 711 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
722 QuicHeadersStream* headers_stream = | 712 QuicHeadersStream* headers_stream = |
723 QuicSessionPeer::GetHeadersStream(&session_); | 713 QuicSessionPeer::GetHeadersStream(&session_); |
724 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); | 714 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
(...skipping 27 matching lines...) Expand all Loading... |
752 CryptoHandshakeMessage msg; | 742 CryptoHandshakeMessage msg; |
753 session_.GetCryptoStream()->OnHandshakeMessage(msg); | 743 session_.GetCryptoStream()->OnHandshakeMessage(msg); |
754 | 744 |
755 // Stream is now unblocked and will no longer have buffered data. | 745 // Stream is now unblocked and will no longer have buffered data. |
756 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); | 746 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
757 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 747 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
758 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 748 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
759 EXPECT_FALSE(headers_stream->HasBufferedData()); | 749 EXPECT_FALSE(headers_stream->HasBufferedData()); |
760 } | 750 } |
761 | 751 |
762 TEST_P(QuicSessionTest, InvalidFlowControlWindowInHandshake) { | |
763 // TODO(rjshade): Remove this test when removing QUIC_VERSION_19. | |
764 // Test that receipt of an invalid (< default) flow control window from | |
765 // the peer results in the connection being torn down. | |
766 if (version() > QUIC_VERSION_19) { | |
767 return; | |
768 } | |
769 | |
770 uint32 kInvalidWindow = kMinimumFlowControlSendWindow - 1; | |
771 QuicConfigPeer::SetReceivedInitialFlowControlWindow(session_.config(), | |
772 kInvalidWindow); | |
773 | |
774 EXPECT_CALL(*connection_, | |
775 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)).Times(2); | |
776 session_.OnConfigNegotiated(); | |
777 } | |
778 | |
779 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) { | 752 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) { |
780 // Test that when we receive an out of order stream RST we correctly adjust | 753 // Test that when we receive an out of order stream RST we correctly adjust |
781 // our connection level flow control receive window. | 754 // our connection level flow control receive window. |
782 // On close, the stream should mark as consumed all bytes between the highest | 755 // On close, the stream should mark as consumed all bytes between the highest |
783 // byte consumed so far and the final byte offset from the RST frame. | 756 // byte consumed so far and the final byte offset from the RST frame. |
784 TestStream* stream = session_.CreateOutgoingDataStream(); | 757 TestStream* stream = session_.CreateOutgoingDataStream(); |
785 | 758 |
786 const QuicStreamOffset kByteOffset = | 759 const QuicStreamOffset kByteOffset = |
787 1 + kInitialSessionFlowControlWindowForTest / 2; | 760 1 + kInitialSessionFlowControlWindowForTest / 2; |
788 | 761 |
(...skipping 24 matching lines...) Expand all Loading... |
813 QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector()); | 786 QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector()); |
814 vector<QuicStreamFrame> frames; | 787 vector<QuicStreamFrame> frames; |
815 frames.push_back(frame); | 788 frames.push_back(frame); |
816 session_.OnStreamFrames(frames); | 789 session_.OnStreamFrames(frames); |
817 session_.PostProcessAfterData(); | 790 session_.PostProcessAfterData(); |
818 | 791 |
819 EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed()); | 792 EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed()); |
820 EXPECT_EQ(kByteOffset, | 793 EXPECT_EQ(kByteOffset, |
821 stream->flow_controller()->highest_received_byte_offset()); | 794 stream->flow_controller()->highest_received_byte_offset()); |
822 | 795 |
823 // We only expect to see a connection WINDOW_UPDATE when talking | |
824 // QUIC_VERSION_19, as in this case both stream and session flow control | |
825 // windows are the same size. In later versions we will not see a connection | |
826 // level WINDOW_UPDATE when exhausting a stream, as the stream flow control | |
827 // limit is much lower than the connection flow control limit. | |
828 if (version() == QUIC_VERSION_19) { | |
829 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. | |
830 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); | |
831 // We do expect a connection level WINDOW_UPDATE when the stream is reset. | |
832 EXPECT_CALL(*connection_, | |
833 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + | |
834 kByteOffset)).Times(1); | |
835 } | |
836 | |
837 // Reset stream locally. | 796 // Reset stream locally. |
838 stream->Reset(QUIC_STREAM_CANCELLED); | 797 stream->Reset(QUIC_STREAM_CANCELLED); |
839 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); | 798 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); |
840 } | 799 } |
841 | 800 |
842 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) { | 801 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) { |
843 // Test that when we RST the stream (and tear down stream state), and then | 802 // Test that when we RST the stream (and tear down stream state), and then |
844 // receive a FIN from the peer, we correctly adjust our connection level flow | 803 // receive a FIN from the peer, we correctly adjust our connection level flow |
845 // control receive window. | 804 // control receive window. |
846 | 805 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 | 866 |
908 EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset, | 867 EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset, |
909 session_.flow_controller()->bytes_consumed()); | 868 session_.flow_controller()->bytes_consumed()); |
910 EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset, | 869 EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset, |
911 session_.flow_controller()->highest_received_byte_offset()); | 870 session_.flow_controller()->highest_received_byte_offset()); |
912 } | 871 } |
913 | 872 |
914 TEST_P(QuicSessionTest, InvalidStreamFlowControlWindowInHandshake) { | 873 TEST_P(QuicSessionTest, InvalidStreamFlowControlWindowInHandshake) { |
915 // Test that receipt of an invalid (< default) stream flow control window from | 874 // Test that receipt of an invalid (< default) stream flow control window from |
916 // the peer results in the connection being torn down. | 875 // the peer results in the connection being torn down. |
917 if (version() <= QUIC_VERSION_19) { | |
918 return; | |
919 } | |
920 | |
921 uint32 kInvalidWindow = kMinimumFlowControlSendWindow - 1; | 876 uint32 kInvalidWindow = kMinimumFlowControlSendWindow - 1; |
922 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(), | 877 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(), |
923 kInvalidWindow); | 878 kInvalidWindow); |
924 | 879 |
925 EXPECT_CALL(*connection_, | 880 EXPECT_CALL(*connection_, |
926 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); | 881 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); |
927 session_.OnConfigNegotiated(); | 882 session_.OnConfigNegotiated(); |
928 } | 883 } |
929 | 884 |
930 TEST_P(QuicSessionTest, InvalidSessionFlowControlWindowInHandshake) { | 885 TEST_P(QuicSessionTest, InvalidSessionFlowControlWindowInHandshake) { |
931 // Test that receipt of an invalid (< default) session flow control window | 886 // Test that receipt of an invalid (< default) session flow control window |
932 // from the peer results in the connection being torn down. | 887 // from the peer results in the connection being torn down. |
933 if (version() == QUIC_VERSION_19) { | |
934 return; | |
935 } | |
936 | |
937 uint32 kInvalidWindow = kMinimumFlowControlSendWindow - 1; | 888 uint32 kInvalidWindow = kMinimumFlowControlSendWindow - 1; |
938 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(), | 889 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(), |
939 kInvalidWindow); | 890 kInvalidWindow); |
940 | 891 |
941 EXPECT_CALL(*connection_, | 892 EXPECT_CALL(*connection_, |
942 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); | 893 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); |
943 session_.OnConfigNegotiated(); | 894 session_.OnConfigNegotiated(); |
944 } | 895 } |
945 | 896 |
946 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { | 897 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { |
(...skipping 14 matching lines...) Expand all Loading... |
961 | 912 |
962 // Check that RST results in connection close. | 913 // Check that RST results in connection close. |
963 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 914 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
964 kLargeOffset); | 915 kLargeOffset); |
965 session_.OnRstStream(rst_frame); | 916 session_.OnRstStream(rst_frame); |
966 } | 917 } |
967 | 918 |
968 TEST_P(QuicSessionTest, WindowUpdateUnblocksHeadersStream) { | 919 TEST_P(QuicSessionTest, WindowUpdateUnblocksHeadersStream) { |
969 // Test that a flow control blocked headers stream gets unblocked on recipt of | 920 // Test that a flow control blocked headers stream gets unblocked on recipt of |
970 // a WINDOW_UPDATE frame. Regression test for b/17413860. | 921 // a WINDOW_UPDATE frame. Regression test for b/17413860. |
971 if (version() < QUIC_VERSION_21) { | |
972 return; | |
973 } | |
974 | 922 |
975 // Set the headers stream to be flow control blocked. | 923 // Set the headers stream to be flow control blocked. |
976 QuicHeadersStream* headers_stream = | 924 QuicHeadersStream* headers_stream = |
977 QuicSessionPeer::GetHeadersStream(&session_); | 925 QuicSessionPeer::GetHeadersStream(&session_); |
978 QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(), | 926 QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(), |
979 0); | 927 0); |
980 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); | 928 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); |
981 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 929 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
982 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); | 930 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); |
983 | 931 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 } | 963 } |
1016 | 964 |
1017 // Called after any new data is received by the session, and triggers the call | 965 // Called after any new data is received by the session, and triggers the call |
1018 // to close the connection. | 966 // to close the connection. |
1019 session_.PostProcessAfterData(); | 967 session_.PostProcessAfterData(); |
1020 } | 968 } |
1021 | 969 |
1022 } // namespace | 970 } // namespace |
1023 } // namespace test | 971 } // namespace test |
1024 } // namespace net | 972 } // namespace net |
OLD | NEW |