| 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <string> | 6 #include <string> |
| 7 #include <sys/epoll.h> | 7 #include <sys/epoll.h> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 vector<TestParams> GetTestParams() { | 140 vector<TestParams> GetTestParams() { |
| 141 // Divide the versions into buckets in which the intra-frame format | 141 // Divide the versions into buckets in which the intra-frame format |
| 142 // is compatible. When clients encounter QUIC version negotiation | 142 // is compatible. When clients encounter QUIC version negotiation |
| 143 // they simply retransmit all packets using the new version's | 143 // they simply retransmit all packets using the new version's |
| 144 // QUIC framing. However, they are unable to change the intra-frame | 144 // QUIC framing. However, they are unable to change the intra-frame |
| 145 // layout (for example to change SPDY/4 headers to SPDY/3). So | 145 // layout (for example to change SPDY/4 headers to SPDY/3). So |
| 146 // these tests need to ensure that clients are never attempting | 146 // these tests need to ensure that clients are never attempting |
| 147 // to do 0-RTT across incompatible versions. Chromium only supports | 147 // to do 0-RTT across incompatible versions. Chromium only supports |
| 148 // a single version at a time anyway. :) | 148 // a single version at a time anyway. :) |
| 149 QuicVersionVector all_supported_versions = QuicSupportedVersions(); | 149 QuicVersionVector all_supported_versions = QuicSupportedVersions(); |
| 150 QuicVersionVector client_version_buckets[2]; | 150 QuicVersionVector version_buckets[2]; |
| 151 for (const QuicVersion version : all_supported_versions) { | 151 for (const QuicVersion version : all_supported_versions) { |
| 152 if (version <= QUIC_VERSION_25) { | 152 if (version <= QUIC_VERSION_25) { |
| 153 // SPDY/4 | 153 // SPDY/4 |
| 154 client_version_buckets[0].push_back(version); | 154 version_buckets[0].push_back(version); |
| 155 } else { | 155 } else { |
| 156 // QUIC_VERSION_26 changes the kdf in a way that is incompatible with | 156 // QUIC_VERSION_26 changes the kdf in a way that is incompatible with |
| 157 // version negotiation across the version 26 boundary. | 157 // version negotiation across the version 26 boundary. |
| 158 client_version_buckets[1].push_back(version); | 158 version_buckets[1].push_back(version); |
| 159 } | 159 } |
| 160 } | 160 } |
| 161 | 161 |
| 162 vector<TestParams> params; | 162 vector<TestParams> params; |
| 163 // TODO(rtenneti): Add kTBBR after BBR code is checked in. | 163 for (bool server_uses_stateless_rejects_if_peer_supported : {true, false}) { |
| 164 // for (const QuicTag congestion_control_tag : {kRENO, kTBBR, kQBIC}) { | 164 for (bool client_supports_stateless_rejects : {true, false}) { |
| 165 for (const QuicTag congestion_control_tag : {kRENO, kQBIC}) { | 165 // TODO(rtenneti): Add kTBBR after BBR code is checked in. |
| 166 for (const bool use_fec : {false, true}) { | 166 for (const QuicTag congestion_control_tag : {kRENO, kQBIC}) { |
| 167 for (const QuicVersionVector& client_versions : client_version_buckets) { | 167 for (bool auto_tune_flow_control_window : {true, false}) { |
| 168 // A number of end to end tests fail when stateless rejects are enabled | 168 for (const bool use_fec : {false, true}) { |
| 169 // *and* there are more than two QUIC versions. | 169 const int kMaxEnabledOptions = 5; |
| 170 for (bool client_supports_stateless_rejects : {true, false}) { | 170 int enabled_options = 0; |
| 171 for (bool server_uses_stateless_rejects_if_peer_supported : | 171 if (congestion_control_tag != kQBIC) { |
| 172 {true, false}) { | 172 ++enabled_options; |
| 173 for (bool auto_tune_flow_control_window : {true, false}) { | 173 } |
| 174 if (use_fec) { |
| 175 ++enabled_options; |
| 176 } |
| 177 if (auto_tune_flow_control_window) { |
| 178 ++enabled_options; |
| 179 } |
| 180 if (client_supports_stateless_rejects) { |
| 181 ++enabled_options; |
| 182 } |
| 183 if (server_uses_stateless_rejects_if_peer_supported) { |
| 184 ++enabled_options; |
| 185 } |
| 186 CHECK_GE(kMaxEnabledOptions, enabled_options); |
| 187 |
| 188 // Run tests with no options, a single option, or all the options |
| 189 // enabled to avoid a combinatorial explosion. |
| 190 if (enabled_options > 1 && enabled_options < kMaxEnabledOptions) { |
| 191 continue; |
| 192 } |
| 193 |
| 194 for (const QuicVersionVector& client_versions : version_buckets) { |
| 174 CHECK(!client_versions.empty()); | 195 CHECK(!client_versions.empty()); |
| 175 // Add an entry for server and client supporting all versions. | 196 // Add an entry for server and client supporting all versions. |
| 176 params.push_back(TestParams( | 197 params.push_back(TestParams( |
| 177 client_versions, all_supported_versions, | 198 client_versions, all_supported_versions, |
| 178 client_versions.front(), use_fec, | 199 client_versions.front(), use_fec, |
| 179 client_supports_stateless_rejects, | 200 client_supports_stateless_rejects, |
| 180 server_uses_stateless_rejects_if_peer_supported, | 201 server_uses_stateless_rejects_if_peer_supported, |
| 181 congestion_control_tag, auto_tune_flow_control_window)); | 202 congestion_control_tag, auto_tune_flow_control_window)); |
| 182 if (client_supports_stateless_rejects && | 203 |
| 183 server_uses_stateless_rejects_if_peer_supported) { | 204 // Run version negotiation tests tests with no options, or all |
| 184 // TODO(b/23745998) Make stateless reject work with version | 205 // the options enabled to avoid a combinatorial explosion. |
| 185 // negotiation. | 206 if (enabled_options > 0 && enabled_options < kMaxEnabledOptions) { |
| 186 continue; | 207 continue; |
| 187 } | 208 } |
| 188 | 209 |
| 189 // Test client supporting all versions and server supporting 1 | 210 // Test client supporting all versions and server supporting 1 |
| 190 // version. Simulate an old server and exercise version downgrade | 211 // version. Simulate an old server and exercise version downgrade |
| 191 // in the client. Protocol negotiation should occur. Skip the i = | 212 // in the client. Protocol negotiation should occur. Skip the i = |
| 192 // 0 case because it is essentially the same as the default case. | 213 // 0 case because it is essentially the same as the default case. |
| 193 for (size_t i = 1; i < client_versions.size(); ++i) { | 214 for (size_t i = 1; i < client_versions.size(); ++i) { |
| 194 QuicVersionVector server_supported_versions; | 215 QuicVersionVector server_supported_versions; |
| 195 server_supported_versions.push_back(client_versions[i]); | 216 server_supported_versions.push_back(client_versions[i]); |
| (...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 // Force the client to write with a stream ID belonging to a nonexistent | 1067 // Force the client to write with a stream ID belonging to a nonexistent |
| 1047 // server-side stream. | 1068 // server-side stream. |
| 1048 QuicSessionPeer::SetNextOutgoingStreamId(client_->client()->session(), 2); | 1069 QuicSessionPeer::SetNextOutgoingStreamId(client_->client()->session(), 2); |
| 1049 | 1070 |
| 1050 client_->SendCustomSynchronousRequest(request); | 1071 client_->SendCustomSynchronousRequest(request); |
| 1051 // EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error()); | 1072 // EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error()); |
| 1052 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error()); | 1073 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error()); |
| 1053 EXPECT_EQ(QUIC_INVALID_STREAM_ID, client_->connection_error()); | 1074 EXPECT_EQ(QUIC_INVALID_STREAM_ID, client_->connection_error()); |
| 1054 } | 1075 } |
| 1055 | 1076 |
| 1077 TEST_P(EndToEndTest, EarlyResponseWithQuicStreamNoError) { |
| 1078 ASSERT_TRUE(Initialize()); |
| 1079 client_->client()->WaitForCryptoHandshakeConfirmed(); |
| 1080 |
| 1081 string large_body; |
| 1082 GenerateBody(&large_body, 1024 * 1024); |
| 1083 |
| 1084 HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::POST, "/foo"); |
| 1085 request.AddBody(large_body, false); |
| 1086 |
| 1087 // Insert an invalid content_length field in request to trigger an early |
| 1088 // response from server. |
| 1089 request.AddHeader("content-length", "-3"); |
| 1090 |
| 1091 request.set_skip_message_validation(true); |
| 1092 client_->SendCustomSynchronousRequest(request); |
| 1093 EXPECT_EQ("bad", client_->response_body()); |
| 1094 EXPECT_EQ(500u, client_->response_headers()->parsed_response_code()); |
| 1095 EXPECT_EQ(QUIC_STREAM_NO_ERROR, client_->stream_error()); |
| 1096 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error()); |
| 1097 } |
| 1098 |
| 1056 // TODO(rch): this test seems to cause net_unittests timeouts :| | 1099 // TODO(rch): this test seems to cause net_unittests timeouts :| |
| 1057 TEST_P(EndToEndTest, DISABLED_MultipleTermination) { | 1100 TEST_P(EndToEndTest, DISABLED_MultipleTermination) { |
| 1058 ASSERT_TRUE(Initialize()); | 1101 ASSERT_TRUE(Initialize()); |
| 1059 | 1102 |
| 1060 HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::POST, "/foo"); | 1103 HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::POST, "/foo"); |
| 1061 request.AddHeader("content-length", "3"); | 1104 request.AddHeader("content-length", "3"); |
| 1062 request.set_has_complete_message(false); | 1105 request.set_has_complete_message(false); |
| 1063 | 1106 |
| 1064 // Set the offset so we won't frame. Otherwise when we pick up termination | 1107 // Set the offset so we won't frame. Otherwise when we pick up termination |
| 1065 // before HTTP framing is complete, we send an error and close the stream, | 1108 // before HTTP framing is complete, we send an error and close the stream, |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1771 } | 1814 } |
| 1772 | 1815 |
| 1773 // Send a version negotiation packet from the server for a different | 1816 // Send a version negotiation packet from the server for a different |
| 1774 // connection ID. It should be ignored. | 1817 // connection ID. It should be ignored. |
| 1775 TEST_P(EndToEndTest, ServerSendVersionNegotiationWithDifferentConnectionId) { | 1818 TEST_P(EndToEndTest, ServerSendVersionNegotiationWithDifferentConnectionId) { |
| 1776 ASSERT_TRUE(Initialize()); | 1819 ASSERT_TRUE(Initialize()); |
| 1777 | 1820 |
| 1778 // Send the version negotiation packet. | 1821 // Send the version negotiation packet. |
| 1779 QuicConnectionId incorrect_connection_id = | 1822 QuicConnectionId incorrect_connection_id = |
| 1780 client_->client()->session()->connection()->connection_id() + 1; | 1823 client_->client()->session()->connection()->connection_id() + 1; |
| 1781 QuicVersionNegotiationPacket header; | |
| 1782 header.connection_id = incorrect_connection_id; | |
| 1783 header.reset_flag = true; | |
| 1784 header.version_flag = true; | |
| 1785 QuicFramer framer(server_supported_versions_, QuicTime::Zero(), | |
| 1786 Perspective::IS_SERVER); | |
| 1787 scoped_ptr<QuicEncryptedPacket> packet( | 1824 scoped_ptr<QuicEncryptedPacket> packet( |
| 1788 framer.BuildVersionNegotiationPacket(header, server_supported_versions_)); | 1825 QuicFramer::BuildVersionNegotiationPacket(incorrect_connection_id, |
| 1826 server_supported_versions_)); |
| 1789 testing::NiceMock<MockQuicConnectionDebugVisitor> visitor; | 1827 testing::NiceMock<MockQuicConnectionDebugVisitor> visitor; |
| 1790 client_->client()->session()->connection()->set_debug_visitor(&visitor); | 1828 client_->client()->session()->connection()->set_debug_visitor(&visitor); |
| 1791 EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id)) | 1829 EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id)) |
| 1792 .Times(1); | 1830 .Times(1); |
| 1793 // We must pause the server's thread in order to call WritePacket without | 1831 // We must pause the server's thread in order to call WritePacket without |
| 1794 // race conditions. | 1832 // race conditions. |
| 1795 server_thread_->Pause(); | 1833 server_thread_->Pause(); |
| 1796 server_writer_->WritePacket(packet->data(), packet->length(), | 1834 server_writer_->WritePacket(packet->data(), packet->length(), |
| 1797 server_address_.address(), | 1835 server_address_.address(), |
| 1798 client_->client()->client_address()); | 1836 client_->client()->client_address()); |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2059 request.set_skip_message_validation(true); | 2097 request.set_skip_message_validation(true); |
| 2060 request.set_has_complete_message(false); | 2098 request.set_has_complete_message(false); |
| 2061 | 2099 |
| 2062 // Tell the client to not close the stream if it receives an early response. | 2100 // Tell the client to not close the stream if it receives an early response. |
| 2063 client_->set_allow_bidirectional_data(true); | 2101 client_->set_allow_bidirectional_data(true); |
| 2064 // Send the headers. | 2102 // Send the headers. |
| 2065 client_->SendMessage(request); | 2103 client_->SendMessage(request); |
| 2066 // Receive the response and let the server close writing. | 2104 // Receive the response and let the server close writing. |
| 2067 client_->WaitForInitialResponse(); | 2105 client_->WaitForInitialResponse(); |
| 2068 EXPECT_EQ(500u, client_->response_headers()->parsed_response_code()); | 2106 EXPECT_EQ(500u, client_->response_headers()->parsed_response_code()); |
| 2107 |
| 2108 if (negotiated_version_ > QUIC_VERSION_28) { |
| 2109 // Receive the reset stream from server on early response. |
| 2110 client_->WaitForResponseForMs(100); |
| 2111 ReliableQuicStream* stream = |
| 2112 client_->client()->session()->GetStream(kClientDataStreamId1); |
| 2113 // The stream is reset by server's reset stream. |
| 2114 EXPECT_EQ(stream, nullptr); |
| 2115 return; |
| 2116 } |
| 2117 |
| 2069 // Send a body larger than the stream flow control window. | 2118 // Send a body larger than the stream flow control window. |
| 2070 string body; | 2119 string body; |
| 2071 GenerateBody(&body, kBodySize); | 2120 GenerateBody(&body, kBodySize); |
| 2072 client_->SendData(body, true); | 2121 client_->SendData(body, true); |
| 2073 | 2122 |
| 2074 if (FLAGS_quic_implement_stop_reading) { | 2123 if (FLAGS_quic_implement_stop_reading) { |
| 2075 // Run the client to let any buffered data be sent. | 2124 // Run the client to let any buffered data be sent. |
| 2076 // (This is OK despite already waiting for a response.) | 2125 // (This is OK despite already waiting for a response.) |
| 2077 client_->WaitForResponse(); | 2126 client_->WaitForResponse(); |
| 2078 // There should be no buffered data to write in the client's stream. | 2127 // There should be no buffered data to write in the client's stream. |
| 2079 ReliableQuicStream* stream = client_->client()->session()->GetStream(5); | 2128 ReliableQuicStream* stream = |
| 2129 client_->client()->session()->GetStream(kClientDataStreamId1); |
| 2080 EXPECT_FALSE(stream != nullptr && stream->HasBufferedData()); | 2130 EXPECT_FALSE(stream != nullptr && stream->HasBufferedData()); |
| 2081 } else { | 2131 } else { |
| 2082 // Run the client for 0.1 second to let any buffered data be sent. | 2132 // Run the client for 0.1 second to let any buffered data be sent. |
| 2083 // Must have a timeout, as the stream will not close and cause a return. | 2133 // Must have a timeout, as the stream will not close and cause a return. |
| 2084 // (This is OK despite already waiting for a response.) | 2134 // (This is OK despite already waiting for a response.) |
| 2085 client_->WaitForResponseForMs(static_cast<int64>(100)); | 2135 client_->WaitForResponseForMs(100); |
| 2086 // There will be buffered data to write in the client's stream. | 2136 // There will be buffered data to write in the client's stream. |
| 2087 ReliableQuicStream* stream = client_->client()->session()->GetStream(5); | 2137 ReliableQuicStream* stream = client_->client()->session()->GetStream(5); |
| 2088 EXPECT_TRUE(stream != nullptr && stream->HasBufferedData()); | 2138 EXPECT_TRUE(stream != nullptr && stream->HasBufferedData()); |
| 2089 } | 2139 } |
| 2090 } | 2140 } |
| 2091 | 2141 |
| 2092 } // namespace | 2142 } // namespace |
| 2093 } // namespace test | 2143 } // namespace test |
| 2094 } // namespace tools | 2144 } // namespace tools |
| 2095 } // namespace net | 2145 } // namespace net |
| OLD | NEW |