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" |
| 13 #include "base/strings/string_number_conversions.h" |
12 #include "net/quic/crypto/crypto_protocol.h" | 14 #include "net/quic/crypto/crypto_protocol.h" |
13 #include "net/quic/quic_crypto_stream.h" | 15 #include "net/quic/quic_crypto_stream.h" |
14 #include "net/quic/quic_flags.h" | 16 #include "net/quic/quic_flags.h" |
15 #include "net/quic/quic_protocol.h" | 17 #include "net/quic/quic_protocol.h" |
16 #include "net/quic/quic_utils.h" | 18 #include "net/quic/quic_utils.h" |
17 #include "net/quic/reliable_quic_stream.h" | 19 #include "net/quic/reliable_quic_stream.h" |
18 #include "net/quic/test_tools/quic_config_peer.h" | 20 #include "net/quic/test_tools/quic_config_peer.h" |
19 #include "net/quic/test_tools/quic_connection_peer.h" | 21 #include "net/quic/test_tools/quic_connection_peer.h" |
20 #include "net/quic/test_tools/quic_data_stream_peer.h" | 22 #include "net/quic/test_tools/quic_data_stream_peer.h" |
21 #include "net/quic/test_tools/quic_flow_controller_peer.h" | 23 #include "net/quic/test_tools/quic_flow_controller_peer.h" |
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 EXPECT_CALL(*stream2, OnCanWrite()); | 651 EXPECT_CALL(*stream2, OnCanWrite()); |
650 // Now complete the crypto handshake, resulting in an increased flow control | 652 // Now complete the crypto handshake, resulting in an increased flow control |
651 // send window. | 653 // send window. |
652 CryptoHandshakeMessage msg; | 654 CryptoHandshakeMessage msg; |
653 session_.GetCryptoStream()->OnHandshakeMessage(msg); | 655 session_.GetCryptoStream()->OnHandshakeMessage(msg); |
654 | 656 |
655 // Stream is now unblocked. | 657 // Stream is now unblocked. |
656 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); | 658 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); |
657 } | 659 } |
658 | 660 |
| 661 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedCryptoStream) { |
| 662 if (version() <= QUIC_VERSION_19) { |
| 663 return; |
| 664 } |
| 665 // Test that if the crypto stream is flow control blocked, then if the SHLO |
| 666 // contains a larger send window offset, the stream becomes unblocked. |
| 667 session_.set_writev_consumes_all_data(true); |
| 668 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); |
| 669 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
| 670 QuicHeadersStream* headers_stream = |
| 671 QuicSessionPeer::GetHeadersStream(&session_); |
| 672 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
| 673 // Write until the crypto stream is flow control blocked. |
| 674 int i = 0; |
| 675 while (!crypto_stream->flow_controller()->IsBlocked() && i < 1000) { |
| 676 QuicConfig config; |
| 677 CryptoHandshakeMessage crypto_message; |
| 678 config.ToHandshakeMessage(&crypto_message); |
| 679 crypto_stream->SendHandshakeMessage(crypto_message); |
| 680 ++i; |
| 681 } |
| 682 EXPECT_TRUE(crypto_stream->flow_controller()->IsBlocked()); |
| 683 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
| 684 EXPECT_FALSE(session_.HasDataToWrite()); |
| 685 EXPECT_TRUE(crypto_stream->HasBufferedData()); |
| 686 |
| 687 // The handshake message will call OnCanWrite, so the stream can |
| 688 // resume writing. |
| 689 EXPECT_CALL(*crypto_stream, OnCanWrite()); |
| 690 // Now complete the crypto handshake, resulting in an increased flow control |
| 691 // send window. |
| 692 CryptoHandshakeMessage msg; |
| 693 session_.GetCryptoStream()->OnHandshakeMessage(msg); |
| 694 |
| 695 // Stream is now unblocked and will no longer have buffered data. |
| 696 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
| 697 } |
| 698 |
| 699 TEST_P(QuicSessionTest, HandshakeUnblocksFlowControlBlockedHeadersStream) { |
| 700 if (version() <= QUIC_VERSION_19) { |
| 701 return; |
| 702 } |
| 703 // Test that if the header stream is flow control blocked, then if the SHLO |
| 704 // contains a larger send window offset, the stream becomes unblocked. |
| 705 session_.set_writev_consumes_all_data(true); |
| 706 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); |
| 707 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
| 708 QuicHeadersStream* headers_stream = |
| 709 QuicSessionPeer::GetHeadersStream(&session_); |
| 710 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
| 711 QuicStreamId stream_id = 5; |
| 712 // Write until the header stream is flow control blocked. |
| 713 while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) { |
| 714 SpdyHeaderBlock headers; |
| 715 headers["header"] = base::Uint64ToString(base::RandUint64()) + |
| 716 base::Uint64ToString(base::RandUint64()) + |
| 717 base::Uint64ToString(base::RandUint64()); |
| 718 headers_stream->WriteHeaders(stream_id, headers, true, nullptr); |
| 719 stream_id += 2; |
| 720 } |
| 721 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); |
| 722 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
| 723 EXPECT_FALSE(session_.HasDataToWrite()); |
| 724 EXPECT_TRUE(headers_stream->HasBufferedData()); |
| 725 |
| 726 // Now complete the crypto handshake, resulting in an increased flow control |
| 727 // send window. |
| 728 CryptoHandshakeMessage msg; |
| 729 session_.GetCryptoStream()->OnHandshakeMessage(msg); |
| 730 |
| 731 // Stream is now unblocked and will no longer have buffered data. |
| 732 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
| 733 EXPECT_FALSE(headers_stream->HasBufferedData()); |
| 734 } |
| 735 |
659 TEST_P(QuicSessionTest, InvalidFlowControlWindowInHandshake) { | 736 TEST_P(QuicSessionTest, InvalidFlowControlWindowInHandshake) { |
660 // TODO(rjshade): Remove this test when removing QUIC_VERSION_19. | 737 // TODO(rjshade): Remove this test when removing QUIC_VERSION_19. |
661 // Test that receipt of an invalid (< default) flow control window from | 738 // Test that receipt of an invalid (< default) flow control window from |
662 // the peer results in the connection being torn down. | 739 // the peer results in the connection being torn down. |
663 if (version() > QUIC_VERSION_19) { | 740 if (version() > QUIC_VERSION_19) { |
664 return; | 741 return; |
665 } | 742 } |
666 | 743 |
667 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; | 744 uint32 kInvalidWindow = kDefaultFlowControlSendWindow - 1; |
668 QuicConfigPeer::SetReceivedInitialFlowControlWindow(session_.config(), | 745 QuicConfigPeer::SetReceivedInitialFlowControlWindow(session_.config(), |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 } | 1025 } |
949 | 1026 |
950 // Called after any new data is received by the session, and triggers the call | 1027 // Called after any new data is received by the session, and triggers the call |
951 // to close the connection. | 1028 // to close the connection. |
952 session_.PostProcessAfterData(); | 1029 session_.PostProcessAfterData(); |
953 } | 1030 } |
954 | 1031 |
955 } // namespace | 1032 } // namespace |
956 } // namespace test | 1033 } // namespace test |
957 } // namespace net | 1034 } // namespace net |
OLD | NEW |