blob: 1baa8b8003d9a51d297b9872e251bcdb2c12c516 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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
3// found in the LICENSE file.
4
5#include <cstddef>
6#include <cstdint>
7#include <list>
8#include <memory>
9#include <ostream>
vasilvv872e7a32019-03-12 16:42:44 -070010#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include <utility>
12#include <vector>
13
14#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
bnc3fc60df2019-07-17 11:55:10 -070015#include "net/third_party/quiche/src/quic/core/http/http_constants.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050016#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_stream.h"
renjietang87cd7de2019-08-16 08:35:10 -070017#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050018#include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h"
19#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
20#include "net/third_party/quiche/src/quic/core/quic_framer.h"
21#include "net/third_party/quiche/src/quic/core/quic_packet_creator.h"
22#include "net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h"
23#include "net/third_party/quiche/src/quic/core/quic_packets.h"
24#include "net/third_party/quiche/src/quic/core/quic_session.h"
25#include "net/third_party/quiche/src/quic/core/quic_utils.h"
26#include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h"
27#include "net/third_party/quiche/src/quic/platform/api/quic_error_code_wrappers.h"
28#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
29#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
30#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
31#include "net/third_party/quiche/src/quic/platform/api/quic_port_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050032#include "net/third_party/quiche/src/quic/platform/api/quic_sleep.h"
33#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050034#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
35#include "net/third_party/quiche/src/quic/platform/api/quic_test_loopback.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050036#include "net/third_party/quiche/src/quic/test_tools/bad_packet_writer.h"
37#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
38#include "net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h"
39#include "net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.h"
bnce42f7ad2019-10-25 17:46:31 -070040#include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_encoder_test_utils.h"
bnc7e9155d2019-11-21 17:50:40 -080041#include "net/third_party/quiche/src/quic/test_tools/qpack/qpack_test_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050042#include "net/third_party/quiche/src/quic/test_tools/quic_client_peer.h"
43#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
44#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
45#include "net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h"
46#include "net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h"
47#include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h"
48#include "net/third_party/quiche/src/quic/test_tools/quic_server_peer.h"
49#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
50#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
51#include "net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.h"
52#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
53#include "net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h"
54#include "net/third_party/quiche/src/quic/test_tools/quic_test_client.h"
55#include "net/third_party/quiche/src/quic/test_tools/quic_test_server.h"
56#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
57#include "net/third_party/quiche/src/quic/test_tools/server_thread.h"
58#include "net/third_party/quiche/src/quic/tools/quic_backend_response.h"
59#include "net/third_party/quiche/src/quic/tools/quic_client.h"
60#include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h"
61#include "net/third_party/quiche/src/quic/tools/quic_server.h"
62#include "net/third_party/quiche/src/quic/tools/quic_simple_client_stream.h"
63#include "net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h"
dmcardleba2fb7e2019-12-13 07:44:34 -080064#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
65#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
66#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050067
68using spdy::kV3LowestPriority;
QUICHE teama6ef0a62019-03-07 20:34:33 -050069using spdy::SpdyFramer;
70using spdy::SpdyHeaderBlock;
71using spdy::SpdySerializedFrame;
72using spdy::SpdySettingsIR;
73
74namespace quic {
75namespace test {
76namespace {
77
78const char kFooResponseBody[] = "Artichoke hearts make me happy.";
79const char kBarResponseBody[] = "Palm hearts are pretty delicious, also.";
80const float kSessionToStreamRatio = 1.5;
81
82// Run all tests with the cross products of all versions.
83struct TestParams {
84 TestParams(const ParsedQuicVersionVector& client_supported_versions,
85 const ParsedQuicVersionVector& server_supported_versions,
86 ParsedQuicVersion negotiated_version,
fayang7379c492020-03-24 14:22:56 -070087 QuicTag congestion_control_tag)
QUICHE teama6ef0a62019-03-07 20:34:33 -050088 : client_supported_versions(client_supported_versions),
89 server_supported_versions(server_supported_versions),
90 negotiated_version(negotiated_version),
fayang7379c492020-03-24 14:22:56 -070091 congestion_control_tag(congestion_control_tag) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050092
93 friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
94 os << "{ server_supported_versions: "
95 << ParsedQuicVersionVectorToString(p.server_supported_versions);
96 os << " client_supported_versions: "
97 << ParsedQuicVersionVectorToString(p.client_supported_versions);
98 os << " negotiated_version: "
99 << ParsedQuicVersionToString(p.negotiated_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500100 os << " congestion_control_tag: "
fayang7379c492020-03-24 14:22:56 -0700101 << QuicTagToString(p.congestion_control_tag) << " }";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500102 return os;
103 }
104
105 ParsedQuicVersionVector client_supported_versions;
106 ParsedQuicVersionVector server_supported_versions;
107 ParsedQuicVersion negotiated_version;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500108 QuicTag congestion_control_tag;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500109};
110
dschinazi142051a2019-09-18 18:17:29 -0700111// Used by ::testing::PrintToStringParamName().
112std::string PrintToString(const TestParams& p) {
dmcardleba2fb7e2019-12-13 07:44:34 -0800113 std::string rv = quiche::QuicheStrCat(
dschinazi142051a2019-09-18 18:17:29 -0700114 ParsedQuicVersionToString(p.negotiated_version), "_Server_",
115 ParsedQuicVersionVectorToString(p.server_supported_versions), "_Client_",
116 ParsedQuicVersionVectorToString(p.client_supported_versions), "_",
fayang7379c492020-03-24 14:22:56 -0700117 QuicTagToString(p.congestion_control_tag));
dschinazi142051a2019-09-18 18:17:29 -0700118 std::replace(rv.begin(), rv.end(), ',', '_');
119 std::replace(rv.begin(), rv.end(), ' ', '_');
120 return rv;
121}
122
QUICHE teama6ef0a62019-03-07 20:34:33 -0500123// Constructs various test permutations.
wubbd64c102019-05-13 11:58:17 -0700124std::vector<TestParams> GetTestParams(bool use_tls_handshake) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500125 // Divide the versions into buckets in which the intra-frame format
126 // is compatible. When clients encounter QUIC version negotiation
127 // they simply retransmit all packets using the new version's
128 // QUIC framing. However, they are unable to change the intra-frame
129 // layout (for example to change HTTP/2 headers to SPDY/3, or a change in the
130 // handshake protocol). So these tests need to ensure that clients are never
131 // attempting to do 0-RTT across incompatible versions. Chromium only
132 // supports a single version at a time anyway. :)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500133 ParsedQuicVersionVector all_supported_versions =
134 FilterSupportedVersions(AllSupportedVersions());
135
dschinazi8b1c45a2019-10-17 08:48:13 -0700136 // Buckets are separated by versions: versions without crypto frames use
QUICHE teama6ef0a62019-03-07 20:34:33 -0500137 // STREAM frames for the handshake, and only have QUIC crypto as the handshake
dschinazi8b1c45a2019-10-17 08:48:13 -0700138 // protocol. Versions that use CRYPTO frames for the handshake must also be
139 // split based on the handshake protocol. If the handshake protocol (QUIC
140 // crypto or TLS) changes, the ClientHello/CHLO must be reconstructed for the
141 // correct protocol.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500142 ParsedQuicVersionVector version_buckets[3];
143
144 for (const ParsedQuicVersion& version : all_supported_versions) {
dschinazi76881f02019-12-09 14:56:14 -0800145 if (!use_tls_handshake && version.handshake_protocol == PROTOCOL_TLS1_3) {
146 continue;
147 }
QUICHE teamea740082019-03-11 17:58:43 -0700148 if (!QuicVersionUsesCryptoFrames(version.transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500149 version_buckets[0].push_back(version);
150 } else if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
151 version_buckets[1].push_back(version);
152 } else {
153 version_buckets[2].push_back(version);
154 }
155 }
156
QUICHE teama6ef0a62019-03-07 20:34:33 -0500157 std::vector<TestParams> params;
fayang7379c492020-03-24 14:22:56 -0700158 for (const QuicTag congestion_control_tag : {kRENO, kTBBR, kQBIC, kB2ON}) {
wuba9a43cb2019-07-17 15:22:42 -0700159 if (!GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
160 congestion_control_tag == kB2ON) {
161 continue;
162 }
wubbd64c102019-05-13 11:58:17 -0700163 for (const ParsedQuicVersionVector& client_versions : version_buckets) {
164 if (FilterSupportedVersions(client_versions).empty()) {
165 continue;
166 }
fayang7379c492020-03-24 14:22:56 -0700167 // Add an entry for server and client supporting all versions.
168 params.push_back(TestParams(client_versions, all_supported_versions,
169 client_versions.front(),
170 congestion_control_tag));
171 // Test client supporting all versions and server supporting
172 // 1 version. Simulate an old server and exercise version
173 // downgrade in the client. Protocol negotiation should
174 // occur. Skip the i = 0 case because it is essentially the
175 // same as the default case.
176 for (size_t i = 1; i < client_versions.size(); ++i) {
177 ParsedQuicVersionVector server_supported_versions;
178 server_supported_versions.push_back(client_versions[i]);
179 if (FilterSupportedVersions(server_supported_versions).empty()) {
180 continue;
181 }
182 params.push_back(TestParams(client_versions, server_supported_versions,
183 server_supported_versions.front(),
184 congestion_control_tag));
185 } // End of inner version loop.
186 } // End of outer version loop.
187 } // End of congestion_control_tag loop.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500188
QUICHE teama6ef0a62019-03-07 20:34:33 -0500189 return params;
190}
191
bnc519216c2019-07-09 05:03:48 -0700192void WriteHeadersOnStream(QuicSpdyStream* stream) {
193 // Since QuicSpdyStream uses QuicHeaderList::empty() to detect too large
194 // headers, it also fails when receiving empty headers.
195 SpdyHeaderBlock headers;
196 headers["foo"] = "bar";
197 stream->WriteHeaders(std::move(headers), /* fin = */ false, nullptr);
198}
199
QUICHE teama6ef0a62019-03-07 20:34:33 -0500200class ServerDelegate : public PacketDroppingTestWriter::Delegate {
201 public:
202 explicit ServerDelegate(QuicDispatcher* dispatcher)
203 : dispatcher_(dispatcher) {}
204 ~ServerDelegate() override = default;
205 void OnCanWrite() override { dispatcher_->OnCanWrite(); }
206
207 private:
208 QuicDispatcher* dispatcher_;
209};
210
211class ClientDelegate : public PacketDroppingTestWriter::Delegate {
212 public:
213 explicit ClientDelegate(QuicClient* client) : client_(client) {}
214 ~ClientDelegate() override = default;
215 void OnCanWrite() override {
216 QuicEpollEvent event(EPOLLOUT);
217 client_->epoll_network_helper()->OnEvent(client_->GetLatestFD(), &event);
218 }
219
220 private:
221 QuicClient* client_;
222};
223
224class EndToEndTest : public QuicTestWithParam<TestParams> {
225 protected:
226 EndToEndTest()
227 : initialized_(false),
228 connect_to_server_on_initialize_(true),
rch13cfcae2019-08-26 14:48:08 -0700229 server_address_(QuicSocketAddress(TestLoopback(),
230 QuicPickServerPortForTestsOrDie())),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500231 server_hostname_("test.example.com"),
232 client_writer_(nullptr),
233 server_writer_(nullptr),
234 negotiated_version_(UnsupportedQuicVersion()),
235 chlo_multiplier_(0),
236 stream_factory_(nullptr),
dschinazi8ff74822019-05-28 16:37:20 -0700237 expected_server_connection_id_length_(kQuicDefaultConnectionIdLength) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500238 client_supported_versions_ = GetParam().client_supported_versions;
239 server_supported_versions_ = GetParam().server_supported_versions;
240 negotiated_version_ = GetParam().negotiated_version;
241
242 QUIC_LOG(INFO) << "Using Configuration: " << GetParam();
243
244 // Use different flow control windows for client/server.
245 client_config_.SetInitialStreamFlowControlWindowToSend(
246 2 * kInitialStreamFlowControlWindowForTest);
247 client_config_.SetInitialSessionFlowControlWindowToSend(
248 2 * kInitialSessionFlowControlWindowForTest);
249 server_config_.SetInitialStreamFlowControlWindowToSend(
250 3 * kInitialStreamFlowControlWindowForTest);
251 server_config_.SetInitialSessionFlowControlWindowToSend(
252 3 * kInitialSessionFlowControlWindowForTest);
253
254 // The default idle timeouts can be too strict when running on a busy
255 // machine.
256 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(30);
257 client_config_.set_max_time_before_crypto_handshake(timeout);
258 client_config_.set_max_idle_time_before_crypto_handshake(timeout);
259 server_config_.set_max_time_before_crypto_handshake(timeout);
260 server_config_.set_max_idle_time_before_crypto_handshake(timeout);
261
262 AddToCache("/foo", 200, kFooResponseBody);
263 AddToCache("/bar", 200, kBarResponseBody);
264 }
265
266 ~EndToEndTest() override { QuicRecyclePort(server_address_.port()); }
267
268 virtual void CreateClientWithWriter() {
269 client_.reset(CreateQuicClient(client_writer_));
270 }
271
272 QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) {
273 QuicTestClient* client =
274 new QuicTestClient(server_address_, server_hostname_, client_config_,
275 client_supported_versions_,
276 crypto_test_utils::ProofVerifierForTesting());
277 client->UseWriter(writer);
278 if (!pre_shared_key_client_.empty()) {
279 client->client()->SetPreSharedKey(pre_shared_key_client_);
280 }
dschinazic8579862019-07-24 18:20:20 -0700281 client->UseConnectionIdLength(override_server_connection_id_length_);
282 client->UseClientConnectionIdLength(override_client_connection_id_length_);
nharper23f4bb92020-02-13 15:34:36 -0800283 client->client()->set_connection_debug_visitor(connection_debug_visitor_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500284 client->Connect();
285 return client;
286 }
287
288 void set_smaller_flow_control_receive_window() {
289 const uint32_t kClientIFCW = 64 * 1024;
290 const uint32_t kServerIFCW = 1024 * 1024;
291 set_client_initial_stream_flow_control_receive_window(kClientIFCW);
292 set_client_initial_session_flow_control_receive_window(
293 kSessionToStreamRatio * kClientIFCW);
294 set_server_initial_stream_flow_control_receive_window(kServerIFCW);
295 set_server_initial_session_flow_control_receive_window(
296 kSessionToStreamRatio * kServerIFCW);
297 }
298
299 void set_client_initial_stream_flow_control_receive_window(uint32_t window) {
dschinazi18cdf132019-10-09 16:08:18 -0700300 ASSERT_TRUE(client_ == nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500301 QUIC_DLOG(INFO) << "Setting client initial stream flow control window: "
302 << window;
303 client_config_.SetInitialStreamFlowControlWindowToSend(window);
304 }
305
306 void set_client_initial_session_flow_control_receive_window(uint32_t window) {
dschinazi18cdf132019-10-09 16:08:18 -0700307 ASSERT_TRUE(client_ == nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500308 QUIC_DLOG(INFO) << "Setting client initial session flow control window: "
309 << window;
310 client_config_.SetInitialSessionFlowControlWindowToSend(window);
311 }
312
dschinazi18cdf132019-10-09 16:08:18 -0700313 void set_client_initial_max_stream_data_incoming_bidirectional(
314 uint32_t window) {
315 ASSERT_TRUE(client_ == nullptr);
316 QUIC_DLOG(INFO)
317 << "Setting client initial max stream data incoming bidirectional: "
318 << window;
319 client_config_.SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
320 window);
321 }
322
323 void set_server_initial_max_stream_data_outgoing_bidirectional(
324 uint32_t window) {
325 ASSERT_TRUE(client_ == nullptr);
326 QUIC_DLOG(INFO)
327 << "Setting server initial max stream data outgoing bidirectional: "
328 << window;
329 server_config_.SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
330 window);
331 }
332
QUICHE teama6ef0a62019-03-07 20:34:33 -0500333 void set_server_initial_stream_flow_control_receive_window(uint32_t window) {
dschinazi18cdf132019-10-09 16:08:18 -0700334 ASSERT_TRUE(server_thread_ == nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500335 QUIC_DLOG(INFO) << "Setting server initial stream flow control window: "
336 << window;
337 server_config_.SetInitialStreamFlowControlWindowToSend(window);
338 }
339
340 void set_server_initial_session_flow_control_receive_window(uint32_t window) {
dschinazi18cdf132019-10-09 16:08:18 -0700341 ASSERT_TRUE(server_thread_ == nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500342 QUIC_DLOG(INFO) << "Setting server initial session flow control window: "
343 << window;
344 server_config_.SetInitialSessionFlowControlWindowToSend(window);
345 }
346
347 const QuicSentPacketManager* GetSentPacketManagerFromFirstServerSession() {
348 return &GetServerConnection()->sent_packet_manager();
349 }
350
fkastenholz7591c282019-08-13 12:58:38 -0700351 QuicSpdyClientSession* GetClientSession() {
352 return client_->client()->client_session();
353 }
354
355 QuicConnection* GetClientConnection() {
356 return GetClientSession()->connection();
357 }
358
QUICHE teama6ef0a62019-03-07 20:34:33 -0500359 QuicConnection* GetServerConnection() {
360 return GetServerSession()->connection();
361 }
362
renjietange01b3eb2019-08-20 11:04:54 -0700363 QuicSpdySession* GetServerSession() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500364 QuicDispatcher* dispatcher =
365 QuicServerPeer::GetDispatcher(server_thread_->server());
366 EXPECT_EQ(1u, dispatcher->session_map().size());
renjietange01b3eb2019-08-20 11:04:54 -0700367 return static_cast<QuicSpdySession*>(
368 dispatcher->session_map().begin()->second.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500369 }
370
371 bool Initialize() {
372 QuicTagVector copt;
373 server_config_.SetConnectionOptionsToSend(copt);
374 copt = client_extra_copts_;
375
376 // TODO(nimia): Consider setting the congestion control algorithm for the
377 // client as well according to the test parameter.
378 copt.push_back(GetParam().congestion_control_tag);
fayang961eaa02020-01-10 13:04:22 -0800379 copt.push_back(k2PTO);
fayangb0c7b4b2019-09-12 06:45:24 -0700380 if (VersionHasIetfQuicFrames(negotiated_version_.transport_version)) {
381 copt.push_back(kILD0);
382 }
fayang2ccfbcf2020-02-28 12:37:08 -0800383 copt.push_back(kPLE1);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500384 client_config_.SetConnectionOptionsToSend(copt);
385
386 // Start the server first, because CreateQuicClient() attempts
387 // to connect to the server.
388 StartServer();
389
390 if (!connect_to_server_on_initialize_) {
391 initialized_ = true;
392 return true;
393 }
394
395 CreateClientWithWriter();
396 static QuicEpollEvent event(EPOLLOUT);
397 if (client_writer_ != nullptr) {
398 client_writer_->Initialize(
fkastenholz7591c282019-08-13 12:58:38 -0700399 QuicConnectionPeer::GetHelper(GetClientConnection()),
400 QuicConnectionPeer::GetAlarmFactory(GetClientConnection()),
vasilvv0fc587f2019-09-06 13:33:08 -0700401 std::make_unique<ClientDelegate>(client_->client()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500402 }
403 initialized_ = true;
404 return client_->client()->connected();
405 }
406
407 void SetUp() override {
408 // The ownership of these gets transferred to the QuicPacketWriterWrapper
409 // when Initialize() is executed.
410 client_writer_ = new PacketDroppingTestWriter();
411 server_writer_ = new PacketDroppingTestWriter();
412 }
413
414 void TearDown() override {
415 ASSERT_TRUE(initialized_) << "You must call Initialize() in every test "
416 << "case. Otherwise, your test will leak memory.";
nharper23f4bb92020-02-13 15:34:36 -0800417 GetClientConnection()->set_debug_visitor(nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500418 StopServer();
419 }
420
421 void StartServer() {
QUICHE team8e2e4532019-03-14 14:37:56 -0700422 auto* test_server = new QuicTestServer(
423 crypto_test_utils::ProofSourceForTesting(), server_config_,
424 server_supported_versions_, &memory_cache_backend_,
dschinazi8ff74822019-05-28 16:37:20 -0700425 expected_server_connection_id_length_);
vasilvv0fc587f2019-09-06 13:33:08 -0700426 server_thread_ =
427 std::make_unique<ServerThread>(test_server, server_address_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500428 if (chlo_multiplier_ != 0) {
429 server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
430 }
431 if (!pre_shared_key_server_.empty()) {
432 server_thread_->server()->SetPreSharedKey(pre_shared_key_server_);
433 }
434 server_thread_->Initialize();
rch13cfcae2019-08-26 14:48:08 -0700435 server_address_ =
436 QuicSocketAddress(server_address_.host(), server_thread_->GetPort());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500437 QuicDispatcher* dispatcher =
438 QuicServerPeer::GetDispatcher(server_thread_->server());
439 QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
440
QUICHE teama6ef0a62019-03-07 20:34:33 -0500441 server_writer_->Initialize(QuicDispatcherPeer::GetHelper(dispatcher),
442 QuicDispatcherPeer::GetAlarmFactory(dispatcher),
vasilvv0fc587f2019-09-06 13:33:08 -0700443 std::make_unique<ServerDelegate>(dispatcher));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500444 if (stream_factory_ != nullptr) {
445 static_cast<QuicTestServer*>(server_thread_->server())
446 ->SetSpdyStreamFactory(stream_factory_);
447 }
448
449 server_thread_->Start();
450 }
451
452 void StopServer() {
453 if (server_thread_) {
454 server_thread_->Quit();
455 server_thread_->Join();
456 }
457 }
458
dmcardleba2fb7e2019-12-13 07:44:34 -0800459 void AddToCache(quiche::QuicheStringPiece path,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500460 int response_code,
dmcardleba2fb7e2019-12-13 07:44:34 -0800461 quiche::QuicheStringPiece body) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500462 memory_cache_backend_.AddSimpleResponse(server_hostname_, path,
463 response_code, body);
464 }
465
466 void SetPacketLossPercentage(int32_t loss) {
467 client_writer_->set_fake_packet_loss_percentage(loss);
468 server_writer_->set_fake_packet_loss_percentage(loss);
469 }
470
471 void SetPacketSendDelay(QuicTime::Delta delay) {
472 client_writer_->set_fake_packet_delay(delay);
473 server_writer_->set_fake_packet_delay(delay);
474 }
475
476 void SetReorderPercentage(int32_t reorder) {
477 client_writer_->set_fake_reorder_percentage(reorder);
478 server_writer_->set_fake_reorder_percentage(reorder);
479 }
480
481 // Verifies that the client and server connections were both free of packets
482 // being discarded, based on connection stats.
483 // Calls server_thread_ Pause() and Resume(), which may only be called once
484 // per test.
485 void VerifyCleanConnection(bool had_packet_loss) {
fkastenholz7591c282019-08-13 12:58:38 -0700486 QuicConnectionStats client_stats = GetClientConnection()->GetStats();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500487 // TODO(ianswett): Determine why this becomes even more flaky with BBR
488 // enabled. b/62141144
489 if (!had_packet_loss && !GetQuicReloadableFlag(quic_default_to_bbr)) {
490 EXPECT_EQ(0u, client_stats.packets_lost);
491 }
492 EXPECT_EQ(0u, client_stats.packets_discarded);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500493 // When client starts with an unsupported version, the version negotiation
494 // packet sent by server for the old connection (respond for the connection
495 // close packet) will be dropped by the client.
wubbd64c102019-05-13 11:58:17 -0700496 if (!ServerSendsVersionNegotiation()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500497 EXPECT_EQ(0u, client_stats.packets_dropped);
498 }
499 if (!ClientSupportsIetfQuicNotSupportedByServer()) {
500 // In this case, if client sends 0-RTT POST with v99, receives IETF
501 // version negotiation packet and speaks a GQUIC version. Server processes
502 // this connection in time wait list and keeps sending IETF version
503 // negotiation packet for incoming packets. But these version negotiation
504 // packets cannot be processed by the client speaking GQUIC.
505 EXPECT_EQ(client_stats.packets_received, client_stats.packets_processed);
506 }
507
QUICHE teama6ef0a62019-03-07 20:34:33 -0500508 server_thread_->Pause();
509 QuicConnectionStats server_stats = GetServerConnection()->GetStats();
510 if (!had_packet_loss) {
511 EXPECT_EQ(0u, server_stats.packets_lost);
512 }
513 EXPECT_EQ(0u, server_stats.packets_discarded);
514 // TODO(ianswett): Restore the check for packets_dropped equals 0.
515 // The expect for packets received is equal to packets processed fails
516 // due to version negotiation packets.
517 server_thread_->Resume();
518 }
519
QUICHE teama6ef0a62019-03-07 20:34:33 -0500520 // Client supports IETF QUIC, while it is not supported by server.
521 bool ClientSupportsIetfQuicNotSupportedByServer() {
fayangd4291e42019-05-30 10:31:21 -0700522 return VersionHasIetfInvariantHeader(
523 client_supported_versions_[0].transport_version) &&
524 !VersionHasIetfInvariantHeader(
525 FilterSupportedVersions(GetParam().server_supported_versions)[0]
526 .transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500527 }
528
529 // Returns true when client starts with an unsupported version, and client
530 // closes connection when version negotiation is received.
531 bool ServerSendsVersionNegotiation() {
fayang9ed391a2019-06-20 11:16:59 -0700532 return client_supported_versions_[0] != GetParam().negotiated_version;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500533 }
534
535 bool SupportsIetfQuicWithTls(ParsedQuicVersion version) {
fayangd4291e42019-05-30 10:31:21 -0700536 return VersionHasIetfInvariantHeader(version.transport_version) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500537 version.handshake_protocol == PROTOCOL_TLS1_3;
538 }
539
bncedeeb472019-08-27 12:19:22 -0700540 static void ExpectFlowControlsSynced(QuicSession* client,
541 QuicSession* server) {
542 EXPECT_EQ(
543 QuicFlowControllerPeer::SendWindowSize(client->flow_controller()),
544 QuicFlowControllerPeer::ReceiveWindowSize(server->flow_controller()));
545 EXPECT_EQ(
546 QuicFlowControllerPeer::ReceiveWindowSize(client->flow_controller()),
547 QuicFlowControllerPeer::SendWindowSize(server->flow_controller()));
548 }
549
550 static void ExpectFlowControlsSynced(QuicStream* client, QuicStream* server) {
551 EXPECT_EQ(
552 QuicFlowControllerPeer::SendWindowSize(client->flow_controller()),
553 QuicFlowControllerPeer::ReceiveWindowSize(server->flow_controller()));
554 EXPECT_EQ(
555 QuicFlowControllerPeer::ReceiveWindowSize(client->flow_controller()),
556 QuicFlowControllerPeer::SendWindowSize(server->flow_controller()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500557 }
558
559 // Must be called before Initialize to have effect.
560 void SetSpdyStreamFactory(QuicTestServer::StreamFactory* factory) {
561 stream_factory_ = factory;
562 }
563
564 QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
565 return GetNthClientInitiatedBidirectionalStreamId(
fkastenholz7591c282019-08-13 12:58:38 -0700566 GetClientConnection()->transport_version(), n);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500567 }
568
569 QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
570 return GetNthServerInitiatedBidirectionalStreamId(
fkastenholz7591c282019-08-13 12:58:38 -0700571 GetClientConnection()->transport_version(), n);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500572 }
573
574 ScopedEnvironmentForThreads environment_;
575 bool initialized_;
576 // If true, the Initialize() function will create |client_| and starts to
577 // connect to the server.
578 // Default is true.
579 bool connect_to_server_on_initialize_;
580 QuicSocketAddress server_address_;
vasilvvc48c8712019-03-11 13:38:16 -0700581 std::string server_hostname_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500582 QuicMemoryCacheBackend memory_cache_backend_;
583 std::unique_ptr<ServerThread> server_thread_;
584 std::unique_ptr<QuicTestClient> client_;
nharper23f4bb92020-02-13 15:34:36 -0800585 QuicConnectionDebugVisitor* connection_debug_visitor_ = nullptr;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500586 PacketDroppingTestWriter* client_writer_;
587 PacketDroppingTestWriter* server_writer_;
588 QuicConfig client_config_;
589 QuicConfig server_config_;
590 ParsedQuicVersionVector client_supported_versions_;
591 ParsedQuicVersionVector server_supported_versions_;
592 QuicTagVector client_extra_copts_;
593 ParsedQuicVersion negotiated_version_;
594 size_t chlo_multiplier_;
595 QuicTestServer::StreamFactory* stream_factory_;
vasilvvc48c8712019-03-11 13:38:16 -0700596 std::string pre_shared_key_client_;
597 std::string pre_shared_key_server_;
dschinazic8579862019-07-24 18:20:20 -0700598 int override_server_connection_id_length_ = -1;
599 int override_client_connection_id_length_ = -1;
dschinazi8ff74822019-05-28 16:37:20 -0700600 uint8_t expected_server_connection_id_length_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500601};
602
603// Run all end to end tests with all supported versions.
604INSTANTIATE_TEST_SUITE_P(EndToEndTests,
605 EndToEndTest,
dschinazi142051a2019-09-18 18:17:29 -0700606 ::testing::ValuesIn(GetTestParams(true)),
607 ::testing::PrintToStringParamName());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500608
bnc40a0b962020-04-23 17:38:25 -0700609// These tests are only run with QUIC versions that do not use TLS.
610// TODO(b/154151800): Run all tests with TLS as well as QUIC crypto.
611class EndToEndTestWithoutTls : public EndToEndTest {};
612
613INSTANTIATE_TEST_SUITE_P(EndToEndTestsWithoutTls,
614 EndToEndTestWithoutTls,
615 ::testing::ValuesIn(GetTestParams(false)),
616 ::testing::PrintToStringParamName());
617
618TEST_P(EndToEndTest, HandshakeSuccessful) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500619 ASSERT_TRUE(Initialize());
620 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
621 server_thread_->WaitForCryptoHandshakeConfirmed();
622 // There have been occasions where it seemed that negotiated_version_ and the
623 // version in the connection are not in sync. If it is happening, it has not
624 // been recreatable; this assert is here just to check and raise a flag if it
625 // happens.
fkastenholz7591c282019-08-13 12:58:38 -0700626 ASSERT_EQ(GetClientConnection()->transport_version(),
627 negotiated_version_.transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500628
fkastenholz7591c282019-08-13 12:58:38 -0700629 QuicCryptoStream* crypto_stream =
630 QuicSessionPeer::GetMutableCryptoStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500631 QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(crypto_stream);
632 EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
633 server_thread_->Pause();
634 crypto_stream = QuicSessionPeer::GetMutableCryptoStream(GetServerSession());
635 sequencer = QuicStreamPeer::sequencer(crypto_stream);
636 EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
637}
638
bnc40a0b962020-04-23 17:38:25 -0700639TEST_P(EndToEndTestWithoutTls, SimpleRequestResponse) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500640 ASSERT_TRUE(Initialize());
641
642 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
643 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
nharper23f4bb92020-02-13 15:34:36 -0800644 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
645 EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
renjietanga29a96a2019-10-10 12:47:50 -0700646 if (VersionUsesHttp3(GetClientConnection()->transport_version())) {
renjietange01b3eb2019-08-20 11:04:54 -0700647 EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(GetClientSession()));
648 EXPECT_TRUE(
649 QuicSpdySessionPeer::GetReceiveControlStream(GetClientSession()));
650 EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(GetServerSession()));
651 EXPECT_TRUE(
652 QuicSpdySessionPeer::GetReceiveControlStream(GetServerSession()));
653 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500654}
655
bnc40a0b962020-04-23 17:38:25 -0700656TEST_P(EndToEndTest, SimpleRequestResponse) {
dschinazi24e7ae82019-07-11 13:07:41 -0700657 ASSERT_TRUE(Initialize());
658 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
659 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
660}
661
bnc40a0b962020-04-23 17:38:25 -0700662TEST_P(EndToEndTest, HandshakeConfirmed) {
fayang01062942020-01-22 07:23:23 -0800663 ASSERT_TRUE(Initialize());
664 if (!GetParam().negotiated_version.HasHandshakeDone()) {
665 return;
666 }
fayang01062942020-01-22 07:23:23 -0800667 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
668 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
669 // Verify handshake state.
670 EXPECT_EQ(HANDSHAKE_CONFIRMED, GetClientSession()->GetHandshakeState());
671 server_thread_->Pause();
672 EXPECT_EQ(HANDSHAKE_CONFIRMED, GetServerSession()->GetHandshakeState());
673 server_thread_->Resume();
674 client_->Disconnect();
fayang01062942020-01-22 07:23:23 -0800675}
676
bnc40a0b962020-04-23 17:38:25 -0700677TEST_P(EndToEndTest, SendAndReceiveCoalescedPackets) {
fayang58f71072019-11-05 08:47:02 -0800678 ASSERT_TRUE(Initialize());
679 if (!GetClientConnection()->version().CanSendCoalescedPackets()) {
680 return;
681 }
682 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
683 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fayang4057e642019-11-08 10:58:00 -0800684 // Verify client successfully processes coalesced packets.
fayang58f71072019-11-05 08:47:02 -0800685 QuicConnectionStats client_stats = GetClientConnection()->GetStats();
686 EXPECT_LT(0u, client_stats.num_coalesced_packets_received);
687 EXPECT_EQ(client_stats.num_coalesced_packets_processed,
688 client_stats.num_coalesced_packets_received);
fayang4057e642019-11-08 10:58:00 -0800689 // TODO(fayang): verify server successfully processes coalesced packets.
fayang58f71072019-11-05 08:47:02 -0800690}
691
fkastenholz4c7303c2019-07-29 08:17:07 -0700692// Simple transaction, but set a non-default ack delay at the client
693// and ensure it gets to the server.
bnc40a0b962020-04-23 17:38:25 -0700694TEST_P(EndToEndTestWithoutTls, SimpleRequestResponseWithAckDelayChange) {
fkastenholz4c7303c2019-07-29 08:17:07 -0700695 // Force the ACK delay to be something other than the default.
696 // Note that it is sent only if doing IETF QUIC.
697 client_config_.SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs + 100u);
698 ASSERT_TRUE(Initialize());
699
700 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
701 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
nharper23f4bb92020-02-13 15:34:36 -0800702 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
703 EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
fkastenholz4c7303c2019-07-29 08:17:07 -0700704 if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
705 EXPECT_EQ(kDefaultDelayedAckTimeMs + 100u,
706 GetSentPacketManagerFromFirstServerSession()
707 ->peer_max_ack_delay()
708 .ToMilliseconds());
709 } else {
710 EXPECT_EQ(kDefaultDelayedAckTimeMs,
711 GetSentPacketManagerFromFirstServerSession()
712 ->peer_max_ack_delay()
713 .ToMilliseconds());
714 }
715}
716
fkastenholz4dc4ba32019-07-30 09:55:25 -0700717// Simple transaction, but set a non-default ack exponent at the client
718// and ensure it gets to the server.
bnc40a0b962020-04-23 17:38:25 -0700719TEST_P(EndToEndTestWithoutTls, SimpleRequestResponseWithAckExponentChange) {
fkastenholz4dc4ba32019-07-30 09:55:25 -0700720 const uint32_t kClientAckDelayExponent = kDefaultAckDelayExponent + 100u;
721 // Force the ACK exponent to be something other than the default.
722 // Note that it is sent only if doing IETF QUIC.
723 client_config_.SetAckDelayExponentToSend(kClientAckDelayExponent);
724 ASSERT_TRUE(Initialize());
725
726 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
727 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz4dc4ba32019-07-30 09:55:25 -0700728
nharper23f4bb92020-02-13 15:34:36 -0800729 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
730 EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
fkastenholz4dc4ba32019-07-30 09:55:25 -0700731 if (VersionHasIetfQuicFrames(
732 GetParam().negotiated_version.transport_version)) {
733 // Should be only for IETF QUIC.
734 EXPECT_EQ(kClientAckDelayExponent,
735 GetServerConnection()->framer().peer_ack_delay_exponent());
736 } else {
737 // No change for Google QUIC.
738 EXPECT_EQ(kDefaultAckDelayExponent,
739 GetServerConnection()->framer().peer_ack_delay_exponent());
740 }
741 // No change, regardless of version.
742 EXPECT_EQ(kDefaultAckDelayExponent,
743 GetServerConnection()->framer().local_ack_delay_exponent());
744}
745
bnc40a0b962020-04-23 17:38:25 -0700746TEST_P(EndToEndTestWithoutTls, SimpleRequestResponseForcedVersionNegotiation) {
dschinazi5a354c92019-05-09 12:18:53 -0700747 client_supported_versions_.insert(client_supported_versions_.begin(),
748 QuicVersionReservedForNegotiation());
nharper23f4bb92020-02-13 15:34:36 -0800749 testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
750 connection_debug_visitor_ = &visitor;
751 EXPECT_CALL(visitor, OnVersionNegotiationPacket(testing::_)).Times(1);
dschinazi5a354c92019-05-09 12:18:53 -0700752 ASSERT_TRUE(Initialize());
753 ASSERT_TRUE(ServerSendsVersionNegotiation());
754
755 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
756 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
757
nharper23f4bb92020-02-13 15:34:36 -0800758 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
759 EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
dschinazi5a354c92019-05-09 12:18:53 -0700760}
761
bnc40a0b962020-04-23 17:38:25 -0700762TEST_P(EndToEndTest, ForcedVersionNegotiation) {
dschinazi24e7ae82019-07-11 13:07:41 -0700763 client_supported_versions_.insert(client_supported_versions_.begin(),
764 QuicVersionReservedForNegotiation());
765 ASSERT_TRUE(Initialize());
766 ASSERT_TRUE(ServerSendsVersionNegotiation());
767
768 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
769 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
770}
771
bnc40a0b962020-04-23 17:38:25 -0700772TEST_P(EndToEndTestWithoutTls, SimpleRequestResponseZeroConnectionID) {
dschinazi97da52b2020-01-13 15:44:43 -0800773 if (!GetParam().negotiated_version.AllowsVariableLengthConnectionIds()) {
dschinazic8579862019-07-24 18:20:20 -0700774 ASSERT_TRUE(Initialize());
775 return;
776 }
777 override_server_connection_id_length_ = 0;
778 expected_server_connection_id_length_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500779 ASSERT_TRUE(Initialize());
780
781 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
782 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
nharper23f4bb92020-02-13 15:34:36 -0800783 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
784 EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
fkastenholz7591c282019-08-13 12:58:38 -0700785 EXPECT_EQ(GetClientConnection()->connection_id(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500786 QuicUtils::CreateZeroConnectionId(
787 GetParam().negotiated_version.transport_version));
788}
789
bnc40a0b962020-04-23 17:38:25 -0700790TEST_P(EndToEndTest, ZeroConnectionID) {
dschinazi97da52b2020-01-13 15:44:43 -0800791 if (!GetParam().negotiated_version.AllowsVariableLengthConnectionIds()) {
dschinazic8579862019-07-24 18:20:20 -0700792 ASSERT_TRUE(Initialize());
793 return;
794 }
795 override_server_connection_id_length_ = 0;
796 expected_server_connection_id_length_ = 0;
dschinazi5c030852019-07-11 15:45:53 -0700797 ASSERT_TRUE(Initialize());
798
799 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
800 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -0700801 EXPECT_EQ(GetClientConnection()->connection_id(),
dschinazi5c030852019-07-11 15:45:53 -0700802 QuicUtils::CreateZeroConnectionId(
803 GetParam().negotiated_version.transport_version));
804}
805
bnc40a0b962020-04-23 17:38:25 -0700806TEST_P(EndToEndTest, BadConnectionIdLength) {
dschinazi97da52b2020-01-13 15:44:43 -0800807 if (!GetParam().negotiated_version.AllowsVariableLengthConnectionIds()) {
QUICHE team8e2e4532019-03-14 14:37:56 -0700808 ASSERT_TRUE(Initialize());
809 return;
810 }
dschinazic8579862019-07-24 18:20:20 -0700811 override_server_connection_id_length_ = 9;
QUICHE teamc65d1d12019-03-19 20:58:04 -0700812 ASSERT_TRUE(Initialize());
813 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
814 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
815 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
816 ->client_session()
817 ->connection()
818 ->connection_id()
819 .length());
QUICHE team8e2e4532019-03-14 14:37:56 -0700820}
821
dschinazi5c030852019-07-11 15:45:53 -0700822// Tests a very long (16-byte) initial destination connection ID to make
823// sure the dispatcher properly replaces it with an 8-byte one.
bnc40a0b962020-04-23 17:38:25 -0700824TEST_P(EndToEndTest, LongBadConnectionIdLength) {
dschinazi97da52b2020-01-13 15:44:43 -0800825 if (!GetParam().negotiated_version.AllowsVariableLengthConnectionIds()) {
dschinazi5c030852019-07-11 15:45:53 -0700826 ASSERT_TRUE(Initialize());
827 return;
828 }
dschinazic8579862019-07-24 18:20:20 -0700829 override_server_connection_id_length_ = 16;
dschinazi5c030852019-07-11 15:45:53 -0700830 ASSERT_TRUE(Initialize());
831 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
832 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
833 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
834 ->client_session()
835 ->connection()
836 ->connection_id()
837 .length());
838}
839
bnc40a0b962020-04-23 17:38:25 -0700840TEST_P(EndToEndTest, ClientConnectionId) {
dschinazi346b7ce2019-06-05 01:38:18 -0700841 if (!GetParam().negotiated_version.SupportsClientConnectionIds()) {
842 ASSERT_TRUE(Initialize());
843 return;
844 }
dschinazic8579862019-07-24 18:20:20 -0700845 override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
dschinazi346b7ce2019-06-05 01:38:18 -0700846 ASSERT_TRUE(Initialize());
847 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
848 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
dschinazic8579862019-07-24 18:20:20 -0700849 EXPECT_EQ(override_client_connection_id_length_, client_->client()
850 ->client_session()
851 ->connection()
852 ->client_connection_id()
853 .length());
dschinazi346b7ce2019-06-05 01:38:18 -0700854}
855
bnc40a0b962020-04-23 17:38:25 -0700856TEST_P(EndToEndTest, ForcedVersionNegotiationAndClientConnectionId) {
dschinazi346b7ce2019-06-05 01:38:18 -0700857 if (!GetParam().negotiated_version.SupportsClientConnectionIds()) {
858 ASSERT_TRUE(Initialize());
859 return;
860 }
861 client_supported_versions_.insert(client_supported_versions_.begin(),
862 QuicVersionReservedForNegotiation());
dschinazic8579862019-07-24 18:20:20 -0700863 override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
dschinazi346b7ce2019-06-05 01:38:18 -0700864 ASSERT_TRUE(Initialize());
865 ASSERT_TRUE(ServerSendsVersionNegotiation());
866 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
867 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
dschinazic8579862019-07-24 18:20:20 -0700868 EXPECT_EQ(override_client_connection_id_length_, client_->client()
869 ->client_session()
870 ->connection()
871 ->client_connection_id()
872 .length());
dschinazi346b7ce2019-06-05 01:38:18 -0700873}
874
bnc40a0b962020-04-23 17:38:25 -0700875TEST_P(EndToEndTest, ForcedVersionNegotiationAndBadConnectionIdLength) {
dschinazi97da52b2020-01-13 15:44:43 -0800876 if (!GetParam().negotiated_version.AllowsVariableLengthConnectionIds()) {
dschinazi8eb45e92019-05-10 11:36:15 -0700877 ASSERT_TRUE(Initialize());
878 return;
879 }
880 client_supported_versions_.insert(client_supported_versions_.begin(),
881 QuicVersionReservedForNegotiation());
dschinazic8579862019-07-24 18:20:20 -0700882 override_server_connection_id_length_ = 9;
dschinazi8eb45e92019-05-10 11:36:15 -0700883 ASSERT_TRUE(Initialize());
884 ASSERT_TRUE(ServerSendsVersionNegotiation());
885 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
886 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
887 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
888 ->client_session()
889 ->connection()
890 ->connection_id()
891 .length());
892}
893
dschinazi5c030852019-07-11 15:45:53 -0700894// Forced Version Negotiation with a client connection ID and a long
895// connection ID.
bnc40a0b962020-04-23 17:38:25 -0700896TEST_P(EndToEndTest, ForcedVersNegoAndClientCIDAndLongCID) {
dschinazi5c030852019-07-11 15:45:53 -0700897 if (!GetParam().negotiated_version.SupportsClientConnectionIds() ||
dschinazi97da52b2020-01-13 15:44:43 -0800898 !GetParam().negotiated_version.AllowsVariableLengthConnectionIds()) {
dschinazi5c030852019-07-11 15:45:53 -0700899 ASSERT_TRUE(Initialize());
900 return;
901 }
902 client_supported_versions_.insert(client_supported_versions_.begin(),
903 QuicVersionReservedForNegotiation());
dschinazic8579862019-07-24 18:20:20 -0700904 override_server_connection_id_length_ = 16;
905 override_client_connection_id_length_ = 18;
dschinazi5c030852019-07-11 15:45:53 -0700906 ASSERT_TRUE(Initialize());
907 ASSERT_TRUE(ServerSendsVersionNegotiation());
908 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
909 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
910 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
911 ->client_session()
912 ->connection()
913 ->connection_id()
914 .length());
dschinazic8579862019-07-24 18:20:20 -0700915 EXPECT_EQ(override_client_connection_id_length_, client_->client()
916 ->client_session()
917 ->connection()
918 ->client_connection_id()
919 .length());
dschinazi5c030852019-07-11 15:45:53 -0700920}
921
bnc40a0b962020-04-23 17:38:25 -0700922TEST_P(EndToEndTestWithoutTls, MixGoodAndBadConnectionIdLengths) {
dschinazi97da52b2020-01-13 15:44:43 -0800923 if (!GetParam().negotiated_version.AllowsVariableLengthConnectionIds()) {
QUICHE team8e2e4532019-03-14 14:37:56 -0700924 ASSERT_TRUE(Initialize());
925 return;
926 }
927
QUICHE teamc65d1d12019-03-19 20:58:04 -0700928 // Start client_ which will use a bad connection ID length.
dschinazic8579862019-07-24 18:20:20 -0700929 override_server_connection_id_length_ = 9;
QUICHE teamc65d1d12019-03-19 20:58:04 -0700930 ASSERT_TRUE(Initialize());
dschinazic8579862019-07-24 18:20:20 -0700931 override_server_connection_id_length_ = -1;
QUICHE team8e2e4532019-03-14 14:37:56 -0700932
QUICHE teamc65d1d12019-03-19 20:58:04 -0700933 // Start client2 which will use a good connection ID length.
QUICHE team8e2e4532019-03-14 14:37:56 -0700934 std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
935 SpdyHeaderBlock headers;
936 headers[":method"] = "POST";
937 headers[":path"] = "/foo";
938 headers[":scheme"] = "https";
939 headers[":authority"] = server_hostname_;
940 headers["content-length"] = "3";
941 client2->SendMessage(headers, "", /*fin=*/false);
942 client2->SendData("eep", true);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700943
944 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
945 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
946 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
947 ->client_session()
948 ->connection()
949 ->connection_id()
950 .length());
951
QUICHE team8e2e4532019-03-14 14:37:56 -0700952 client2->WaitForResponse();
953 EXPECT_EQ(kFooResponseBody, client2->response_body());
954 EXPECT_EQ("200", client2->response_headers()->find(":status")->second);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700955 EXPECT_EQ(kQuicDefaultConnectionIdLength, client2->client()
956 ->client_session()
957 ->connection()
958 ->connection_id()
959 .length());
QUICHE team8e2e4532019-03-14 14:37:56 -0700960}
961
bnc40a0b962020-04-23 17:38:25 -0700962TEST_P(EndToEndTest, SimpleRequestResponseWithIetfDraftSupport) {
dschinazi38cc1ee2020-02-28 14:33:58 -0800963 if (!GetParam().negotiated_version.HasIetfQuicFrames()) {
dschinazi552accc2019-06-17 17:07:34 -0700964 ASSERT_TRUE(Initialize());
965 return;
966 }
rcha702be22019-08-30 15:20:12 -0700967 QuicVersionInitializeSupportForIetfDraft();
dschinazi552accc2019-06-17 17:07:34 -0700968 ASSERT_TRUE(Initialize());
969
970 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
971 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
972}
973
bnc40a0b962020-04-23 17:38:25 -0700974TEST_P(EndToEndTestWithoutTls, SimpleRequestResponseWithLargeReject) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500975 chlo_multiplier_ = 1;
976 ASSERT_TRUE(Initialize());
977
978 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
979 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
nharper23f4bb92020-02-13 15:34:36 -0800980 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
981 EXPECT_TRUE(client_->client()->ReceivedInchoateReject());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500982}
983
bnc40a0b962020-04-23 17:38:25 -0700984TEST_P(EndToEndTest, SimpleRequestResponsev6) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500985 server_address_ =
986 QuicSocketAddress(QuicIpAddress::Loopback6(), server_address_.port());
987 ASSERT_TRUE(Initialize());
988
989 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
990 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
991}
992
bnc40a0b962020-04-23 17:38:25 -0700993TEST_P(EndToEndTest,
dschinazi18cdf132019-10-09 16:08:18 -0700994 ClientDoesNotAllowServerDataOnServerInitiatedBidirectionalStreams) {
995 set_client_initial_max_stream_data_incoming_bidirectional(0);
996 ASSERT_TRUE(Initialize());
997 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
998 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
999}
1000
bnc40a0b962020-04-23 17:38:25 -07001001TEST_P(EndToEndTest,
dschinazi18cdf132019-10-09 16:08:18 -07001002 ServerDoesNotAllowClientDataOnServerInitiatedBidirectionalStreams) {
1003 set_server_initial_max_stream_data_outgoing_bidirectional(0);
1004 ASSERT_TRUE(Initialize());
1005 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1006 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1007}
1008
bnc40a0b962020-04-23 17:38:25 -07001009TEST_P(EndToEndTest,
dschinazi18cdf132019-10-09 16:08:18 -07001010 BothEndpointsDisallowDataOnServerInitiatedBidirectionalStreams) {
1011 set_client_initial_max_stream_data_incoming_bidirectional(0);
1012 set_server_initial_max_stream_data_outgoing_bidirectional(0);
1013 ASSERT_TRUE(Initialize());
1014 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1015 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1016}
1017
dschinazi7d0f3c82019-09-16 16:14:32 -07001018// Regression test for a bug where we would always fail to decrypt the first
1019// initial packet. Undecryptable packets can be seen after the handshake
1020// is complete due to dropping the initial keys at that point, so we only test
1021// for undecryptable packets before then.
bnc40a0b962020-04-23 17:38:25 -07001022TEST_P(EndToEndTest, NoUndecryptablePacketsBeforeHandshakeComplete) {
dschinazi6ece5002019-05-22 06:35:49 -07001023 ASSERT_TRUE(Initialize());
1024
1025 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1026 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1027
fkastenholz7591c282019-08-13 12:58:38 -07001028 QuicConnectionStats client_stats = GetClientConnection()->GetStats();
dschinazi7d0f3c82019-09-16 16:14:32 -07001029 EXPECT_EQ(
1030 0u,
1031 client_stats.undecryptable_packets_received_before_handshake_complete);
dschinazi02208652019-05-28 02:57:47 -07001032
1033 server_thread_->Pause();
1034 QuicConnectionStats server_stats = GetServerConnection()->GetStats();
dschinazi7d0f3c82019-09-16 16:14:32 -07001035 EXPECT_EQ(
1036 0u,
1037 server_stats.undecryptable_packets_received_before_handshake_complete);
dschinazi02208652019-05-28 02:57:47 -07001038 server_thread_->Resume();
dschinazi6ece5002019-05-22 06:35:49 -07001039}
1040
bnc40a0b962020-04-23 17:38:25 -07001041TEST_P(EndToEndTest, SeparateFinPacket) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001042 ASSERT_TRUE(Initialize());
1043
1044 // Send a request in two parts: the request and then an empty packet with FIN.
1045 SpdyHeaderBlock headers;
1046 headers[":method"] = "POST";
1047 headers[":path"] = "/foo";
1048 headers[":scheme"] = "https";
1049 headers[":authority"] = server_hostname_;
1050 client_->SendMessage(headers, "", /*fin=*/false);
1051 client_->SendData("", true);
1052 client_->WaitForResponse();
1053 EXPECT_EQ(kFooResponseBody, client_->response_body());
1054 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1055
1056 // Now do the same thing but with a content length.
1057 headers["content-length"] = "3";
1058 client_->SendMessage(headers, "", /*fin=*/false);
1059 client_->SendData("foo", true);
1060 client_->WaitForResponse();
1061 EXPECT_EQ(kFooResponseBody, client_->response_body());
1062 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1063}
1064
bnc40a0b962020-04-23 17:38:25 -07001065TEST_P(EndToEndTest, MultipleRequestResponse) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001066 ASSERT_TRUE(Initialize());
1067
1068 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1069 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1070 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
1071 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1072}
1073
bnc40a0b962020-04-23 17:38:25 -07001074TEST_P(EndToEndTestWithoutTls, MultipleRequestResponseZeroConnectionID) {
dschinazi97da52b2020-01-13 15:44:43 -08001075 if (!GetParam().negotiated_version.AllowsVariableLengthConnectionIds()) {
dschinazic8579862019-07-24 18:20:20 -07001076 ASSERT_TRUE(Initialize());
1077 return;
1078 }
1079 override_server_connection_id_length_ = 0;
1080 expected_server_connection_id_length_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001081 ASSERT_TRUE(Initialize());
1082
1083 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1084 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1085 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
1086 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1087}
1088
bnc40a0b962020-04-23 17:38:25 -07001089TEST_P(EndToEndTest, MultipleStreams) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001090 // Verifies quic_test_client can track responses of all active streams.
1091 ASSERT_TRUE(Initialize());
1092
1093 const int kNumRequests = 10;
1094
1095 SpdyHeaderBlock headers;
1096 headers[":method"] = "POST";
1097 headers[":path"] = "/foo";
1098 headers[":scheme"] = "https";
1099 headers[":authority"] = server_hostname_;
1100 headers["content-length"] = "3";
1101
1102 for (int i = 0; i < kNumRequests; ++i) {
1103 client_->SendMessage(headers, "bar", /*fin=*/true);
1104 }
1105
1106 while (kNumRequests > client_->num_responses()) {
1107 client_->ClearPerRequestState();
1108 client_->WaitForResponse();
1109 EXPECT_EQ(kFooResponseBody, client_->response_body());
1110 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1111 }
1112}
1113
bnc40a0b962020-04-23 17:38:25 -07001114TEST_P(EndToEndTest, MultipleClients) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001115 ASSERT_TRUE(Initialize());
1116 std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
1117
1118 SpdyHeaderBlock headers;
1119 headers[":method"] = "POST";
1120 headers[":path"] = "/foo";
1121 headers[":scheme"] = "https";
1122 headers[":authority"] = server_hostname_;
1123 headers["content-length"] = "3";
1124
1125 client_->SendMessage(headers, "", /*fin=*/false);
1126 client2->SendMessage(headers, "", /*fin=*/false);
1127
1128 client_->SendData("bar", true);
1129 client_->WaitForResponse();
1130 EXPECT_EQ(kFooResponseBody, client_->response_body());
1131 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1132
1133 client2->SendData("eep", true);
1134 client2->WaitForResponse();
1135 EXPECT_EQ(kFooResponseBody, client2->response_body());
1136 EXPECT_EQ("200", client2->response_headers()->find(":status")->second);
1137}
1138
bnc40a0b962020-04-23 17:38:25 -07001139TEST_P(EndToEndTest, RequestOverMultiplePackets) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001140 // Send a large enough request to guarantee fragmentation.
vasilvvc48c8712019-03-11 13:38:16 -07001141 std::string huge_request =
dschinazi66dea072019-04-09 11:41:06 -07001142 "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001143 AddToCache(huge_request, 200, kBarResponseBody);
1144
1145 ASSERT_TRUE(Initialize());
1146
1147 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
1148 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1149}
1150
bnc40a0b962020-04-23 17:38:25 -07001151TEST_P(EndToEndTest, MultiplePacketsRandomOrder) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001152 // Send a large enough request to guarantee fragmentation.
vasilvvc48c8712019-03-11 13:38:16 -07001153 std::string huge_request =
dschinazi66dea072019-04-09 11:41:06 -07001154 "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001155 AddToCache(huge_request, 200, kBarResponseBody);
1156
1157 ASSERT_TRUE(Initialize());
1158 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
1159 SetReorderPercentage(50);
1160
1161 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
1162 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1163}
1164
bnc40a0b962020-04-23 17:38:25 -07001165TEST_P(EndToEndTest, PostMissingBytes) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001166 ASSERT_TRUE(Initialize());
1167
1168 // Add a content length header with no body.
1169 SpdyHeaderBlock headers;
1170 headers[":method"] = "POST";
1171 headers[":path"] = "/foo";
1172 headers[":scheme"] = "https";
1173 headers[":authority"] = server_hostname_;
1174 headers["content-length"] = "3";
1175
1176 // This should be detected as stream fin without complete request,
1177 // triggering an error response.
1178 client_->SendCustomSynchronousRequest(headers, "");
1179 EXPECT_EQ(QuicSimpleServerStream::kErrorResponseBody,
1180 client_->response_body());
1181 EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
1182}
1183
bnc40a0b962020-04-23 17:38:25 -07001184TEST_P(EndToEndTestWithoutTls, LargePostNoPacketLoss) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001185 ASSERT_TRUE(Initialize());
1186
1187 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1188
1189 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07001190 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001191 SpdyHeaderBlock headers;
1192 headers[":method"] = "POST";
1193 headers[":path"] = "/foo";
1194 headers[":scheme"] = "https";
1195 headers[":authority"] = server_hostname_;
1196
1197 EXPECT_EQ(kFooResponseBody,
1198 client_->SendCustomSynchronousRequest(headers, body));
1199 // TODO(ianswett): There should not be packet loss in this test, but on some
1200 // platforms the receive buffer overflows.
1201 VerifyCleanConnection(true);
1202}
1203
bnc40a0b962020-04-23 17:38:25 -07001204TEST_P(EndToEndTestWithoutTls, LargePostNoPacketLoss1sRTT) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001205 ASSERT_TRUE(Initialize());
1206 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
1207
1208 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1209
1210 // 100 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001211 std::string body(100 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001212 SpdyHeaderBlock headers;
1213 headers[":method"] = "POST";
1214 headers[":path"] = "/foo";
1215 headers[":scheme"] = "https";
1216 headers[":authority"] = server_hostname_;
1217
1218 EXPECT_EQ(kFooResponseBody,
1219 client_->SendCustomSynchronousRequest(headers, body));
1220 VerifyCleanConnection(false);
1221}
1222
bnc40a0b962020-04-23 17:38:25 -07001223TEST_P(EndToEndTestWithoutTls, LargePostWithPacketLoss) {
wubbd64c102019-05-13 11:58:17 -07001224 // Connect with lower fake packet loss than we'd like to test.
1225 // Until b/10126687 is fixed, losing handshake packets is pretty
1226 // brutal.
1227 SetPacketLossPercentage(5);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001228 ASSERT_TRUE(Initialize());
1229
1230 // Wait for the server SHLO before upping the packet loss.
1231 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1232 SetPacketLossPercentage(30);
1233
1234 // 10 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001235 std::string body(1024 * 10, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001236 SpdyHeaderBlock headers;
1237 headers[":method"] = "POST";
1238 headers[":path"] = "/foo";
1239 headers[":scheme"] = "https";
1240 headers[":authority"] = server_hostname_;
1241
1242 EXPECT_EQ(kFooResponseBody,
1243 client_->SendCustomSynchronousRequest(headers, body));
1244 VerifyCleanConnection(true);
1245}
1246
1247// Regression test for b/80090281.
bnc40a0b962020-04-23 17:38:25 -07001248TEST_P(EndToEndTestWithoutTls,
1249 LargePostWithPacketLossAndAlwaysBundleWindowUpdates) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001250 ASSERT_TRUE(Initialize());
1251
1252 // Wait for the server SHLO before upping the packet loss.
1253 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1254 server_thread_->WaitForCryptoHandshakeConfirmed();
1255
1256 // Normally server only bundles a retransmittable frame once every other
1257 // kMaxConsecutiveNonRetransmittablePackets ack-only packets. Setting the max
1258 // to 0 to reliably reproduce b/80090281.
1259 server_thread_->Schedule([this]() {
1260 QuicConnectionPeer::SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
1261 GetServerConnection(), 0);
1262 });
1263
1264 SetPacketLossPercentage(30);
1265
1266 // 10 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001267 std::string body(1024 * 10, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001268 SpdyHeaderBlock headers;
1269 headers[":method"] = "POST";
1270 headers[":path"] = "/foo";
1271 headers[":scheme"] = "https";
1272 headers[":authority"] = server_hostname_;
1273
1274 EXPECT_EQ(kFooResponseBody,
1275 client_->SendCustomSynchronousRequest(headers, body));
1276 VerifyCleanConnection(true);
1277}
1278
bnc40a0b962020-04-23 17:38:25 -07001279TEST_P(EndToEndTestWithoutTls, LargePostWithPacketLossAndBlockedSocket) {
wubbd64c102019-05-13 11:58:17 -07001280 // Connect with lower fake packet loss than we'd like to test. Until
1281 // b/10126687 is fixed, losing handshake packets is pretty brutal.
1282 SetPacketLossPercentage(5);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001283 ASSERT_TRUE(Initialize());
1284
1285 // Wait for the server SHLO before upping the packet loss.
1286 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1287 SetPacketLossPercentage(10);
1288 client_writer_->set_fake_blocked_socket_percentage(10);
1289
1290 // 10 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001291 std::string body(1024 * 10, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001292 SpdyHeaderBlock headers;
1293 headers[":method"] = "POST";
1294 headers[":path"] = "/foo";
1295 headers[":scheme"] = "https";
1296 headers[":authority"] = server_hostname_;
1297
1298 EXPECT_EQ(kFooResponseBody,
1299 client_->SendCustomSynchronousRequest(headers, body));
1300}
1301
bnc40a0b962020-04-23 17:38:25 -07001302TEST_P(EndToEndTestWithoutTls, LargePostNoPacketLossWithDelayAndReordering) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001303 ASSERT_TRUE(Initialize());
1304
1305 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1306 // Both of these must be called when the writer is not actively used.
1307 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
1308 SetReorderPercentage(30);
1309
1310 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07001311 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001312 SpdyHeaderBlock headers;
1313 headers[":method"] = "POST";
1314 headers[":path"] = "/foo";
1315 headers[":scheme"] = "https";
1316 headers[":authority"] = server_hostname_;
1317
1318 EXPECT_EQ(kFooResponseBody,
1319 client_->SendCustomSynchronousRequest(headers, body));
1320}
1321
bnc40a0b962020-04-23 17:38:25 -07001322TEST_P(EndToEndTestWithoutTls, LargePostZeroRTTFailure) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001323 // Send a request and then disconnect. This prepares the client to attempt
1324 // a 0-RTT handshake for the next request.
1325 ASSERT_TRUE(Initialize());
1326
vasilvvc48c8712019-03-11 13:38:16 -07001327 std::string body(20480, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001328 SpdyHeaderBlock headers;
1329 headers[":method"] = "POST";
1330 headers[":path"] = "/foo";
1331 headers[":scheme"] = "https";
1332 headers[":authority"] = server_hostname_;
1333
1334 EXPECT_EQ(kFooResponseBody,
1335 client_->SendCustomSynchronousRequest(headers, body));
nharper23f4bb92020-02-13 15:34:36 -08001336 EXPECT_FALSE(GetClientSession()->EarlyDataAccepted());
1337 EXPECT_FALSE(GetClientSession()->ReceivedInchoateReject());
1338 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
1339 EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001340
1341 client_->Disconnect();
1342
1343 // The 0-RTT handshake should succeed.
1344 client_->Connect();
1345 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1346 ASSERT_TRUE(client_->client()->connected());
1347 EXPECT_EQ(kFooResponseBody,
1348 client_->SendCustomSynchronousRequest(headers, body));
1349
nharper23f4bb92020-02-13 15:34:36 -08001350 EXPECT_TRUE(GetClientSession()->EarlyDataAccepted());
1351 EXPECT_TRUE(client_->client()->EarlyDataAccepted());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001352
1353 client_->Disconnect();
1354
1355 // Restart the server so that the 0-RTT handshake will take 1 RTT.
1356 StopServer();
1357 server_writer_ = new PacketDroppingTestWriter();
1358 StartServer();
1359
1360 client_->Connect();
1361 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1362 ASSERT_TRUE(client_->client()->connected());
1363 EXPECT_EQ(kFooResponseBody,
1364 client_->SendCustomSynchronousRequest(headers, body));
nharper23f4bb92020-02-13 15:34:36 -08001365 EXPECT_FALSE(GetClientSession()->EarlyDataAccepted());
1366 EXPECT_FALSE(GetClientSession()->ReceivedInchoateReject());
1367 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
1368 EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001369
1370 VerifyCleanConnection(false);
1371}
1372
bnc40a0b962020-04-23 17:38:25 -07001373TEST_P(EndToEndTestWithoutTls, SynchronousRequestZeroRTTFailure) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001374 // Send a request and then disconnect. This prepares the client to attempt
1375 // a 0-RTT handshake for the next request.
1376 ASSERT_TRUE(Initialize());
1377
1378 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
nharper23f4bb92020-02-13 15:34:36 -08001379 EXPECT_FALSE(GetClientSession()->EarlyDataAccepted());
1380 EXPECT_FALSE(GetClientSession()->ReceivedInchoateReject());
1381 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
1382 EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001383
1384 client_->Disconnect();
1385
1386 // The 0-RTT handshake should succeed.
1387 client_->Connect();
1388 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1389 ASSERT_TRUE(client_->client()->connected());
1390 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1391
nharper23f4bb92020-02-13 15:34:36 -08001392 EXPECT_TRUE(GetClientSession()->EarlyDataAccepted());
1393 EXPECT_TRUE(client_->client()->EarlyDataAccepted());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001394
1395 client_->Disconnect();
1396
1397 // Restart the server so that the 0-RTT handshake will take 1 RTT.
1398 StopServer();
1399 server_writer_ = new PacketDroppingTestWriter();
1400 StartServer();
1401
1402 client_->Connect();
1403 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1404 ASSERT_TRUE(client_->client()->connected());
1405 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
wubbd64c102019-05-13 11:58:17 -07001406
nharper23f4bb92020-02-13 15:34:36 -08001407 EXPECT_FALSE(GetClientSession()->EarlyDataAccepted());
1408 EXPECT_FALSE(GetClientSession()->ReceivedInchoateReject());
1409 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
1410 EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001411
1412 VerifyCleanConnection(false);
1413}
1414
bnc40a0b962020-04-23 17:38:25 -07001415TEST_P(EndToEndTestWithoutTls, LargePostSynchronousRequest) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001416 // Send a request and then disconnect. This prepares the client to attempt
1417 // a 0-RTT handshake for the next request.
1418 ASSERT_TRUE(Initialize());
1419
vasilvvc48c8712019-03-11 13:38:16 -07001420 std::string body(20480, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001421 SpdyHeaderBlock headers;
1422 headers[":method"] = "POST";
1423 headers[":path"] = "/foo";
1424 headers[":scheme"] = "https";
1425 headers[":authority"] = server_hostname_;
1426
1427 EXPECT_EQ(kFooResponseBody,
1428 client_->SendCustomSynchronousRequest(headers, body));
nharper23f4bb92020-02-13 15:34:36 -08001429 EXPECT_FALSE(GetClientSession()->EarlyDataAccepted());
1430 EXPECT_FALSE(GetClientSession()->ReceivedInchoateReject());
1431 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
1432 EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001433
1434 client_->Disconnect();
1435
1436 // The 0-RTT handshake should succeed.
1437 client_->Connect();
1438 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1439 ASSERT_TRUE(client_->client()->connected());
1440 EXPECT_EQ(kFooResponseBody,
1441 client_->SendCustomSynchronousRequest(headers, body));
1442
nharper23f4bb92020-02-13 15:34:36 -08001443 EXPECT_TRUE(GetClientSession()->EarlyDataAccepted());
1444 EXPECT_TRUE(client_->client()->EarlyDataAccepted());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001445
1446 client_->Disconnect();
1447
1448 // Restart the server so that the 0-RTT handshake will take 1 RTT.
1449 StopServer();
1450 server_writer_ = new PacketDroppingTestWriter();
1451 StartServer();
1452
1453 client_->Connect();
1454 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1455 ASSERT_TRUE(client_->client()->connected());
1456 EXPECT_EQ(kFooResponseBody,
1457 client_->SendCustomSynchronousRequest(headers, body));
wubbd64c102019-05-13 11:58:17 -07001458
nharper23f4bb92020-02-13 15:34:36 -08001459 EXPECT_FALSE(GetClientSession()->EarlyDataAccepted());
1460 EXPECT_FALSE(GetClientSession()->ReceivedInchoateReject());
1461 EXPECT_FALSE(client_->client()->EarlyDataAccepted());
1462 EXPECT_FALSE(client_->client()->ReceivedInchoateReject());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001463
1464 VerifyCleanConnection(false);
1465}
1466
bnc40a0b962020-04-23 17:38:25 -07001467TEST_P(EndToEndTestWithoutTls, RejectWithPacketLoss) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001468 // In this test, we intentionally drop the first packet from the
wubbd64c102019-05-13 11:58:17 -07001469 // server, which corresponds with the initial REJ response from
QUICHE teama6ef0a62019-03-07 20:34:33 -05001470 // the server.
1471 server_writer_->set_fake_drop_first_n_packets(1);
1472 ASSERT_TRUE(Initialize());
1473}
1474
bnc40a0b962020-04-23 17:38:25 -07001475TEST_P(EndToEndTestWithoutTls, SetInitialReceivedConnectionOptions) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001476 QuicTagVector initial_received_options;
1477 initial_received_options.push_back(kTBBR);
1478 initial_received_options.push_back(kIW10);
1479 initial_received_options.push_back(kPRST);
1480 EXPECT_TRUE(server_config_.SetInitialReceivedConnectionOptions(
1481 initial_received_options));
1482
1483 ASSERT_TRUE(Initialize());
1484 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1485 server_thread_->WaitForCryptoHandshakeConfirmed();
1486
1487 EXPECT_FALSE(server_config_.SetInitialReceivedConnectionOptions(
1488 initial_received_options));
1489
1490 // Verify that server's configuration is correct.
1491 server_thread_->Pause();
1492 EXPECT_TRUE(server_config_.HasReceivedConnectionOptions());
1493 EXPECT_TRUE(
1494 ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kTBBR));
1495 EXPECT_TRUE(
1496 ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kIW10));
1497 EXPECT_TRUE(
1498 ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kPRST));
1499}
1500
bnc40a0b962020-04-23 17:38:25 -07001501TEST_P(EndToEndTestWithoutTls, LargePostSmallBandwidthLargeBuffer) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001502 ASSERT_TRUE(Initialize());
1503 SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
1504 // 256KB per second with a 256KB buffer from server to client. Wireless
1505 // clients commonly have larger buffers, but our max CWND is 200.
1506 server_writer_->set_max_bandwidth_and_buffer_size(
1507 QuicBandwidth::FromBytesPerSecond(256 * 1024), 256 * 1024);
1508
1509 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1510
1511 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07001512 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001513 SpdyHeaderBlock headers;
1514 headers[":method"] = "POST";
1515 headers[":path"] = "/foo";
1516 headers[":scheme"] = "https";
1517 headers[":authority"] = server_hostname_;
1518
1519 EXPECT_EQ(kFooResponseBody,
1520 client_->SendCustomSynchronousRequest(headers, body));
1521 // This connection may drop packets, because the buffer is smaller than the
1522 // max CWND.
1523 VerifyCleanConnection(true);
1524}
1525
bnc40a0b962020-04-23 17:38:25 -07001526TEST_P(EndToEndTest, DoNotSetSendAlarmIfConnectionFlowControlBlocked) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001527 // Regression test for b/14677858.
1528 // Test that the resume write alarm is not set in QuicConnection::OnCanWrite
1529 // if currently connection level flow control blocked. If set, this results in
1530 // an infinite loop in the EpollServer, as the alarm fires and is immediately
1531 // rescheduled.
1532 ASSERT_TRUE(Initialize());
1533 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1534
1535 // Ensure both stream and connection level are flow control blocked by setting
1536 // the send window offset to 0.
1537 const uint64_t flow_control_window =
1538 server_config_.GetInitialStreamFlowControlWindowToSend();
1539 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
fkastenholz7591c282019-08-13 12:58:38 -07001540 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001541 QuicFlowControllerPeer::SetSendWindowOffset(stream->flow_controller(), 0);
1542 QuicFlowControllerPeer::SetSendWindowOffset(session->flow_controller(), 0);
1543 EXPECT_TRUE(stream->flow_controller()->IsBlocked());
1544 EXPECT_TRUE(session->flow_controller()->IsBlocked());
1545
1546 // Make sure that the stream has data pending so that it will be marked as
1547 // write blocked when it receives a stream level WINDOW_UPDATE.
1548 stream->WriteOrBufferBody("hello", false);
1549
1550 // The stream now attempts to write, fails because it is still connection
1551 // level flow control blocked, and is added to the write blocked list.
1552 QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream->id(),
1553 2 * flow_control_window);
1554 stream->OnWindowUpdateFrame(window_update);
1555
1556 // Prior to fixing b/14677858 this call would result in an infinite loop in
1557 // Chromium. As a proxy for detecting this, we now check whether the
1558 // send alarm is set after OnCanWrite. It should not be, as the
1559 // connection is still flow control blocked.
1560 session->connection()->OnCanWrite();
1561
1562 QuicAlarm* send_alarm =
1563 QuicConnectionPeer::GetSendAlarm(session->connection());
1564 EXPECT_FALSE(send_alarm->IsSet());
1565}
1566
bnc40a0b962020-04-23 17:38:25 -07001567// TODO(b/154151800): Needs to get turned back to EndToEndTest when we figure
1568// out why the test doesn't work on chrome.
1569TEST_P(EndToEndTestWithoutTls, InvalidStream) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001570 ASSERT_TRUE(Initialize());
1571 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1572
dschinazi66dea072019-04-09 11:41:06 -07001573 std::string body(kMaxOutgoingPacketSize, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001574 SpdyHeaderBlock headers;
1575 headers[":method"] = "POST";
1576 headers[":path"] = "/foo";
1577 headers[":scheme"] = "https";
1578 headers[":authority"] = server_hostname_;
1579
1580 // Force the client to write with a stream ID belonging to a nonexistent
1581 // server-side stream.
fkastenholz7591c282019-08-13 12:58:38 -07001582 QuicSpdySession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001583 QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
1584 session, GetNthServerInitiatedBidirectionalId(0));
1585
1586 client_->SendCustomSynchronousRequest(headers, body);
bncc5769502019-11-27 10:01:44 -08001587 EXPECT_THAT(client_->stream_error(),
1588 IsStreamError(QUIC_STREAM_CONNECTION_ERROR));
1589 EXPECT_THAT(client_->connection_error(), IsError(QUIC_INVALID_STREAM_ID));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001590}
1591
1592// Test that if the server will close the connection if the client attempts
1593// to send a request with overly large headers.
bnc40a0b962020-04-23 17:38:25 -07001594TEST_P(EndToEndTestWithoutTls, LargeHeaders) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001595 ASSERT_TRUE(Initialize());
1596 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1597
dschinazi66dea072019-04-09 11:41:06 -07001598 std::string body(kMaxOutgoingPacketSize, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001599 SpdyHeaderBlock headers;
1600 headers[":method"] = "POST";
1601 headers[":path"] = "/foo";
1602 headers[":scheme"] = "https";
1603 headers[":authority"] = server_hostname_;
vasilvvc48c8712019-03-11 13:38:16 -07001604 headers["key1"] = std::string(15 * 1024, 'a');
1605 headers["key2"] = std::string(15 * 1024, 'a');
1606 headers["key3"] = std::string(15 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001607
1608 client_->SendCustomSynchronousRequest(headers, body);
renjietang2abedac2019-05-20 14:04:50 -07001609
renjietanga29a96a2019-10-10 12:47:50 -07001610 if (VersionUsesHttp3(client_->client()
renjietang2abedac2019-05-20 14:04:50 -07001611 ->client_session()
1612 ->connection()
1613 ->transport_version())) {
bncc5769502019-11-27 10:01:44 -08001614 EXPECT_THAT(client_->connection_error(),
1615 IsError(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE));
renjietang2abedac2019-05-20 14:04:50 -07001616 } else {
bncc5769502019-11-27 10:01:44 -08001617 EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_HEADERS_TOO_LARGE));
1618 EXPECT_THAT(client_->connection_error(), IsQuicNoError());
renjietang2abedac2019-05-20 14:04:50 -07001619 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001620}
1621
bnc40a0b962020-04-23 17:38:25 -07001622TEST_P(EndToEndTestWithoutTls, EarlyResponseWithQuicStreamNoError) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001623 ASSERT_TRUE(Initialize());
1624 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1625
vasilvvc48c8712019-03-11 13:38:16 -07001626 std::string large_body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001627 SpdyHeaderBlock headers;
1628 headers[":method"] = "POST";
1629 headers[":path"] = "/foo";
1630 headers[":scheme"] = "https";
1631 headers[":authority"] = server_hostname_;
1632 // Insert an invalid content_length field in request to trigger an early
1633 // response from server.
1634 headers["content-length"] = "-3";
1635
1636 client_->SendCustomSynchronousRequest(headers, large_body);
1637 EXPECT_EQ("bad", client_->response_body());
1638 EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
bncc5769502019-11-27 10:01:44 -08001639 EXPECT_THAT(client_->stream_error(), IsQuicStreamNoError());
1640 EXPECT_THAT(client_->connection_error(), IsQuicNoError());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001641}
1642
1643// TODO(rch): this test seems to cause net_unittests timeouts :|
bnc40a0b962020-04-23 17:38:25 -07001644TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(MultipleTermination)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001645 ASSERT_TRUE(Initialize());
1646
1647 // Set the offset so we won't frame. Otherwise when we pick up termination
1648 // before HTTP framing is complete, we send an error and close the stream,
1649 // and the second write is picked up as writing on a closed stream.
1650 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
1651 ASSERT_TRUE(stream != nullptr);
1652 QuicStreamPeer::SetStreamBytesWritten(3, stream);
1653
1654 client_->SendData("bar", true);
1655 client_->WaitForWriteToFlush();
1656
1657 // By default the stream protects itself from writes after terminte is set.
1658 // Override this to test the server handling buggy clients.
1659 QuicStreamPeer::SetWriteSideClosed(false, client_->GetOrCreateStream());
1660
1661 EXPECT_QUIC_BUG(client_->SendData("eep", true), "Fin already buffered");
1662}
1663
bnc40a0b962020-04-23 17:38:25 -07001664// TODO(b/154151800): Needs to get turned back to EndToEndTest when we figure
1665// out why the test doesn't work on chrome.
1666TEST_P(EndToEndTestWithoutTls, Timeout) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001667 client_config_.SetIdleNetworkTimeout(QuicTime::Delta::FromMicroseconds(500),
1668 QuicTime::Delta::FromMicroseconds(500));
1669 // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
1670 // that's enough to validate timeout in this case.
1671 Initialize();
1672 while (client_->client()->connected()) {
1673 client_->client()->WaitForEvents();
1674 }
1675}
1676
bnc40a0b962020-04-23 17:38:25 -07001677TEST_P(EndToEndTest, MaxDynamicStreamsLimitRespected) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001678 // Set a limit on maximum number of incoming dynamic streams.
renjietange6d94672020-01-07 10:30:10 -08001679 // Make sure the limit is respected by the peer.
1680 const uint32_t kServerMaxDynamicStreams = 1;
1681 server_config_.SetMaxBidirectionalStreamsToSend(kServerMaxDynamicStreams);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001682 ASSERT_TRUE(Initialize());
fkastenholz305e1732019-06-18 05:01:22 -07001683 if (VersionHasIetfQuicFrames(
1684 GetParam().negotiated_version.transport_version)) {
renjietang8b871952019-11-14 14:36:50 -08001685 // Do not run this test for /IETF QUIC. This test relies on the fact that
1686 // Google QUIC allows a small number of additional streams beyond the
1687 // negotiated limit, which is not supported in IETF QUIC. Note that the test
1688 // needs to be here, after calling Initialize(), because all tests end up
1689 // calling EndToEndTest::TearDown(), which asserts that Initialize has been
1690 // called and then proceeds to tear things down -- which fails if they are
1691 // not properly set up.
fkastenholz3c4eabf2019-04-22 07:49:59 -07001692 return;
1693 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001694 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001695
1696 // Make the client misbehave after negotiation.
1697 const int kServerMaxStreams = kMaxStreamsMinimumIncrement + 1;
fkastenholz7591c282019-08-13 12:58:38 -07001698 QuicSessionPeer::SetMaxOpenOutgoingStreams(GetClientSession(),
1699 kServerMaxStreams + 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001700
1701 SpdyHeaderBlock headers;
1702 headers[":method"] = "POST";
1703 headers[":path"] = "/foo";
1704 headers[":scheme"] = "https";
1705 headers[":authority"] = server_hostname_;
1706 headers["content-length"] = "3";
1707
1708 // The server supports a small number of additional streams beyond the
1709 // negotiated limit. Open enough streams to go beyond that limit.
1710 for (int i = 0; i < kServerMaxStreams + 1; ++i) {
1711 client_->SendMessage(headers, "", /*fin=*/false);
1712 }
1713 client_->WaitForResponse();
fkastenholz3c4eabf2019-04-22 07:49:59 -07001714
1715 EXPECT_TRUE(client_->connected());
bncc5769502019-11-27 10:01:44 -08001716 EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_REFUSED_STREAM));
1717 EXPECT_THAT(client_->connection_error(), IsQuicNoError());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001718}
1719
bnc40a0b962020-04-23 17:38:25 -07001720TEST_P(EndToEndTestWithoutTls, SetIndependentMaxDynamicStreamsLimits) {
renjietange6d94672020-01-07 10:30:10 -08001721 // Each endpoint can set max dynamic streams independently.
1722 const uint32_t kClientMaxDynamicStreams = 4;
1723 const uint32_t kServerMaxDynamicStreams = 3;
1724 client_config_.SetMaxBidirectionalStreamsToSend(kClientMaxDynamicStreams);
1725 server_config_.SetMaxBidirectionalStreamsToSend(kServerMaxDynamicStreams);
1726 client_config_.SetMaxUnidirectionalStreamsToSend(kClientMaxDynamicStreams);
1727 server_config_.SetMaxUnidirectionalStreamsToSend(kServerMaxDynamicStreams);
fkastenholzd3a1de92019-05-15 07:00:07 -07001728
QUICHE teama6ef0a62019-03-07 20:34:33 -05001729 ASSERT_TRUE(Initialize());
1730 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1731
1732 // The client has received the server's limit and vice versa.
fkastenholz7591c282019-08-13 12:58:38 -07001733 QuicSpdyClientSession* client_session = GetClientSession();
fkastenholz3c4eabf2019-04-22 07:49:59 -07001734 // The value returned by max_allowed... includes the Crypto and Header
1735 // stream (created as a part of initialization). The config. values,
1736 // above, are treated as "number of requests/responses" - that is, they do
1737 // not include the static Crypto and Header streams. Reduce the value
1738 // returned by max_allowed... by 2 to remove the static streams from the
1739 // count.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001740 size_t client_max_open_outgoing_bidirectional_streams =
fkastenholz305e1732019-06-18 05:01:22 -07001741 VersionHasIetfQuicFrames(
1742 client_session->connection()->transport_version())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001743 ? QuicSessionPeer::v99_streamid_manager(client_session)
ianswettd1414532019-09-18 20:12:59 -07001744 ->max_outgoing_bidirectional_streams()
QUICHE teama6ef0a62019-03-07 20:34:33 -05001745 : QuicSessionPeer::GetStreamIdManager(client_session)
1746 ->max_open_outgoing_streams();
1747 size_t client_max_open_outgoing_unidirectional_streams =
fkastenholz305e1732019-06-18 05:01:22 -07001748 VersionHasIetfQuicFrames(
1749 client_session->connection()->transport_version())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001750 ? QuicSessionPeer::v99_streamid_manager(client_session)
ianswettd1414532019-09-18 20:12:59 -07001751 ->max_outgoing_unidirectional_streams() -
renjietang216dc012019-08-27 11:28:27 -07001752 client_session->num_expected_unidirectional_static_streams()
QUICHE teama6ef0a62019-03-07 20:34:33 -05001753 : QuicSessionPeer::GetStreamIdManager(client_session)
1754 ->max_open_outgoing_streams();
renjietange6d94672020-01-07 10:30:10 -08001755 EXPECT_EQ(kServerMaxDynamicStreams,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001756 client_max_open_outgoing_bidirectional_streams);
renjietange6d94672020-01-07 10:30:10 -08001757 EXPECT_EQ(kServerMaxDynamicStreams,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001758 client_max_open_outgoing_unidirectional_streams);
1759 server_thread_->Pause();
1760 QuicSession* server_session = GetServerSession();
1761 size_t server_max_open_outgoing_bidirectional_streams =
fkastenholz305e1732019-06-18 05:01:22 -07001762 VersionHasIetfQuicFrames(
1763 server_session->connection()->transport_version())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001764 ? QuicSessionPeer::v99_streamid_manager(server_session)
ianswettd1414532019-09-18 20:12:59 -07001765 ->max_outgoing_bidirectional_streams()
QUICHE teama6ef0a62019-03-07 20:34:33 -05001766 : QuicSessionPeer::GetStreamIdManager(server_session)
1767 ->max_open_outgoing_streams();
1768 size_t server_max_open_outgoing_unidirectional_streams =
fkastenholz305e1732019-06-18 05:01:22 -07001769 VersionHasIetfQuicFrames(
1770 server_session->connection()->transport_version())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001771 ? QuicSessionPeer::v99_streamid_manager(server_session)
ianswettd1414532019-09-18 20:12:59 -07001772 ->max_outgoing_unidirectional_streams() -
renjietang216dc012019-08-27 11:28:27 -07001773 server_session->num_expected_unidirectional_static_streams()
QUICHE teama6ef0a62019-03-07 20:34:33 -05001774 : QuicSessionPeer::GetStreamIdManager(server_session)
1775 ->max_open_outgoing_streams();
renjietange6d94672020-01-07 10:30:10 -08001776 EXPECT_EQ(kClientMaxDynamicStreams,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001777 server_max_open_outgoing_bidirectional_streams);
renjietange6d94672020-01-07 10:30:10 -08001778 EXPECT_EQ(kClientMaxDynamicStreams,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001779 server_max_open_outgoing_unidirectional_streams);
renjietang87cd7de2019-08-16 08:35:10 -07001780
QUICHE teama6ef0a62019-03-07 20:34:33 -05001781 server_thread_->Resume();
1782}
1783
bnc40a0b962020-04-23 17:38:25 -07001784TEST_P(EndToEndTestWithoutTls, NegotiateCongestionControl) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001785 ASSERT_TRUE(Initialize());
1786
QUICHE teama6ef0a62019-03-07 20:34:33 -05001787 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1788
1789 CongestionControlType expected_congestion_control_type = kRenoBytes;
1790 switch (GetParam().congestion_control_tag) {
1791 case kRENO:
1792 expected_congestion_control_type = kRenoBytes;
1793 break;
1794 case kTBBR:
1795 expected_congestion_control_type = kBBR;
1796 break;
1797 case kQBIC:
1798 expected_congestion_control_type = kCubicBytes;
1799 break;
wuba9a43cb2019-07-17 15:22:42 -07001800 case kB2ON:
1801 expected_congestion_control_type = kBBRv2;
1802 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001803 default:
1804 QUIC_DLOG(FATAL) << "Unexpected congestion control tag";
1805 }
1806
1807 server_thread_->Pause();
1808 EXPECT_EQ(expected_congestion_control_type,
1809 QuicSentPacketManagerPeer::GetSendAlgorithm(
1810 *GetSentPacketManagerFromFirstServerSession())
1811 ->GetCongestionControlType());
1812 server_thread_->Resume();
1813}
1814
bnc40a0b962020-04-23 17:38:25 -07001815TEST_P(EndToEndTestWithoutTls, ClientSuggestsRTT) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001816 // Client suggests initial RTT, verify it is used.
1817 const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
1818 client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
1819
1820 ASSERT_TRUE(Initialize());
1821 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1822 server_thread_->WaitForCryptoHandshakeConfirmed();
1823
1824 // Pause the server so we can access the server's internals without races.
1825 server_thread_->Pause();
1826 QuicDispatcher* dispatcher =
1827 QuicServerPeer::GetDispatcher(server_thread_->server());
1828 ASSERT_EQ(1u, dispatcher->session_map().size());
1829 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001830 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001831 const QuicSentPacketManager* server_sent_packet_manager =
1832 GetSentPacketManagerFromFirstServerSession();
1833
1834 EXPECT_EQ(kInitialRTT,
1835 client_sent_packet_manager.GetRttStats()->initial_rtt());
1836 EXPECT_EQ(kInitialRTT,
1837 server_sent_packet_manager->GetRttStats()->initial_rtt());
1838 server_thread_->Resume();
1839}
1840
bnc40a0b962020-04-23 17:38:25 -07001841TEST_P(EndToEndTestWithoutTls, ClientSuggestsIgnoredRTT) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001842 // Client suggests initial RTT, but also specifies NRTT, so it's not used.
1843 const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
1844 client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
1845 QuicTagVector options;
1846 options.push_back(kNRTT);
1847 client_config_.SetConnectionOptionsToSend(options);
1848
1849 ASSERT_TRUE(Initialize());
1850 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1851 server_thread_->WaitForCryptoHandshakeConfirmed();
1852
1853 // Pause the server so we can access the server's internals without races.
1854 server_thread_->Pause();
1855 QuicDispatcher* dispatcher =
1856 QuicServerPeer::GetDispatcher(server_thread_->server());
1857 ASSERT_EQ(1u, dispatcher->session_map().size());
1858 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001859 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001860 const QuicSentPacketManager* server_sent_packet_manager =
1861 GetSentPacketManagerFromFirstServerSession();
1862
1863 EXPECT_EQ(kInitialRTT,
1864 client_sent_packet_manager.GetRttStats()->initial_rtt());
1865 EXPECT_EQ(kInitialRTT,
1866 server_sent_packet_manager->GetRttStats()->initial_rtt());
1867 server_thread_->Resume();
1868}
1869
bnc40a0b962020-04-23 17:38:25 -07001870TEST_P(EndToEndTestWithoutTls, MaxInitialRTT) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001871 // Client tries to suggest twice the server's max initial rtt and the server
1872 // uses the max.
1873 client_config_.SetInitialRoundTripTimeUsToSend(2 *
1874 kMaxInitialRoundTripTimeUs);
1875
1876 ASSERT_TRUE(Initialize());
1877 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1878 server_thread_->WaitForCryptoHandshakeConfirmed();
1879
1880 // Pause the server so we can access the server's internals without races.
1881 server_thread_->Pause();
1882 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001883 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001884
1885 // Now that acks have been exchanged, the RTT estimate has decreased on the
1886 // server and is not infinite on the client.
1887 EXPECT_FALSE(
1888 client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
1889 const RttStats& server_rtt_stats =
1890 *GetServerConnection()->sent_packet_manager().GetRttStats();
1891 EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
1892 server_rtt_stats.initial_rtt().ToMicroseconds());
1893 EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
1894 server_rtt_stats.smoothed_rtt().ToMicroseconds());
1895 server_thread_->Resume();
1896}
1897
bnc40a0b962020-04-23 17:38:25 -07001898TEST_P(EndToEndTestWithoutTls, MinInitialRTT) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001899 // Client tries to suggest 0 and the server uses the default.
1900 client_config_.SetInitialRoundTripTimeUsToSend(0);
1901
1902 ASSERT_TRUE(Initialize());
1903 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1904 server_thread_->WaitForCryptoHandshakeConfirmed();
1905
1906 // Pause the server so we can access the server's internals without races.
1907 server_thread_->Pause();
1908 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001909 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001910 const QuicSentPacketManager& server_sent_packet_manager =
1911 GetServerConnection()->sent_packet_manager();
1912
1913 // Now that acks have been exchanged, the RTT estimate has decreased on the
1914 // server and is not infinite on the client.
1915 EXPECT_FALSE(
1916 client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
1917 // Expect the default rtt of 100ms.
1918 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
1919 server_sent_packet_manager.GetRttStats()->initial_rtt());
1920 // Ensure the bandwidth is valid.
1921 client_sent_packet_manager.BandwidthEstimate();
1922 server_sent_packet_manager.BandwidthEstimate();
1923 server_thread_->Resume();
1924}
1925
bnc40a0b962020-04-23 17:38:25 -07001926TEST_P(EndToEndTestWithoutTls, 0ByteConnectionId) {
fayangd4291e42019-05-30 10:31:21 -07001927 if (VersionHasIetfInvariantHeader(
1928 GetParam().negotiated_version.transport_version)) {
dschinazi6dc83682019-05-28 16:46:47 -07001929 // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
1930 ASSERT_TRUE(Initialize());
1931 return;
1932 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001933 client_config_.SetBytesForConnectionIdToSend(0);
1934 ASSERT_TRUE(Initialize());
1935
1936 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1937 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -07001938 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001939 QuicPacketHeader* header =
1940 QuicConnectionPeer::GetLastHeader(client_connection);
dschinazi5e1a7b22019-07-31 12:23:21 -07001941 EXPECT_EQ(CONNECTION_ID_ABSENT, header->source_connection_id_included);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001942}
1943
bnc40a0b962020-04-23 17:38:25 -07001944TEST_P(EndToEndTest, 8ByteConnectionId) {
fayangd4291e42019-05-30 10:31:21 -07001945 if (VersionHasIetfInvariantHeader(
1946 GetParam().negotiated_version.transport_version)) {
dschinazi6dc83682019-05-28 16:46:47 -07001947 // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
1948 ASSERT_TRUE(Initialize());
1949 return;
1950 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001951 client_config_.SetBytesForConnectionIdToSend(8);
1952 ASSERT_TRUE(Initialize());
1953
1954 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1955 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -07001956 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001957 QuicPacketHeader* header =
1958 QuicConnectionPeer::GetLastHeader(client_connection);
dschinazi6dc83682019-05-28 16:46:47 -07001959 EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001960}
1961
bnc40a0b962020-04-23 17:38:25 -07001962TEST_P(EndToEndTest, 15ByteConnectionId) {
fayangd4291e42019-05-30 10:31:21 -07001963 if (VersionHasIetfInvariantHeader(
1964 GetParam().negotiated_version.transport_version)) {
dschinazi6dc83682019-05-28 16:46:47 -07001965 // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
1966 ASSERT_TRUE(Initialize());
1967 return;
1968 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001969 client_config_.SetBytesForConnectionIdToSend(15);
1970 ASSERT_TRUE(Initialize());
1971
1972 // Our server is permissive and allows for out of bounds values.
1973 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1974 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -07001975 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001976 QuicPacketHeader* header =
1977 QuicConnectionPeer::GetLastHeader(client_connection);
dschinazi6dc83682019-05-28 16:46:47 -07001978 EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001979}
1980
bnc40a0b962020-04-23 17:38:25 -07001981TEST_P(EndToEndTest, ResetConnection) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001982 ASSERT_TRUE(Initialize());
1983
1984 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1985 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1986 client_->ResetConnection();
1987 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1988 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
1989 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1990}
1991
bnc40a0b962020-04-23 17:38:25 -07001992// TODO(b/154151800): Needs to get turned back to EndToEndTest when we figure
1993// out why the test doesn't work on chrome.
1994TEST_P(EndToEndTestWithoutTls, MaxStreamsUberTest) {
wubbd64c102019-05-13 11:58:17 -07001995 // Connect with lower fake packet loss than we'd like to test. Until
1996 // b/10126687 is fixed, losing handshake packets is pretty brutal.
1997 SetPacketLossPercentage(1);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001998 ASSERT_TRUE(Initialize());
vasilvvc48c8712019-03-11 13:38:16 -07001999 std::string large_body(10240, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002000 int max_streams = 100;
2001
2002 AddToCache("/large_response", 200, large_body);
2003
2004 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2005 SetPacketLossPercentage(10);
2006
2007 for (int i = 0; i < max_streams; ++i) {
2008 EXPECT_LT(0, client_->SendRequest("/large_response"));
2009 }
2010
2011 // WaitForEvents waits 50ms and returns true if there are outstanding
2012 // requests.
2013 while (client_->client()->WaitForEvents() == true) {
2014 }
2015}
2016
bnc40a0b962020-04-23 17:38:25 -07002017TEST_P(EndToEndTest, StreamCancelErrorTest) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002018 ASSERT_TRUE(Initialize());
vasilvvc48c8712019-03-11 13:38:16 -07002019 std::string small_body(256, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002020
2021 AddToCache("/small_response", 200, small_body);
2022
2023 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2024
fkastenholz7591c282019-08-13 12:58:38 -07002025 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002026 // Lose the request.
2027 SetPacketLossPercentage(100);
2028 EXPECT_LT(0, client_->SendRequest("/small_response"));
2029 client_->client()->WaitForEvents();
2030 // Transmit the cancel, and ensure the connection is torn down properly.
2031 SetPacketLossPercentage(0);
2032 QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
fayangd62ea772020-04-17 06:32:16 -07002033 if (session->break_close_loop()) {
2034 session->ResetStream(stream_id, QUIC_STREAM_CANCELLED, 0);
2035 } else {
2036 session->SendRstStream(stream_id, QUIC_STREAM_CANCELLED, 0);
2037 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002038
2039 // WaitForEvents waits 50ms and returns true if there are outstanding
2040 // requests.
2041 while (client_->client()->WaitForEvents() == true) {
2042 }
2043 // It should be completely fine to RST a stream before any data has been
2044 // received for that stream.
bncc5769502019-11-27 10:01:44 -08002045 EXPECT_THAT(client_->connection_error(), IsQuicNoError());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002046}
2047
bnc40a0b962020-04-23 17:38:25 -07002048TEST_P(EndToEndTestWithoutTls, ConnectionMigrationClientIPChanged) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002049 ASSERT_TRUE(Initialize());
2050 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2051 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2052
2053 // Store the client IP address which was used to send the first request.
2054 QuicIpAddress old_host =
2055 client_->client()->network_helper()->GetLatestClientAddress().host();
2056
2057 // Migrate socket to the new IP address.
2058 QuicIpAddress new_host = TestLoopback(2);
2059 EXPECT_NE(old_host, new_host);
2060 ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
2061
2062 // Send a request using the new socket.
2063 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
2064 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2065}
2066
bnc40a0b962020-04-23 17:38:25 -07002067TEST_P(EndToEndTestWithoutTls, ConnectionMigrationClientPortChanged) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002068 // Tests that the client's port can change during an established QUIC
2069 // connection, and that doing so does not result in the connection being
2070 // closed by the server.
2071 ASSERT_TRUE(Initialize());
2072
2073 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2074 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2075
2076 // Store the client address which was used to send the first request.
2077 QuicSocketAddress old_address =
2078 client_->client()->network_helper()->GetLatestClientAddress();
2079 int old_fd = client_->client()->GetLatestFD();
2080
2081 // Create a new socket before closing the old one, which will result in a new
2082 // ephemeral port.
2083 QuicClientPeer::CreateUDPSocketAndBind(client_->client());
2084
2085 // Stop listening and close the old FD.
2086 QuicClientPeer::CleanUpUDPSocket(client_->client(), old_fd);
2087
2088 // The packet writer needs to be updated to use the new FD.
2089 client_->client()->network_helper()->CreateQuicPacketWriter();
2090
2091 // Change the internal state of the client and connection to use the new port,
2092 // this is done because in a real NAT rebinding the client wouldn't see any
2093 // port change, and so expects no change to incoming port.
2094 // This is kind of ugly, but needed as we are simply swapping out the client
2095 // FD rather than any more complex NAT rebinding simulation.
2096 int new_port =
2097 client_->client()->network_helper()->GetLatestClientAddress().port();
2098 QuicClientPeer::SetClientPort(client_->client(), new_port);
fkastenholz7591c282019-08-13 12:58:38 -07002099 QuicConnectionPeer::SetSelfAddress(GetClientConnection(),
2100 QuicSocketAddress(client_->client()
2101 ->client_session()
2102 ->connection()
2103 ->self_address()
2104 .host(),
2105 new_port));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002106
2107 // Register the new FD for epoll events.
2108 int new_fd = client_->client()->GetLatestFD();
2109 QuicEpollServer* eps = client_->epoll_server();
2110 eps->RegisterFD(new_fd, client_->client()->epoll_network_helper(),
2111 EPOLLIN | EPOLLOUT | EPOLLET);
2112
2113 // Send a second request, using the new FD.
2114 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
2115 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2116
2117 // Verify that the client's ephemeral port is different.
2118 QuicSocketAddress new_address =
2119 client_->client()->network_helper()->GetLatestClientAddress();
2120 EXPECT_EQ(old_address.host(), new_address.host());
2121 EXPECT_NE(old_address.port(), new_address.port());
2122}
2123
bnc40a0b962020-04-23 17:38:25 -07002124TEST_P(EndToEndTestWithoutTls, NegotiatedInitialCongestionWindow) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002125 SetQuicReloadableFlag(quic_unified_iw_options, true);
2126 client_extra_copts_.push_back(kIW03);
2127
2128 ASSERT_TRUE(Initialize());
2129
2130 // Values are exchanged during crypto handshake, so wait for that to finish.
2131 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2132 server_thread_->WaitForCryptoHandshakeConfirmed();
2133 server_thread_->Pause();
2134
2135 QuicPacketCount cwnd =
2136 GetServerConnection()->sent_packet_manager().initial_congestion_window();
2137 EXPECT_EQ(3u, cwnd);
2138}
2139
bnc40a0b962020-04-23 17:38:25 -07002140TEST_P(EndToEndTestWithoutTls, DifferentFlowControlWindows) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002141 // Client and server can set different initial flow control receive windows.
2142 // These are sent in CHLO/SHLO. Tests that these values are exchanged properly
2143 // in the crypto handshake.
2144 const uint32_t kClientStreamIFCW = 123456;
2145 const uint32_t kClientSessionIFCW = 234567;
2146 set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
2147 set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
2148
2149 uint32_t kServerStreamIFCW = 32 * 1024;
2150 uint32_t kServerSessionIFCW = 48 * 1024;
2151 set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
2152 set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
2153
2154 ASSERT_TRUE(Initialize());
2155
2156 // Values are exchanged during crypto handshake, so wait for that to finish.
2157 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2158 server_thread_->WaitForCryptoHandshakeConfirmed();
2159
2160 // Open a data stream to make sure the stream level flow control is updated.
2161 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
bnc519216c2019-07-09 05:03:48 -07002162 WriteHeadersOnStream(stream);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002163 stream->WriteOrBufferBody("hello", false);
2164
2165 // Client should have the right values for server's receive window.
2166 EXPECT_EQ(kServerStreamIFCW,
2167 client_->client()
2168 ->client_session()
2169 ->config()
2170 ->ReceivedInitialStreamFlowControlWindowBytes());
2171 EXPECT_EQ(kServerSessionIFCW,
2172 client_->client()
2173 ->client_session()
2174 ->config()
2175 ->ReceivedInitialSessionFlowControlWindowBytes());
2176 EXPECT_EQ(kServerStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
2177 stream->flow_controller()));
fkastenholz7591c282019-08-13 12:58:38 -07002178 EXPECT_EQ(kServerSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
2179 GetClientSession()->flow_controller()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002180
2181 // Server should have the right values for client's receive window.
2182 server_thread_->Pause();
2183 QuicSession* session = GetServerSession();
2184 EXPECT_EQ(kClientStreamIFCW,
2185 session->config()->ReceivedInitialStreamFlowControlWindowBytes());
2186 EXPECT_EQ(kClientSessionIFCW,
2187 session->config()->ReceivedInitialSessionFlowControlWindowBytes());
2188 EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
2189 session->flow_controller()));
2190 server_thread_->Resume();
2191}
2192
2193// Test negotiation of IFWA connection option.
bnc40a0b962020-04-23 17:38:25 -07002194TEST_P(EndToEndTestWithoutTls, NegotiatedServerInitialFlowControlWindow) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002195 const uint32_t kClientStreamIFCW = 123456;
2196 const uint32_t kClientSessionIFCW = 234567;
2197 set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
2198 set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
2199
2200 uint32_t kServerStreamIFCW = 32 * 1024;
2201 uint32_t kServerSessionIFCW = 48 * 1024;
2202 set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
2203 set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
2204
2205 // Bump the window.
2206 const uint32_t kExpectedStreamIFCW = 1024 * 1024;
2207 const uint32_t kExpectedSessionIFCW = 1.5 * 1024 * 1024;
2208 client_extra_copts_.push_back(kIFWA);
2209
2210 ASSERT_TRUE(Initialize());
2211
2212 // Values are exchanged during crypto handshake, so wait for that to finish.
2213 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2214 server_thread_->WaitForCryptoHandshakeConfirmed();
2215
2216 // Open a data stream to make sure the stream level flow control is updated.
2217 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
bnc519216c2019-07-09 05:03:48 -07002218 WriteHeadersOnStream(stream);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002219 stream->WriteOrBufferBody("hello", false);
2220
2221 // Client should have the right values for server's receive window.
2222 EXPECT_EQ(kExpectedStreamIFCW,
2223 client_->client()
2224 ->client_session()
2225 ->config()
2226 ->ReceivedInitialStreamFlowControlWindowBytes());
2227 EXPECT_EQ(kExpectedSessionIFCW,
2228 client_->client()
2229 ->client_session()
2230 ->config()
2231 ->ReceivedInitialSessionFlowControlWindowBytes());
2232 EXPECT_EQ(kExpectedStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
2233 stream->flow_controller()));
fkastenholz7591c282019-08-13 12:58:38 -07002234 EXPECT_EQ(kExpectedSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
2235 GetClientSession()->flow_controller()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002236}
2237
bnc40a0b962020-04-23 17:38:25 -07002238TEST_P(EndToEndTestWithoutTls, HeadersAndCryptoStreamsNoConnectionFlowControl) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002239 // The special headers and crypto streams should be subject to per-stream flow
2240 // control limits, but should not be subject to connection level flow control
2241 const uint32_t kStreamIFCW = 32 * 1024;
2242 const uint32_t kSessionIFCW = 48 * 1024;
2243 set_client_initial_stream_flow_control_receive_window(kStreamIFCW);
2244 set_client_initial_session_flow_control_receive_window(kSessionIFCW);
2245 set_server_initial_stream_flow_control_receive_window(kStreamIFCW);
2246 set_server_initial_session_flow_control_receive_window(kSessionIFCW);
2247
2248 ASSERT_TRUE(Initialize());
2249
2250 // Wait for crypto handshake to finish. This should have contributed to the
2251 // crypto stream flow control window, but not affected the session flow
2252 // control window.
2253 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2254 server_thread_->WaitForCryptoHandshakeConfirmed();
2255
fkastenholz7591c282019-08-13 12:58:38 -07002256 QuicCryptoStream* crypto_stream =
2257 QuicSessionPeer::GetMutableCryptoStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002258 // In v47 and later, the crypto handshake (sent in CRYPTO frames) is not
2259 // subject to flow control.
renjietang2abedac2019-05-20 14:04:50 -07002260 const QuicTransportVersion transport_version =
fkastenholz7591c282019-08-13 12:58:38 -07002261 GetClientConnection()->transport_version();
renjietang2abedac2019-05-20 14:04:50 -07002262 if (!QuicVersionUsesCryptoFrames(transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002263 EXPECT_LT(QuicFlowControllerPeer::SendWindowSize(
2264 crypto_stream->flow_controller()),
2265 kStreamIFCW);
2266 }
renjietang3a1bb802019-06-11 10:42:41 -07002267 // When stream type is enabled, control streams will send settings and
2268 // contribute to flow control windows, so this expectation is no longer valid.
renjietanga29a96a2019-10-10 12:47:50 -07002269 if (!VersionUsesHttp3(transport_version)) {
fkastenholz7591c282019-08-13 12:58:38 -07002270 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
2271 GetClientSession()->flow_controller()));
renjietang3a1bb802019-06-11 10:42:41 -07002272 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002273
2274 // Send a request with no body, and verify that the connection level window
2275 // has not been affected.
2276 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2277
renjietang2abedac2019-05-20 14:04:50 -07002278 // No headers stream in IETF QUIC.
renjietanga29a96a2019-10-10 12:47:50 -07002279 if (VersionUsesHttp3(transport_version)) {
renjietang2abedac2019-05-20 14:04:50 -07002280 return;
2281 }
2282
fkastenholz7591c282019-08-13 12:58:38 -07002283 QuicHeadersStream* headers_stream =
2284 QuicSpdySessionPeer::GetHeadersStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002285 EXPECT_LT(
2286 QuicFlowControllerPeer::SendWindowSize(headers_stream->flow_controller()),
2287 kStreamIFCW);
fkastenholz7591c282019-08-13 12:58:38 -07002288 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
2289 GetClientSession()->flow_controller()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002290
2291 // Server should be in a similar state: connection flow control window should
2292 // not have any bytes marked as received.
2293 server_thread_->Pause();
2294 QuicSession* session = GetServerSession();
2295 QuicFlowController* server_connection_flow_controller =
2296 session->flow_controller();
2297 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize(
2298 server_connection_flow_controller));
2299 server_thread_->Resume();
2300}
2301
bnc40a0b962020-04-23 17:38:25 -07002302TEST_P(EndToEndTestWithoutTls, FlowControlsSynced) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002303 set_smaller_flow_control_receive_window();
2304
2305 ASSERT_TRUE(Initialize());
2306
2307 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2308 server_thread_->WaitForCryptoHandshakeConfirmed();
2309
fkastenholz7591c282019-08-13 12:58:38 -07002310 QuicSpdySession* const client_session = GetClientSession();
bncedeeb472019-08-27 12:19:22 -07002311 const QuicTransportVersion version =
2312 client_session->connection()->transport_version();
renjietang3a1bb802019-06-11 10:42:41 -07002313
renjietanga29a96a2019-10-10 12:47:50 -07002314 if (VersionUsesHttp3(version)) {
bncedeeb472019-08-27 12:19:22 -07002315 // Make sure that the client has received the initial SETTINGS frame, which
2316 // is sent in the first packet on the control stream.
2317 while (!QuicSpdySessionPeer::GetReceiveControlStream(client_session)) {
2318 client_->client()->WaitForEvents();
2319 }
renjietang3a1bb802019-06-11 10:42:41 -07002320 }
2321
bncedeeb472019-08-27 12:19:22 -07002322 // Make sure that all data sent by the client has been received by the server
2323 // (and the ack received by the client).
2324 while (client_session->HasUnackedStreamData()) {
2325 client_->client()->WaitForEvents();
2326 }
2327
2328 server_thread_->Pause();
2329
2330 QuicSpdySession* const server_session = GetServerSession();
2331 ExpectFlowControlsSynced(client_session, server_session);
2332
2333 // Check control streams.
renjietanga29a96a2019-10-10 12:47:50 -07002334 if (VersionUsesHttp3(version)) {
nharperd5c4a932019-05-13 13:58:49 -07002335 ExpectFlowControlsSynced(
bncedeeb472019-08-27 12:19:22 -07002336 QuicSpdySessionPeer::GetReceiveControlStream(client_session),
2337 QuicSpdySessionPeer::GetSendControlStream(server_session));
2338 ExpectFlowControlsSynced(
2339 QuicSpdySessionPeer::GetSendControlStream(client_session),
2340 QuicSpdySessionPeer::GetReceiveControlStream(server_session));
nharperd5c4a932019-05-13 13:58:49 -07002341 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002342
bncedeeb472019-08-27 12:19:22 -07002343 // Check crypto stream.
2344 if (!QuicVersionUsesCryptoFrames(version)) {
2345 ExpectFlowControlsSynced(
2346 QuicSessionPeer::GetMutableCryptoStream(client_session),
2347 QuicSessionPeer::GetMutableCryptoStream(server_session));
2348 }
2349
2350 // Check headers stream.
renjietanga29a96a2019-10-10 12:47:50 -07002351 if (!VersionUsesHttp3(version)) {
bncedeeb472019-08-27 12:19:22 -07002352 SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
2353 SpdySettingsIR settings_frame;
2354 settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE,
2355 kDefaultMaxUncompressedHeaderSize);
2356 SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame));
2357
2358 QuicFlowController* client_header_stream_flow_controller =
2359 QuicSpdySessionPeer::GetHeadersStream(client_session)
2360 ->flow_controller();
2361 QuicFlowController* server_header_stream_flow_controller =
2362 QuicSpdySessionPeer::GetHeadersStream(server_session)
2363 ->flow_controller();
2364 // Both client and server are sending this SETTINGS frame, and the send
2365 // window is consumed. But because of timing issue, the server may send or
2366 // not send the frame, and the client may send/ not send / receive / not
2367 // receive the frame.
2368 // TODO(fayang): Rewrite this part because it is hacky.
2369 QuicByteCount win_difference1 = QuicFlowControllerPeer::ReceiveWindowSize(
2370 server_header_stream_flow_controller) -
2371 QuicFlowControllerPeer::SendWindowSize(
2372 client_header_stream_flow_controller);
2373 if (win_difference1 != 0) {
2374 EXPECT_EQ(frame.size(), win_difference1);
2375 }
2376
2377 QuicByteCount win_difference2 = QuicFlowControllerPeer::ReceiveWindowSize(
2378 client_header_stream_flow_controller) -
2379 QuicFlowControllerPeer::SendWindowSize(
2380 server_header_stream_flow_controller);
2381 if (win_difference2 != 0) {
2382 EXPECT_EQ(frame.size(), win_difference2);
2383 }
2384
2385 // Client *may* have received the SETTINGs frame.
2386 // TODO(fayang): Rewrite this part because it is hacky.
2387 float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
2388 client_session->flow_controller())) /
2389 QuicFlowControllerPeer::ReceiveWindowSize(
2390 QuicSpdySessionPeer::GetHeadersStream(client_session)
2391 ->flow_controller());
2392 float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
2393 client_session->flow_controller())) /
2394 (QuicFlowControllerPeer::ReceiveWindowSize(
2395 QuicSpdySessionPeer::GetHeadersStream(client_session)
2396 ->flow_controller()) +
2397 frame.size());
2398 EXPECT_TRUE(ratio1 == kSessionToStreamRatio ||
2399 ratio2 == kSessionToStreamRatio);
2400 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002401
2402 server_thread_->Resume();
2403}
2404
bnc40a0b962020-04-23 17:38:25 -07002405TEST_P(EndToEndTest, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002406 // A stream created on receipt of a simple request with no body will never get
2407 // a stream frame with a FIN. Verify that we don't keep track of the stream in
2408 // the locally closed streams map: it will never be removed if so.
2409 ASSERT_TRUE(Initialize());
2410
2411 // Send a simple headers only request, and receive response.
2412 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2413 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2414
2415 // Now verify that the server is not waiting for a final FIN or RST.
2416 server_thread_->Pause();
2417 QuicSession* session = GetServerSession();
2418 EXPECT_EQ(
2419 0u,
2420 QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(session).size());
2421 server_thread_->Resume();
2422}
2423
2424// A TestAckListener verifies that its OnAckNotification method has been
2425// called exactly once on destruction.
2426class TestAckListener : public QuicAckListenerInterface {
2427 public:
2428 explicit TestAckListener(int bytes_to_ack) : bytes_to_ack_(bytes_to_ack) {}
2429
2430 void OnPacketAcked(int acked_bytes,
2431 QuicTime::Delta /*delta_largest_observed*/) override {
2432 ASSERT_LE(acked_bytes, bytes_to_ack_);
2433 bytes_to_ack_ -= acked_bytes;
2434 }
2435
2436 void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
2437
2438 bool has_been_notified() const { return bytes_to_ack_ == 0; }
2439
2440 protected:
2441 // Object is ref counted.
2442 ~TestAckListener() override { EXPECT_EQ(0, bytes_to_ack_); }
2443
2444 private:
2445 int bytes_to_ack_;
2446};
2447
2448class TestResponseListener : public QuicSpdyClientBase::ResponseListener {
2449 public:
2450 void OnCompleteResponse(QuicStreamId id,
2451 const SpdyHeaderBlock& response_headers,
vasilvvc48c8712019-03-11 13:38:16 -07002452 const std::string& response_body) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002453 QUIC_DVLOG(1) << "response for stream " << id << " "
2454 << response_headers.DebugString() << "\n"
2455 << response_body;
2456 }
2457};
2458
bnc40a0b962020-04-23 17:38:25 -07002459TEST_P(EndToEndTestWithoutTls, AckNotifierWithPacketLossAndBlockedSocket) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002460 // Verify that even in the presence of packet loss and occasionally blocked
2461 // socket, an AckNotifierDelegate will get informed that the data it is
2462 // interested in has been ACKed. This tests end-to-end ACK notification, and
2463 // demonstrates that retransmissions do not break this functionality.
wubbd64c102019-05-13 11:58:17 -07002464
2465 SetPacketLossPercentage(5);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002466 ASSERT_TRUE(Initialize());
2467
2468 // Wait for the server SHLO before upping the packet loss.
2469 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2470 SetPacketLossPercentage(30);
2471 client_writer_->set_fake_blocked_socket_percentage(10);
2472
2473 // Create a POST request and send the headers only.
2474 SpdyHeaderBlock headers;
2475 headers[":method"] = "POST";
2476 headers[":path"] = "/foo";
2477 headers[":scheme"] = "https";
2478 headers[":authority"] = server_hostname_;
2479
2480 client_->SendMessage(headers, "", /*fin=*/false);
2481
renjietang2abedac2019-05-20 14:04:50 -07002482 // Size of headers on the request stream. Zero if headers are sent on the
2483 // header stream.
2484 size_t header_size = 0;
renjietanga29a96a2019-10-10 12:47:50 -07002485 if (VersionUsesHttp3(client_->client()
renjietang2abedac2019-05-20 14:04:50 -07002486 ->client_session()
2487 ->connection()
2488 ->transport_version())) {
2489 // Determine size of compressed headers.
2490 NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
renjietangc2aa5cb2019-06-20 12:22:53 -07002491 NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
renjietang8a2df8f2019-08-07 10:43:52 -07002492 QpackEncoder qpack_encoder(&decoder_stream_error_delegate);
2493 qpack_encoder.set_qpack_stream_sender_delegate(
2494 &encoder_stream_sender_delegate);
bncf21c1ad2019-06-20 20:09:50 -07002495 std::string encoded_headers =
bnc609c24e2019-09-10 05:24:32 -07002496 qpack_encoder.EncodeHeaderList(/* stream_id = */ 0, headers, nullptr);
renjietang2abedac2019-05-20 14:04:50 -07002497 header_size = encoded_headers.size();
2498 }
2499
QUICHE teama6ef0a62019-03-07 20:34:33 -05002500 // Test the AckNotifier's ability to track multiple packets by making the
2501 // request body exceed the size of a single packet.
vasilvvc48c8712019-03-11 13:38:16 -07002502 std::string request_string = "a request body bigger than one packet" +
dschinazi66dea072019-04-09 11:41:06 -07002503 std::string(kMaxOutgoingPacketSize, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002504
2505 // The TestAckListener will cause a failure if not notified.
2506 QuicReferenceCountedPointer<TestAckListener> ack_listener(
renjietang2abedac2019-05-20 14:04:50 -07002507 new TestAckListener(header_size + request_string.length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002508
2509 // Send the request, and register the delegate for ACKs.
2510 client_->SendData(request_string, true, ack_listener);
2511 client_->WaitForResponse();
2512 EXPECT_EQ(kFooResponseBody, client_->response_body());
2513 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2514
2515 // Send another request to flush out any pending ACKs on the server.
2516 client_->SendSynchronousRequest("/bar");
2517
2518 // Make sure the delegate does get the notification it expects.
2519 while (!ack_listener->has_been_notified()) {
2520 // Waits for up to 50 ms.
2521 client_->client()->WaitForEvents();
2522 }
2523}
2524
2525// Send a public reset from the server.
bnc40a0b962020-04-23 17:38:25 -07002526TEST_P(EndToEndTest, ServerSendPublicReset) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002527 ASSERT_TRUE(Initialize());
2528
2529 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
fkastenholz7591c282019-08-13 12:58:38 -07002530 QuicConnection* client_connection = GetClientConnection();
dschinazi82884662019-08-02 13:25:15 -07002531 QuicConfig* config = client_->client()->session()->config();
2532 EXPECT_TRUE(config->HasReceivedStatelessResetToken());
2533 QuicUint128 stateless_reset_token = config->ReceivedStatelessResetToken();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002534
2535 // Send the public reset.
2536 QuicConnectionId connection_id = client_connection->connection_id();
2537 QuicPublicResetPacket header;
2538 header.connection_id = connection_id;
2539 QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
2540 Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
2541 std::unique_ptr<QuicEncryptedPacket> packet;
fayangd4291e42019-05-30 10:31:21 -07002542 if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002543 packet = framer.BuildIetfStatelessResetPacket(connection_id,
2544 stateless_reset_token);
2545 } else {
2546 packet = framer.BuildPublicResetPacket(header);
2547 }
2548 // We must pause the server's thread in order to call WritePacket without
2549 // race conditions.
2550 server_thread_->Pause();
2551 server_writer_->WritePacket(
2552 packet->data(), packet->length(), server_address_.host(),
2553 client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
2554 server_thread_->Resume();
2555
2556 // The request should fail.
2557 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
2558 EXPECT_TRUE(client_->response_headers()->empty());
bncc5769502019-11-27 10:01:44 -08002559 EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002560}
2561
2562// Send a public reset from the server for a different connection ID.
2563// It should be ignored.
bnc40a0b962020-04-23 17:38:25 -07002564TEST_P(EndToEndTest, ServerSendPublicResetWithDifferentConnectionId) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002565 ASSERT_TRUE(Initialize());
2566
2567 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
fkastenholz7591c282019-08-13 12:58:38 -07002568 QuicConnection* client_connection = GetClientConnection();
dschinazi82884662019-08-02 13:25:15 -07002569 QuicConfig* config = client_->client()->session()->config();
2570 EXPECT_TRUE(config->HasReceivedStatelessResetToken());
2571 QuicUint128 stateless_reset_token = config->ReceivedStatelessResetToken();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002572 // Send the public reset.
2573 QuicConnectionId incorrect_connection_id = TestConnectionId(
2574 TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
2575 QuicPublicResetPacket header;
2576 header.connection_id = incorrect_connection_id;
2577 QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
2578 Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
2579 std::unique_ptr<QuicEncryptedPacket> packet;
2580 testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
fkastenholz7591c282019-08-13 12:58:38 -07002581 GetClientConnection()->set_debug_visitor(&visitor);
fayangd4291e42019-05-30 10:31:21 -07002582 if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002583 packet = framer.BuildIetfStatelessResetPacket(incorrect_connection_id,
2584 stateless_reset_token);
2585 EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
2586 .Times(0);
2587 } else {
2588 packet = framer.BuildPublicResetPacket(header);
2589 EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
2590 .Times(1);
2591 }
2592 // We must pause the server's thread in order to call WritePacket without
2593 // race conditions.
2594 server_thread_->Pause();
2595 server_writer_->WritePacket(
2596 packet->data(), packet->length(), server_address_.host(),
2597 client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
2598 server_thread_->Resume();
2599
fayangd4291e42019-05-30 10:31:21 -07002600 if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002601 // The request should fail. IETF stateless reset does not include connection
2602 // ID.
2603 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
2604 EXPECT_TRUE(client_->response_headers()->empty());
bncc5769502019-11-27 10:01:44 -08002605 EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002606 return;
2607 }
2608 // The connection should be unaffected.
2609 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2610 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2611
fkastenholz7591c282019-08-13 12:58:38 -07002612 GetClientConnection()->set_debug_visitor(nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002613}
2614
2615// Send a public reset from the client for a different connection ID.
2616// It should be ignored.
bnc40a0b962020-04-23 17:38:25 -07002617TEST_P(EndToEndTest, ClientSendPublicResetWithDifferentConnectionId) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002618 ASSERT_TRUE(Initialize());
2619
2620 // Send the public reset.
2621 QuicConnectionId incorrect_connection_id = TestConnectionId(
fkastenholz7591c282019-08-13 12:58:38 -07002622 TestConnectionIdToUInt64(GetClientConnection()->connection_id()) + 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002623 QuicPublicResetPacket header;
2624 header.connection_id = incorrect_connection_id;
2625 QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
2626 Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
2627 std::unique_ptr<QuicEncryptedPacket> packet(
2628 framer.BuildPublicResetPacket(header));
2629 client_writer_->WritePacket(
2630 packet->data(), packet->length(),
2631 client_->client()->network_helper()->GetLatestClientAddress().host(),
2632 server_address_, nullptr);
2633
2634 // The connection should be unaffected.
2635 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2636 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2637}
2638
2639// Send a version negotiation packet from the server for a different
2640// connection ID. It should be ignored.
bnc40a0b962020-04-23 17:38:25 -07002641TEST_P(EndToEndTest, ServerSendVersionNegotiationWithDifferentConnectionId) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002642 ASSERT_TRUE(Initialize());
2643
2644 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2645
2646 // Send the version negotiation packet.
fkastenholz7591c282019-08-13 12:58:38 -07002647 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002648 QuicConnectionId incorrect_connection_id = TestConnectionId(
2649 TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
2650 std::unique_ptr<QuicEncryptedPacket> packet(
2651 QuicFramer::BuildVersionNegotiationPacket(
dschinazib417d602019-05-29 13:08:45 -07002652 incorrect_connection_id, EmptyQuicConnectionId(),
fayangd4291e42019-05-30 10:31:21 -07002653 VersionHasIetfInvariantHeader(client_connection->transport_version()),
dschinazi48ac9192019-07-31 00:07:26 -07002654 client_connection->version().HasLengthPrefixedConnectionIds(),
QUICHE teama6ef0a62019-03-07 20:34:33 -05002655 server_supported_versions_));
2656 testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
2657 client_connection->set_debug_visitor(&visitor);
2658 EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
2659 .Times(1);
2660 // We must pause the server's thread in order to call WritePacket without
2661 // race conditions.
2662 server_thread_->Pause();
2663 server_writer_->WritePacket(
2664 packet->data(), packet->length(), server_address_.host(),
2665 client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
2666 server_thread_->Resume();
2667
2668 // The connection should be unaffected.
2669 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2670 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2671
2672 client_connection->set_debug_visitor(nullptr);
2673}
2674
2675// A bad header shouldn't tear down the connection, because the receiver can't
2676// tell the connection ID.
bnc40a0b962020-04-23 17:38:25 -07002677TEST_P(EndToEndTest, BadPacketHeaderTruncated) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002678 ASSERT_TRUE(Initialize());
2679
2680 // Start the connection.
2681 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2682 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2683
2684 // Packet with invalid public flags.
2685 char packet[] = {// public flags (8 byte connection_id)
2686 0x3C,
2687 // truncated connection ID
2688 0x11};
2689 client_writer_->WritePacket(
2690 &packet[0], sizeof(packet),
2691 client_->client()->network_helper()->GetLatestClientAddress().host(),
2692 server_address_, nullptr);
wub051660f2020-02-06 11:51:50 -08002693 EXPECT_TRUE(server_thread_->WaitUntil(
2694 [&] {
2695 return QuicDispatcherPeer::GetAndClearLastError(
2696 QuicServerPeer::GetDispatcher(server_thread_->server())) ==
2697 QUIC_INVALID_PACKET_HEADER;
2698 },
2699 QuicTime::Delta::FromSeconds(5)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002700
2701 // The connection should not be terminated.
2702 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2703 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2704}
2705
2706// A bad header shouldn't tear down the connection, because the receiver can't
2707// tell the connection ID.
bnc40a0b962020-04-23 17:38:25 -07002708TEST_P(EndToEndTest, BadPacketHeaderFlags) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002709 ASSERT_TRUE(Initialize());
2710
2711 // Start the connection.
2712 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2713 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2714
2715 // Packet with invalid public flags.
2716 char packet[] = {
2717 // invalid public flags
2718 0xFF,
2719 // connection_id
2720 0x10,
2721 0x32,
2722 0x54,
2723 0x76,
2724 0x98,
2725 0xBA,
2726 0xDC,
2727 0xFE,
2728 // packet sequence number
2729 0xBC,
2730 0x9A,
2731 0x78,
2732 0x56,
2733 0x34,
2734 0x12,
2735 // private flags
2736 0x00,
2737 };
2738 client_writer_->WritePacket(
2739 &packet[0], sizeof(packet),
2740 client_->client()->network_helper()->GetLatestClientAddress().host(),
2741 server_address_, nullptr);
wub051660f2020-02-06 11:51:50 -08002742
2743 EXPECT_TRUE(server_thread_->WaitUntil(
2744 [&] {
2745 return QuicDispatcherPeer::GetAndClearLastError(
2746 QuicServerPeer::GetDispatcher(server_thread_->server())) ==
2747 QUIC_INVALID_PACKET_HEADER;
2748 },
2749 QuicTime::Delta::FromSeconds(5)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002750
2751 // The connection should not be terminated.
2752 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2753 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2754}
2755
2756// Send a packet from the client with bad encrypted data. The server should not
2757// tear down the connection.
bnc40a0b962020-04-23 17:38:25 -07002758TEST_P(EndToEndTest, BadEncryptedData) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002759 ASSERT_TRUE(Initialize());
2760
2761 // Start the connection.
2762 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2763 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2764
2765 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
fkastenholz7591c282019-08-13 12:58:38 -07002766 GetClientConnection()->connection_id(), EmptyQuicConnectionId(), false,
2767 false, 1, "At least 20 characters.", CONNECTION_ID_PRESENT,
2768 CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002769 // Damage the encrypted data.
vasilvvc48c8712019-03-11 13:38:16 -07002770 std::string damaged_packet(packet->data(), packet->length());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002771 damaged_packet[30] ^= 0x01;
2772 QUIC_DLOG(INFO) << "Sending bad packet.";
2773 client_writer_->WritePacket(
2774 damaged_packet.data(), damaged_packet.length(),
2775 client_->client()->network_helper()->GetLatestClientAddress().host(),
2776 server_address_, nullptr);
2777 // Give the server time to process the packet.
wub374bd172020-02-04 11:39:11 -08002778 QuicSleep(QuicTime::Delta::FromSeconds(1));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002779 // This error is sent to the connection's OnError (which ignores it), so the
2780 // dispatcher doesn't see it.
2781 // Pause the server so we can access the server's internals without races.
2782 server_thread_->Pause();
2783 QuicDispatcher* dispatcher =
2784 QuicServerPeer::GetDispatcher(server_thread_->server());
bncc5769502019-11-27 10:01:44 -08002785 EXPECT_THAT(QuicDispatcherPeer::GetAndClearLastError(dispatcher),
2786 IsQuicNoError());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002787 server_thread_->Resume();
2788
2789 // The connection should not be terminated.
2790 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2791 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2792}
2793
bnc40a0b962020-04-23 17:38:25 -07002794TEST_P(EndToEndTest, CanceledStreamDoesNotBecomeZombie) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002795 ASSERT_TRUE(Initialize());
2796 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2797 // Lose the request.
2798 SetPacketLossPercentage(100);
2799 SpdyHeaderBlock headers;
2800 headers[":method"] = "POST";
2801 headers[":path"] = "/foo";
2802 headers[":scheme"] = "https";
2803 headers[":authority"] = server_hostname_;
2804 client_->SendMessage(headers, "test_body", /*fin=*/false);
2805 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
2806
2807 // Cancel the stream.
2808 stream->Reset(QUIC_STREAM_CANCELLED);
fkastenholz7591c282019-08-13 12:58:38 -07002809 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002810 // Verify canceled stream does not become zombie.
2811 EXPECT_TRUE(QuicSessionPeer::zombie_streams(session).empty());
2812 EXPECT_EQ(1u, QuicSessionPeer::closed_streams(session).size());
2813}
2814
2815// A test stream that gives |response_body_| as an error response body.
2816class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
2817 public:
2818 ServerStreamWithErrorResponseBody(
2819 QuicStreamId id,
2820 QuicSpdySession* session,
2821 QuicSimpleServerBackend* quic_simple_server_backend,
vasilvvc48c8712019-03-11 13:38:16 -07002822 std::string response_body)
QUICHE teama6ef0a62019-03-07 20:34:33 -05002823 : QuicSimpleServerStream(id,
2824 session,
2825 BIDIRECTIONAL,
2826 quic_simple_server_backend),
2827 response_body_(std::move(response_body)) {}
2828
2829 ~ServerStreamWithErrorResponseBody() override = default;
2830
2831 protected:
2832 void SendErrorResponse() override {
2833 QUIC_DLOG(INFO) << "Sending error response for stream " << id();
2834 SpdyHeaderBlock headers;
2835 headers[":status"] = "500";
2836 headers["content-length"] =
dmcardleba2fb7e2019-12-13 07:44:34 -08002837 quiche::QuicheTextUtils::Uint64ToString(response_body_.size());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002838 // This method must call CloseReadSide to cause the test case, StopReading
2839 // is not sufficient.
2840 QuicStreamPeer::CloseReadSide(this);
2841 SendHeadersAndBody(std::move(headers), response_body_);
2842 }
2843
vasilvvc48c8712019-03-11 13:38:16 -07002844 std::string response_body_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002845};
2846
2847class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
2848 public:
vasilvvc48c8712019-03-11 13:38:16 -07002849 explicit StreamWithErrorFactory(std::string response_body)
QUICHE teama6ef0a62019-03-07 20:34:33 -05002850 : response_body_(std::move(response_body)) {}
2851
2852 ~StreamWithErrorFactory() override = default;
2853
2854 QuicSimpleServerStream* CreateStream(
2855 QuicStreamId id,
2856 QuicSpdySession* session,
2857 QuicSimpleServerBackend* quic_simple_server_backend) override {
2858 return new ServerStreamWithErrorResponseBody(
2859 id, session, quic_simple_server_backend, response_body_);
2860 }
2861
2862 private:
vasilvvc48c8712019-03-11 13:38:16 -07002863 std::string response_body_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002864};
2865
2866// A test server stream that drops all received body.
2867class ServerStreamThatDropsBody : public QuicSimpleServerStream {
2868 public:
2869 ServerStreamThatDropsBody(QuicStreamId id,
2870 QuicSpdySession* session,
2871 QuicSimpleServerBackend* quic_simple_server_backend)
2872 : QuicSimpleServerStream(id,
2873 session,
2874 BIDIRECTIONAL,
2875 quic_simple_server_backend) {}
2876
2877 ~ServerStreamThatDropsBody() override = default;
2878
2879 protected:
2880 void OnBodyAvailable() override {
2881 while (HasBytesToRead()) {
2882 struct iovec iov;
2883 if (GetReadableRegions(&iov, 1) == 0) {
2884 // No more data to read.
2885 break;
2886 }
2887 QUIC_DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream "
2888 << id();
2889 MarkConsumed(iov.iov_len);
2890 }
2891
2892 if (!sequencer()->IsClosed()) {
2893 sequencer()->SetUnblocked();
2894 return;
2895 }
2896
2897 // If the sequencer is closed, then all the body, including the fin, has
2898 // been consumed.
2899 OnFinRead();
2900
2901 if (write_side_closed() || fin_buffered()) {
2902 return;
2903 }
2904
2905 SendResponse();
2906 }
2907};
2908
2909class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
2910 public:
2911 ServerStreamThatDropsBodyFactory() = default;
2912
2913 ~ServerStreamThatDropsBodyFactory() override = default;
2914
2915 QuicSimpleServerStream* CreateStream(
2916 QuicStreamId id,
2917 QuicSpdySession* session,
2918 QuicSimpleServerBackend* quic_simple_server_backend) override {
2919 return new ServerStreamThatDropsBody(id, session,
2920 quic_simple_server_backend);
2921 }
2922};
2923
2924// A test server stream that sends response with body size greater than 4GB.
2925class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
2926 public:
2927 ServerStreamThatSendsHugeResponse(
2928 QuicStreamId id,
2929 QuicSpdySession* session,
2930 QuicSimpleServerBackend* quic_simple_server_backend,
2931 int64_t body_bytes)
2932 : QuicSimpleServerStream(id,
2933 session,
2934 BIDIRECTIONAL,
2935 quic_simple_server_backend),
2936 body_bytes_(body_bytes) {}
2937
2938 ~ServerStreamThatSendsHugeResponse() override = default;
2939
2940 protected:
2941 void SendResponse() override {
2942 QuicBackendResponse response;
vasilvvc48c8712019-03-11 13:38:16 -07002943 std::string body(body_bytes_, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002944 response.set_body(body);
2945 SendHeadersAndBodyAndTrailers(response.headers().Clone(), response.body(),
2946 response.trailers().Clone());
2947 }
2948
2949 private:
2950 // Use a explicit int64_t rather than size_t to simulate a 64-bit server
2951 // talking to a 32-bit client.
2952 int64_t body_bytes_;
2953};
2954
2955class ServerStreamThatSendsHugeResponseFactory
2956 : public QuicTestServer::StreamFactory {
2957 public:
2958 explicit ServerStreamThatSendsHugeResponseFactory(int64_t body_bytes)
2959 : body_bytes_(body_bytes) {}
2960
2961 ~ServerStreamThatSendsHugeResponseFactory() override = default;
2962
2963 QuicSimpleServerStream* CreateStream(
2964 QuicStreamId id,
2965 QuicSpdySession* session,
2966 QuicSimpleServerBackend* quic_simple_server_backend) override {
2967 return new ServerStreamThatSendsHugeResponse(
2968 id, session, quic_simple_server_backend, body_bytes_);
2969 }
2970
2971 int64_t body_bytes_;
2972};
2973
bnc40a0b962020-04-23 17:38:25 -07002974TEST_P(EndToEndTestWithoutTls, EarlyResponseFinRecording) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002975 set_smaller_flow_control_receive_window();
2976
2977 // Verify that an incoming FIN is recorded in a stream object even if the read
2978 // side has been closed. This prevents an entry from being made in
2979 // locally_close_streams_highest_offset_ (which will never be deleted).
2980 // To set up the test condition, the server must do the following in order:
2981 // start sending the response and call CloseReadSide
2982 // receive the FIN of the request
2983 // send the FIN of the response
2984
2985 // The response body must be larger than the flow control window so the server
2986 // must receive a window update from the client before it can finish sending
2987 // it.
2988 uint32_t response_body_size =
2989 2 * client_config_.GetInitialStreamFlowControlWindowToSend();
vasilvvc48c8712019-03-11 13:38:16 -07002990 std::string response_body(response_body_size, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002991
2992 StreamWithErrorFactory stream_factory(response_body);
2993 SetSpdyStreamFactory(&stream_factory);
2994
2995 ASSERT_TRUE(Initialize());
2996
2997 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2998
2999 // A POST that gets an early error response, after the headers are received
3000 // and before the body is received, due to invalid content-length.
3001 // Set an invalid content-length, so the request will receive an early 500
3002 // response.
3003 SpdyHeaderBlock headers;
3004 headers[":method"] = "POST";
3005 headers[":path"] = "/garbage";
3006 headers[":scheme"] = "https";
3007 headers[":authority"] = server_hostname_;
3008 headers["content-length"] = "-1";
3009
3010 // The body must be large enough that the FIN will be in a different packet
3011 // than the end of the headers, but short enough to not require a flow control
3012 // update. This allows headers processing to trigger the error response
3013 // before the request FIN is processed but receive the request FIN before the
3014 // response is sent completely.
dschinazi66dea072019-04-09 11:41:06 -07003015 const uint32_t kRequestBodySize = kMaxOutgoingPacketSize + 10;
vasilvvc48c8712019-03-11 13:38:16 -07003016 std::string request_body(kRequestBodySize, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003017
3018 // Send the request.
3019 client_->SendMessage(headers, request_body);
3020 client_->WaitForResponse();
3021 EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
3022
3023 // Pause the server so we can access the server's internals without races.
3024 server_thread_->Pause();
3025
3026 QuicDispatcher* dispatcher =
3027 QuicServerPeer::GetDispatcher(server_thread_->server());
3028 QuicDispatcher::SessionMap const& map =
3029 QuicDispatcherPeer::session_map(dispatcher);
3030 auto it = map.begin();
3031 EXPECT_TRUE(it != map.end());
3032 QuicSession* server_session = it->second.get();
3033
3034 // The stream is not waiting for the arrival of the peer's final offset.
3035 EXPECT_EQ(
3036 0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(server_session)
3037 .size());
3038
3039 server_thread_->Resume();
3040}
3041
bnc40a0b962020-04-23 17:38:25 -07003042TEST_P(EndToEndTest, Trailers) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003043 // Test sending and receiving HTTP/2 Trailers (trailing HEADERS frames).
3044 ASSERT_TRUE(Initialize());
3045 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3046
3047 // Set reordering to ensure that Trailers arriving before body is ok.
3048 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3049 SetReorderPercentage(30);
3050
3051 // Add a response with headers, body, and trailers.
vasilvvc48c8712019-03-11 13:38:16 -07003052 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003053
3054 SpdyHeaderBlock headers;
3055 headers[":status"] = "200";
dmcardleba2fb7e2019-12-13 07:44:34 -08003056 headers["content-length"] =
3057 quiche::QuicheTextUtils::Uint64ToString(kBody.size());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003058
3059 SpdyHeaderBlock trailers;
3060 trailers["some-trailing-header"] = "trailing-header-value";
3061
3062 memory_cache_backend_.AddResponse(server_hostname_, "/trailer_url",
3063 std::move(headers), kBody,
3064 trailers.Clone());
3065
3066 EXPECT_EQ(kBody, client_->SendSynchronousRequest("/trailer_url"));
3067 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3068 EXPECT_EQ(trailers, client_->response_trailers());
3069}
3070
bnc1faf10c2020-03-23 10:31:29 -07003071// TODO(b/151749109): Test server push for IETF QUIC.
QUICHE teama6ef0a62019-03-07 20:34:33 -05003072class EndToEndTestServerPush : public EndToEndTest {
3073 protected:
3074 const size_t kNumMaxStreams = 10;
3075
3076 EndToEndTestServerPush() : EndToEndTest() {
renjietange6d94672020-01-07 10:30:10 -08003077 client_config_.SetMaxBidirectionalStreamsToSend(kNumMaxStreams);
3078 server_config_.SetMaxBidirectionalStreamsToSend(kNumMaxStreams);
3079 client_config_.SetMaxUnidirectionalStreamsToSend(kNumMaxStreams);
3080 server_config_.SetMaxUnidirectionalStreamsToSend(kNumMaxStreams);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003081 }
3082
3083 // Add a request with its response and |num_resources| push resources into
3084 // cache.
3085 // If |resource_size| == 0, response body of push resources use default string
3086 // concatenating with resource url. Otherwise, generate a string of
3087 // |resource_size| as body.
vasilvvc48c8712019-03-11 13:38:16 -07003088 void AddRequestAndResponseWithServerPush(std::string host,
3089 std::string path,
3090 std::string response_body,
3091 std::string* push_urls,
QUICHE teama6ef0a62019-03-07 20:34:33 -05003092 const size_t num_resources,
3093 const size_t resource_size) {
3094 bool use_large_response = resource_size != 0;
vasilvvc48c8712019-03-11 13:38:16 -07003095 std::string large_resource;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003096 if (use_large_response) {
3097 // Generate a response common body larger than flow control window for
3098 // push response.
vasilvvc48c8712019-03-11 13:38:16 -07003099 large_resource = std::string(resource_size, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003100 }
3101 std::list<QuicBackendResponse::ServerPushInfo> push_resources;
3102 for (size_t i = 0; i < num_resources; ++i) {
vasilvvc48c8712019-03-11 13:38:16 -07003103 std::string url = push_urls[i];
QUICHE teama6ef0a62019-03-07 20:34:33 -05003104 QuicUrl resource_url(url);
vasilvvc48c8712019-03-11 13:38:16 -07003105 std::string body =
QUICHE teama6ef0a62019-03-07 20:34:33 -05003106 use_large_response
3107 ? large_resource
dmcardleba2fb7e2019-12-13 07:44:34 -08003108 : quiche::QuicheStrCat("This is server push response body for ",
3109 url);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003110 SpdyHeaderBlock response_headers;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003111 response_headers[":status"] = "200";
3112 response_headers["content-length"] =
dmcardleba2fb7e2019-12-13 07:44:34 -08003113 quiche::QuicheTextUtils::Uint64ToString(body.size());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003114 push_resources.push_back(QuicBackendResponse::ServerPushInfo(
3115 resource_url, std::move(response_headers), kV3LowestPriority, body));
3116 }
3117
3118 memory_cache_backend_.AddSimpleResponseWithServerPushResources(
3119 host, path, 200, response_body, push_resources);
3120 }
3121};
3122
3123// Run all server push end to end tests with all supported versions.
3124INSTANTIATE_TEST_SUITE_P(EndToEndTestsServerPush,
3125 EndToEndTestServerPush,
dschinazi142051a2019-09-18 18:17:29 -07003126 ::testing::ValuesIn(GetTestParams(false)),
3127 ::testing::PrintToStringParamName());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003128
3129TEST_P(EndToEndTestServerPush, ServerPush) {
3130 ASSERT_TRUE(Initialize());
3131 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3132
3133 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3134 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3135 SetReorderPercentage(30);
3136
3137 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003138 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003139 size_t kNumResources = 4;
vasilvvc48c8712019-03-11 13:38:16 -07003140 std::string push_urls[] = {"https://example.com/font.woff",
3141 "https://example.com/script.js",
3142 "https://fonts.example.com/font.woff",
3143 "https://example.com/logo-hires.jpg"};
QUICHE teama6ef0a62019-03-07 20:34:33 -05003144 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3145 push_urls, kNumResources, 0);
3146
3147 client_->client()->set_response_listener(
3148 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3149 new TestResponseListener));
3150
3151 QUIC_DVLOG(1) << "send request for /push_example";
3152 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
3153 "https://example.com/push_example"));
renjietang3c3dfb72019-07-26 11:55:52 -07003154 QuicStreamSequencer* sequencer;
renjietanga29a96a2019-10-10 12:47:50 -07003155 if (!VersionUsesHttp3(client_->client()
renjietang3c3dfb72019-07-26 11:55:52 -07003156 ->client_session()
3157 ->connection()
3158 ->transport_version())) {
fkastenholz7591c282019-08-13 12:58:38 -07003159 QuicHeadersStream* headers_stream =
3160 QuicSpdySessionPeer::GetHeadersStream(GetClientSession());
renjietang3c3dfb72019-07-26 11:55:52 -07003161 sequencer = QuicStreamPeer::sequencer(headers_stream);
3162 // Headers stream's sequencer buffer shouldn't be released because server
3163 // push hasn't finished yet.
3164 EXPECT_TRUE(
3165 QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
3166 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05003167
vasilvvc48c8712019-03-11 13:38:16 -07003168 for (const std::string& url : push_urls) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003169 QUIC_DVLOG(1) << "send request for pushed stream on url " << url;
vasilvvc48c8712019-03-11 13:38:16 -07003170 std::string expected_body =
dmcardleba2fb7e2019-12-13 07:44:34 -08003171 quiche::QuicheStrCat("This is server push response body for ", url);
vasilvvc48c8712019-03-11 13:38:16 -07003172 std::string response_body = client_->SendSynchronousRequest(url);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003173 QUIC_DVLOG(1) << "response body " << response_body;
3174 EXPECT_EQ(expected_body, response_body);
3175 }
renjietanga29a96a2019-10-10 12:47:50 -07003176 if (!VersionUsesHttp3(client_->client()
renjietang3c3dfb72019-07-26 11:55:52 -07003177 ->client_session()
3178 ->connection()
3179 ->transport_version())) {
3180 EXPECT_FALSE(
3181 QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
3182 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05003183}
3184
3185TEST_P(EndToEndTestServerPush, ServerPushUnderLimit) {
3186 // Tests that sending a request which has 4 push resources will trigger server
3187 // to push those 4 resources and client can handle pushed resources and match
3188 // them with requests later.
3189 ASSERT_TRUE(Initialize());
3190
3191 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3192
3193 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3194 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3195 SetReorderPercentage(30);
3196
3197 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003198 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003199 size_t const kNumResources = 4;
vasilvvc48c8712019-03-11 13:38:16 -07003200 std::string push_urls[] = {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003201 "https://example.com/font.woff",
3202 "https://example.com/script.js",
3203 "https://fonts.example.com/font.woff",
3204 "https://example.com/logo-hires.jpg",
3205 };
3206 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3207 push_urls, kNumResources, 0);
3208 client_->client()->set_response_listener(
3209 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3210 new TestResponseListener));
3211
3212 // Send the first request: this will trigger the server to send all the push
3213 // resources associated with this request, and these will be cached by the
3214 // client.
3215 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
3216 "https://example.com/push_example"));
3217
vasilvvc48c8712019-03-11 13:38:16 -07003218 for (const std::string& url : push_urls) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003219 // Sending subsequent requesets will not actually send anything on the wire,
3220 // as the responses are already in the client's cache.
3221 QUIC_DVLOG(1) << "send request for pushed stream on url " << url;
vasilvvc48c8712019-03-11 13:38:16 -07003222 std::string expected_body =
dmcardleba2fb7e2019-12-13 07:44:34 -08003223 quiche::QuicheStrCat("This is server push response body for ", url);
vasilvvc48c8712019-03-11 13:38:16 -07003224 std::string response_body = client_->SendSynchronousRequest(url);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003225 QUIC_DVLOG(1) << "response body " << response_body;
3226 EXPECT_EQ(expected_body, response_body);
3227 }
3228 // Expect only original request has been sent and push responses have been
3229 // received as normal response.
3230 EXPECT_EQ(1u, client_->num_requests());
3231 EXPECT_EQ(1u + kNumResources, client_->num_responses());
3232}
3233
3234TEST_P(EndToEndTestServerPush, ServerPushOverLimitNonBlocking) {
3235 // Tests that when streams are not blocked by flow control or congestion
3236 // control, pushing even more resources than max number of open outgoing
3237 // streams should still work because all response streams get closed
3238 // immediately after pushing resources.
3239 ASSERT_TRUE(Initialize());
3240 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3241
rch5e9191e2019-10-10 17:02:19 -07003242 if (VersionUsesHttp3(client_->client()
3243 ->client_session()
3244 ->connection()
3245 ->transport_version())) {
3246 // TODO(b/142504641): Re-enable this test when we support push streams
3247 // arriving before the corresponding promises.
3248 return;
3249 }
3250
QUICHE teama6ef0a62019-03-07 20:34:33 -05003251 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3252 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3253 SetReorderPercentage(30);
3254
3255 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003256 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003257
3258 // One more resource than max number of outgoing stream of this session.
3259 const size_t kNumResources = 1 + kNumMaxStreams; // 11.
vasilvvc48c8712019-03-11 13:38:16 -07003260 std::string push_urls[11];
QUICHE teama6ef0a62019-03-07 20:34:33 -05003261 for (size_t i = 0; i < kNumResources; ++i) {
dmcardleba2fb7e2019-12-13 07:44:34 -08003262 push_urls[i] =
3263 quiche::QuicheStrCat("https://example.com/push_resources", i);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003264 }
3265 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3266 push_urls, kNumResources, 0);
3267 client_->client()->set_response_listener(
3268 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3269 new TestResponseListener));
3270
3271 // Send the first request: this will trigger the server to send all the push
3272 // resources associated with this request, and these will be cached by the
3273 // client.
3274 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
3275 "https://example.com/push_example"));
3276
vasilvvc48c8712019-03-11 13:38:16 -07003277 for (const std::string& url : push_urls) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003278 // Sending subsequent requesets will not actually send anything on the wire,
3279 // as the responses are already in the client's cache.
dmcardleba2fb7e2019-12-13 07:44:34 -08003280 EXPECT_EQ(
3281 quiche::QuicheStrCat("This is server push response body for ", url),
3282 client_->SendSynchronousRequest(url));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003283 }
3284
3285 // Only 1 request should have been sent.
3286 EXPECT_EQ(1u, client_->num_requests());
3287 // The responses to the original request and all the promised resources
3288 // should have been received.
3289 EXPECT_EQ(12u, client_->num_responses());
3290}
3291
3292TEST_P(EndToEndTestServerPush, ServerPushOverLimitWithBlocking) {
3293 // Tests that when server tries to send more large resources(large enough to
3294 // be blocked by flow control window or congestion control window) than max
3295 // open outgoing streams , server can open upto max number of outgoing
3296 // streams for them, and the rest will be queued up.
3297
3298 // Reset flow control windows.
3299 size_t kFlowControlWnd = 20 * 1024; // 20KB.
3300 // Response body is larger than 1 flow controlblock window.
3301 size_t kBodySize = kFlowControlWnd * 2;
3302 set_client_initial_stream_flow_control_receive_window(kFlowControlWnd);
3303 // Make sure conntection level flow control window is large enough not to
3304 // block data being sent out though they will be blocked by stream level one.
3305 set_client_initial_session_flow_control_receive_window(
3306 kBodySize * kNumMaxStreams + 1024);
3307
3308 ASSERT_TRUE(Initialize());
3309 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3310
3311 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3312 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3313 SetReorderPercentage(30);
3314
3315 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003316 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003317
3318 const size_t kNumResources = kNumMaxStreams + 1;
vasilvvc48c8712019-03-11 13:38:16 -07003319 std::string push_urls[11];
QUICHE teama6ef0a62019-03-07 20:34:33 -05003320 for (size_t i = 0; i < kNumResources; ++i) {
dmcardleba2fb7e2019-12-13 07:44:34 -08003321 push_urls[i] = quiche::QuicheStrCat("http://example.com/push_resources", i);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003322 }
3323 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3324 push_urls, kNumResources, kBodySize);
3325
3326 client_->client()->set_response_listener(
3327 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3328 new TestResponseListener));
3329
3330 client_->SendRequest("https://example.com/push_example");
3331
3332 // Pause after the first response arrives.
3333 while (!client_->response_complete()) {
3334 // Because of priority, the first response arrived should be to original
3335 // request.
3336 client_->WaitForResponse();
3337 }
3338
3339 // Check server session to see if it has max number of outgoing streams opened
3340 // though more resources need to be pushed.
3341 server_thread_->Pause();
3342 EXPECT_EQ(kNumMaxStreams, GetServerSession()->GetNumOpenOutgoingStreams());
3343 server_thread_->Resume();
3344
3345 EXPECT_EQ(1u, client_->num_requests());
3346 EXPECT_EQ(1u, client_->num_responses());
3347 EXPECT_EQ(kBody, client_->response_body());
3348
3349 // "Send" request for a promised resources will not really send out it because
3350 // its response is being pushed(but blocked). And the following ack and
3351 // flow control behavior of SendSynchronousRequests()
3352 // will unblock the stream to finish receiving response.
3353 client_->SendSynchronousRequest(push_urls[0]);
3354 EXPECT_EQ(1u, client_->num_requests());
3355 EXPECT_EQ(2u, client_->num_responses());
3356
3357 // Do same thing for the rest 10 resources.
3358 for (size_t i = 1; i < kNumResources; ++i) {
3359 client_->SendSynchronousRequest(push_urls[i]);
3360 }
3361
3362 // Because of server push, client gets all pushed resources without actually
3363 // sending requests for them.
3364 EXPECT_EQ(1u, client_->num_requests());
3365 // Including response to original request, 12 responses in total were
3366 // received.
3367 EXPECT_EQ(12u, client_->num_responses());
3368}
3369
3370// TODO(fayang): this test seems to cause net_unittests timeouts :|
bnc40a0b962020-04-23 17:38:25 -07003371TEST_P(EndToEndTestWithoutTls, DISABLED_TestHugePostWithPacketLoss) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003372 // This test tests a huge post with introduced packet loss from client to
3373 // server and body size greater than 4GB, making sure QUIC code does not break
3374 // for 32-bit builds.
3375 ServerStreamThatDropsBodyFactory stream_factory;
3376 SetSpdyStreamFactory(&stream_factory);
3377 ASSERT_TRUE(Initialize());
3378 // Set client's epoll server's time out to 0 to make this test be finished
3379 // within a short time.
3380 client_->epoll_server()->set_timeout_in_us(0);
3381
3382 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3383 SetPacketLossPercentage(1);
3384 // To avoid storing the whole request body in memory, use a loop to repeatedly
3385 // send body size of kSizeBytes until the whole request body size is reached.
3386 const int kSizeBytes = 128 * 1024;
3387 // Request body size is 4G plus one more kSizeBytes.
3388 int64_t request_body_size_bytes = pow(2, 32) + kSizeBytes;
3389 ASSERT_LT(INT64_C(4294967296), request_body_size_bytes);
vasilvvc48c8712019-03-11 13:38:16 -07003390 std::string body(kSizeBytes, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003391
3392 SpdyHeaderBlock headers;
3393 headers[":method"] = "POST";
3394 headers[":path"] = "/foo";
3395 headers[":scheme"] = "https";
3396 headers[":authority"] = server_hostname_;
3397 headers["content-length"] =
dmcardleba2fb7e2019-12-13 07:44:34 -08003398 quiche::QuicheTextUtils::Uint64ToString(request_body_size_bytes);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003399
3400 client_->SendMessage(headers, "", /*fin=*/false);
3401
3402 for (int i = 0; i < request_body_size_bytes / kSizeBytes; ++i) {
3403 bool fin = (i == request_body_size_bytes - 1);
vasilvvc48c8712019-03-11 13:38:16 -07003404 client_->SendData(std::string(body.data(), kSizeBytes), fin);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003405 client_->client()->WaitForEvents();
3406 }
3407 VerifyCleanConnection(true);
3408}
3409
3410// TODO(fayang): this test seems to cause net_unittests timeouts :|
bnc40a0b962020-04-23 17:38:25 -07003411TEST_P(EndToEndTestWithoutTls, DISABLED_TestHugeResponseWithPacketLoss) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003412 // This test tests a huge response with introduced loss from server to client
3413 // and body size greater than 4GB, making sure QUIC code does not break for
3414 // 32-bit builds.
3415 const int kSizeBytes = 128 * 1024;
3416 int64_t response_body_size_bytes = pow(2, 32) + kSizeBytes;
3417 ASSERT_LT(4294967296, response_body_size_bytes);
3418 ServerStreamThatSendsHugeResponseFactory stream_factory(
3419 response_body_size_bytes);
3420 SetSpdyStreamFactory(&stream_factory);
3421
3422 StartServer();
3423
3424 // Use a quic client that drops received body.
3425 QuicTestClient* client =
3426 new QuicTestClient(server_address_, server_hostname_, client_config_,
3427 client_supported_versions_);
3428 client->client()->set_drop_response_body(true);
3429 client->UseWriter(client_writer_);
3430 client->Connect();
3431 client_.reset(client);
3432 static QuicEpollEvent event(EPOLLOUT);
3433 client_writer_->Initialize(
fkastenholz7591c282019-08-13 12:58:38 -07003434 QuicConnectionPeer::GetHelper(GetClientConnection()),
3435 QuicConnectionPeer::GetAlarmFactory(GetClientConnection()),
vasilvv0fc587f2019-09-06 13:33:08 -07003436 std::make_unique<ClientDelegate>(client_->client()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003437 initialized_ = true;
3438 ASSERT_TRUE(client_->client()->connected());
3439
3440 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3441 SetPacketLossPercentage(1);
3442 client_->SendRequest("/huge_response");
3443 client_->WaitForResponse();
wubbd64c102019-05-13 11:58:17 -07003444 VerifyCleanConnection(true);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003445}
3446
3447// Regression test for b/111515567
bnc40a0b962020-04-23 17:38:25 -07003448TEST_P(EndToEndTestWithoutTls, AgreeOnStopWaiting) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003449 ASSERT_TRUE(Initialize());
3450 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3451
fkastenholz7591c282019-08-13 12:58:38 -07003452 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003453 server_thread_->Pause();
3454 QuicConnection* server_connection = GetServerConnection();
3455 // Verify client and server connections agree on the value of
3456 // no_stop_waiting_frames.
3457 EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
3458 QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
3459 server_thread_->Resume();
3460}
3461
3462// Regression test for b/111515567
bnc40a0b962020-04-23 17:38:25 -07003463TEST_P(EndToEndTestWithoutTls, AgreeOnStopWaitingWithNoStopWaitingOption) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003464 QuicTagVector options;
3465 options.push_back(kNSTP);
3466 client_config_.SetConnectionOptionsToSend(options);
3467 ASSERT_TRUE(Initialize());
3468 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3469
fkastenholz7591c282019-08-13 12:58:38 -07003470 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003471 server_thread_->Pause();
3472 QuicConnection* server_connection = GetServerConnection();
3473 // Verify client and server connections agree on the value of
3474 // no_stop_waiting_frames.
3475 EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
3476 QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
3477 server_thread_->Resume();
3478}
3479
bnc40a0b962020-04-23 17:38:25 -07003480TEST_P(EndToEndTestWithoutTls, ReleaseHeadersStreamBufferWhenIdle) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003481 // Tests that when client side has no active request and no waiting
3482 // PUSH_PROMISE, its headers stream's sequencer buffer should be released.
3483 ASSERT_TRUE(Initialize());
3484 client_->SendSynchronousRequest("/foo");
renjietanga29a96a2019-10-10 12:47:50 -07003485 if (VersionUsesHttp3(client_->client()
renjietang118c8ac2019-07-30 11:43:59 -07003486 ->client_session()
3487 ->connection()
3488 ->transport_version())) {
3489 return;
3490 }
fkastenholz7591c282019-08-13 12:58:38 -07003491 QuicHeadersStream* headers_stream =
3492 QuicSpdySessionPeer::GetHeadersStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003493 QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
3494 EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
3495}
3496
bnc40a0b962020-04-23 17:38:25 -07003497TEST_P(EndToEndTestWithoutTls, WayTooLongRequestHeaders) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003498 ASSERT_TRUE(Initialize());
3499 SpdyHeaderBlock headers;
3500 headers[":method"] = "GET";
3501 headers[":path"] = "/foo";
3502 headers[":scheme"] = "https";
3503 headers[":authority"] = server_hostname_;
vasilvvc48c8712019-03-11 13:38:16 -07003504 headers["key"] = std::string(64 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003505
3506 client_->SendMessage(headers, "");
3507 client_->WaitForResponse();
bnc77b46412020-02-21 08:09:09 -08003508
bnc260f2e42020-04-28 10:29:08 -07003509 EXPECT_THAT(client_->connection_error(),
3510 IsError(QUIC_HPACK_INDEX_VARINT_ERROR));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003511}
3512
3513class WindowUpdateObserver : public QuicConnectionDebugVisitor {
3514 public:
3515 WindowUpdateObserver() : num_window_update_frames_(0), num_ping_frames_(0) {}
3516
3517 size_t num_window_update_frames() const { return num_window_update_frames_; }
3518
3519 size_t num_ping_frames() const { return num_ping_frames_; }
3520
dschinazi17d42422019-06-18 16:35:07 -07003521 void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/,
3522 const QuicTime& /*receive_time*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003523 ++num_window_update_frames_;
3524 }
3525
dschinazi17d42422019-06-18 16:35:07 -07003526 void OnPingFrame(const QuicPingFrame& /*frame*/) override {
3527 ++num_ping_frames_;
3528 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05003529
3530 private:
3531 size_t num_window_update_frames_;
3532 size_t num_ping_frames_;
3533};
3534
bnc40a0b962020-04-23 17:38:25 -07003535TEST_P(EndToEndTestWithoutTls, WindowUpdateInAck) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003536 ASSERT_TRUE(Initialize());
3537 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3538 WindowUpdateObserver observer;
fkastenholz7591c282019-08-13 12:58:38 -07003539 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003540 client_connection->set_debug_visitor(&observer);
3541 // 100KB body.
vasilvvc48c8712019-03-11 13:38:16 -07003542 std::string body(100 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003543 SpdyHeaderBlock headers;
3544 headers[":method"] = "POST";
3545 headers[":path"] = "/foo";
3546 headers[":scheme"] = "https";
3547 headers[":authority"] = server_hostname_;
3548
3549 EXPECT_EQ(kFooResponseBody,
3550 client_->SendCustomSynchronousRequest(headers, body));
3551 client_->Disconnect();
3552 EXPECT_LT(0u, observer.num_window_update_frames());
3553 EXPECT_EQ(0u, observer.num_ping_frames());
3554}
3555
bnc40a0b962020-04-23 17:38:25 -07003556TEST_P(EndToEndTest, SendStatelessResetTokenInShlo) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003557 ASSERT_TRUE(Initialize());
3558 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3559 QuicConfig* config = client_->client()->session()->config();
3560 EXPECT_TRUE(config->HasReceivedStatelessResetToken());
3561 EXPECT_EQ(QuicUtils::GenerateStatelessResetToken(
3562 client_->client()->session()->connection()->connection_id()),
3563 config->ReceivedStatelessResetToken());
3564 client_->Disconnect();
3565}
3566
3567// Regression test for b/116200989.
bnc40a0b962020-04-23 17:38:25 -07003568TEST_P(EndToEndTestWithoutTls,
QUICHE teama6ef0a62019-03-07 20:34:33 -05003569 SendStatelessResetIfServerConnectionClosedLocallyDuringHandshake) {
3570 connect_to_server_on_initialize_ = false;
3571 ASSERT_TRUE(Initialize());
3572
3573 server_thread_->Pause();
3574 QuicDispatcher* dispatcher =
3575 QuicServerPeer::GetDispatcher(server_thread_->server());
3576 ASSERT_EQ(0u, dispatcher->session_map().size());
3577 // Note: this writer will only used by the server connection, not the time
3578 // wait list.
3579 QuicDispatcherPeer::UseWriter(
3580 dispatcher,
3581 // This cause the first server-sent packet, a.k.a REJ, to fail.
3582 new BadPacketWriter(/*packet_causing_write_error=*/0, EPERM));
3583 server_thread_->Resume();
3584
3585 client_.reset(CreateQuicClient(client_writer_));
3586 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
bncc5769502019-11-27 10:01:44 -08003587 EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_FAILED));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003588}
3589
3590// Regression test for b/116200989.
bnc40a0b962020-04-23 17:38:25 -07003591TEST_P(EndToEndTestWithoutTls,
QUICHE teama6ef0a62019-03-07 20:34:33 -05003592 SendStatelessResetIfServerConnectionClosedLocallyAfterHandshake) {
3593 // Prevent the connection from expiring in the time wait list.
dschinazi552accc2019-06-17 17:07:34 -07003594 SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003595 connect_to_server_on_initialize_ = false;
3596 ASSERT_TRUE(Initialize());
3597
3598 // big_response_body is 64K, which is about 48 full-sized packets.
3599 const size_t kBigResponseBodySize = 65536;
3600 QuicData big_response_body(new char[kBigResponseBodySize](),
3601 kBigResponseBodySize, /*owns_buffer=*/true);
3602 AddToCache("/big_response", 200, big_response_body.AsStringPiece());
3603
3604 server_thread_->Pause();
3605 QuicDispatcher* dispatcher =
3606 QuicServerPeer::GetDispatcher(server_thread_->server());
3607 ASSERT_EQ(0u, dispatcher->session_map().size());
3608 QuicDispatcherPeer::UseWriter(
3609 dispatcher,
3610 // This will cause an server write error with EPERM, while sending the
3611 // response for /big_response.
3612 new BadPacketWriter(/*packet_causing_write_error=*/20, EPERM));
3613 server_thread_->Resume();
3614
3615 client_.reset(CreateQuicClient(client_writer_));
3616
3617 // First, a /foo request with small response should succeed.
3618 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3619 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3620
3621 // Second, a /big_response request with big response should fail.
3622 EXPECT_LT(client_->SendSynchronousRequest("/big_response").length(),
3623 kBigResponseBodySize);
bncc5769502019-11-27 10:01:44 -08003624 EXPECT_THAT(client_->connection_error(), IsError(QUIC_PUBLIC_RESET));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003625}
3626
3627// Regression test of b/70782529.
bnc40a0b962020-04-23 17:38:25 -07003628TEST_P(EndToEndTestWithoutTls, DoNotCrashOnPacketWriteError) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003629 ASSERT_TRUE(Initialize());
3630 BadPacketWriter* bad_writer =
3631 new BadPacketWriter(/*packet_causing_write_error=*/5,
3632 /*error_code=*/90);
3633 std::unique_ptr<QuicTestClient> client(CreateQuicClient(bad_writer));
3634
3635 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07003636 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003637 SpdyHeaderBlock headers;
3638 headers[":method"] = "POST";
3639 headers[":path"] = "/foo";
3640 headers[":scheme"] = "https";
3641 headers[":authority"] = server_hostname_;
3642
3643 client->SendCustomSynchronousRequest(headers, body);
3644}
3645
3646// Regression test for b/71711996. This test sends a connectivity probing packet
3647// as its last sent packet, and makes sure the server's ACK of that packet does
3648// not cause the client to fail.
bnc40a0b962020-04-23 17:38:25 -07003649TEST_P(EndToEndTestWithoutTls, LastPacketSentIsConnectivityProbing) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003650 ASSERT_TRUE(Initialize());
3651
3652 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3653 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3654
3655 // Wait for the client's ACK (of the response) to be received by the server.
3656 client_->WaitForDelayedAcks();
3657
3658 // We are sending a connectivity probing packet from an unchanged client
3659 // address, so the server will not respond to us with a connectivity probing
3660 // packet, however the server should send an ack-only packet to us.
3661 client_->SendConnectivityProbing();
3662
3663 // Wait for the server's last ACK to be received by the client.
3664 client_->WaitForDelayedAcks();
3665}
3666
bnc40a0b962020-04-23 17:38:25 -07003667TEST_P(EndToEndTest, PreSharedKey) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003668 client_config_.set_max_time_before_crypto_handshake(
wub57cd22a2020-02-07 07:22:24 -08003669 QuicTime::Delta::FromSeconds(5));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003670 client_config_.set_max_idle_time_before_crypto_handshake(
wub57cd22a2020-02-07 07:22:24 -08003671 QuicTime::Delta::FromSeconds(5));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003672 pre_shared_key_client_ = "foobar";
3673 pre_shared_key_server_ = "foobar";
dschinaziaaaf1a42020-04-16 11:44:31 -07003674
3675 if (GetParam().negotiated_version.handshake_protocol == PROTOCOL_TLS1_3) {
3676 // TODO(b/154162689) add PSK support to QUIC+TLS.
3677 bool ok;
3678 EXPECT_QUIC_BUG(ok = Initialize(),
3679 "QUIC client pre-shared keys not yet supported with TLS");
3680 EXPECT_FALSE(ok);
3681 return;
3682 }
3683
QUICHE teama6ef0a62019-03-07 20:34:33 -05003684 ASSERT_TRUE(Initialize());
3685
3686 ASSERT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3687 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3688}
3689
3690// TODO: reenable once we have a way to make this run faster.
bnc40a0b962020-04-23 17:38:25 -07003691TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyMismatch)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003692 client_config_.set_max_time_before_crypto_handshake(
3693 QuicTime::Delta::FromSeconds(1));
3694 client_config_.set_max_idle_time_before_crypto_handshake(
3695 QuicTime::Delta::FromSeconds(1));
3696 pre_shared_key_client_ = "foo";
3697 pre_shared_key_server_ = "bar";
dschinaziaaaf1a42020-04-16 11:44:31 -07003698
3699 if (GetParam().negotiated_version.handshake_protocol == PROTOCOL_TLS1_3) {
3700 // TODO(b/154162689) add PSK support to QUIC+TLS.
3701 bool ok;
3702 EXPECT_QUIC_BUG(ok = Initialize(),
3703 "QUIC client pre-shared keys not yet supported with TLS");
3704 EXPECT_FALSE(ok);
3705 return;
3706 }
3707
QUICHE teama6ef0a62019-03-07 20:34:33 -05003708 // One of two things happens when Initialize() returns:
3709 // 1. Crypto handshake has completed, and it is unsuccessful. Initialize()
3710 // returns false.
3711 // 2. Crypto handshake has not completed, Initialize() returns true. The call
3712 // to WaitForCryptoHandshakeConfirmed() will wait for the handshake and
3713 // return whether it is successful.
3714 ASSERT_FALSE(Initialize() &&
3715 client_->client()->WaitForCryptoHandshakeConfirmed());
bncc5769502019-11-27 10:01:44 -08003716 EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003717}
3718
3719// TODO: reenable once we have a way to make this run faster.
bnc40a0b962020-04-23 17:38:25 -07003720TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoClient)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003721 client_config_.set_max_time_before_crypto_handshake(
3722 QuicTime::Delta::FromSeconds(1));
3723 client_config_.set_max_idle_time_before_crypto_handshake(
3724 QuicTime::Delta::FromSeconds(1));
3725 pre_shared_key_server_ = "foobar";
dschinaziaaaf1a42020-04-16 11:44:31 -07003726
3727 if (GetParam().negotiated_version.handshake_protocol == PROTOCOL_TLS1_3) {
3728 // TODO(b/154162689) add PSK support to QUIC+TLS.
3729 bool ok;
3730 EXPECT_QUIC_BUG(ok = Initialize(),
3731 "QUIC server pre-shared keys not yet supported with TLS");
3732 EXPECT_FALSE(ok);
3733 return;
3734 }
3735
QUICHE teama6ef0a62019-03-07 20:34:33 -05003736 ASSERT_FALSE(Initialize() &&
3737 client_->client()->WaitForCryptoHandshakeConfirmed());
bncc5769502019-11-27 10:01:44 -08003738 EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003739}
3740
3741// TODO: reenable once we have a way to make this run faster.
bnc40a0b962020-04-23 17:38:25 -07003742TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoServer)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003743 client_config_.set_max_time_before_crypto_handshake(
3744 QuicTime::Delta::FromSeconds(1));
3745 client_config_.set_max_idle_time_before_crypto_handshake(
3746 QuicTime::Delta::FromSeconds(1));
3747 pre_shared_key_client_ = "foobar";
dschinaziaaaf1a42020-04-16 11:44:31 -07003748
3749 if (GetParam().negotiated_version.handshake_protocol == PROTOCOL_TLS1_3) {
3750 // TODO(b/154162689) add PSK support to QUIC+TLS.
3751 bool ok;
3752 EXPECT_QUIC_BUG(ok = Initialize(),
3753 "QUIC client pre-shared keys not yet supported with TLS");
3754 EXPECT_FALSE(ok);
3755 return;
3756 }
3757
QUICHE teama6ef0a62019-03-07 20:34:33 -05003758 ASSERT_FALSE(Initialize() &&
3759 client_->client()->WaitForCryptoHandshakeConfirmed());
bncc5769502019-11-27 10:01:44 -08003760 EXPECT_THAT(client_->connection_error(), IsError(QUIC_HANDSHAKE_TIMEOUT));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003761}
3762
bnc40a0b962020-04-23 17:38:25 -07003763TEST_P(EndToEndTestWithoutTls, RequestAndStreamRstInOnePacket) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003764 // Regression test for b/80234898.
3765 ASSERT_TRUE(Initialize());
3766
3767 // INCOMPLETE_RESPONSE will cause the server to not to send the trailer
3768 // (and the FIN) after the response body.
vasilvvc48c8712019-03-11 13:38:16 -07003769 std::string response_body(1305, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003770 SpdyHeaderBlock response_headers;
dmcardleba2fb7e2019-12-13 07:44:34 -08003771 response_headers[":status"] = quiche::QuicheTextUtils::Uint64ToString(200);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003772 response_headers["content-length"] =
dmcardleba2fb7e2019-12-13 07:44:34 -08003773 quiche::QuicheTextUtils::Uint64ToString(response_body.length());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003774 memory_cache_backend_.AddSpecialResponse(
3775 server_hostname_, "/test_url", std::move(response_headers), response_body,
3776 QuicBackendResponse::INCOMPLETE_RESPONSE);
3777
3778 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3779 client_->WaitForDelayedAcks();
3780
fkastenholz7591c282019-08-13 12:58:38 -07003781 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003782 const QuicPacketCount packets_sent_before =
3783 session->connection()->GetStats().packets_sent;
3784
3785 client_->SendRequestAndRstTogether("/test_url");
3786
3787 // Expect exactly one packet is sent from the block above.
3788 ASSERT_EQ(packets_sent_before + 1,
3789 session->connection()->GetStats().packets_sent);
3790
3791 // Wait for the connection to become idle.
3792 client_->WaitForDelayedAcks();
3793
3794 // The real expectation is the test does not crash or timeout.
bncc5769502019-11-27 10:01:44 -08003795 EXPECT_THAT(client_->connection_error(), IsQuicNoError());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003796}
3797
bnc40a0b962020-04-23 17:38:25 -07003798TEST_P(EndToEndTestWithoutTls, ResetStreamOnTtlExpires) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003799 ASSERT_TRUE(Initialize());
3800 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003801 SetPacketLossPercentage(30);
3802
3803 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
3804 // Set a TTL which expires immediately.
3805 stream->MaybeSetTtl(QuicTime::Delta::FromMicroseconds(1));
3806
bnc519216c2019-07-09 05:03:48 -07003807 WriteHeadersOnStream(stream);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003808 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07003809 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003810 stream->WriteOrBufferBody(body, true);
3811 client_->WaitForResponse();
bncc5769502019-11-27 10:01:44 -08003812 EXPECT_THAT(client_->stream_error(), IsStreamError(QUIC_STREAM_TTL_EXPIRED));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003813}
3814
bnc40a0b962020-04-23 17:38:25 -07003815TEST_P(EndToEndTestWithoutTls, SendMessages) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003816 ASSERT_TRUE(Initialize());
3817 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
fkastenholz7591c282019-08-13 12:58:38 -07003818 QuicSession* client_session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003819 QuicConnection* client_connection = client_session->connection();
fayangd4291e42019-05-30 10:31:21 -07003820 if (!VersionSupportsMessageFrames(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003821 return;
3822 }
3823
3824 SetPacketLossPercentage(30);
dschinazi66dea072019-04-09 11:41:06 -07003825 ASSERT_GT(kMaxOutgoingPacketSize,
3826 client_session->GetCurrentLargestMessagePayload());
ianswettb239f862019-04-05 09:15:06 -07003827 ASSERT_LT(0, client_session->GetCurrentLargestMessagePayload());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003828
dschinazi66dea072019-04-09 11:41:06 -07003829 std::string message_string(kMaxOutgoingPacketSize, 'a');
dmcardleba2fb7e2019-12-13 07:44:34 -08003830 quiche::QuicheStringPiece message_buffer(message_string);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003831 QuicRandom* random =
3832 QuicConnectionPeer::GetHelper(client_connection)->GetRandomGenerator();
3833 QuicMemSliceStorage storage(nullptr, 0, nullptr, 0);
3834 {
fayanga4b37b22019-06-18 13:37:47 -07003835 QuicConnection::ScopedPacketFlusher flusher(client_session->connection());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003836 // Verify the largest message gets successfully sent.
dmcardleba2fb7e2019-12-13 07:44:34 -08003837 EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, 1),
3838 client_session->SendMessage(MakeSpan(
3839 client_session->connection()
3840 ->helper()
3841 ->GetStreamSendBufferAllocator(),
3842 quiche::QuicheStringPiece(
3843 message_buffer.data(),
3844 client_session->GetCurrentLargestMessagePayload()),
3845 &storage)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003846 // Send more messages with size (0, largest_payload] until connection is
3847 // write blocked.
3848 const int kTestMaxNumberOfMessages = 100;
3849 for (size_t i = 2; i <= kTestMaxNumberOfMessages; ++i) {
3850 size_t message_length =
ianswettb239f862019-04-05 09:15:06 -07003851 random->RandUint64() %
3852 client_session->GetCurrentLargestMessagePayload() +
3853 1;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003854 MessageResult result = client_session->SendMessage(MakeSpan(
3855 client_session->connection()
3856 ->helper()
3857 ->GetStreamSendBufferAllocator(),
dmcardleba2fb7e2019-12-13 07:44:34 -08003858 quiche::QuicheStringPiece(message_buffer.data(), message_length),
3859 &storage));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003860 if (result.status == MESSAGE_STATUS_BLOCKED) {
3861 // Connection is write blocked.
3862 break;
3863 }
3864 EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, i), result);
3865 }
3866 }
3867
3868 client_->WaitForDelayedAcks();
ianswettb239f862019-04-05 09:15:06 -07003869 EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
3870 client_session
3871 ->SendMessage(MakeSpan(
3872 client_session->connection()
3873 ->helper()
3874 ->GetStreamSendBufferAllocator(),
dmcardleba2fb7e2019-12-13 07:44:34 -08003875 quiche::QuicheStringPiece(
ianswettb239f862019-04-05 09:15:06 -07003876 message_buffer.data(),
3877 client_session->GetCurrentLargestMessagePayload() + 1),
3878 &storage))
3879 .status);
bncc5769502019-11-27 10:01:44 -08003880 EXPECT_THAT(client_->connection_error(), IsQuicNoError());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003881}
3882
3883class EndToEndPacketReorderingTest : public EndToEndTest {
3884 public:
3885 void CreateClientWithWriter() override {
3886 QUIC_LOG(ERROR) << "create client with reorder_writer_";
3887 reorder_writer_ = new PacketReorderingWriter();
3888 client_.reset(EndToEndTest::CreateQuicClient(reorder_writer_));
3889 }
3890
3891 void SetUp() override {
3892 // Don't initialize client writer in base class.
3893 server_writer_ = new PacketDroppingTestWriter();
3894 }
3895
3896 protected:
3897 PacketReorderingWriter* reorder_writer_;
3898};
3899
3900INSTANTIATE_TEST_SUITE_P(EndToEndPacketReorderingTests,
3901 EndToEndPacketReorderingTest,
dschinazi142051a2019-09-18 18:17:29 -07003902 ::testing::ValuesIn(GetTestParams(false)),
3903 ::testing::PrintToStringParamName());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003904
3905TEST_P(EndToEndPacketReorderingTest, ReorderedConnectivityProbing) {
3906 ASSERT_TRUE(Initialize());
3907
3908 // Finish one request to make sure handshake established.
3909 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3910
3911 // Wait for the connection to become idle, to make sure the packet gets
3912 // delayed is the connectivity probing packet.
3913 client_->WaitForDelayedAcks();
3914
3915 QuicSocketAddress old_addr =
3916 client_->client()->network_helper()->GetLatestClientAddress();
3917
3918 // Migrate socket to the new IP address.
3919 QuicIpAddress new_host = TestLoopback(2);
3920 EXPECT_NE(old_addr.host(), new_host);
3921 ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
3922
3923 // Write a connectivity probing after the next /foo request.
3924 reorder_writer_->SetDelay(1);
3925 client_->SendConnectivityProbing();
3926
3927 ASSERT_TRUE(client_->MigrateSocketWithSpecifiedPort(old_addr.host(),
3928 old_addr.port()));
3929
3930 // The (delayed) connectivity probing will be sent after this request.
3931 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3932
3933 // Send yet another request after the connectivity probing, when this request
3934 // returns, the probing is guaranteed to have been received by the server, and
3935 // the server's response to probing is guaranteed to have been received by the
3936 // client.
3937 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3938
3939 server_thread_->Pause();
3940 QuicConnection* server_connection = GetServerConnection();
3941 EXPECT_EQ(1u,
3942 server_connection->GetStats().num_connectivity_probing_received);
3943 server_thread_->Resume();
3944
fkastenholz7591c282019-08-13 12:58:38 -07003945 EXPECT_EQ(
3946 1u, GetClientConnection()->GetStats().num_connectivity_probing_received);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003947}
3948
3949TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
3950 ASSERT_TRUE(Initialize());
3951 // Finish one request to make sure handshake established.
3952 client_->SendSynchronousRequest("/foo");
3953 // Disconnect for next 0-rtt request.
3954 client_->Disconnect();
3955
3956 // Client get valid STK now. Do a 0-rtt request.
3957 // Buffer a CHLO till another packets sent out.
3958 reorder_writer_->SetDelay(1);
3959 // Only send out a CHLO.
3960 client_->client()->Initialize();
3961 client_->client()->StartConnect();
3962 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3963 ASSERT_TRUE(client_->client()->connected());
3964
3965 // Send a request before handshake finishes.
3966 SpdyHeaderBlock headers;
3967 headers[":method"] = "POST";
3968 headers[":path"] = "/bar";
3969 headers[":scheme"] = "https";
3970 headers[":authority"] = server_hostname_;
3971
3972 client_->SendMessage(headers, "");
3973 client_->WaitForResponse();
3974 EXPECT_EQ(kBarResponseBody, client_->response_body());
fkastenholz7591c282019-08-13 12:58:38 -07003975 QuicConnectionStats client_stats = GetClientConnection()->GetStats();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003976 EXPECT_EQ(0u, client_stats.packets_lost);
nharper23f4bb92020-02-13 15:34:36 -08003977 EXPECT_TRUE(client_->client()->EarlyDataAccepted());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003978}
3979
ianswett0a8ff622020-02-05 23:28:58 -08003980// Test that STOP_SENDING makes it to the peer. Create a stream and send a
3981// STOP_SENDING. The receiver should get a call to QuicStream::OnStopSending.
bnc40a0b962020-04-23 17:38:25 -07003982TEST_P(EndToEndTestWithoutTls, SimpleStopSendingTest) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003983 const uint16_t kStopSendingTestCode = 123;
3984 ASSERT_TRUE(Initialize());
fkastenholz305e1732019-06-18 05:01:22 -07003985 if (!VersionHasIetfQuicFrames(negotiated_version_.transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003986 return;
3987 }
fkastenholz7591c282019-08-13 12:58:38 -07003988 QuicSession* client_session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003989 ASSERT_NE(nullptr, client_session);
3990 QuicConnection* client_connection = client_session->connection();
3991 ASSERT_NE(nullptr, client_connection);
3992
vasilvvc48c8712019-03-11 13:38:16 -07003993 std::string response_body(1305, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003994 SpdyHeaderBlock response_headers;
dmcardleba2fb7e2019-12-13 07:44:34 -08003995 response_headers[":status"] = quiche::QuicheTextUtils::Uint64ToString(200);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003996 response_headers["content-length"] =
dmcardleba2fb7e2019-12-13 07:44:34 -08003997 quiche::QuicheTextUtils::Uint64ToString(response_body.length());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003998 memory_cache_backend_.AddStopSendingResponse(
3999 server_hostname_, "/test_url", std::move(response_headers), response_body,
4000 kStopSendingTestCode);
4001
4002 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
4003 client_->WaitForDelayedAcks();
4004
fkastenholz7591c282019-08-13 12:58:38 -07004005 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05004006 const QuicPacketCount packets_sent_before =
4007 session->connection()->GetStats().packets_sent;
4008
4009 QuicStreamId stream_id = session->next_outgoing_bidirectional_stream_id();
4010 client_->SendRequest("/test_url");
4011
4012 // Expect exactly one packet is sent from the block above.
4013 ASSERT_EQ(packets_sent_before + 1,
4014 session->connection()->GetStats().packets_sent);
4015
4016 // Wait for the connection to become idle.
4017 client_->WaitForDelayedAcks();
4018
bncc5769502019-11-27 10:01:44 -08004019 EXPECT_THAT(client_->connection_error(), IsQuicNoError());
QUICHE teama6ef0a62019-03-07 20:34:33 -05004020 QuicSimpleClientStream* client_stream =
4021 static_cast<QuicSimpleClientStream*>(client_->latest_created_stream());
4022 ASSERT_NE(nullptr, client_stream);
ianswett0a8ff622020-02-05 23:28:58 -08004023 // Ensure the stream has been write closed upon receiving STOP_SENDING.
QUICHE teama6ef0a62019-03-07 20:34:33 -05004024 EXPECT_EQ(stream_id, client_stream->id());
ianswett0a8ff622020-02-05 23:28:58 -08004025 EXPECT_TRUE(client_stream->write_side_closed());
renjietange5c12382019-11-07 10:13:14 -08004026 EXPECT_EQ(kStopSendingTestCode,
4027 static_cast<uint16_t>(client_stream->stream_error()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05004028}
4029
bnc40a0b962020-04-23 17:38:25 -07004030TEST_P(EndToEndTestWithoutTls, SimpleStopSendingRstStreamTest) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05004031 ASSERT_TRUE(Initialize());
4032
4033 // Send a request without a fin, to keep the stream open
4034 SpdyHeaderBlock headers;
4035 headers[":method"] = "POST";
4036 headers[":path"] = "/foo";
4037 headers[":scheme"] = "https";
4038 headers[":authority"] = server_hostname_;
4039 client_->SendMessage(headers, "", /*fin=*/false);
4040 // Stream should be open
4041 ASSERT_NE(nullptr, client_->latest_created_stream());
bncc7d9e0c2019-04-16 10:22:15 -07004042 EXPECT_FALSE(client_->latest_created_stream()->write_side_closed());
QUICHE teama6ef0a62019-03-07 20:34:33 -05004043 EXPECT_FALSE(
4044 QuicStreamPeer::read_side_closed(client_->latest_created_stream()));
4045
4046 // Send a RST_STREAM+STOP_SENDING on the stream
4047 // Code is not important.
4048 client_->latest_created_stream()->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
4049 client_->WaitForResponse();
4050
4051 // Stream should be gone.
4052 ASSERT_EQ(nullptr, client_->latest_created_stream());
4053}
4054
4055class BadShloPacketWriter : public QuicPacketWriterWrapper {
4056 public:
4057 BadShloPacketWriter() : error_returned_(false) {}
4058 ~BadShloPacketWriter() override {}
4059
4060 WriteResult WritePacket(const char* buffer,
4061 size_t buf_len,
4062 const QuicIpAddress& self_address,
4063 const QuicSocketAddress& peer_address,
4064 quic::PerPacketOptions* options) override {
4065 const WriteResult result = QuicPacketWriterWrapper::WritePacket(
4066 buffer, buf_len, self_address, peer_address, options);
4067 const uint8_t type_byte = buffer[0];
4068 if (!error_returned_ && (type_byte & FLAGS_LONG_HEADER) &&
4069 (((type_byte & 0x30) >> 4) == 1 || (type_byte & 0x7F) == 0x7C)) {
4070 QUIC_DVLOG(1) << "Return write error for ZERO_RTT_PACKET";
4071 error_returned_ = true;
4072 return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
4073 }
4074 return result;
4075 }
4076
4077 private:
4078 bool error_returned_;
4079};
4080
bnc40a0b962020-04-23 17:38:25 -07004081TEST_P(EndToEndTestWithoutTls, ZeroRttProtectedConnectionClose) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05004082 // This test ensures ZERO_RTT_PROTECTED connection close could close a client
4083 // which has switched to forward secure.
4084 connect_to_server_on_initialize_ =
fayangd4291e42019-05-30 10:31:21 -07004085 !VersionHasIetfInvariantHeader(negotiated_version_.transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -05004086 ASSERT_TRUE(Initialize());
fayangd4291e42019-05-30 10:31:21 -07004087 if (!VersionHasIetfInvariantHeader(negotiated_version_.transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05004088 // Only runs for IETF QUIC header.
4089 return;
4090 }
4091 server_thread_->Pause();
4092 QuicDispatcher* dispatcher =
4093 QuicServerPeer::GetDispatcher(server_thread_->server());
4094 ASSERT_EQ(0u, dispatcher->session_map().size());
4095 // Note: this writer will only used by the server connection, not the time
4096 // wait list.
4097 QuicDispatcherPeer::UseWriter(
4098 dispatcher,
4099 // This causes the first server sent ZERO_RTT_PROTECTED packet (i.e.,
4100 // SHLO) to be sent, but WRITE_ERROR is returned. Such that a
4101 // ZERO_RTT_PROTECTED connection close would be sent to a client with
4102 // encryption level FORWARD_SECURE.
4103 new BadShloPacketWriter());
4104 server_thread_->Resume();
4105
4106 client_.reset(CreateQuicClient(client_writer_));
4107 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
4108 // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
4109 // client which switches to FORWARD_SECURE.
bncc5769502019-11-27 10:01:44 -08004110 EXPECT_THAT(client_->connection_error(), IsError(QUIC_PACKET_WRITE_ERROR));
QUICHE teama6ef0a62019-03-07 20:34:33 -05004111}
4112
4113class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
4114 public:
4115 BadShloPacketWriter2() : error_returned_(false) {}
4116 ~BadShloPacketWriter2() override {}
4117
4118 WriteResult WritePacket(const char* buffer,
4119 size_t buf_len,
4120 const QuicIpAddress& self_address,
4121 const QuicSocketAddress& peer_address,
4122 quic::PerPacketOptions* options) override {
4123 const uint8_t type_byte = buffer[0];
4124 if ((type_byte & FLAGS_LONG_HEADER) &&
4125 (((type_byte & 0x30) >> 4) == 1 || (type_byte & 0x7F) == 0x7C)) {
4126 QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
4127 return WriteResult(WRITE_STATUS_OK, buf_len);
4128 }
4129 if (!error_returned_ && !(type_byte & FLAGS_LONG_HEADER)) {
4130 QUIC_DVLOG(1) << "Return write error for short header packet";
4131 error_returned_ = true;
4132 return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
4133 }
4134 return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
4135 peer_address, options);
4136 }
4137
4138 private:
4139 bool error_returned_;
4140};
4141
bnc40a0b962020-04-23 17:38:25 -07004142TEST_P(EndToEndTestWithoutTls, ForwardSecureConnectionClose) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05004143 // This test ensures ZERO_RTT_PROTECTED connection close is sent to a client
4144 // which has ZERO_RTT_PROTECTED encryption level.
QUICHE teama6ef0a62019-03-07 20:34:33 -05004145 connect_to_server_on_initialize_ =
fayangd4291e42019-05-30 10:31:21 -07004146 !VersionHasIetfInvariantHeader(negotiated_version_.transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -05004147 ASSERT_TRUE(Initialize());
fayangd4291e42019-05-30 10:31:21 -07004148 if (!VersionHasIetfInvariantHeader(negotiated_version_.transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05004149 // Only runs for IETF QUIC header.
4150 return;
4151 }
4152 server_thread_->Pause();
4153 QuicDispatcher* dispatcher =
4154 QuicServerPeer::GetDispatcher(server_thread_->server());
4155 ASSERT_EQ(0u, dispatcher->session_map().size());
4156 // Note: this writer will only used by the server connection, not the time
4157 // wait list.
4158 QuicDispatcherPeer::UseWriter(
4159 dispatcher,
4160 // This causes the all server sent ZERO_RTT_PROTECTED packets to be
4161 // dropped, and first short header packet causes write error.
4162 new BadShloPacketWriter2());
4163 server_thread_->Resume();
4164 client_.reset(CreateQuicClient(client_writer_));
4165 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
4166 // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
4167 // client.
bncc5769502019-11-27 10:01:44 -08004168 EXPECT_THAT(client_->connection_error(), IsError(QUIC_PACKET_WRITE_ERROR));
QUICHE teama6ef0a62019-03-07 20:34:33 -05004169}
4170
fkastenholz3c4eabf2019-04-22 07:49:59 -07004171// Test that the stream id manager closes the connection if a stream
4172// in excess of the allowed maximum.
bnc40a0b962020-04-23 17:38:25 -07004173TEST_P(EndToEndTestWithoutTls, TooBigStreamIdClosesConnection) {
fkastenholz3c4eabf2019-04-22 07:49:59 -07004174 // Has to be before version test, see EndToEndTest::TearDown()
4175 ASSERT_TRUE(Initialize());
fkastenholz305e1732019-06-18 05:01:22 -07004176 if (!VersionHasIetfQuicFrames(negotiated_version_.transport_version)) {
fkastenholz3c4eabf2019-04-22 07:49:59 -07004177 // Only runs for IETF QUIC.
4178 return;
4179 }
4180 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
4181
4182 std::string body(kMaxOutgoingPacketSize, 'a');
4183 SpdyHeaderBlock headers;
4184 headers[":method"] = "POST";
4185 headers[":path"] = "/foo";
4186 headers[":scheme"] = "https";
4187 headers[":authority"] = server_hostname_;
4188
4189 // Force the client to write with a stream ID that exceeds the limit.
fkastenholz7591c282019-08-13 12:58:38 -07004190 QuicSpdySession* session = GetClientSession();
fkastenholz3c4eabf2019-04-22 07:49:59 -07004191 QuicStreamIdManager* stream_id_manager =
4192 QuicSessionPeer::v99_bidirectional_stream_id_manager(session);
4193 QuicStreamCount max_number_of_streams =
4194 stream_id_manager->outgoing_max_streams();
4195 QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
4196 session, GetNthClientInitiatedBidirectionalId(max_number_of_streams + 1));
4197 client_->SendCustomSynchronousRequest(headers, body);
bncc5769502019-11-27 10:01:44 -08004198 EXPECT_THAT(client_->stream_error(),
4199 IsStreamError(QUIC_STREAM_CONNECTION_ERROR));
4200 EXPECT_THAT(GetClientSession()->error(), IsError(QUIC_INVALID_STREAM_ID));
fkastenholza3660102019-08-28 05:19:24 -07004201 EXPECT_EQ(IETF_QUIC_TRANSPORT_CONNECTION_CLOSE,
4202 GetClientSession()->close_type());
4203 EXPECT_TRUE(
4204 IS_IETF_STREAM_FRAME(GetClientSession()->transport_close_frame_type()));
fkastenholz3c4eabf2019-04-22 07:49:59 -07004205}
4206
bnc40a0b962020-04-23 17:38:25 -07004207TEST_P(EndToEndTestWithoutTls, TestMaxPushId) {
QUICHE teamc258e4f2019-08-14 10:04:58 -07004208 // Has to be before version test, see EndToEndTest::TearDown()
4209 ASSERT_TRUE(Initialize());
4210 if (!VersionHasIetfQuicFrames(negotiated_version_.transport_version)) {
4211 // Only runs for IETF QUIC.
4212 return;
4213 }
4214
4215 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
4216 static_cast<QuicSpdySession*>(client_->client()->session())
bnc361c4962020-03-24 09:57:47 -07004217 ->SetMaxPushId(kMaxQuicStreamId);
QUICHE teamc258e4f2019-08-14 10:04:58 -07004218
4219 client_->SendSynchronousRequest("/foo");
4220
bnc60ba1932020-03-26 11:16:18 -07004221 EXPECT_TRUE(static_cast<QuicSpdySession*>(client_->client()->session())
4222 ->CanCreatePushStreamWithId(kMaxQuicStreamId));
QUICHE teamc258e4f2019-08-14 10:04:58 -07004223
bnc60ba1932020-03-26 11:16:18 -07004224 EXPECT_TRUE(static_cast<QuicSpdySession*>(GetServerSession())
4225 ->CanCreatePushStreamWithId(kMaxQuicStreamId));
QUICHE teamc258e4f2019-08-14 10:04:58 -07004226}
4227
bnc40a0b962020-04-23 17:38:25 -07004228TEST_P(EndToEndTestWithoutTls, CustomTransportParameters) {
vasilvva2ef3012019-09-12 18:32:14 -07004229 if (GetParam().negotiated_version.handshake_protocol != PROTOCOL_TLS1_3) {
4230 Initialize();
4231 return;
4232 }
4233
4234 constexpr auto kCustomParameter =
4235 static_cast<TransportParameters::TransportParameterId>(0xff34);
4236 client_config_.custom_transport_parameters_to_send()[kCustomParameter] =
4237 "test";
4238 ASSERT_TRUE(Initialize());
4239
4240 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
4241 EXPECT_EQ(server_config_.received_custom_transport_parameters().at(
4242 kCustomParameter),
4243 "test");
4244}
4245
QUICHE teama6ef0a62019-03-07 20:34:33 -05004246} // namespace
4247} // namespace test
4248} // namespace quic