| 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 |