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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 : QuicCryptoStream(session) { | 51 : QuicCryptoStream(session) { |
52 } | 52 } |
53 | 53 |
54 virtual void OnHandshakeMessage( | 54 virtual void OnHandshakeMessage( |
55 const CryptoHandshakeMessage& message) OVERRIDE { | 55 const CryptoHandshakeMessage& message) OVERRIDE { |
56 encryption_established_ = true; | 56 encryption_established_ = true; |
57 handshake_confirmed_ = true; | 57 handshake_confirmed_ = true; |
58 CryptoHandshakeMessage msg; | 58 CryptoHandshakeMessage msg; |
59 string error_details; | 59 string error_details; |
60 session()->config()->SetInitialFlowControlWindowToSend( | 60 session()->config()->SetInitialFlowControlWindowToSend( |
61 kInitialFlowControlWindowForTest); | 61 kInitialSessionFlowControlWindowForTest); |
| 62 session()->config()->SetInitialStreamFlowControlWindowToSend( |
| 63 kInitialStreamFlowControlWindowForTest); |
| 64 session()->config()->SetInitialSessionFlowControlWindowToSend( |
| 65 kInitialSessionFlowControlWindowForTest); |
62 session()->config()->ToHandshakeMessage(&msg); | 66 session()->config()->ToHandshakeMessage(&msg); |
63 const QuicErrorCode error = session()->config()->ProcessPeerHello( | 67 const QuicErrorCode error = session()->config()->ProcessPeerHello( |
64 msg, CLIENT, &error_details); | 68 msg, CLIENT, &error_details); |
65 EXPECT_EQ(QUIC_NO_ERROR, error); | 69 EXPECT_EQ(QUIC_NO_ERROR, error); |
66 session()->OnConfigNegotiated(); | 70 session()->OnConfigNegotiated(); |
67 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); | 71 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); |
68 } | 72 } |
69 | 73 |
70 MOCK_METHOD0(OnCanWrite, void()); | 74 MOCK_METHOD0(OnCanWrite, void()); |
71 }; | 75 }; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 | 180 |
177 bool writev_consumes_all_data_; | 181 bool writev_consumes_all_data_; |
178 }; | 182 }; |
179 | 183 |
180 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> { | 184 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> { |
181 protected: | 185 protected: |
182 QuicSessionTest() | 186 QuicSessionTest() |
183 : connection_(new MockConnection(true, SupportedVersions(GetParam()))), | 187 : connection_(new MockConnection(true, SupportedVersions(GetParam()))), |
184 session_(connection_) { | 188 session_(connection_) { |
185 session_.config()->SetInitialFlowControlWindowToSend( | 189 session_.config()->SetInitialFlowControlWindowToSend( |
186 kInitialFlowControlWindowForTest); | 190 kInitialSessionFlowControlWindowForTest); |
| 191 session_.config()->SetInitialStreamFlowControlWindowToSend( |
| 192 kInitialStreamFlowControlWindowForTest); |
| 193 session_.config()->SetInitialSessionFlowControlWindowToSend( |
| 194 kInitialSessionFlowControlWindowForTest); |
187 headers_[":host"] = "www.google.com"; | 195 headers_[":host"] = "www.google.com"; |
188 headers_[":path"] = "/index.hml"; | 196 headers_[":path"] = "/index.hml"; |
189 headers_[":scheme"] = "http"; | 197 headers_[":scheme"] = "http"; |
190 headers_["cookie"] = | 198 headers_["cookie"] = |
191 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " | 199 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " |
192 "__utmc=160408618; " | 200 "__utmc=160408618; " |
193 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX" | 201 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX" |
194 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX" | 202 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX" |
195 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT" | 203 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT" |
196 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0" | 204 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0" |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 // Now complete the crypto handshake, resulting in an increased flow control | 650 // Now complete the crypto handshake, resulting in an increased flow control |
643 // send window. | 651 // send window. |
644 CryptoHandshakeMessage msg; | 652 CryptoHandshakeMessage msg; |
645 session_.GetCryptoStream()->OnHandshakeMessage(msg); | 653 session_.GetCryptoStream()->OnHandshakeMessage(msg); |
646 | 654 |
647 // Stream is now unblocked. | 655 // Stream is now unblocked. |
648 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); | 656 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); |
649 } | 657 } |
650 | 658 |
651 TEST_P(QuicSessionTest, InvalidFlowControlWindowInHandshake) { | 659 TEST_P(QuicSessionTest, InvalidFlowControlWindowInHandshake) { |
652 // Test that receipt of an invalid (< default) flow control window from peer | 660 // TODO(rjshade): Remove this test when removing QUIC_VERSION_19. |
653 // results in the connection being torn down. | 661 // Test that receipt of an invalid (< default) flow control window from |
654 if (version() < QUIC_VERSION_17) { | 662 // the peer results in the connection being torn down. |
| 663 if (version() <= QUIC_VERSION_16 || version() > QUIC_VERSION_19) { |
655 return; | 664 return; |
656 } | 665 } |
657 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); | 666 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); |
658 | 667 |
659 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; | 668 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; |
660 QuicConfigPeer::SetReceivedInitialFlowControlWindow(session_.config(), | 669 QuicConfigPeer::SetReceivedInitialFlowControlWindow(session_.config(), |
661 kInvalidWindow); | 670 kInvalidWindow); |
662 | 671 |
663 EXPECT_CALL(*connection_, | 672 EXPECT_CALL(*connection_, |
664 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)).Times(2); | 673 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)).Times(2); |
665 session_.OnConfigNegotiated(); | 674 session_.OnConfigNegotiated(); |
666 } | 675 } |
667 | 676 |
| 677 TEST_P(QuicSessionTest, InvalidStreamFlowControlWindowInHandshake) { |
| 678 // Test that receipt of an invalid (< default) stream flow control window from |
| 679 // the peer results in the connection being torn down. |
| 680 if (version() <= QUIC_VERSION_19) { |
| 681 return; |
| 682 } |
| 683 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); |
| 684 |
| 685 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; |
| 686 QuicConfigPeer::SetReceivedInitialStreamFlowControlWindow(session_.config(), |
| 687 kInvalidWindow); |
| 688 |
| 689 EXPECT_CALL(*connection_, |
| 690 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); |
| 691 session_.OnConfigNegotiated(); |
| 692 } |
| 693 |
| 694 TEST_P(QuicSessionTest, InvalidSessionFlowControlWindowInHandshake) { |
| 695 // Test that receipt of an invalid (< default) session flow control window |
| 696 // from the peer results in the connection being torn down. |
| 697 if (version() <= QUIC_VERSION_19) { |
| 698 return; |
| 699 } |
| 700 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); |
| 701 |
| 702 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; |
| 703 QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(), |
| 704 kInvalidWindow); |
| 705 |
| 706 EXPECT_CALL(*connection_, |
| 707 SendConnectionClose(QUIC_FLOW_CONTROL_INVALID_WINDOW)); |
| 708 session_.OnConfigNegotiated(); |
| 709 } |
| 710 |
668 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) { | 711 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingRstOutOfOrder) { |
669 if (version() < QUIC_VERSION_19) { | 712 if (version() < QUIC_VERSION_19) { |
670 return; | 713 return; |
671 } | 714 } |
672 | 715 |
673 ValueRestore<bool> old_flag2(&FLAGS_enable_quic_stream_flow_control_2, true); | 716 ValueRestore<bool> old_flag2(&FLAGS_enable_quic_stream_flow_control_2, true); |
674 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, | 717 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, |
675 true); | 718 true); |
676 // Test that when we receive an out of order stream RST we correctly adjust | 719 // Test that when we receive an out of order stream RST we correctly adjust |
677 // our connection level flow control receive window. | 720 // our connection level flow control receive window. |
678 // On close, the stream should mark as consumed all bytes between the highest | 721 // On close, the stream should mark as consumed all bytes between the highest |
679 // byte consumed so far and the final byte offset from the RST frame. | 722 // byte consumed so far and the final byte offset from the RST frame. |
680 TestStream* stream = session_.CreateOutgoingDataStream(); | 723 TestStream* stream = session_.CreateOutgoingDataStream(); |
681 | 724 |
682 const QuicStreamOffset kByteOffset = 1 + kInitialFlowControlWindowForTest / 2; | 725 const QuicStreamOffset kByteOffset = |
| 726 1 + kInitialSessionFlowControlWindowForTest / 2; |
| 727 |
683 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. | 728 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. |
684 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); | 729 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); |
685 // We do expect a connection level WINDOW_UPDATE when the stream is reset. | 730 // We do expect a connection level WINDOW_UPDATE when the stream is reset. |
686 EXPECT_CALL(*connection_, | 731 EXPECT_CALL(*connection_, |
687 SendWindowUpdate( | 732 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + |
688 0, kInitialFlowControlWindowForTest + kByteOffset)).Times(1); | 733 kByteOffset)).Times(1); |
689 | 734 |
690 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 735 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
691 kByteOffset); | 736 kByteOffset); |
692 session_.OnRstStream(rst_frame); | 737 session_.OnRstStream(rst_frame); |
693 session_.PostProcessAfterData(); | 738 session_.PostProcessAfterData(); |
694 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); | 739 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); |
695 } | 740 } |
696 | 741 |
697 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAndLocalReset) { | 742 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAndLocalReset) { |
698 if (version() < QUIC_VERSION_19) { | 743 if (version() < QUIC_VERSION_19) { |
699 return; | 744 return; |
700 } | 745 } |
701 | 746 |
702 ValueRestore<bool> old_flag2(&FLAGS_enable_quic_stream_flow_control_2, true); | 747 ValueRestore<bool> old_flag2(&FLAGS_enable_quic_stream_flow_control_2, true); |
703 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, | 748 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, |
704 true); | 749 true); |
705 // Test the situation where we receive a FIN on a stream, and before we fully | 750 // Test the situation where we receive a FIN on a stream, and before we fully |
706 // consume all the data from the sequencer buffer we locally RST the stream. | 751 // consume all the data from the sequencer buffer we locally RST the stream. |
707 // The bytes between highest consumed byte, and the final byte offset that we | 752 // The bytes between highest consumed byte, and the final byte offset that we |
708 // determined when the FIN arrived, should be marked as consumed at the | 753 // determined when the FIN arrived, should be marked as consumed at the |
709 // connection level flow controller when the stream is reset. | 754 // connection level flow controller when the stream is reset. |
710 TestStream* stream = session_.CreateOutgoingDataStream(); | 755 TestStream* stream = session_.CreateOutgoingDataStream(); |
711 | 756 |
712 const QuicStreamOffset kByteOffset = 1 + kInitialFlowControlWindowForTest / 2; | 757 const QuicStreamOffset kByteOffset = |
| 758 1 + kInitialSessionFlowControlWindowForTest / 2; |
713 QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector()); | 759 QuicStreamFrame frame(stream->id(), true, kByteOffset, IOVector()); |
714 vector<QuicStreamFrame> frames; | 760 vector<QuicStreamFrame> frames; |
715 frames.push_back(frame); | 761 frames.push_back(frame); |
716 session_.OnStreamFrames(frames); | 762 session_.OnStreamFrames(frames); |
717 session_.PostProcessAfterData(); | 763 session_.PostProcessAfterData(); |
718 | 764 |
719 EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed()); | 765 EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed()); |
720 EXPECT_EQ(kByteOffset, | 766 EXPECT_EQ(kByteOffset, |
721 stream->flow_controller()->highest_received_byte_offset()); | 767 stream->flow_controller()->highest_received_byte_offset()); |
722 | 768 |
723 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. | 769 // We only expect to see a connection WINDOW_UPDATE when talking |
724 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); | 770 // QUIC_VERSION_19, as in this case both stream and session flow control |
725 // We do expect a connection level WINDOW_UPDATE when the stream is reset. | 771 // windows are the same size. In later versions we will not see a connection |
726 EXPECT_CALL(*connection_, | 772 // level WINDOW_UPDATE when exhausting a stream, as the stream flow control |
727 SendWindowUpdate( | 773 // limit is much lower than the connection flow control limit. |
728 0, kInitialFlowControlWindowForTest + kByteOffset)).Times(1); | 774 if (version() == QUIC_VERSION_19) { |
| 775 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. |
| 776 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); |
| 777 // We do expect a connection level WINDOW_UPDATE when the stream is reset. |
| 778 EXPECT_CALL(*connection_, |
| 779 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + |
| 780 kByteOffset)).Times(1); |
| 781 } |
729 | 782 |
730 // Reset stream locally. | 783 // Reset stream locally. |
731 stream->Reset(QUIC_STREAM_CANCELLED); | 784 stream->Reset(QUIC_STREAM_CANCELLED); |
732 | |
733 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); | 785 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); |
734 } | 786 } |
735 | 787 |
736 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) { | 788 TEST_P(QuicSessionTest, ConnectionFlowControlAccountingFinAfterRst) { |
737 // Test that when we RST the stream (and tear down stream state), and then | 789 // Test that when we RST the stream (and tear down stream state), and then |
738 // receive a FIN from the peer, we correctly adjust our connection level flow | 790 // receive a FIN from the peer, we correctly adjust our connection level flow |
739 // control receive window. | 791 // control receive window. |
740 if (version() < QUIC_VERSION_19) { | 792 if (version() < QUIC_VERSION_19) { |
741 return; | 793 return; |
742 } | 794 } |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { | 872 TEST_P(QuicSessionTest, FlowControlWithInvalidFinalOffset) { |
821 // Test that if we receive a stream RST with a highest byte offset that | 873 // Test that if we receive a stream RST with a highest byte offset that |
822 // violates flow control, that we close the connection. | 874 // violates flow control, that we close the connection. |
823 if (version() < QUIC_VERSION_17) { | 875 if (version() < QUIC_VERSION_17) { |
824 return; | 876 return; |
825 } | 877 } |
826 ValueRestore<bool> old_flag2(&FLAGS_enable_quic_stream_flow_control_2, true); | 878 ValueRestore<bool> old_flag2(&FLAGS_enable_quic_stream_flow_control_2, true); |
827 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, | 879 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2, |
828 true); | 880 true); |
829 | 881 |
830 const uint64 kLargeOffset = kInitialFlowControlWindowForTest + 1; | 882 const uint64 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; |
831 EXPECT_CALL(*connection_, | 883 EXPECT_CALL(*connection_, |
832 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)) | 884 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)) |
833 .Times(2); | 885 .Times(2); |
834 | 886 |
835 // Check that stream frame + FIN results in connection close. | 887 // Check that stream frame + FIN results in connection close. |
836 TestStream* stream = session_.CreateOutgoingDataStream(); | 888 TestStream* stream = session_.CreateOutgoingDataStream(); |
837 stream->Reset(QUIC_STREAM_CANCELLED); | 889 stream->Reset(QUIC_STREAM_CANCELLED); |
838 QuicStreamFrame frame(stream->id(), true, kLargeOffset, IOVector()); | 890 QuicStreamFrame frame(stream->id(), true, kLargeOffset, IOVector()); |
839 vector<QuicStreamFrame> frames; | 891 vector<QuicStreamFrame> frames; |
840 frames.push_back(frame); | 892 frames.push_back(frame); |
(...skipping 29 matching lines...) Expand all Loading... |
870 | 922 |
871 // Version 16 means all flow control is disabled. | 923 // Version 16 means all flow control is disabled. |
872 session_.OnSuccessfulVersionNegotiation(QUIC_VERSION_16); | 924 session_.OnSuccessfulVersionNegotiation(QUIC_VERSION_16); |
873 EXPECT_FALSE(session_.flow_controller()->IsEnabled()); | 925 EXPECT_FALSE(session_.flow_controller()->IsEnabled()); |
874 EXPECT_FALSE(stream->flow_controller()->IsEnabled()); | 926 EXPECT_FALSE(stream->flow_controller()->IsEnabled()); |
875 } | 927 } |
876 | 928 |
877 } // namespace | 929 } // namespace |
878 } // namespace test | 930 } // namespace test |
879 } // namespace net | 931 } // namespace net |
OLD | NEW |