blob: 6eb6ac6f7d3b1b7961e0a9c58d9b35ab32b8249f [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"
renjietang2abedac2019-05-20 14:04:50 -070017#include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test_utils.h"
renjietang87cd7de2019-08-16 08:35:10 -070018#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050019#include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h"
20#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
21#include "net/third_party/quiche/src/quic/core/quic_framer.h"
22#include "net/third_party/quiche/src/quic/core/quic_packet_creator.h"
23#include "net/third_party/quiche/src/quic/core/quic_packet_writer_wrapper.h"
24#include "net/third_party/quiche/src/quic/core/quic_packets.h"
25#include "net/third_party/quiche/src/quic/core/quic_session.h"
26#include "net/third_party/quiche/src/quic/core/quic_utils.h"
27#include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h"
28#include "net/third_party/quiche/src/quic/platform/api/quic_error_code_wrappers.h"
29#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
30#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
31#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
32#include "net/third_party/quiche/src/quic/platform/api/quic_port_utils.h"
33#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
34#include "net/third_party/quiche/src/quic/platform/api/quic_sleep.h"
35#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
36#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050037#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
38#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
39#include "net/third_party/quiche/src/quic/platform/api/quic_test_loopback.h"
40#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
41#include "net/quic/platform/impl/quic_socket_utils.h"
42#include "net/third_party/quiche/src/quic/test_tools/bad_packet_writer.h"
43#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
44#include "net/third_party/quiche/src/quic/test_tools/packet_dropping_test_writer.h"
45#include "net/third_party/quiche/src/quic/test_tools/packet_reordering_writer.h"
46#include "net/third_party/quiche/src/quic/test_tools/quic_client_peer.h"
47#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
48#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
49#include "net/third_party/quiche/src/quic/test_tools/quic_dispatcher_peer.h"
50#include "net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h"
51#include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h"
52#include "net/third_party/quiche/src/quic/test_tools/quic_server_peer.h"
53#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
54#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
55#include "net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.h"
56#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
57#include "net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h"
58#include "net/third_party/quiche/src/quic/test_tools/quic_test_client.h"
59#include "net/third_party/quiche/src/quic/test_tools/quic_test_server.h"
60#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
61#include "net/third_party/quiche/src/quic/test_tools/server_thread.h"
62#include "net/third_party/quiche/src/quic/tools/quic_backend_response.h"
63#include "net/third_party/quiche/src/quic/tools/quic_client.h"
64#include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h"
65#include "net/third_party/quiche/src/quic/tools/quic_server.h"
66#include "net/third_party/quiche/src/quic/tools/quic_simple_client_stream.h"
67#include "net/third_party/quiche/src/quic/tools/quic_simple_server_stream.h"
68
69using spdy::kV3LowestPriority;
70using spdy::SETTINGS_MAX_HEADER_LIST_SIZE;
71using spdy::SpdyFramer;
72using spdy::SpdyHeaderBlock;
73using spdy::SpdySerializedFrame;
74using spdy::SpdySettingsIR;
75
76namespace quic {
77namespace test {
78namespace {
79
80const char kFooResponseBody[] = "Artichoke hearts make me happy.";
81const char kBarResponseBody[] = "Palm hearts are pretty delicious, also.";
82const float kSessionToStreamRatio = 1.5;
83
84// Run all tests with the cross products of all versions.
85struct TestParams {
86 TestParams(const ParsedQuicVersionVector& client_supported_versions,
87 const ParsedQuicVersionVector& server_supported_versions,
88 ParsedQuicVersion negotiated_version,
fayange606e0c2019-08-05 06:56:05 -070089 QuicTag congestion_control_tag,
90 QuicTag priority_tag)
QUICHE teama6ef0a62019-03-07 20:34:33 -050091 : client_supported_versions(client_supported_versions),
92 server_supported_versions(server_supported_versions),
93 negotiated_version(negotiated_version),
fayange606e0c2019-08-05 06:56:05 -070094 congestion_control_tag(congestion_control_tag),
95 priority_tag(priority_tag) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050096
97 friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
98 os << "{ server_supported_versions: "
99 << ParsedQuicVersionVectorToString(p.server_supported_versions);
100 os << " client_supported_versions: "
101 << ParsedQuicVersionVectorToString(p.client_supported_versions);
102 os << " negotiated_version: "
103 << ParsedQuicVersionToString(p.negotiated_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500104 os << " congestion_control_tag: "
fayange606e0c2019-08-05 06:56:05 -0700105 << QuicTagToString(p.congestion_control_tag);
106 os << " priority_tag: " << QuicTagToString(p.priority_tag) << " }";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500107 return os;
108 }
109
110 ParsedQuicVersionVector client_supported_versions;
111 ParsedQuicVersionVector server_supported_versions;
112 ParsedQuicVersion negotiated_version;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500113 QuicTag congestion_control_tag;
fayange606e0c2019-08-05 06:56:05 -0700114 QuicTag priority_tag;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500115};
116
117// Constructs various test permutations.
wubbd64c102019-05-13 11:58:17 -0700118std::vector<TestParams> GetTestParams(bool use_tls_handshake) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500119 QuicFlagSaver flags;
120 // Divide the versions into buckets in which the intra-frame format
121 // is compatible. When clients encounter QUIC version negotiation
122 // they simply retransmit all packets using the new version's
123 // QUIC framing. However, they are unable to change the intra-frame
124 // layout (for example to change HTTP/2 headers to SPDY/3, or a change in the
125 // handshake protocol). So these tests need to ensure that clients are never
126 // attempting to do 0-RTT across incompatible versions. Chromium only
127 // supports a single version at a time anyway. :)
wub49855982019-05-01 14:16:26 -0700128 SetQuicFlag(FLAGS_quic_supports_tls_handshake, use_tls_handshake);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500129 ParsedQuicVersionVector all_supported_versions =
130 FilterSupportedVersions(AllSupportedVersions());
131
132 // Buckets are separated by versions: versions prior to QUIC_VERSION_47 use
133 // STREAM frames for the handshake, and only have QUIC crypto as the handshake
134 // protocol. Version 47 and greater use CRYPTO frames for the handshake, and
135 // must also be split based on the handshake protocol. If the handshake
136 // protocol (QUIC crypto or TLS) changes, the ClientHello/CHLO must be
137 // reconstructed for the correct protocol.
138 ParsedQuicVersionVector version_buckets[3];
139
140 for (const ParsedQuicVersion& version : all_supported_versions) {
QUICHE teamea740082019-03-11 17:58:43 -0700141 if (!QuicVersionUsesCryptoFrames(version.transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500142 version_buckets[0].push_back(version);
143 } else if (version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
144 version_buckets[1].push_back(version);
145 } else {
146 version_buckets[2].push_back(version);
147 }
148 }
149
QUICHE teama6ef0a62019-03-07 20:34:33 -0500150 std::vector<TestParams> params;
wuba9a43cb2019-07-17 15:22:42 -0700151 for (const QuicTag congestion_control_tag :
152 {kRENO, kTBBR, kQBIC, kTPCC, kB2ON}) {
153 if (!GetQuicReloadableFlag(quic_allow_client_enabled_bbr_v2) &&
154 congestion_control_tag == kB2ON) {
155 continue;
156 }
wubbd64c102019-05-13 11:58:17 -0700157 for (const ParsedQuicVersionVector& client_versions : version_buckets) {
158 if (FilterSupportedVersions(client_versions).empty()) {
159 continue;
160 }
fayange606e0c2019-08-05 06:56:05 -0700161 for (const QuicTag priority_tag :
fayangae266342019-08-05 12:19:59 -0700162 {/*no tag*/ static_cast<QuicTag>(0), kH2PR, kFIFO, kLIFO}) {
fayange606e0c2019-08-05 06:56:05 -0700163 // Add an entry for server and client supporting all versions.
164 params.push_back(TestParams(client_versions, all_supported_versions,
165 client_versions.front(),
166 congestion_control_tag, priority_tag));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500167
fayange606e0c2019-08-05 06:56:05 -0700168 // Test client supporting all versions and server supporting
169 // 1 version. Simulate an old server and exercise version
170 // downgrade in the client. Protocol negotiation should
171 // occur. Skip the i = 0 case because it is essentially the
172 // same as the default case.
173 for (size_t i = 1; i < client_versions.size(); ++i) {
174 ParsedQuicVersionVector server_supported_versions;
175 server_supported_versions.push_back(client_versions[i]);
176 if (FilterSupportedVersions(server_supported_versions).empty()) {
177 continue;
178 }
179 params.push_back(TestParams(client_versions,
180 server_supported_versions,
181 server_supported_versions.front(),
182 congestion_control_tag, priority_tag));
183 } // End of inner version loop.
184 } // End of priority_tag loop.
185 } // End of outer version loop.
186 } // End of congestion_control_tag loop.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500187
QUICHE teama6ef0a62019-03-07 20:34:33 -0500188 return params;
189}
190
bnc519216c2019-07-09 05:03:48 -0700191void WriteHeadersOnStream(QuicSpdyStream* stream) {
192 // Since QuicSpdyStream uses QuicHeaderList::empty() to detect too large
193 // headers, it also fails when receiving empty headers.
194 SpdyHeaderBlock headers;
195 headers["foo"] = "bar";
196 stream->WriteHeaders(std::move(headers), /* fin = */ false, nullptr);
197}
198
QUICHE teama6ef0a62019-03-07 20:34:33 -0500199class ServerDelegate : public PacketDroppingTestWriter::Delegate {
200 public:
201 explicit ServerDelegate(QuicDispatcher* dispatcher)
202 : dispatcher_(dispatcher) {}
203 ~ServerDelegate() override = default;
204 void OnCanWrite() override { dispatcher_->OnCanWrite(); }
205
206 private:
207 QuicDispatcher* dispatcher_;
208};
209
210class ClientDelegate : public PacketDroppingTestWriter::Delegate {
211 public:
212 explicit ClientDelegate(QuicClient* client) : client_(client) {}
213 ~ClientDelegate() override = default;
214 void OnCanWrite() override {
215 QuicEpollEvent event(EPOLLOUT);
216 client_->epoll_network_helper()->OnEvent(client_->GetLatestFD(), &event);
217 }
218
219 private:
220 QuicClient* client_;
221};
222
223class EndToEndTest : public QuicTestWithParam<TestParams> {
224 protected:
225 EndToEndTest()
226 : initialized_(false),
227 connect_to_server_on_initialize_(true),
228 server_address_(
229 QuicSocketAddress(TestLoopback(), QuicPickUnusedPortOrDie())),
230 server_hostname_("test.example.com"),
231 client_writer_(nullptr),
232 server_writer_(nullptr),
233 negotiated_version_(UnsupportedQuicVersion()),
234 chlo_multiplier_(0),
235 stream_factory_(nullptr),
236 support_server_push_(false),
dschinazi8ff74822019-05-28 16:37:20 -0700237 expected_server_connection_id_length_(kQuicDefaultConnectionIdLength) {
wub49855982019-05-01 14:16:26 -0700238 SetQuicFlag(FLAGS_quic_supports_tls_handshake, true);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500239 client_supported_versions_ = GetParam().client_supported_versions;
240 server_supported_versions_ = GetParam().server_supported_versions;
241 negotiated_version_ = GetParam().negotiated_version;
242
243 QUIC_LOG(INFO) << "Using Configuration: " << GetParam();
244
245 // Use different flow control windows for client/server.
246 client_config_.SetInitialStreamFlowControlWindowToSend(
247 2 * kInitialStreamFlowControlWindowForTest);
248 client_config_.SetInitialSessionFlowControlWindowToSend(
249 2 * kInitialSessionFlowControlWindowForTest);
250 server_config_.SetInitialStreamFlowControlWindowToSend(
251 3 * kInitialStreamFlowControlWindowForTest);
252 server_config_.SetInitialSessionFlowControlWindowToSend(
253 3 * kInitialSessionFlowControlWindowForTest);
254
255 // The default idle timeouts can be too strict when running on a busy
256 // machine.
257 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(30);
258 client_config_.set_max_time_before_crypto_handshake(timeout);
259 client_config_.set_max_idle_time_before_crypto_handshake(timeout);
260 server_config_.set_max_time_before_crypto_handshake(timeout);
261 server_config_.set_max_idle_time_before_crypto_handshake(timeout);
262
263 AddToCache("/foo", 200, kFooResponseBody);
264 AddToCache("/bar", 200, kBarResponseBody);
265 }
266
267 ~EndToEndTest() override { QuicRecyclePort(server_address_.port()); }
268
269 virtual void CreateClientWithWriter() {
270 client_.reset(CreateQuicClient(client_writer_));
271 }
272
273 QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) {
274 QuicTestClient* client =
275 new QuicTestClient(server_address_, server_hostname_, client_config_,
276 client_supported_versions_,
277 crypto_test_utils::ProofVerifierForTesting());
278 client->UseWriter(writer);
279 if (!pre_shared_key_client_.empty()) {
280 client->client()->SetPreSharedKey(pre_shared_key_client_);
281 }
dschinazic8579862019-07-24 18:20:20 -0700282 client->UseConnectionIdLength(override_server_connection_id_length_);
283 client->UseClientConnectionIdLength(override_client_connection_id_length_);
QUICHE teamc258e4f2019-08-14 10:04:58 -0700284 if (support_server_push_) {
285 client->client()->set_max_allowed_push_id(kMaxQuicStreamId);
286 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500287 client->Connect();
288 return client;
289 }
290
291 void set_smaller_flow_control_receive_window() {
292 const uint32_t kClientIFCW = 64 * 1024;
293 const uint32_t kServerIFCW = 1024 * 1024;
294 set_client_initial_stream_flow_control_receive_window(kClientIFCW);
295 set_client_initial_session_flow_control_receive_window(
296 kSessionToStreamRatio * kClientIFCW);
297 set_server_initial_stream_flow_control_receive_window(kServerIFCW);
298 set_server_initial_session_flow_control_receive_window(
299 kSessionToStreamRatio * kServerIFCW);
300 }
301
302 void set_client_initial_stream_flow_control_receive_window(uint32_t window) {
303 CHECK(client_ == nullptr);
304 QUIC_DLOG(INFO) << "Setting client initial stream flow control window: "
305 << window;
306 client_config_.SetInitialStreamFlowControlWindowToSend(window);
307 }
308
309 void set_client_initial_session_flow_control_receive_window(uint32_t window) {
310 CHECK(client_ == nullptr);
311 QUIC_DLOG(INFO) << "Setting client initial session flow control window: "
312 << window;
313 client_config_.SetInitialSessionFlowControlWindowToSend(window);
314 }
315
316 void set_server_initial_stream_flow_control_receive_window(uint32_t window) {
317 CHECK(server_thread_ == nullptr);
318 QUIC_DLOG(INFO) << "Setting server initial stream flow control window: "
319 << window;
320 server_config_.SetInitialStreamFlowControlWindowToSend(window);
321 }
322
323 void set_server_initial_session_flow_control_receive_window(uint32_t window) {
324 CHECK(server_thread_ == nullptr);
325 QUIC_DLOG(INFO) << "Setting server initial session flow control window: "
326 << window;
327 server_config_.SetInitialSessionFlowControlWindowToSend(window);
328 }
329
330 const QuicSentPacketManager* GetSentPacketManagerFromFirstServerSession() {
331 return &GetServerConnection()->sent_packet_manager();
332 }
333
fkastenholz7591c282019-08-13 12:58:38 -0700334 QuicSpdyClientSession* GetClientSession() {
335 return client_->client()->client_session();
336 }
337
338 QuicConnection* GetClientConnection() {
339 return GetClientSession()->connection();
340 }
341
QUICHE teama6ef0a62019-03-07 20:34:33 -0500342 QuicConnection* GetServerConnection() {
343 return GetServerSession()->connection();
344 }
345
renjietange01b3eb2019-08-20 11:04:54 -0700346 QuicSpdySession* GetServerSession() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500347 QuicDispatcher* dispatcher =
348 QuicServerPeer::GetDispatcher(server_thread_->server());
349 EXPECT_EQ(1u, dispatcher->session_map().size());
renjietange01b3eb2019-08-20 11:04:54 -0700350 return static_cast<QuicSpdySession*>(
351 dispatcher->session_map().begin()->second.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500352 }
353
354 bool Initialize() {
355 QuicTagVector copt;
356 server_config_.SetConnectionOptionsToSend(copt);
357 copt = client_extra_copts_;
358
359 // TODO(nimia): Consider setting the congestion control algorithm for the
360 // client as well according to the test parameter.
361 copt.push_back(GetParam().congestion_control_tag);
362 if (GetParam().congestion_control_tag == kTPCC &&
363 GetQuicReloadableFlag(quic_enable_pcc3)) {
364 copt.push_back(kTPCC);
365 }
fayange606e0c2019-08-05 06:56:05 -0700366 copt.push_back(GetParam().priority_tag);
fayangce0a3162019-08-15 09:05:36 -0700367 if (GetQuicReloadableFlag(quic_enable_pto)) {
368 copt.push_back(k2PTO);
369 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500370 client_config_.SetConnectionOptionsToSend(copt);
371
372 // Start the server first, because CreateQuicClient() attempts
373 // to connect to the server.
374 StartServer();
375
376 if (!connect_to_server_on_initialize_) {
377 initialized_ = true;
378 return true;
379 }
380
381 CreateClientWithWriter();
382 static QuicEpollEvent event(EPOLLOUT);
383 if (client_writer_ != nullptr) {
384 client_writer_->Initialize(
fkastenholz7591c282019-08-13 12:58:38 -0700385 QuicConnectionPeer::GetHelper(GetClientConnection()),
386 QuicConnectionPeer::GetAlarmFactory(GetClientConnection()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500387 QuicMakeUnique<ClientDelegate>(client_->client()));
388 }
389 initialized_ = true;
390 return client_->client()->connected();
391 }
392
393 void SetUp() override {
394 // The ownership of these gets transferred to the QuicPacketWriterWrapper
395 // when Initialize() is executed.
396 client_writer_ = new PacketDroppingTestWriter();
397 server_writer_ = new PacketDroppingTestWriter();
398 }
399
400 void TearDown() override {
401 ASSERT_TRUE(initialized_) << "You must call Initialize() in every test "
402 << "case. Otherwise, your test will leak memory.";
403 StopServer();
404 }
405
406 void StartServer() {
QUICHE team8e2e4532019-03-14 14:37:56 -0700407 auto* test_server = new QuicTestServer(
408 crypto_test_utils::ProofSourceForTesting(), server_config_,
409 server_supported_versions_, &memory_cache_backend_,
dschinazi8ff74822019-05-28 16:37:20 -0700410 expected_server_connection_id_length_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500411 server_thread_ = QuicMakeUnique<ServerThread>(test_server, server_address_);
412 if (chlo_multiplier_ != 0) {
413 server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
414 }
415 if (!pre_shared_key_server_.empty()) {
416 server_thread_->server()->SetPreSharedKey(pre_shared_key_server_);
417 }
418 server_thread_->Initialize();
419 QuicDispatcher* dispatcher =
420 QuicServerPeer::GetDispatcher(server_thread_->server());
421 QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
422
QUICHE teama6ef0a62019-03-07 20:34:33 -0500423 server_writer_->Initialize(QuicDispatcherPeer::GetHelper(dispatcher),
424 QuicDispatcherPeer::GetAlarmFactory(dispatcher),
425 QuicMakeUnique<ServerDelegate>(dispatcher));
426 if (stream_factory_ != nullptr) {
427 static_cast<QuicTestServer*>(server_thread_->server())
428 ->SetSpdyStreamFactory(stream_factory_);
429 }
430
431 server_thread_->Start();
432 }
433
434 void StopServer() {
435 if (server_thread_) {
436 server_thread_->Quit();
437 server_thread_->Join();
438 }
439 }
440
441 void AddToCache(QuicStringPiece path,
442 int response_code,
443 QuicStringPiece body) {
444 memory_cache_backend_.AddSimpleResponse(server_hostname_, path,
445 response_code, body);
446 }
447
448 void SetPacketLossPercentage(int32_t loss) {
449 client_writer_->set_fake_packet_loss_percentage(loss);
450 server_writer_->set_fake_packet_loss_percentage(loss);
451 }
452
453 void SetPacketSendDelay(QuicTime::Delta delay) {
454 client_writer_->set_fake_packet_delay(delay);
455 server_writer_->set_fake_packet_delay(delay);
456 }
457
458 void SetReorderPercentage(int32_t reorder) {
459 client_writer_->set_fake_reorder_percentage(reorder);
460 server_writer_->set_fake_reorder_percentage(reorder);
461 }
462
463 // Verifies that the client and server connections were both free of packets
464 // being discarded, based on connection stats.
465 // Calls server_thread_ Pause() and Resume(), which may only be called once
466 // per test.
467 void VerifyCleanConnection(bool had_packet_loss) {
fkastenholz7591c282019-08-13 12:58:38 -0700468 QuicConnectionStats client_stats = GetClientConnection()->GetStats();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500469 // TODO(ianswett): Determine why this becomes even more flaky with BBR
470 // enabled. b/62141144
471 if (!had_packet_loss && !GetQuicReloadableFlag(quic_default_to_bbr)) {
472 EXPECT_EQ(0u, client_stats.packets_lost);
473 }
474 EXPECT_EQ(0u, client_stats.packets_discarded);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500475 // When client starts with an unsupported version, the version negotiation
476 // packet sent by server for the old connection (respond for the connection
477 // close packet) will be dropped by the client.
wubbd64c102019-05-13 11:58:17 -0700478 if (!ServerSendsVersionNegotiation()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500479 EXPECT_EQ(0u, client_stats.packets_dropped);
480 }
481 if (!ClientSupportsIetfQuicNotSupportedByServer()) {
482 // In this case, if client sends 0-RTT POST with v99, receives IETF
483 // version negotiation packet and speaks a GQUIC version. Server processes
484 // this connection in time wait list and keeps sending IETF version
485 // negotiation packet for incoming packets. But these version negotiation
486 // packets cannot be processed by the client speaking GQUIC.
487 EXPECT_EQ(client_stats.packets_received, client_stats.packets_processed);
488 }
489
QUICHE teama6ef0a62019-03-07 20:34:33 -0500490 server_thread_->Pause();
491 QuicConnectionStats server_stats = GetServerConnection()->GetStats();
492 if (!had_packet_loss) {
493 EXPECT_EQ(0u, server_stats.packets_lost);
494 }
495 EXPECT_EQ(0u, server_stats.packets_discarded);
496 // TODO(ianswett): Restore the check for packets_dropped equals 0.
497 // The expect for packets received is equal to packets processed fails
498 // due to version negotiation packets.
499 server_thread_->Resume();
500 }
501
QUICHE teama6ef0a62019-03-07 20:34:33 -0500502 // Client supports IETF QUIC, while it is not supported by server.
503 bool ClientSupportsIetfQuicNotSupportedByServer() {
fayangd4291e42019-05-30 10:31:21 -0700504 return VersionHasIetfInvariantHeader(
505 client_supported_versions_[0].transport_version) &&
506 !VersionHasIetfInvariantHeader(
507 FilterSupportedVersions(GetParam().server_supported_versions)[0]
508 .transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500509 }
510
511 // Returns true when client starts with an unsupported version, and client
512 // closes connection when version negotiation is received.
513 bool ServerSendsVersionNegotiation() {
fayang9ed391a2019-06-20 11:16:59 -0700514 return client_supported_versions_[0] != GetParam().negotiated_version;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500515 }
516
517 bool SupportsIetfQuicWithTls(ParsedQuicVersion version) {
fayangd4291e42019-05-30 10:31:21 -0700518 return VersionHasIetfInvariantHeader(version.transport_version) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500519 version.handshake_protocol == PROTOCOL_TLS1_3;
520 }
521
522 void ExpectFlowControlsSynced(QuicFlowController* client,
523 QuicFlowController* server) {
524 EXPECT_EQ(QuicFlowControllerPeer::SendWindowSize(client),
525 QuicFlowControllerPeer::ReceiveWindowSize(server));
526 EXPECT_EQ(QuicFlowControllerPeer::ReceiveWindowSize(client),
527 QuicFlowControllerPeer::SendWindowSize(server));
528 }
529
530 // Must be called before Initialize to have effect.
531 void SetSpdyStreamFactory(QuicTestServer::StreamFactory* factory) {
532 stream_factory_ = factory;
533 }
534
535 QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
536 return GetNthClientInitiatedBidirectionalStreamId(
fkastenholz7591c282019-08-13 12:58:38 -0700537 GetClientConnection()->transport_version(), n);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500538 }
539
540 QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
541 return GetNthServerInitiatedBidirectionalStreamId(
fkastenholz7591c282019-08-13 12:58:38 -0700542 GetClientConnection()->transport_version(), n);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500543 }
544
545 ScopedEnvironmentForThreads environment_;
546 bool initialized_;
547 // If true, the Initialize() function will create |client_| and starts to
548 // connect to the server.
549 // Default is true.
550 bool connect_to_server_on_initialize_;
551 QuicSocketAddress server_address_;
vasilvvc48c8712019-03-11 13:38:16 -0700552 std::string server_hostname_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500553 QuicMemoryCacheBackend memory_cache_backend_;
554 std::unique_ptr<ServerThread> server_thread_;
555 std::unique_ptr<QuicTestClient> client_;
556 PacketDroppingTestWriter* client_writer_;
557 PacketDroppingTestWriter* server_writer_;
558 QuicConfig client_config_;
559 QuicConfig server_config_;
560 ParsedQuicVersionVector client_supported_versions_;
561 ParsedQuicVersionVector server_supported_versions_;
562 QuicTagVector client_extra_copts_;
563 ParsedQuicVersion negotiated_version_;
564 size_t chlo_multiplier_;
565 QuicTestServer::StreamFactory* stream_factory_;
566 bool support_server_push_;
vasilvvc48c8712019-03-11 13:38:16 -0700567 std::string pre_shared_key_client_;
568 std::string pre_shared_key_server_;
dschinazic8579862019-07-24 18:20:20 -0700569 int override_server_connection_id_length_ = -1;
570 int override_client_connection_id_length_ = -1;
dschinazi8ff74822019-05-28 16:37:20 -0700571 uint8_t expected_server_connection_id_length_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500572};
573
574// Run all end to end tests with all supported versions.
575INSTANTIATE_TEST_SUITE_P(EndToEndTests,
576 EndToEndTest,
wubbd64c102019-05-13 11:58:17 -0700577 ::testing::ValuesIn(GetTestParams(false)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500578
579class EndToEndTestWithTls : public EndToEndTest {};
580
581INSTANTIATE_TEST_SUITE_P(EndToEndTestsWithTls,
582 EndToEndTestWithTls,
wubbd64c102019-05-13 11:58:17 -0700583 ::testing::ValuesIn(GetTestParams(true)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500584
585TEST_P(EndToEndTestWithTls, HandshakeSuccessful) {
586 ASSERT_TRUE(Initialize());
587 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
588 server_thread_->WaitForCryptoHandshakeConfirmed();
589 // There have been occasions where it seemed that negotiated_version_ and the
590 // version in the connection are not in sync. If it is happening, it has not
591 // been recreatable; this assert is here just to check and raise a flag if it
592 // happens.
fkastenholz7591c282019-08-13 12:58:38 -0700593 ASSERT_EQ(GetClientConnection()->transport_version(),
594 negotiated_version_.transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500595
fkastenholz7591c282019-08-13 12:58:38 -0700596 QuicCryptoStream* crypto_stream =
597 QuicSessionPeer::GetMutableCryptoStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500598 QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(crypto_stream);
599 EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
600 server_thread_->Pause();
601 crypto_stream = QuicSessionPeer::GetMutableCryptoStream(GetServerSession());
602 sequencer = QuicStreamPeer::sequencer(crypto_stream);
603 EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
604}
605
QUICHE teama6ef0a62019-03-07 20:34:33 -0500606TEST_P(EndToEndTest, SimpleRequestResponse) {
607 ASSERT_TRUE(Initialize());
608
609 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
610 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
611 int expected_num_client_hellos = 2;
612 if (ServerSendsVersionNegotiation()) {
613 ++expected_num_client_hellos;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500614 }
615 EXPECT_EQ(expected_num_client_hellos,
616 client_->client()->GetNumSentClientHellos());
renjietange01b3eb2019-08-20 11:04:54 -0700617 if (VersionUsesQpack(GetClientConnection()->transport_version())) {
618 EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(GetClientSession()));
619 EXPECT_TRUE(
620 QuicSpdySessionPeer::GetReceiveControlStream(GetClientSession()));
621 EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(GetServerSession()));
622 EXPECT_TRUE(
623 QuicSpdySessionPeer::GetReceiveControlStream(GetServerSession()));
624 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500625}
626
dschinazi24e7ae82019-07-11 13:07:41 -0700627TEST_P(EndToEndTestWithTls, SimpleRequestResponse) {
628 ASSERT_TRUE(Initialize());
629 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
630 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
631}
632
fkastenholz4c7303c2019-07-29 08:17:07 -0700633// Simple transaction, but set a non-default ack delay at the client
634// and ensure it gets to the server.
635TEST_P(EndToEndTest, SimpleRequestResponseWithAckDelayChange) {
636 // Force the ACK delay to be something other than the default.
637 // Note that it is sent only if doing IETF QUIC.
638 client_config_.SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs + 100u);
639 ASSERT_TRUE(Initialize());
640
641 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
642 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
643 int expected_num_client_hellos = 2;
644 if (ServerSendsVersionNegotiation()) {
645 ++expected_num_client_hellos;
646 }
647 EXPECT_EQ(expected_num_client_hellos,
648 client_->client()->GetNumSentClientHellos());
649 if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
650 EXPECT_EQ(kDefaultDelayedAckTimeMs + 100u,
651 GetSentPacketManagerFromFirstServerSession()
652 ->peer_max_ack_delay()
653 .ToMilliseconds());
654 } else {
655 EXPECT_EQ(kDefaultDelayedAckTimeMs,
656 GetSentPacketManagerFromFirstServerSession()
657 ->peer_max_ack_delay()
658 .ToMilliseconds());
659 }
660}
661
fkastenholz4dc4ba32019-07-30 09:55:25 -0700662// Simple transaction, but set a non-default ack exponent at the client
663// and ensure it gets to the server.
664TEST_P(EndToEndTest, SimpleRequestResponseWithAckExponentChange) {
665 const uint32_t kClientAckDelayExponent = kDefaultAckDelayExponent + 100u;
666 // Force the ACK exponent to be something other than the default.
667 // Note that it is sent only if doing IETF QUIC.
668 client_config_.SetAckDelayExponentToSend(kClientAckDelayExponent);
669 ASSERT_TRUE(Initialize());
670
671 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
672 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
673 int expected_num_client_hellos = 2;
674 if (ServerSendsVersionNegotiation()) {
675 ++expected_num_client_hellos;
676 }
677
678 EXPECT_EQ(expected_num_client_hellos,
679 client_->client()->GetNumSentClientHellos());
680 if (VersionHasIetfQuicFrames(
681 GetParam().negotiated_version.transport_version)) {
682 // Should be only for IETF QUIC.
683 EXPECT_EQ(kClientAckDelayExponent,
684 GetServerConnection()->framer().peer_ack_delay_exponent());
685 } else {
686 // No change for Google QUIC.
687 EXPECT_EQ(kDefaultAckDelayExponent,
688 GetServerConnection()->framer().peer_ack_delay_exponent());
689 }
690 // No change, regardless of version.
691 EXPECT_EQ(kDefaultAckDelayExponent,
692 GetServerConnection()->framer().local_ack_delay_exponent());
693}
694
dschinazi5a354c92019-05-09 12:18:53 -0700695TEST_P(EndToEndTest, SimpleRequestResponseForcedVersionNegotiation) {
dschinazi48ac9192019-07-31 00:07:26 -0700696 SetQuicReloadableFlag(quic_use_parse_public_header, true);
dschinazi5a354c92019-05-09 12:18:53 -0700697 client_supported_versions_.insert(client_supported_versions_.begin(),
698 QuicVersionReservedForNegotiation());
699 ASSERT_TRUE(Initialize());
700 ASSERT_TRUE(ServerSendsVersionNegotiation());
701
702 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
703 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
704
wubbd64c102019-05-13 11:58:17 -0700705 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
dschinazi5a354c92019-05-09 12:18:53 -0700706}
707
dschinazi24e7ae82019-07-11 13:07:41 -0700708TEST_P(EndToEndTestWithTls, ForcedVersionNegotiation) {
dschinazi48ac9192019-07-31 00:07:26 -0700709 SetQuicReloadableFlag(quic_use_parse_public_header, true);
dschinazi24e7ae82019-07-11 13:07:41 -0700710 client_supported_versions_.insert(client_supported_versions_.begin(),
711 QuicVersionReservedForNegotiation());
712 ASSERT_TRUE(Initialize());
713 ASSERT_TRUE(ServerSendsVersionNegotiation());
714
715 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
716 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
717}
718
QUICHE teama6ef0a62019-03-07 20:34:33 -0500719TEST_P(EndToEndTest, SimpleRequestResponseZeroConnectionID) {
dschinazic8579862019-07-24 18:20:20 -0700720 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
721 GetParam().negotiated_version.transport_version)) {
722 ASSERT_TRUE(Initialize());
723 return;
724 }
725 override_server_connection_id_length_ = 0;
726 expected_server_connection_id_length_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500727 ASSERT_TRUE(Initialize());
728
729 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
730 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
731 int expected_num_client_hellos = 2;
732 if (ServerSendsVersionNegotiation()) {
733 ++expected_num_client_hellos;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500734 }
735 EXPECT_EQ(expected_num_client_hellos,
736 client_->client()->GetNumSentClientHellos());
fkastenholz7591c282019-08-13 12:58:38 -0700737 EXPECT_EQ(GetClientConnection()->connection_id(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500738 QuicUtils::CreateZeroConnectionId(
739 GetParam().negotiated_version.transport_version));
740}
741
dschinazi5c030852019-07-11 15:45:53 -0700742TEST_P(EndToEndTestWithTls, ZeroConnectionID) {
dschinazic8579862019-07-24 18:20:20 -0700743 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
744 GetParam().negotiated_version.transport_version)) {
745 ASSERT_TRUE(Initialize());
746 return;
747 }
748 override_server_connection_id_length_ = 0;
749 expected_server_connection_id_length_ = 0;
dschinazi5c030852019-07-11 15:45:53 -0700750 ASSERT_TRUE(Initialize());
751
752 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
753 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -0700754 EXPECT_EQ(GetClientConnection()->connection_id(),
dschinazi5c030852019-07-11 15:45:53 -0700755 QuicUtils::CreateZeroConnectionId(
756 GetParam().negotiated_version.transport_version));
757}
758
759TEST_P(EndToEndTestWithTls, BadConnectionIdLength) {
QUICHE team8e2e4532019-03-14 14:37:56 -0700760 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
761 GetParam().negotiated_version.transport_version)) {
762 ASSERT_TRUE(Initialize());
763 return;
764 }
dschinazic8579862019-07-24 18:20:20 -0700765 override_server_connection_id_length_ = 9;
QUICHE teamc65d1d12019-03-19 20:58:04 -0700766 ASSERT_TRUE(Initialize());
767 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
768 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
769 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
770 ->client_session()
771 ->connection()
772 ->connection_id()
773 .length());
QUICHE team8e2e4532019-03-14 14:37:56 -0700774}
775
dschinazi5c030852019-07-11 15:45:53 -0700776// Tests a very long (16-byte) initial destination connection ID to make
777// sure the dispatcher properly replaces it with an 8-byte one.
778TEST_P(EndToEndTestWithTls, LongBadConnectionIdLength) {
779 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
780 GetParam().negotiated_version.transport_version)) {
781 ASSERT_TRUE(Initialize());
782 return;
783 }
dschinazic8579862019-07-24 18:20:20 -0700784 override_server_connection_id_length_ = 16;
dschinazi5c030852019-07-11 15:45:53 -0700785 ASSERT_TRUE(Initialize());
786 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
787 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
788 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
789 ->client_session()
790 ->connection()
791 ->connection_id()
792 .length());
793}
794
795TEST_P(EndToEndTestWithTls, ClientConnectionId) {
dschinazi346b7ce2019-06-05 01:38:18 -0700796 if (!GetParam().negotiated_version.SupportsClientConnectionIds()) {
797 ASSERT_TRUE(Initialize());
798 return;
799 }
dschinazic8579862019-07-24 18:20:20 -0700800 override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
dschinazi346b7ce2019-06-05 01:38:18 -0700801 ASSERT_TRUE(Initialize());
802 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
803 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
dschinazic8579862019-07-24 18:20:20 -0700804 EXPECT_EQ(override_client_connection_id_length_, client_->client()
805 ->client_session()
806 ->connection()
807 ->client_connection_id()
808 .length());
dschinazi346b7ce2019-06-05 01:38:18 -0700809}
810
dschinazi5c030852019-07-11 15:45:53 -0700811TEST_P(EndToEndTestWithTls, ForcedVersionNegotiationAndClientConnectionId) {
dschinazi346b7ce2019-06-05 01:38:18 -0700812 if (!GetParam().negotiated_version.SupportsClientConnectionIds()) {
813 ASSERT_TRUE(Initialize());
814 return;
815 }
dschinazi8c79ac82019-07-31 12:23:05 -0700816 SetQuicReloadableFlag(quic_use_parse_public_header, true);
dschinazi346b7ce2019-06-05 01:38:18 -0700817 client_supported_versions_.insert(client_supported_versions_.begin(),
818 QuicVersionReservedForNegotiation());
dschinazic8579862019-07-24 18:20:20 -0700819 override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
dschinazi346b7ce2019-06-05 01:38:18 -0700820 ASSERT_TRUE(Initialize());
821 ASSERT_TRUE(ServerSendsVersionNegotiation());
822 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
823 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
dschinazic8579862019-07-24 18:20:20 -0700824 EXPECT_EQ(override_client_connection_id_length_, client_->client()
825 ->client_session()
826 ->connection()
827 ->client_connection_id()
828 .length());
dschinazi346b7ce2019-06-05 01:38:18 -0700829}
830
dschinazi5c030852019-07-11 15:45:53 -0700831TEST_P(EndToEndTestWithTls, ForcedVersionNegotiationAndBadConnectionIdLength) {
dschinazi8eb45e92019-05-10 11:36:15 -0700832 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
833 GetParam().negotiated_version.transport_version)) {
834 ASSERT_TRUE(Initialize());
835 return;
836 }
dschinazi8c79ac82019-07-31 12:23:05 -0700837 SetQuicReloadableFlag(quic_use_parse_public_header, true);
dschinazi8eb45e92019-05-10 11:36:15 -0700838 client_supported_versions_.insert(client_supported_versions_.begin(),
839 QuicVersionReservedForNegotiation());
dschinazic8579862019-07-24 18:20:20 -0700840 override_server_connection_id_length_ = 9;
dschinazi8eb45e92019-05-10 11:36:15 -0700841 ASSERT_TRUE(Initialize());
842 ASSERT_TRUE(ServerSendsVersionNegotiation());
843 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
844 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
845 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
846 ->client_session()
847 ->connection()
848 ->connection_id()
849 .length());
850}
851
dschinazi5c030852019-07-11 15:45:53 -0700852// Forced Version Negotiation with a client connection ID and a long
853// connection ID.
854TEST_P(EndToEndTestWithTls, ForcedVersNegoAndClientCIDAndLongCID) {
855 if (!GetParam().negotiated_version.SupportsClientConnectionIds() ||
856 !QuicUtils::VariableLengthConnectionIdAllowedForVersion(
857 GetParam().negotiated_version.transport_version)) {
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_server_connection_id_length_ = 16;
864 override_client_connection_id_length_ = 18;
dschinazi5c030852019-07-11 15:45:53 -0700865 ASSERT_TRUE(Initialize());
866 ASSERT_TRUE(ServerSendsVersionNegotiation());
867 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
868 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
869 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
870 ->client_session()
871 ->connection()
872 ->connection_id()
873 .length());
dschinazic8579862019-07-24 18:20:20 -0700874 EXPECT_EQ(override_client_connection_id_length_, client_->client()
875 ->client_session()
876 ->connection()
877 ->client_connection_id()
878 .length());
dschinazi5c030852019-07-11 15:45:53 -0700879}
880
QUICHE team8e2e4532019-03-14 14:37:56 -0700881TEST_P(EndToEndTest, MixGoodAndBadConnectionIdLengths) {
882 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
883 GetParam().negotiated_version.transport_version)) {
884 ASSERT_TRUE(Initialize());
885 return;
886 }
887
QUICHE teamc65d1d12019-03-19 20:58:04 -0700888 // Start client_ which will use a bad connection ID length.
dschinazic8579862019-07-24 18:20:20 -0700889 override_server_connection_id_length_ = 9;
QUICHE teamc65d1d12019-03-19 20:58:04 -0700890 ASSERT_TRUE(Initialize());
dschinazic8579862019-07-24 18:20:20 -0700891 override_server_connection_id_length_ = -1;
QUICHE team8e2e4532019-03-14 14:37:56 -0700892
QUICHE teamc65d1d12019-03-19 20:58:04 -0700893 // Start client2 which will use a good connection ID length.
QUICHE team8e2e4532019-03-14 14:37:56 -0700894 std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
895 SpdyHeaderBlock headers;
896 headers[":method"] = "POST";
897 headers[":path"] = "/foo";
898 headers[":scheme"] = "https";
899 headers[":authority"] = server_hostname_;
900 headers["content-length"] = "3";
901 client2->SendMessage(headers, "", /*fin=*/false);
902 client2->SendData("eep", true);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700903
904 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
905 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
906 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
907 ->client_session()
908 ->connection()
909 ->connection_id()
910 .length());
911
QUICHE team8e2e4532019-03-14 14:37:56 -0700912 client2->WaitForResponse();
913 EXPECT_EQ(kFooResponseBody, client2->response_body());
914 EXPECT_EQ("200", client2->response_headers()->find(":status")->second);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700915 EXPECT_EQ(kQuicDefaultConnectionIdLength, client2->client()
916 ->client_session()
917 ->connection()
918 ->connection_id()
919 .length());
QUICHE team8e2e4532019-03-14 14:37:56 -0700920}
921
dschinazi552accc2019-06-17 17:07:34 -0700922TEST_P(EndToEndTestWithTls, SimpleRequestResponseWithIetfDraftSupport) {
923 if (GetParam().negotiated_version.transport_version != QUIC_VERSION_99 ||
924 GetParam().negotiated_version.handshake_protocol != PROTOCOL_TLS1_3) {
925 ASSERT_TRUE(Initialize());
926 return;
927 }
928 QuicVersionInitializeSupportForIetfDraft(1);
929 ASSERT_TRUE(Initialize());
930
931 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
932 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
933}
934
QUICHE teama6ef0a62019-03-07 20:34:33 -0500935TEST_P(EndToEndTest, SimpleRequestResponseWithLargeReject) {
936 chlo_multiplier_ = 1;
937 ASSERT_TRUE(Initialize());
938
939 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
940 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
941 if (ServerSendsVersionNegotiation()) {
942 EXPECT_EQ(4, client_->client()->GetNumSentClientHellos());
943 } else {
944 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
945 }
946}
947
948TEST_P(EndToEndTestWithTls, SimpleRequestResponsev6) {
949 server_address_ =
950 QuicSocketAddress(QuicIpAddress::Loopback6(), server_address_.port());
951 ASSERT_TRUE(Initialize());
952
953 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
954 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
955}
956
dschinazi6ece5002019-05-22 06:35:49 -0700957TEST_P(EndToEndTestWithTls, NoUndecryptablePackets) {
958 ASSERT_TRUE(Initialize());
959
960 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
961 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
962
fkastenholz7591c282019-08-13 12:58:38 -0700963 QuicConnectionStats client_stats = GetClientConnection()->GetStats();
dschinazi6ece5002019-05-22 06:35:49 -0700964 EXPECT_EQ(0u, client_stats.undecryptable_packets_received);
dschinazi02208652019-05-28 02:57:47 -0700965
966 server_thread_->Pause();
967 QuicConnectionStats server_stats = GetServerConnection()->GetStats();
dschinazi6ece5002019-05-22 06:35:49 -0700968 EXPECT_EQ(0u, server_stats.undecryptable_packets_received);
dschinazi02208652019-05-28 02:57:47 -0700969 server_thread_->Resume();
dschinazi6ece5002019-05-22 06:35:49 -0700970}
971
QUICHE teama6ef0a62019-03-07 20:34:33 -0500972TEST_P(EndToEndTestWithTls, SeparateFinPacket) {
973 ASSERT_TRUE(Initialize());
974
975 // Send a request in two parts: the request and then an empty packet with FIN.
976 SpdyHeaderBlock headers;
977 headers[":method"] = "POST";
978 headers[":path"] = "/foo";
979 headers[":scheme"] = "https";
980 headers[":authority"] = server_hostname_;
981 client_->SendMessage(headers, "", /*fin=*/false);
982 client_->SendData("", true);
983 client_->WaitForResponse();
984 EXPECT_EQ(kFooResponseBody, client_->response_body());
985 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
986
987 // Now do the same thing but with a content length.
988 headers["content-length"] = "3";
989 client_->SendMessage(headers, "", /*fin=*/false);
990 client_->SendData("foo", true);
991 client_->WaitForResponse();
992 EXPECT_EQ(kFooResponseBody, client_->response_body());
993 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
994}
995
996TEST_P(EndToEndTestWithTls, MultipleRequestResponse) {
997 ASSERT_TRUE(Initialize());
998
999 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1000 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1001 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
1002 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1003}
1004
1005TEST_P(EndToEndTest, MultipleRequestResponseZeroConnectionID) {
dschinazic8579862019-07-24 18:20:20 -07001006 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
1007 GetParam().negotiated_version.transport_version)) {
1008 ASSERT_TRUE(Initialize());
1009 return;
1010 }
1011 override_server_connection_id_length_ = 0;
1012 expected_server_connection_id_length_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001013 ASSERT_TRUE(Initialize());
1014
1015 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1016 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1017 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
1018 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1019}
1020
1021TEST_P(EndToEndTestWithTls, MultipleStreams) {
1022 // Verifies quic_test_client can track responses of all active streams.
1023 ASSERT_TRUE(Initialize());
1024
1025 const int kNumRequests = 10;
1026
1027 SpdyHeaderBlock headers;
1028 headers[":method"] = "POST";
1029 headers[":path"] = "/foo";
1030 headers[":scheme"] = "https";
1031 headers[":authority"] = server_hostname_;
1032 headers["content-length"] = "3";
1033
1034 for (int i = 0; i < kNumRequests; ++i) {
1035 client_->SendMessage(headers, "bar", /*fin=*/true);
1036 }
1037
1038 while (kNumRequests > client_->num_responses()) {
1039 client_->ClearPerRequestState();
1040 client_->WaitForResponse();
1041 EXPECT_EQ(kFooResponseBody, client_->response_body());
1042 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1043 }
1044}
1045
1046TEST_P(EndToEndTestWithTls, MultipleClients) {
1047 ASSERT_TRUE(Initialize());
1048 std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
1049
1050 SpdyHeaderBlock headers;
1051 headers[":method"] = "POST";
1052 headers[":path"] = "/foo";
1053 headers[":scheme"] = "https";
1054 headers[":authority"] = server_hostname_;
1055 headers["content-length"] = "3";
1056
1057 client_->SendMessage(headers, "", /*fin=*/false);
1058 client2->SendMessage(headers, "", /*fin=*/false);
1059
1060 client_->SendData("bar", true);
1061 client_->WaitForResponse();
1062 EXPECT_EQ(kFooResponseBody, client_->response_body());
1063 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1064
1065 client2->SendData("eep", true);
1066 client2->WaitForResponse();
1067 EXPECT_EQ(kFooResponseBody, client2->response_body());
1068 EXPECT_EQ("200", client2->response_headers()->find(":status")->second);
1069}
1070
1071TEST_P(EndToEndTestWithTls, RequestOverMultiplePackets) {
1072 // Send a large enough request to guarantee fragmentation.
vasilvvc48c8712019-03-11 13:38:16 -07001073 std::string huge_request =
dschinazi66dea072019-04-09 11:41:06 -07001074 "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001075 AddToCache(huge_request, 200, kBarResponseBody);
1076
1077 ASSERT_TRUE(Initialize());
1078
1079 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
1080 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1081}
1082
1083TEST_P(EndToEndTestWithTls, MultiplePacketsRandomOrder) {
1084 // Send a large enough request to guarantee fragmentation.
vasilvvc48c8712019-03-11 13:38:16 -07001085 std::string huge_request =
dschinazi66dea072019-04-09 11:41:06 -07001086 "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001087 AddToCache(huge_request, 200, kBarResponseBody);
1088
1089 ASSERT_TRUE(Initialize());
1090 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
1091 SetReorderPercentage(50);
1092
1093 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
1094 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1095}
1096
1097TEST_P(EndToEndTestWithTls, PostMissingBytes) {
1098 ASSERT_TRUE(Initialize());
1099
1100 // Add a content length header with no body.
1101 SpdyHeaderBlock headers;
1102 headers[":method"] = "POST";
1103 headers[":path"] = "/foo";
1104 headers[":scheme"] = "https";
1105 headers[":authority"] = server_hostname_;
1106 headers["content-length"] = "3";
1107
1108 // This should be detected as stream fin without complete request,
1109 // triggering an error response.
1110 client_->SendCustomSynchronousRequest(headers, "");
1111 EXPECT_EQ(QuicSimpleServerStream::kErrorResponseBody,
1112 client_->response_body());
1113 EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
1114}
1115
1116TEST_P(EndToEndTest, LargePostNoPacketLoss) {
1117 ASSERT_TRUE(Initialize());
1118
1119 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1120
1121 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07001122 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001123 SpdyHeaderBlock headers;
1124 headers[":method"] = "POST";
1125 headers[":path"] = "/foo";
1126 headers[":scheme"] = "https";
1127 headers[":authority"] = server_hostname_;
1128
1129 EXPECT_EQ(kFooResponseBody,
1130 client_->SendCustomSynchronousRequest(headers, body));
1131 // TODO(ianswett): There should not be packet loss in this test, but on some
1132 // platforms the receive buffer overflows.
1133 VerifyCleanConnection(true);
1134}
1135
1136TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) {
1137 ASSERT_TRUE(Initialize());
1138 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
1139
1140 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1141
1142 // 100 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001143 std::string body(100 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001144 SpdyHeaderBlock headers;
1145 headers[":method"] = "POST";
1146 headers[":path"] = "/foo";
1147 headers[":scheme"] = "https";
1148 headers[":authority"] = server_hostname_;
1149
1150 EXPECT_EQ(kFooResponseBody,
1151 client_->SendCustomSynchronousRequest(headers, body));
1152 VerifyCleanConnection(false);
1153}
1154
1155TEST_P(EndToEndTest, LargePostWithPacketLoss) {
wubbd64c102019-05-13 11:58:17 -07001156 // Connect with lower fake packet loss than we'd like to test.
1157 // Until b/10126687 is fixed, losing handshake packets is pretty
1158 // brutal.
1159 SetPacketLossPercentage(5);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001160 ASSERT_TRUE(Initialize());
1161
1162 // Wait for the server SHLO before upping the packet loss.
1163 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1164 SetPacketLossPercentage(30);
1165
1166 // 10 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001167 std::string body(1024 * 10, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001168 SpdyHeaderBlock headers;
1169 headers[":method"] = "POST";
1170 headers[":path"] = "/foo";
1171 headers[":scheme"] = "https";
1172 headers[":authority"] = server_hostname_;
1173
1174 EXPECT_EQ(kFooResponseBody,
1175 client_->SendCustomSynchronousRequest(headers, body));
1176 VerifyCleanConnection(true);
1177}
1178
1179// Regression test for b/80090281.
1180TEST_P(EndToEndTest, LargePostWithPacketLossAndAlwaysBundleWindowUpdates) {
1181 ASSERT_TRUE(Initialize());
1182
1183 // Wait for the server SHLO before upping the packet loss.
1184 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1185 server_thread_->WaitForCryptoHandshakeConfirmed();
1186
1187 // Normally server only bundles a retransmittable frame once every other
1188 // kMaxConsecutiveNonRetransmittablePackets ack-only packets. Setting the max
1189 // to 0 to reliably reproduce b/80090281.
1190 server_thread_->Schedule([this]() {
1191 QuicConnectionPeer::SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
1192 GetServerConnection(), 0);
1193 });
1194
1195 SetPacketLossPercentage(30);
1196
1197 // 10 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001198 std::string body(1024 * 10, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001199 SpdyHeaderBlock headers;
1200 headers[":method"] = "POST";
1201 headers[":path"] = "/foo";
1202 headers[":scheme"] = "https";
1203 headers[":authority"] = server_hostname_;
1204
1205 EXPECT_EQ(kFooResponseBody,
1206 client_->SendCustomSynchronousRequest(headers, body));
1207 VerifyCleanConnection(true);
1208}
1209
1210TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) {
wubbd64c102019-05-13 11:58:17 -07001211 // Connect with lower fake packet loss than we'd like to test. Until
1212 // b/10126687 is fixed, losing handshake packets is pretty brutal.
1213 SetPacketLossPercentage(5);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001214 ASSERT_TRUE(Initialize());
1215
1216 // Wait for the server SHLO before upping the packet loss.
1217 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1218 SetPacketLossPercentage(10);
1219 client_writer_->set_fake_blocked_socket_percentage(10);
1220
1221 // 10 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001222 std::string body(1024 * 10, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001223 SpdyHeaderBlock headers;
1224 headers[":method"] = "POST";
1225 headers[":path"] = "/foo";
1226 headers[":scheme"] = "https";
1227 headers[":authority"] = server_hostname_;
1228
1229 EXPECT_EQ(kFooResponseBody,
1230 client_->SendCustomSynchronousRequest(headers, body));
1231}
1232
1233TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
1234 ASSERT_TRUE(Initialize());
1235
1236 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1237 // Both of these must be called when the writer is not actively used.
1238 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
1239 SetReorderPercentage(30);
1240
1241 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07001242 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001243 SpdyHeaderBlock headers;
1244 headers[":method"] = "POST";
1245 headers[":path"] = "/foo";
1246 headers[":scheme"] = "https";
1247 headers[":authority"] = server_hostname_;
1248
1249 EXPECT_EQ(kFooResponseBody,
1250 client_->SendCustomSynchronousRequest(headers, body));
1251}
1252
1253TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
1254 // Send a request and then disconnect. This prepares the client to attempt
1255 // a 0-RTT handshake for the next request.
1256 ASSERT_TRUE(Initialize());
1257
vasilvvc48c8712019-03-11 13:38:16 -07001258 std::string body(20480, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001259 SpdyHeaderBlock headers;
1260 headers[":method"] = "POST";
1261 headers[":path"] = "/foo";
1262 headers[":scheme"] = "https";
1263 headers[":authority"] = server_hostname_;
1264
1265 EXPECT_EQ(kFooResponseBody,
1266 client_->SendCustomSynchronousRequest(headers, body));
wubbd64c102019-05-13 11:58:17 -07001267 // The same session is used for both hellos, so the number of hellos sent on
1268 // that session is 2.
fkastenholz7591c282019-08-13 12:58:38 -07001269 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001270 if (ServerSendsVersionNegotiation()) {
1271 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1272 } else {
1273 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1274 }
1275
1276 client_->Disconnect();
1277
1278 // The 0-RTT handshake should succeed.
1279 client_->Connect();
1280 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1281 ASSERT_TRUE(client_->client()->connected());
1282 EXPECT_EQ(kFooResponseBody,
1283 client_->SendCustomSynchronousRequest(headers, body));
1284
fkastenholz7591c282019-08-13 12:58:38 -07001285 EXPECT_EQ(1, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001286 if (ServerSendsVersionNegotiation()) {
1287 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1288 } else {
1289 EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
1290 }
1291
1292 client_->Disconnect();
1293
1294 // Restart the server so that the 0-RTT handshake will take 1 RTT.
1295 StopServer();
1296 server_writer_ = new PacketDroppingTestWriter();
1297 StartServer();
1298
1299 client_->Connect();
1300 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1301 ASSERT_TRUE(client_->client()->connected());
1302 EXPECT_EQ(kFooResponseBody,
1303 client_->SendCustomSynchronousRequest(headers, body));
wubbd64c102019-05-13 11:58:17 -07001304 // The same session is used for both hellos, so the number of hellos sent on
1305 // that session is 2.
fkastenholz7591c282019-08-13 12:58:38 -07001306 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001307 if (ServerSendsVersionNegotiation()) {
1308 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1309 } else {
1310 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1311 }
1312
1313 VerifyCleanConnection(false);
1314}
1315
1316TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
1317 // Send a request and then disconnect. This prepares the client to attempt
1318 // a 0-RTT handshake for the next request.
1319 ASSERT_TRUE(Initialize());
1320
1321 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
wubbd64c102019-05-13 11:58:17 -07001322 // The same session is used for both hellos, so the number of hellos sent on
1323 // that session is 2.
fkastenholz7591c282019-08-13 12:58:38 -07001324 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001325 if (ServerSendsVersionNegotiation()) {
1326 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1327 } else {
1328 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1329 }
1330
1331 client_->Disconnect();
1332
1333 // The 0-RTT handshake should succeed.
1334 client_->Connect();
1335 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1336 ASSERT_TRUE(client_->client()->connected());
1337 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1338
fkastenholz7591c282019-08-13 12:58:38 -07001339 EXPECT_EQ(1, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001340 if (ServerSendsVersionNegotiation()) {
1341 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1342 } else {
1343 EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
1344 }
1345
1346 client_->Disconnect();
1347
1348 // Restart the server so that the 0-RTT handshake will take 1 RTT.
1349 StopServer();
1350 server_writer_ = new PacketDroppingTestWriter();
1351 StartServer();
1352
1353 client_->Connect();
1354 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1355 ASSERT_TRUE(client_->client()->connected());
1356 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
wubbd64c102019-05-13 11:58:17 -07001357
fkastenholz7591c282019-08-13 12:58:38 -07001358 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001359 if (ServerSendsVersionNegotiation()) {
1360 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1361 } else {
1362 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1363 }
1364
1365 VerifyCleanConnection(false);
1366}
1367
1368TEST_P(EndToEndTest, LargePostSynchronousRequest) {
1369 // Send a request and then disconnect. This prepares the client to attempt
1370 // a 0-RTT handshake for the next request.
1371 ASSERT_TRUE(Initialize());
1372
vasilvvc48c8712019-03-11 13:38:16 -07001373 std::string body(20480, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001374 SpdyHeaderBlock headers;
1375 headers[":method"] = "POST";
1376 headers[":path"] = "/foo";
1377 headers[":scheme"] = "https";
1378 headers[":authority"] = server_hostname_;
1379
1380 EXPECT_EQ(kFooResponseBody,
1381 client_->SendCustomSynchronousRequest(headers, body));
wubbd64c102019-05-13 11:58:17 -07001382 // The same session is used for both hellos, so the number of hellos sent on
1383 // that session is 2.
fkastenholz7591c282019-08-13 12:58:38 -07001384 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001385 if (ServerSendsVersionNegotiation()) {
1386 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1387 } else {
1388 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1389 }
1390
1391 client_->Disconnect();
1392
1393 // The 0-RTT handshake should succeed.
1394 client_->Connect();
1395 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1396 ASSERT_TRUE(client_->client()->connected());
1397 EXPECT_EQ(kFooResponseBody,
1398 client_->SendCustomSynchronousRequest(headers, body));
1399
fkastenholz7591c282019-08-13 12:58:38 -07001400 EXPECT_EQ(1, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001401 if (ServerSendsVersionNegotiation()) {
1402 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1403 } else {
1404 EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
1405 }
1406
1407 client_->Disconnect();
1408
1409 // Restart the server so that the 0-RTT handshake will take 1 RTT.
1410 StopServer();
1411 server_writer_ = new PacketDroppingTestWriter();
1412 StartServer();
1413
1414 client_->Connect();
1415 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1416 ASSERT_TRUE(client_->client()->connected());
1417 EXPECT_EQ(kFooResponseBody,
1418 client_->SendCustomSynchronousRequest(headers, body));
wubbd64c102019-05-13 11:58:17 -07001419
fkastenholz7591c282019-08-13 12:58:38 -07001420 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001421 if (ServerSendsVersionNegotiation()) {
1422 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1423 } else {
1424 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1425 }
1426
1427 VerifyCleanConnection(false);
1428}
1429
wubbd64c102019-05-13 11:58:17 -07001430TEST_P(EndToEndTest, RejectWithPacketLoss) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001431 // In this test, we intentionally drop the first packet from the
wubbd64c102019-05-13 11:58:17 -07001432 // server, which corresponds with the initial REJ response from
QUICHE teama6ef0a62019-03-07 20:34:33 -05001433 // the server.
1434 server_writer_->set_fake_drop_first_n_packets(1);
1435 ASSERT_TRUE(Initialize());
1436}
1437
1438TEST_P(EndToEndTest, SetInitialReceivedConnectionOptions) {
1439 QuicTagVector initial_received_options;
1440 initial_received_options.push_back(kTBBR);
1441 initial_received_options.push_back(kIW10);
1442 initial_received_options.push_back(kPRST);
1443 EXPECT_TRUE(server_config_.SetInitialReceivedConnectionOptions(
1444 initial_received_options));
1445
1446 ASSERT_TRUE(Initialize());
1447 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1448 server_thread_->WaitForCryptoHandshakeConfirmed();
1449
1450 EXPECT_FALSE(server_config_.SetInitialReceivedConnectionOptions(
1451 initial_received_options));
1452
1453 // Verify that server's configuration is correct.
1454 server_thread_->Pause();
1455 EXPECT_TRUE(server_config_.HasReceivedConnectionOptions());
1456 EXPECT_TRUE(
1457 ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kTBBR));
1458 EXPECT_TRUE(
1459 ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kIW10));
1460 EXPECT_TRUE(
1461 ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kPRST));
1462}
1463
1464TEST_P(EndToEndTest, LargePostSmallBandwidthLargeBuffer) {
1465 ASSERT_TRUE(Initialize());
1466 SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
1467 // 256KB per second with a 256KB buffer from server to client. Wireless
1468 // clients commonly have larger buffers, but our max CWND is 200.
1469 server_writer_->set_max_bandwidth_and_buffer_size(
1470 QuicBandwidth::FromBytesPerSecond(256 * 1024), 256 * 1024);
1471
1472 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1473
1474 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07001475 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001476 SpdyHeaderBlock headers;
1477 headers[":method"] = "POST";
1478 headers[":path"] = "/foo";
1479 headers[":scheme"] = "https";
1480 headers[":authority"] = server_hostname_;
1481
1482 EXPECT_EQ(kFooResponseBody,
1483 client_->SendCustomSynchronousRequest(headers, body));
1484 // This connection may drop packets, because the buffer is smaller than the
1485 // max CWND.
1486 VerifyCleanConnection(true);
1487}
1488
1489TEST_P(EndToEndTestWithTls, DoNotSetSendAlarmIfConnectionFlowControlBlocked) {
1490 // Regression test for b/14677858.
1491 // Test that the resume write alarm is not set in QuicConnection::OnCanWrite
1492 // if currently connection level flow control blocked. If set, this results in
1493 // an infinite loop in the EpollServer, as the alarm fires and is immediately
1494 // rescheduled.
1495 ASSERT_TRUE(Initialize());
1496 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1497
1498 // Ensure both stream and connection level are flow control blocked by setting
1499 // the send window offset to 0.
1500 const uint64_t flow_control_window =
1501 server_config_.GetInitialStreamFlowControlWindowToSend();
1502 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
fkastenholz7591c282019-08-13 12:58:38 -07001503 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001504 QuicFlowControllerPeer::SetSendWindowOffset(stream->flow_controller(), 0);
1505 QuicFlowControllerPeer::SetSendWindowOffset(session->flow_controller(), 0);
1506 EXPECT_TRUE(stream->flow_controller()->IsBlocked());
1507 EXPECT_TRUE(session->flow_controller()->IsBlocked());
1508
1509 // Make sure that the stream has data pending so that it will be marked as
1510 // write blocked when it receives a stream level WINDOW_UPDATE.
1511 stream->WriteOrBufferBody("hello", false);
1512
1513 // The stream now attempts to write, fails because it is still connection
1514 // level flow control blocked, and is added to the write blocked list.
1515 QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream->id(),
1516 2 * flow_control_window);
1517 stream->OnWindowUpdateFrame(window_update);
1518
1519 // Prior to fixing b/14677858 this call would result in an infinite loop in
1520 // Chromium. As a proxy for detecting this, we now check whether the
1521 // send alarm is set after OnCanWrite. It should not be, as the
1522 // connection is still flow control blocked.
1523 session->connection()->OnCanWrite();
1524
1525 QuicAlarm* send_alarm =
1526 QuicConnectionPeer::GetSendAlarm(session->connection());
1527 EXPECT_FALSE(send_alarm->IsSet());
1528}
1529
1530// TODO(nharper): Needs to get turned back to EndToEndTestWithTls
1531// when we figure out why the test doesn't work on chrome.
1532TEST_P(EndToEndTest, InvalidStream) {
1533 ASSERT_TRUE(Initialize());
1534 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1535
dschinazi66dea072019-04-09 11:41:06 -07001536 std::string body(kMaxOutgoingPacketSize, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001537 SpdyHeaderBlock headers;
1538 headers[":method"] = "POST";
1539 headers[":path"] = "/foo";
1540 headers[":scheme"] = "https";
1541 headers[":authority"] = server_hostname_;
1542
1543 // Force the client to write with a stream ID belonging to a nonexistent
1544 // server-side stream.
fkastenholz7591c282019-08-13 12:58:38 -07001545 QuicSpdySession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001546 QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
1547 session, GetNthServerInitiatedBidirectionalId(0));
1548
1549 client_->SendCustomSynchronousRequest(headers, body);
1550 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
1551 EXPECT_EQ(QUIC_INVALID_STREAM_ID, client_->connection_error());
1552}
1553
1554// Test that if the server will close the connection if the client attempts
1555// to send a request with overly large headers.
1556TEST_P(EndToEndTest, LargeHeaders) {
1557 ASSERT_TRUE(Initialize());
1558 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1559
dschinazi66dea072019-04-09 11:41:06 -07001560 std::string body(kMaxOutgoingPacketSize, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001561 SpdyHeaderBlock headers;
1562 headers[":method"] = "POST";
1563 headers[":path"] = "/foo";
1564 headers[":scheme"] = "https";
1565 headers[":authority"] = server_hostname_;
vasilvvc48c8712019-03-11 13:38:16 -07001566 headers["key1"] = std::string(15 * 1024, 'a');
1567 headers["key2"] = std::string(15 * 1024, 'a');
1568 headers["key3"] = std::string(15 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001569
1570 client_->SendCustomSynchronousRequest(headers, body);
renjietang2abedac2019-05-20 14:04:50 -07001571
1572 if (VersionUsesQpack(client_->client()
1573 ->client_session()
1574 ->connection()
1575 ->transport_version())) {
1576 EXPECT_EQ(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
1577 client_->connection_error());
1578 } else {
1579 EXPECT_EQ(QUIC_HEADERS_TOO_LARGE, client_->stream_error());
1580 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
1581 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001582}
1583
1584TEST_P(EndToEndTest, EarlyResponseWithQuicStreamNoError) {
1585 ASSERT_TRUE(Initialize());
1586 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1587
vasilvvc48c8712019-03-11 13:38:16 -07001588 std::string large_body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001589 SpdyHeaderBlock headers;
1590 headers[":method"] = "POST";
1591 headers[":path"] = "/foo";
1592 headers[":scheme"] = "https";
1593 headers[":authority"] = server_hostname_;
1594 // Insert an invalid content_length field in request to trigger an early
1595 // response from server.
1596 headers["content-length"] = "-3";
1597
1598 client_->SendCustomSynchronousRequest(headers, large_body);
1599 EXPECT_EQ("bad", client_->response_body());
1600 EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
1601 EXPECT_EQ(QUIC_STREAM_NO_ERROR, client_->stream_error());
1602 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
1603}
1604
1605// TODO(rch): this test seems to cause net_unittests timeouts :|
1606TEST_P(EndToEndTestWithTls, QUIC_TEST_DISABLED_IN_CHROME(MultipleTermination)) {
1607 ASSERT_TRUE(Initialize());
1608
1609 // Set the offset so we won't frame. Otherwise when we pick up termination
1610 // before HTTP framing is complete, we send an error and close the stream,
1611 // and the second write is picked up as writing on a closed stream.
1612 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
1613 ASSERT_TRUE(stream != nullptr);
1614 QuicStreamPeer::SetStreamBytesWritten(3, stream);
1615
1616 client_->SendData("bar", true);
1617 client_->WaitForWriteToFlush();
1618
1619 // By default the stream protects itself from writes after terminte is set.
1620 // Override this to test the server handling buggy clients.
1621 QuicStreamPeer::SetWriteSideClosed(false, client_->GetOrCreateStream());
1622
1623 EXPECT_QUIC_BUG(client_->SendData("eep", true), "Fin already buffered");
1624}
1625
1626// TODO(nharper): Needs to get turned back to EndToEndTestWithTls
1627// when we figure out why the test doesn't work on chrome.
1628TEST_P(EndToEndTest, Timeout) {
1629 client_config_.SetIdleNetworkTimeout(QuicTime::Delta::FromMicroseconds(500),
1630 QuicTime::Delta::FromMicroseconds(500));
1631 // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
1632 // that's enough to validate timeout in this case.
1633 Initialize();
1634 while (client_->client()->connected()) {
1635 client_->client()->WaitForEvents();
1636 }
1637}
1638
1639TEST_P(EndToEndTestWithTls, MaxIncomingDynamicStreamsLimitRespected) {
1640 // Set a limit on maximum number of incoming dynamic streams.
1641 // Make sure the limit is respected.
1642 const uint32_t kServerMaxIncomingDynamicStreams = 1;
fkastenholzd3a1de92019-05-15 07:00:07 -07001643 server_config_.SetMaxIncomingBidirectionalStreamsToSend(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001644 kServerMaxIncomingDynamicStreams);
1645 ASSERT_TRUE(Initialize());
fkastenholz305e1732019-06-18 05:01:22 -07001646 if (VersionHasIetfQuicFrames(
1647 GetParam().negotiated_version.transport_version)) {
1648 // Do not run this test for /IETF QUIC. Note that the test needs
fkastenholz3c4eabf2019-04-22 07:49:59 -07001649 // to be here, after calling Initialize(), because all tests end up calling
1650 // EndToEndTest::TearDown(), which asserts that Initialize has been called
1651 // and then proceeds to tear things down -- which fails if they are not
1652 // properly set up.
1653 return;
1654 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001655 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001656
1657 // Make the client misbehave after negotiation.
1658 const int kServerMaxStreams = kMaxStreamsMinimumIncrement + 1;
fkastenholz7591c282019-08-13 12:58:38 -07001659 QuicSessionPeer::SetMaxOpenOutgoingStreams(GetClientSession(),
1660 kServerMaxStreams + 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001661
1662 SpdyHeaderBlock headers;
1663 headers[":method"] = "POST";
1664 headers[":path"] = "/foo";
1665 headers[":scheme"] = "https";
1666 headers[":authority"] = server_hostname_;
1667 headers["content-length"] = "3";
1668
1669 // The server supports a small number of additional streams beyond the
1670 // negotiated limit. Open enough streams to go beyond that limit.
1671 for (int i = 0; i < kServerMaxStreams + 1; ++i) {
1672 client_->SendMessage(headers, "", /*fin=*/false);
1673 }
1674 client_->WaitForResponse();
fkastenholz3c4eabf2019-04-22 07:49:59 -07001675
1676 EXPECT_TRUE(client_->connected());
1677 EXPECT_EQ(QUIC_REFUSED_STREAM, client_->stream_error());
1678 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001679}
1680
1681TEST_P(EndToEndTest, SetIndependentMaxIncomingDynamicStreamsLimits) {
1682 // Each endpoint can set max incoming dynamic streams independently.
renjietang87cd7de2019-08-16 08:35:10 -07001683 const uint32_t kClientMaxIncomingDynamicStreams = 4;
1684 const uint32_t kServerMaxIncomingDynamicStreams = 3;
fkastenholzd3a1de92019-05-15 07:00:07 -07001685 client_config_.SetMaxIncomingBidirectionalStreamsToSend(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001686 kClientMaxIncomingDynamicStreams);
fkastenholzd3a1de92019-05-15 07:00:07 -07001687 server_config_.SetMaxIncomingBidirectionalStreamsToSend(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001688 kServerMaxIncomingDynamicStreams);
fkastenholzd3a1de92019-05-15 07:00:07 -07001689 client_config_.SetMaxIncomingUnidirectionalStreamsToSend(
1690 kClientMaxIncomingDynamicStreams);
1691 server_config_.SetMaxIncomingUnidirectionalStreamsToSend(
1692 kServerMaxIncomingDynamicStreams);
1693
QUICHE teama6ef0a62019-03-07 20:34:33 -05001694 ASSERT_TRUE(Initialize());
1695 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1696
1697 // The client has received the server's limit and vice versa.
fkastenholz7591c282019-08-13 12:58:38 -07001698 QuicSpdyClientSession* client_session = GetClientSession();
fkastenholz3c4eabf2019-04-22 07:49:59 -07001699 // The value returned by max_allowed... includes the Crypto and Header
1700 // stream (created as a part of initialization). The config. values,
1701 // above, are treated as "number of requests/responses" - that is, they do
1702 // not include the static Crypto and Header streams. Reduce the value
1703 // returned by max_allowed... by 2 to remove the static streams from the
1704 // count.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001705 size_t client_max_open_outgoing_bidirectional_streams =
fkastenholz305e1732019-06-18 05:01:22 -07001706 VersionHasIetfQuicFrames(
1707 client_session->connection()->transport_version())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001708 ? QuicSessionPeer::v99_streamid_manager(client_session)
fkastenholz3c4eabf2019-04-22 07:49:59 -07001709 ->max_allowed_outgoing_bidirectional_streams() -
1710 QuicSessionPeer::v99_bidirectional_stream_id_manager(
1711 client_session)
1712 ->outgoing_static_stream_count()
QUICHE teama6ef0a62019-03-07 20:34:33 -05001713 : QuicSessionPeer::GetStreamIdManager(client_session)
1714 ->max_open_outgoing_streams();
1715 size_t client_max_open_outgoing_unidirectional_streams =
fkastenholz305e1732019-06-18 05:01:22 -07001716 VersionHasIetfQuicFrames(
1717 client_session->connection()->transport_version())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001718 ? QuicSessionPeer::v99_streamid_manager(client_session)
renjietang3a1bb802019-06-11 10:42:41 -07001719 ->max_allowed_outgoing_unidirectional_streams() -
1720 QuicSessionPeer::v99_unidirectional_stream_id_manager(
1721 client_session)
1722 ->outgoing_static_stream_count()
QUICHE teama6ef0a62019-03-07 20:34:33 -05001723 : QuicSessionPeer::GetStreamIdManager(client_session)
1724 ->max_open_outgoing_streams();
1725 EXPECT_EQ(kServerMaxIncomingDynamicStreams,
1726 client_max_open_outgoing_bidirectional_streams);
1727 EXPECT_EQ(kServerMaxIncomingDynamicStreams,
1728 client_max_open_outgoing_unidirectional_streams);
1729 server_thread_->Pause();
1730 QuicSession* server_session = GetServerSession();
1731 size_t server_max_open_outgoing_bidirectional_streams =
fkastenholz305e1732019-06-18 05:01:22 -07001732 VersionHasIetfQuicFrames(
1733 server_session->connection()->transport_version())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001734 ? QuicSessionPeer::v99_streamid_manager(server_session)
1735 ->max_allowed_outgoing_bidirectional_streams()
1736 : QuicSessionPeer::GetStreamIdManager(server_session)
1737 ->max_open_outgoing_streams();
1738 size_t server_max_open_outgoing_unidirectional_streams =
fkastenholz305e1732019-06-18 05:01:22 -07001739 VersionHasIetfQuicFrames(
1740 server_session->connection()->transport_version())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001741 ? QuicSessionPeer::v99_streamid_manager(server_session)
renjietang3a1bb802019-06-11 10:42:41 -07001742 ->max_allowed_outgoing_unidirectional_streams() -
1743 QuicSessionPeer::v99_unidirectional_stream_id_manager(
1744 server_session)
1745 ->outgoing_static_stream_count()
QUICHE teama6ef0a62019-03-07 20:34:33 -05001746 : QuicSessionPeer::GetStreamIdManager(server_session)
1747 ->max_open_outgoing_streams();
1748 EXPECT_EQ(kClientMaxIncomingDynamicStreams,
1749 server_max_open_outgoing_bidirectional_streams);
1750 EXPECT_EQ(kClientMaxIncomingDynamicStreams,
1751 server_max_open_outgoing_unidirectional_streams);
renjietang87cd7de2019-08-16 08:35:10 -07001752
QUICHE teama6ef0a62019-03-07 20:34:33 -05001753 server_thread_->Resume();
1754}
1755
1756TEST_P(EndToEndTest, NegotiateCongestionControl) {
1757 ASSERT_TRUE(Initialize());
1758
1759 // For PCC, the underlying implementation may be a stub with a
1760 // different name-tag. Skip the rest of this test.
1761 if (GetParam().congestion_control_tag == kTPCC) {
1762 return;
1763 }
1764
1765 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1766
1767 CongestionControlType expected_congestion_control_type = kRenoBytes;
1768 switch (GetParam().congestion_control_tag) {
1769 case kRENO:
1770 expected_congestion_control_type = kRenoBytes;
1771 break;
1772 case kTBBR:
1773 expected_congestion_control_type = kBBR;
1774 break;
1775 case kQBIC:
1776 expected_congestion_control_type = kCubicBytes;
1777 break;
wuba9a43cb2019-07-17 15:22:42 -07001778 case kB2ON:
1779 expected_congestion_control_type = kBBRv2;
1780 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001781 default:
1782 QUIC_DLOG(FATAL) << "Unexpected congestion control tag";
1783 }
1784
1785 server_thread_->Pause();
1786 EXPECT_EQ(expected_congestion_control_type,
1787 QuicSentPacketManagerPeer::GetSendAlgorithm(
1788 *GetSentPacketManagerFromFirstServerSession())
1789 ->GetCongestionControlType());
1790 server_thread_->Resume();
1791}
1792
1793TEST_P(EndToEndTest, ClientSuggestsRTT) {
1794 // Client suggests initial RTT, verify it is used.
1795 const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
1796 client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
1797
1798 ASSERT_TRUE(Initialize());
1799 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1800 server_thread_->WaitForCryptoHandshakeConfirmed();
1801
1802 // Pause the server so we can access the server's internals without races.
1803 server_thread_->Pause();
1804 QuicDispatcher* dispatcher =
1805 QuicServerPeer::GetDispatcher(server_thread_->server());
1806 ASSERT_EQ(1u, dispatcher->session_map().size());
1807 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001808 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001809 const QuicSentPacketManager* server_sent_packet_manager =
1810 GetSentPacketManagerFromFirstServerSession();
1811
1812 EXPECT_EQ(kInitialRTT,
1813 client_sent_packet_manager.GetRttStats()->initial_rtt());
1814 EXPECT_EQ(kInitialRTT,
1815 server_sent_packet_manager->GetRttStats()->initial_rtt());
1816 server_thread_->Resume();
1817}
1818
1819TEST_P(EndToEndTest, ClientSuggestsIgnoredRTT) {
1820 // Client suggests initial RTT, but also specifies NRTT, so it's not used.
1821 const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
1822 client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
1823 QuicTagVector options;
1824 options.push_back(kNRTT);
1825 client_config_.SetConnectionOptionsToSend(options);
1826
1827 ASSERT_TRUE(Initialize());
1828 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1829 server_thread_->WaitForCryptoHandshakeConfirmed();
1830
1831 // Pause the server so we can access the server's internals without races.
1832 server_thread_->Pause();
1833 QuicDispatcher* dispatcher =
1834 QuicServerPeer::GetDispatcher(server_thread_->server());
1835 ASSERT_EQ(1u, dispatcher->session_map().size());
1836 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001837 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001838 const QuicSentPacketManager* server_sent_packet_manager =
1839 GetSentPacketManagerFromFirstServerSession();
1840
1841 EXPECT_EQ(kInitialRTT,
1842 client_sent_packet_manager.GetRttStats()->initial_rtt());
1843 EXPECT_EQ(kInitialRTT,
1844 server_sent_packet_manager->GetRttStats()->initial_rtt());
1845 server_thread_->Resume();
1846}
1847
1848TEST_P(EndToEndTest, MaxInitialRTT) {
1849 // Client tries to suggest twice the server's max initial rtt and the server
1850 // uses the max.
1851 client_config_.SetInitialRoundTripTimeUsToSend(2 *
1852 kMaxInitialRoundTripTimeUs);
1853
1854 ASSERT_TRUE(Initialize());
1855 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1856 server_thread_->WaitForCryptoHandshakeConfirmed();
1857
1858 // Pause the server so we can access the server's internals without races.
1859 server_thread_->Pause();
1860 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001861 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001862
1863 // Now that acks have been exchanged, the RTT estimate has decreased on the
1864 // server and is not infinite on the client.
1865 EXPECT_FALSE(
1866 client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
1867 const RttStats& server_rtt_stats =
1868 *GetServerConnection()->sent_packet_manager().GetRttStats();
1869 EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
1870 server_rtt_stats.initial_rtt().ToMicroseconds());
1871 EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
1872 server_rtt_stats.smoothed_rtt().ToMicroseconds());
1873 server_thread_->Resume();
1874}
1875
1876TEST_P(EndToEndTest, MinInitialRTT) {
1877 // Client tries to suggest 0 and the server uses the default.
1878 client_config_.SetInitialRoundTripTimeUsToSend(0);
1879
1880 ASSERT_TRUE(Initialize());
1881 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1882 server_thread_->WaitForCryptoHandshakeConfirmed();
1883
1884 // Pause the server so we can access the server's internals without races.
1885 server_thread_->Pause();
1886 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001887 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001888 const QuicSentPacketManager& server_sent_packet_manager =
1889 GetServerConnection()->sent_packet_manager();
1890
1891 // Now that acks have been exchanged, the RTT estimate has decreased on the
1892 // server and is not infinite on the client.
1893 EXPECT_FALSE(
1894 client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
1895 // Expect the default rtt of 100ms.
1896 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
1897 server_sent_packet_manager.GetRttStats()->initial_rtt());
1898 // Ensure the bandwidth is valid.
1899 client_sent_packet_manager.BandwidthEstimate();
1900 server_sent_packet_manager.BandwidthEstimate();
1901 server_thread_->Resume();
1902}
1903
1904TEST_P(EndToEndTest, 0ByteConnectionId) {
fayangd4291e42019-05-30 10:31:21 -07001905 if (VersionHasIetfInvariantHeader(
1906 GetParam().negotiated_version.transport_version)) {
dschinazi6dc83682019-05-28 16:46:47 -07001907 // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
1908 ASSERT_TRUE(Initialize());
1909 return;
1910 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001911 client_config_.SetBytesForConnectionIdToSend(0);
1912 ASSERT_TRUE(Initialize());
1913
1914 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1915 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -07001916 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001917 QuicPacketHeader* header =
1918 QuicConnectionPeer::GetLastHeader(client_connection);
dschinazi5e1a7b22019-07-31 12:23:21 -07001919 EXPECT_EQ(CONNECTION_ID_ABSENT, header->source_connection_id_included);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001920}
1921
1922TEST_P(EndToEndTestWithTls, 8ByteConnectionId) {
fayangd4291e42019-05-30 10:31:21 -07001923 if (VersionHasIetfInvariantHeader(
1924 GetParam().negotiated_version.transport_version)) {
dschinazi6dc83682019-05-28 16:46:47 -07001925 // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
1926 ASSERT_TRUE(Initialize());
1927 return;
1928 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001929 client_config_.SetBytesForConnectionIdToSend(8);
1930 ASSERT_TRUE(Initialize());
1931
1932 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1933 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -07001934 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001935 QuicPacketHeader* header =
1936 QuicConnectionPeer::GetLastHeader(client_connection);
dschinazi6dc83682019-05-28 16:46:47 -07001937 EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001938}
1939
1940TEST_P(EndToEndTestWithTls, 15ByteConnectionId) {
fayangd4291e42019-05-30 10:31:21 -07001941 if (VersionHasIetfInvariantHeader(
1942 GetParam().negotiated_version.transport_version)) {
dschinazi6dc83682019-05-28 16:46:47 -07001943 // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
1944 ASSERT_TRUE(Initialize());
1945 return;
1946 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001947 client_config_.SetBytesForConnectionIdToSend(15);
1948 ASSERT_TRUE(Initialize());
1949
1950 // Our server is permissive and allows for out of bounds values.
1951 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1952 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -07001953 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001954 QuicPacketHeader* header =
1955 QuicConnectionPeer::GetLastHeader(client_connection);
dschinazi6dc83682019-05-28 16:46:47 -07001956 EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001957}
1958
1959TEST_P(EndToEndTestWithTls, ResetConnection) {
1960 ASSERT_TRUE(Initialize());
1961
1962 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1963 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1964 client_->ResetConnection();
1965 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1966 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
1967 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1968}
1969
1970// TODO(nharper): Needs to get turned back to EndToEndTestWithTls
1971// when we figure out why the test doesn't work on chrome.
1972TEST_P(EndToEndTest, MaxStreamsUberTest) {
wubbd64c102019-05-13 11:58:17 -07001973 // Connect with lower fake packet loss than we'd like to test. Until
1974 // b/10126687 is fixed, losing handshake packets is pretty brutal.
1975 SetPacketLossPercentage(1);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001976 ASSERT_TRUE(Initialize());
vasilvvc48c8712019-03-11 13:38:16 -07001977 std::string large_body(10240, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001978 int max_streams = 100;
1979
1980 AddToCache("/large_response", 200, large_body);
1981
1982 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1983 SetPacketLossPercentage(10);
1984
1985 for (int i = 0; i < max_streams; ++i) {
1986 EXPECT_LT(0, client_->SendRequest("/large_response"));
1987 }
1988
1989 // WaitForEvents waits 50ms and returns true if there are outstanding
1990 // requests.
1991 while (client_->client()->WaitForEvents() == true) {
1992 }
1993}
1994
1995TEST_P(EndToEndTestWithTls, StreamCancelErrorTest) {
1996 ASSERT_TRUE(Initialize());
vasilvvc48c8712019-03-11 13:38:16 -07001997 std::string small_body(256, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001998
1999 AddToCache("/small_response", 200, small_body);
2000
2001 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2002
fkastenholz7591c282019-08-13 12:58:38 -07002003 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002004 // Lose the request.
2005 SetPacketLossPercentage(100);
2006 EXPECT_LT(0, client_->SendRequest("/small_response"));
2007 client_->client()->WaitForEvents();
2008 // Transmit the cancel, and ensure the connection is torn down properly.
2009 SetPacketLossPercentage(0);
2010 QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
2011 session->SendRstStream(stream_id, QUIC_STREAM_CANCELLED, 0);
2012
2013 // WaitForEvents waits 50ms and returns true if there are outstanding
2014 // requests.
2015 while (client_->client()->WaitForEvents() == true) {
2016 }
2017 // It should be completely fine to RST a stream before any data has been
2018 // received for that stream.
2019 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
2020}
2021
2022TEST_P(EndToEndTest, ConnectionMigrationClientIPChanged) {
2023 ASSERT_TRUE(Initialize());
2024 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2025 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2026
2027 // Store the client IP address which was used to send the first request.
2028 QuicIpAddress old_host =
2029 client_->client()->network_helper()->GetLatestClientAddress().host();
2030
2031 // Migrate socket to the new IP address.
2032 QuicIpAddress new_host = TestLoopback(2);
2033 EXPECT_NE(old_host, new_host);
2034 ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
2035
2036 // Send a request using the new socket.
2037 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
2038 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2039}
2040
2041TEST_P(EndToEndTest, ConnectionMigrationClientPortChanged) {
2042 // Tests that the client's port can change during an established QUIC
2043 // connection, and that doing so does not result in the connection being
2044 // closed by the server.
2045 ASSERT_TRUE(Initialize());
2046
2047 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2048 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2049
2050 // Store the client address which was used to send the first request.
2051 QuicSocketAddress old_address =
2052 client_->client()->network_helper()->GetLatestClientAddress();
2053 int old_fd = client_->client()->GetLatestFD();
2054
2055 // Create a new socket before closing the old one, which will result in a new
2056 // ephemeral port.
2057 QuicClientPeer::CreateUDPSocketAndBind(client_->client());
2058
2059 // Stop listening and close the old FD.
2060 QuicClientPeer::CleanUpUDPSocket(client_->client(), old_fd);
2061
2062 // The packet writer needs to be updated to use the new FD.
2063 client_->client()->network_helper()->CreateQuicPacketWriter();
2064
2065 // Change the internal state of the client and connection to use the new port,
2066 // this is done because in a real NAT rebinding the client wouldn't see any
2067 // port change, and so expects no change to incoming port.
2068 // This is kind of ugly, but needed as we are simply swapping out the client
2069 // FD rather than any more complex NAT rebinding simulation.
2070 int new_port =
2071 client_->client()->network_helper()->GetLatestClientAddress().port();
2072 QuicClientPeer::SetClientPort(client_->client(), new_port);
fkastenholz7591c282019-08-13 12:58:38 -07002073 QuicConnectionPeer::SetSelfAddress(GetClientConnection(),
2074 QuicSocketAddress(client_->client()
2075 ->client_session()
2076 ->connection()
2077 ->self_address()
2078 .host(),
2079 new_port));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002080
2081 // Register the new FD for epoll events.
2082 int new_fd = client_->client()->GetLatestFD();
2083 QuicEpollServer* eps = client_->epoll_server();
2084 eps->RegisterFD(new_fd, client_->client()->epoll_network_helper(),
2085 EPOLLIN | EPOLLOUT | EPOLLET);
2086
2087 // Send a second request, using the new FD.
2088 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
2089 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2090
2091 // Verify that the client's ephemeral port is different.
2092 QuicSocketAddress new_address =
2093 client_->client()->network_helper()->GetLatestClientAddress();
2094 EXPECT_EQ(old_address.host(), new_address.host());
2095 EXPECT_NE(old_address.port(), new_address.port());
2096}
2097
2098TEST_P(EndToEndTest, NegotiatedInitialCongestionWindow) {
2099 SetQuicReloadableFlag(quic_unified_iw_options, true);
2100 client_extra_copts_.push_back(kIW03);
2101
2102 ASSERT_TRUE(Initialize());
2103
2104 // Values are exchanged during crypto handshake, so wait for that to finish.
2105 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2106 server_thread_->WaitForCryptoHandshakeConfirmed();
2107 server_thread_->Pause();
2108
2109 QuicPacketCount cwnd =
2110 GetServerConnection()->sent_packet_manager().initial_congestion_window();
2111 EXPECT_EQ(3u, cwnd);
2112}
2113
2114TEST_P(EndToEndTest, DifferentFlowControlWindows) {
2115 // Client and server can set different initial flow control receive windows.
2116 // These are sent in CHLO/SHLO. Tests that these values are exchanged properly
2117 // in the crypto handshake.
2118 const uint32_t kClientStreamIFCW = 123456;
2119 const uint32_t kClientSessionIFCW = 234567;
2120 set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
2121 set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
2122
2123 uint32_t kServerStreamIFCW = 32 * 1024;
2124 uint32_t kServerSessionIFCW = 48 * 1024;
2125 set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
2126 set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
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
2134 // Open a data stream to make sure the stream level flow control is updated.
2135 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
bnc519216c2019-07-09 05:03:48 -07002136 WriteHeadersOnStream(stream);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002137 stream->WriteOrBufferBody("hello", false);
2138
2139 // Client should have the right values for server's receive window.
2140 EXPECT_EQ(kServerStreamIFCW,
2141 client_->client()
2142 ->client_session()
2143 ->config()
2144 ->ReceivedInitialStreamFlowControlWindowBytes());
2145 EXPECT_EQ(kServerSessionIFCW,
2146 client_->client()
2147 ->client_session()
2148 ->config()
2149 ->ReceivedInitialSessionFlowControlWindowBytes());
2150 EXPECT_EQ(kServerStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
2151 stream->flow_controller()));
fkastenholz7591c282019-08-13 12:58:38 -07002152 EXPECT_EQ(kServerSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
2153 GetClientSession()->flow_controller()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002154
2155 // Server should have the right values for client's receive window.
2156 server_thread_->Pause();
2157 QuicSession* session = GetServerSession();
2158 EXPECT_EQ(kClientStreamIFCW,
2159 session->config()->ReceivedInitialStreamFlowControlWindowBytes());
2160 EXPECT_EQ(kClientSessionIFCW,
2161 session->config()->ReceivedInitialSessionFlowControlWindowBytes());
2162 EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
2163 session->flow_controller()));
2164 server_thread_->Resume();
2165}
2166
2167// Test negotiation of IFWA connection option.
2168TEST_P(EndToEndTest, NegotiatedServerInitialFlowControlWindow) {
2169 const uint32_t kClientStreamIFCW = 123456;
2170 const uint32_t kClientSessionIFCW = 234567;
2171 set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
2172 set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
2173
2174 uint32_t kServerStreamIFCW = 32 * 1024;
2175 uint32_t kServerSessionIFCW = 48 * 1024;
2176 set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
2177 set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
2178
2179 // Bump the window.
2180 const uint32_t kExpectedStreamIFCW = 1024 * 1024;
2181 const uint32_t kExpectedSessionIFCW = 1.5 * 1024 * 1024;
2182 client_extra_copts_.push_back(kIFWA);
2183
2184 ASSERT_TRUE(Initialize());
2185
2186 // Values are exchanged during crypto handshake, so wait for that to finish.
2187 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2188 server_thread_->WaitForCryptoHandshakeConfirmed();
2189
2190 // Open a data stream to make sure the stream level flow control is updated.
2191 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
bnc519216c2019-07-09 05:03:48 -07002192 WriteHeadersOnStream(stream);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002193 stream->WriteOrBufferBody("hello", false);
2194
2195 // Client should have the right values for server's receive window.
2196 EXPECT_EQ(kExpectedStreamIFCW,
2197 client_->client()
2198 ->client_session()
2199 ->config()
2200 ->ReceivedInitialStreamFlowControlWindowBytes());
2201 EXPECT_EQ(kExpectedSessionIFCW,
2202 client_->client()
2203 ->client_session()
2204 ->config()
2205 ->ReceivedInitialSessionFlowControlWindowBytes());
2206 EXPECT_EQ(kExpectedStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
2207 stream->flow_controller()));
fkastenholz7591c282019-08-13 12:58:38 -07002208 EXPECT_EQ(kExpectedSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
2209 GetClientSession()->flow_controller()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002210}
2211
2212TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
2213 // The special headers and crypto streams should be subject to per-stream flow
2214 // control limits, but should not be subject to connection level flow control
2215 const uint32_t kStreamIFCW = 32 * 1024;
2216 const uint32_t kSessionIFCW = 48 * 1024;
2217 set_client_initial_stream_flow_control_receive_window(kStreamIFCW);
2218 set_client_initial_session_flow_control_receive_window(kSessionIFCW);
2219 set_server_initial_stream_flow_control_receive_window(kStreamIFCW);
2220 set_server_initial_session_flow_control_receive_window(kSessionIFCW);
2221
2222 ASSERT_TRUE(Initialize());
2223
2224 // Wait for crypto handshake to finish. This should have contributed to the
2225 // crypto stream flow control window, but not affected the session flow
2226 // control window.
2227 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2228 server_thread_->WaitForCryptoHandshakeConfirmed();
2229
fkastenholz7591c282019-08-13 12:58:38 -07002230 QuicCryptoStream* crypto_stream =
2231 QuicSessionPeer::GetMutableCryptoStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002232 // In v47 and later, the crypto handshake (sent in CRYPTO frames) is not
2233 // subject to flow control.
renjietang2abedac2019-05-20 14:04:50 -07002234 const QuicTransportVersion transport_version =
fkastenholz7591c282019-08-13 12:58:38 -07002235 GetClientConnection()->transport_version();
renjietang2abedac2019-05-20 14:04:50 -07002236 if (!QuicVersionUsesCryptoFrames(transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002237 EXPECT_LT(QuicFlowControllerPeer::SendWindowSize(
2238 crypto_stream->flow_controller()),
2239 kStreamIFCW);
2240 }
renjietang3a1bb802019-06-11 10:42:41 -07002241 // When stream type is enabled, control streams will send settings and
2242 // contribute to flow control windows, so this expectation is no longer valid.
2243 if (!VersionHasStreamType(transport_version)) {
fkastenholz7591c282019-08-13 12:58:38 -07002244 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
2245 GetClientSession()->flow_controller()));
renjietang3a1bb802019-06-11 10:42:41 -07002246 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002247
2248 // Send a request with no body, and verify that the connection level window
2249 // has not been affected.
2250 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2251
renjietang2abedac2019-05-20 14:04:50 -07002252 // No headers stream in IETF QUIC.
2253 if (VersionUsesQpack(transport_version)) {
2254 return;
2255 }
2256
fkastenholz7591c282019-08-13 12:58:38 -07002257 QuicHeadersStream* headers_stream =
2258 QuicSpdySessionPeer::GetHeadersStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002259 EXPECT_LT(
2260 QuicFlowControllerPeer::SendWindowSize(headers_stream->flow_controller()),
2261 kStreamIFCW);
fkastenholz7591c282019-08-13 12:58:38 -07002262 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
2263 GetClientSession()->flow_controller()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002264
2265 // Server should be in a similar state: connection flow control window should
2266 // not have any bytes marked as received.
2267 server_thread_->Pause();
2268 QuicSession* session = GetServerSession();
2269 QuicFlowController* server_connection_flow_controller =
2270 session->flow_controller();
2271 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize(
2272 server_connection_flow_controller));
2273 server_thread_->Resume();
2274}
2275
2276TEST_P(EndToEndTest, FlowControlsSynced) {
2277 set_smaller_flow_control_receive_window();
2278
2279 ASSERT_TRUE(Initialize());
2280
2281 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2282 server_thread_->WaitForCryptoHandshakeConfirmed();
2283
2284 server_thread_->Pause();
fkastenholz7591c282019-08-13 12:58:38 -07002285 QuicSpdySession* const client_session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002286 auto* server_session = static_cast<QuicSpdySession*>(GetServerSession());
renjietang3a1bb802019-06-11 10:42:41 -07002287
renjietang118c8ac2019-07-30 11:43:59 -07002288 if (VersionHasStreamType(server_session->connection()->transport_version())) {
renjietang3a1bb802019-06-11 10:42:41 -07002289 // Settings frame will be sent through control streams, which contribute
2290 // to the session's flow controller. And due to the timing issue described
2291 // below, the settings frame might not be received.
2292 HttpEncoder encoder;
2293 SettingsFrame settings;
renjietang87cd7de2019-08-16 08:35:10 -07002294 settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] =
2295 kDefaultMaxUncompressedHeaderSize;
2296 settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
2297 kDefaultQpackMaxDynamicTableCapacity;
renjietang3a1bb802019-06-11 10:42:41 -07002298 std::unique_ptr<char[]> buffer;
2299 auto header_length = encoder.SerializeSettingsFrame(settings, &buffer);
2300 QuicByteCount win_difference1 = QuicFlowControllerPeer::ReceiveWindowSize(
2301 server_session->flow_controller()) -
2302 QuicFlowControllerPeer::SendWindowSize(
2303 client_session->flow_controller());
2304 QuicByteCount win_difference2 = QuicFlowControllerPeer::ReceiveWindowSize(
2305 client_session->flow_controller()) -
2306 QuicFlowControllerPeer::SendWindowSize(
2307 server_session->flow_controller());
2308 EXPECT_TRUE(win_difference1 == 0 ||
2309 win_difference1 ==
2310 header_length +
renjietang87cd7de2019-08-16 08:35:10 -07002311 QuicDataWriter::GetVarInt62Len(kControlStream) +
2312 QuicDataWriter::GetVarInt62Len(kQpackEncoderStream) +
2313 QuicDataWriter::GetVarInt62Len(kQpackDecoderStream));
renjietang3a1bb802019-06-11 10:42:41 -07002314 EXPECT_TRUE(win_difference2 == 0 ||
2315 win_difference2 ==
2316 header_length +
renjietang87cd7de2019-08-16 08:35:10 -07002317 QuicDataWriter::GetVarInt62Len(kControlStream) +
2318 QuicDataWriter::GetVarInt62Len(kQpackEncoderStream) +
2319 QuicDataWriter::GetVarInt62Len(kQpackDecoderStream));
renjietang3a1bb802019-06-11 10:42:41 -07002320 // The test returns early because in this version, headers stream no longer
2321 // sends settings.
2322 return;
2323 }
2324
QUICHE teama6ef0a62019-03-07 20:34:33 -05002325 ExpectFlowControlsSynced(client_session->flow_controller(),
2326 server_session->flow_controller());
nharperd5c4a932019-05-13 13:58:49 -07002327 if (!QuicVersionUsesCryptoFrames(client_->client()
2328 ->client_session()
2329 ->connection()
2330 ->transport_version())) {
2331 ExpectFlowControlsSynced(
2332 QuicSessionPeer::GetMutableCryptoStream(client_session)
2333 ->flow_controller(),
2334 QuicSessionPeer::GetMutableCryptoStream(server_session)
2335 ->flow_controller());
2336 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002337 SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
2338 SpdySettingsIR settings_frame;
2339 settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE,
2340 kDefaultMaxUncompressedHeaderSize);
2341 SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame));
2342 QuicFlowController* client_header_stream_flow_controller =
2343 QuicSpdySessionPeer::GetHeadersStream(client_session)->flow_controller();
2344 QuicFlowController* server_header_stream_flow_controller =
2345 QuicSpdySessionPeer::GetHeadersStream(server_session)->flow_controller();
2346 // Both client and server are sending this SETTINGS frame, and the send
2347 // window is consumed. But because of timing issue, the server may send or
2348 // not send the frame, and the client may send/ not send / receive / not
2349 // receive the frame.
2350 // TODO(fayang): Rewrite this part because it is hacky.
2351 QuicByteCount win_difference1 = QuicFlowControllerPeer::ReceiveWindowSize(
2352 server_header_stream_flow_controller) -
2353 QuicFlowControllerPeer::SendWindowSize(
2354 client_header_stream_flow_controller);
2355 QuicByteCount win_difference2 = QuicFlowControllerPeer::ReceiveWindowSize(
2356 client_header_stream_flow_controller) -
2357 QuicFlowControllerPeer::SendWindowSize(
2358 server_header_stream_flow_controller);
2359 EXPECT_TRUE(win_difference1 == 0 || win_difference1 == frame.size());
2360 EXPECT_TRUE(win_difference2 == 0 || win_difference2 == frame.size());
2361
2362 // Client *may* have received the SETTINGs frame.
2363 // TODO(fayang): Rewrite this part because it is hacky.
2364 float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
2365 client_session->flow_controller())) /
2366 QuicFlowControllerPeer::ReceiveWindowSize(
2367 QuicSpdySessionPeer::GetHeadersStream(client_session)
2368 ->flow_controller());
2369 float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
2370 client_session->flow_controller())) /
2371 (QuicFlowControllerPeer::ReceiveWindowSize(
2372 QuicSpdySessionPeer::GetHeadersStream(client_session)
2373 ->flow_controller()) +
2374 frame.size());
2375 EXPECT_TRUE(ratio1 == kSessionToStreamRatio ||
2376 ratio2 == kSessionToStreamRatio);
2377
2378 server_thread_->Resume();
2379}
2380
2381TEST_P(EndToEndTestWithTls, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
2382 // A stream created on receipt of a simple request with no body will never get
2383 // a stream frame with a FIN. Verify that we don't keep track of the stream in
2384 // the locally closed streams map: it will never be removed if so.
2385 ASSERT_TRUE(Initialize());
2386
2387 // Send a simple headers only request, and receive response.
2388 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2389 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2390
2391 // Now verify that the server is not waiting for a final FIN or RST.
2392 server_thread_->Pause();
2393 QuicSession* session = GetServerSession();
2394 EXPECT_EQ(
2395 0u,
2396 QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(session).size());
2397 server_thread_->Resume();
2398}
2399
2400// A TestAckListener verifies that its OnAckNotification method has been
2401// called exactly once on destruction.
2402class TestAckListener : public QuicAckListenerInterface {
2403 public:
2404 explicit TestAckListener(int bytes_to_ack) : bytes_to_ack_(bytes_to_ack) {}
2405
2406 void OnPacketAcked(int acked_bytes,
2407 QuicTime::Delta /*delta_largest_observed*/) override {
2408 ASSERT_LE(acked_bytes, bytes_to_ack_);
2409 bytes_to_ack_ -= acked_bytes;
2410 }
2411
2412 void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
2413
2414 bool has_been_notified() const { return bytes_to_ack_ == 0; }
2415
2416 protected:
2417 // Object is ref counted.
2418 ~TestAckListener() override { EXPECT_EQ(0, bytes_to_ack_); }
2419
2420 private:
2421 int bytes_to_ack_;
2422};
2423
2424class TestResponseListener : public QuicSpdyClientBase::ResponseListener {
2425 public:
2426 void OnCompleteResponse(QuicStreamId id,
2427 const SpdyHeaderBlock& response_headers,
vasilvvc48c8712019-03-11 13:38:16 -07002428 const std::string& response_body) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002429 QUIC_DVLOG(1) << "response for stream " << id << " "
2430 << response_headers.DebugString() << "\n"
2431 << response_body;
2432 }
2433};
2434
2435TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
2436 // Verify that even in the presence of packet loss and occasionally blocked
2437 // socket, an AckNotifierDelegate will get informed that the data it is
2438 // interested in has been ACKed. This tests end-to-end ACK notification, and
2439 // demonstrates that retransmissions do not break this functionality.
wubbd64c102019-05-13 11:58:17 -07002440
2441 SetPacketLossPercentage(5);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002442 ASSERT_TRUE(Initialize());
2443
2444 // Wait for the server SHLO before upping the packet loss.
2445 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2446 SetPacketLossPercentage(30);
2447 client_writer_->set_fake_blocked_socket_percentage(10);
2448
2449 // Create a POST request and send the headers only.
2450 SpdyHeaderBlock headers;
2451 headers[":method"] = "POST";
2452 headers[":path"] = "/foo";
2453 headers[":scheme"] = "https";
2454 headers[":authority"] = server_hostname_;
2455
2456 client_->SendMessage(headers, "", /*fin=*/false);
2457
renjietang2abedac2019-05-20 14:04:50 -07002458 // Size of headers on the request stream. Zero if headers are sent on the
2459 // header stream.
2460 size_t header_size = 0;
2461 if (VersionUsesQpack(client_->client()
2462 ->client_session()
2463 ->connection()
2464 ->transport_version())) {
2465 // Determine size of compressed headers.
2466 NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
renjietangc2aa5cb2019-06-20 12:22:53 -07002467 NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
renjietang8a2df8f2019-08-07 10:43:52 -07002468 QpackEncoder qpack_encoder(&decoder_stream_error_delegate);
2469 qpack_encoder.set_qpack_stream_sender_delegate(
2470 &encoder_stream_sender_delegate);
bncf21c1ad2019-06-20 20:09:50 -07002471 std::string encoded_headers =
bnc8c016222019-08-22 04:43:41 -07002472 qpack_encoder.EncodeHeaderList(/* stream_id = */ 0, headers);
renjietang2abedac2019-05-20 14:04:50 -07002473 header_size = encoded_headers.size();
2474 }
2475
QUICHE teama6ef0a62019-03-07 20:34:33 -05002476 // Test the AckNotifier's ability to track multiple packets by making the
2477 // request body exceed the size of a single packet.
vasilvvc48c8712019-03-11 13:38:16 -07002478 std::string request_string = "a request body bigger than one packet" +
dschinazi66dea072019-04-09 11:41:06 -07002479 std::string(kMaxOutgoingPacketSize, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002480
2481 // The TestAckListener will cause a failure if not notified.
2482 QuicReferenceCountedPointer<TestAckListener> ack_listener(
renjietang2abedac2019-05-20 14:04:50 -07002483 new TestAckListener(header_size + request_string.length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002484
2485 // Send the request, and register the delegate for ACKs.
2486 client_->SendData(request_string, true, ack_listener);
2487 client_->WaitForResponse();
2488 EXPECT_EQ(kFooResponseBody, client_->response_body());
2489 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2490
2491 // Send another request to flush out any pending ACKs on the server.
2492 client_->SendSynchronousRequest("/bar");
2493
2494 // Make sure the delegate does get the notification it expects.
2495 while (!ack_listener->has_been_notified()) {
2496 // Waits for up to 50 ms.
2497 client_->client()->WaitForEvents();
2498 }
2499}
2500
2501// Send a public reset from the server.
2502TEST_P(EndToEndTestWithTls, ServerSendPublicReset) {
2503 ASSERT_TRUE(Initialize());
2504
2505 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
fkastenholz7591c282019-08-13 12:58:38 -07002506 QuicConnection* client_connection = GetClientConnection();
dschinazi82884662019-08-02 13:25:15 -07002507 QuicConfig* config = client_->client()->session()->config();
2508 EXPECT_TRUE(config->HasReceivedStatelessResetToken());
2509 QuicUint128 stateless_reset_token = config->ReceivedStatelessResetToken();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002510
2511 // Send the public reset.
2512 QuicConnectionId connection_id = client_connection->connection_id();
2513 QuicPublicResetPacket header;
2514 header.connection_id = connection_id;
2515 QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
2516 Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
2517 std::unique_ptr<QuicEncryptedPacket> packet;
fayangd4291e42019-05-30 10:31:21 -07002518 if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002519 packet = framer.BuildIetfStatelessResetPacket(connection_id,
2520 stateless_reset_token);
2521 } else {
2522 packet = framer.BuildPublicResetPacket(header);
2523 }
2524 // We must pause the server's thread in order to call WritePacket without
2525 // race conditions.
2526 server_thread_->Pause();
2527 server_writer_->WritePacket(
2528 packet->data(), packet->length(), server_address_.host(),
2529 client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
2530 server_thread_->Resume();
2531
2532 // The request should fail.
2533 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
2534 EXPECT_TRUE(client_->response_headers()->empty());
2535 EXPECT_EQ(QUIC_PUBLIC_RESET, client_->connection_error());
2536}
2537
2538// Send a public reset from the server for a different connection ID.
2539// It should be ignored.
2540TEST_P(EndToEndTestWithTls, ServerSendPublicResetWithDifferentConnectionId) {
2541 ASSERT_TRUE(Initialize());
2542
2543 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
fkastenholz7591c282019-08-13 12:58:38 -07002544 QuicConnection* client_connection = GetClientConnection();
dschinazi82884662019-08-02 13:25:15 -07002545 QuicConfig* config = client_->client()->session()->config();
2546 EXPECT_TRUE(config->HasReceivedStatelessResetToken());
2547 QuicUint128 stateless_reset_token = config->ReceivedStatelessResetToken();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002548 // Send the public reset.
2549 QuicConnectionId incorrect_connection_id = TestConnectionId(
2550 TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
2551 QuicPublicResetPacket header;
2552 header.connection_id = incorrect_connection_id;
2553 QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
2554 Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
2555 std::unique_ptr<QuicEncryptedPacket> packet;
2556 testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
fkastenholz7591c282019-08-13 12:58:38 -07002557 GetClientConnection()->set_debug_visitor(&visitor);
fayangd4291e42019-05-30 10:31:21 -07002558 if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002559 packet = framer.BuildIetfStatelessResetPacket(incorrect_connection_id,
2560 stateless_reset_token);
2561 EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
2562 .Times(0);
2563 } else {
2564 packet = framer.BuildPublicResetPacket(header);
2565 EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
2566 .Times(1);
2567 }
2568 // We must pause the server's thread in order to call WritePacket without
2569 // race conditions.
2570 server_thread_->Pause();
2571 server_writer_->WritePacket(
2572 packet->data(), packet->length(), server_address_.host(),
2573 client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
2574 server_thread_->Resume();
2575
fayangd4291e42019-05-30 10:31:21 -07002576 if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002577 // The request should fail. IETF stateless reset does not include connection
2578 // ID.
2579 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
2580 EXPECT_TRUE(client_->response_headers()->empty());
2581 EXPECT_EQ(QUIC_PUBLIC_RESET, client_->connection_error());
2582 return;
2583 }
2584 // The connection should be unaffected.
2585 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2586 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2587
fkastenholz7591c282019-08-13 12:58:38 -07002588 GetClientConnection()->set_debug_visitor(nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002589}
2590
2591// Send a public reset from the client for a different connection ID.
2592// It should be ignored.
2593TEST_P(EndToEndTestWithTls, ClientSendPublicResetWithDifferentConnectionId) {
2594 ASSERT_TRUE(Initialize());
2595
2596 // Send the public reset.
2597 QuicConnectionId incorrect_connection_id = TestConnectionId(
fkastenholz7591c282019-08-13 12:58:38 -07002598 TestConnectionIdToUInt64(GetClientConnection()->connection_id()) + 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002599 QuicPublicResetPacket header;
2600 header.connection_id = incorrect_connection_id;
2601 QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
2602 Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
2603 std::unique_ptr<QuicEncryptedPacket> packet(
2604 framer.BuildPublicResetPacket(header));
2605 client_writer_->WritePacket(
2606 packet->data(), packet->length(),
2607 client_->client()->network_helper()->GetLatestClientAddress().host(),
2608 server_address_, nullptr);
2609
2610 // The connection should be unaffected.
2611 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2612 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2613}
2614
2615// Send a version negotiation packet from the server for a different
2616// connection ID. It should be ignored.
2617TEST_P(EndToEndTestWithTls,
2618 ServerSendVersionNegotiationWithDifferentConnectionId) {
2619 ASSERT_TRUE(Initialize());
2620
2621 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2622
2623 // Send the version negotiation packet.
fkastenholz7591c282019-08-13 12:58:38 -07002624 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002625 QuicConnectionId incorrect_connection_id = TestConnectionId(
2626 TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
2627 std::unique_ptr<QuicEncryptedPacket> packet(
2628 QuicFramer::BuildVersionNegotiationPacket(
dschinazib417d602019-05-29 13:08:45 -07002629 incorrect_connection_id, EmptyQuicConnectionId(),
fayangd4291e42019-05-30 10:31:21 -07002630 VersionHasIetfInvariantHeader(client_connection->transport_version()),
dschinazi48ac9192019-07-31 00:07:26 -07002631 client_connection->version().HasLengthPrefixedConnectionIds(),
QUICHE teama6ef0a62019-03-07 20:34:33 -05002632 server_supported_versions_));
2633 testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
2634 client_connection->set_debug_visitor(&visitor);
2635 EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
2636 .Times(1);
2637 // We must pause the server's thread in order to call WritePacket without
2638 // race conditions.
2639 server_thread_->Pause();
2640 server_writer_->WritePacket(
2641 packet->data(), packet->length(), server_address_.host(),
2642 client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
2643 server_thread_->Resume();
2644
2645 // The connection should be unaffected.
2646 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2647 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2648
2649 client_connection->set_debug_visitor(nullptr);
2650}
2651
2652// A bad header shouldn't tear down the connection, because the receiver can't
2653// tell the connection ID.
2654TEST_P(EndToEndTestWithTls, BadPacketHeaderTruncated) {
2655 ASSERT_TRUE(Initialize());
2656
2657 // Start the connection.
2658 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2659 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2660
2661 // Packet with invalid public flags.
2662 char packet[] = {// public flags (8 byte connection_id)
2663 0x3C,
2664 // truncated connection ID
2665 0x11};
2666 client_writer_->WritePacket(
2667 &packet[0], sizeof(packet),
2668 client_->client()->network_helper()->GetLatestClientAddress().host(),
2669 server_address_, nullptr);
2670 // Give the server time to process the packet.
2671 QuicSleep(QuicTime::Delta::FromMilliseconds(100));
2672 // Pause the server so we can access the server's internals without races.
2673 server_thread_->Pause();
2674 QuicDispatcher* dispatcher =
2675 QuicServerPeer::GetDispatcher(server_thread_->server());
2676 EXPECT_EQ(QUIC_INVALID_PACKET_HEADER,
2677 QuicDispatcherPeer::GetAndClearLastError(dispatcher));
2678 server_thread_->Resume();
2679
2680 // The connection should not be terminated.
2681 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2682 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2683}
2684
2685// A bad header shouldn't tear down the connection, because the receiver can't
2686// tell the connection ID.
2687TEST_P(EndToEndTestWithTls, BadPacketHeaderFlags) {
2688 ASSERT_TRUE(Initialize());
2689
2690 // Start the connection.
2691 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2692 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2693
2694 // Packet with invalid public flags.
2695 char packet[] = {
2696 // invalid public flags
2697 0xFF,
2698 // connection_id
2699 0x10,
2700 0x32,
2701 0x54,
2702 0x76,
2703 0x98,
2704 0xBA,
2705 0xDC,
2706 0xFE,
2707 // packet sequence number
2708 0xBC,
2709 0x9A,
2710 0x78,
2711 0x56,
2712 0x34,
2713 0x12,
2714 // private flags
2715 0x00,
2716 };
2717 client_writer_->WritePacket(
2718 &packet[0], sizeof(packet),
2719 client_->client()->network_helper()->GetLatestClientAddress().host(),
2720 server_address_, nullptr);
2721 // Give the server time to process the packet.
2722 QuicSleep(QuicTime::Delta::FromMilliseconds(100));
2723 // Pause the server so we can access the server's internals without races.
2724 server_thread_->Pause();
2725 QuicDispatcher* dispatcher =
2726 QuicServerPeer::GetDispatcher(server_thread_->server());
2727 EXPECT_EQ(QUIC_INVALID_PACKET_HEADER,
2728 QuicDispatcherPeer::GetAndClearLastError(dispatcher));
2729 server_thread_->Resume();
2730
2731 // The connection should not be terminated.
2732 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2733 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2734}
2735
2736// Send a packet from the client with bad encrypted data. The server should not
2737// tear down the connection.
2738TEST_P(EndToEndTestWithTls, BadEncryptedData) {
2739 ASSERT_TRUE(Initialize());
2740
2741 // Start the connection.
2742 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2743 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2744
2745 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
fkastenholz7591c282019-08-13 12:58:38 -07002746 GetClientConnection()->connection_id(), EmptyQuicConnectionId(), false,
2747 false, 1, "At least 20 characters.", CONNECTION_ID_PRESENT,
2748 CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002749 // Damage the encrypted data.
vasilvvc48c8712019-03-11 13:38:16 -07002750 std::string damaged_packet(packet->data(), packet->length());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002751 damaged_packet[30] ^= 0x01;
2752 QUIC_DLOG(INFO) << "Sending bad packet.";
2753 client_writer_->WritePacket(
2754 damaged_packet.data(), damaged_packet.length(),
2755 client_->client()->network_helper()->GetLatestClientAddress().host(),
2756 server_address_, nullptr);
2757 // Give the server time to process the packet.
2758 QuicSleep(QuicTime::Delta::FromMilliseconds(100));
2759 // This error is sent to the connection's OnError (which ignores it), so the
2760 // dispatcher doesn't see it.
2761 // Pause the server so we can access the server's internals without races.
2762 server_thread_->Pause();
2763 QuicDispatcher* dispatcher =
2764 QuicServerPeer::GetDispatcher(server_thread_->server());
2765 EXPECT_EQ(QUIC_NO_ERROR,
2766 QuicDispatcherPeer::GetAndClearLastError(dispatcher));
2767 server_thread_->Resume();
2768
2769 // The connection should not be terminated.
2770 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2771 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2772}
2773
2774TEST_P(EndToEndTestWithTls, CanceledStreamDoesNotBecomeZombie) {
2775 ASSERT_TRUE(Initialize());
2776 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2777 // Lose the request.
2778 SetPacketLossPercentage(100);
2779 SpdyHeaderBlock headers;
2780 headers[":method"] = "POST";
2781 headers[":path"] = "/foo";
2782 headers[":scheme"] = "https";
2783 headers[":authority"] = server_hostname_;
2784 client_->SendMessage(headers, "test_body", /*fin=*/false);
2785 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
2786
2787 // Cancel the stream.
2788 stream->Reset(QUIC_STREAM_CANCELLED);
fkastenholz7591c282019-08-13 12:58:38 -07002789 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002790 // Verify canceled stream does not become zombie.
2791 EXPECT_TRUE(QuicSessionPeer::zombie_streams(session).empty());
2792 EXPECT_EQ(1u, QuicSessionPeer::closed_streams(session).size());
2793}
2794
2795// A test stream that gives |response_body_| as an error response body.
2796class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
2797 public:
2798 ServerStreamWithErrorResponseBody(
2799 QuicStreamId id,
2800 QuicSpdySession* session,
2801 QuicSimpleServerBackend* quic_simple_server_backend,
vasilvvc48c8712019-03-11 13:38:16 -07002802 std::string response_body)
QUICHE teama6ef0a62019-03-07 20:34:33 -05002803 : QuicSimpleServerStream(id,
2804 session,
2805 BIDIRECTIONAL,
2806 quic_simple_server_backend),
2807 response_body_(std::move(response_body)) {}
2808
2809 ~ServerStreamWithErrorResponseBody() override = default;
2810
2811 protected:
2812 void SendErrorResponse() override {
2813 QUIC_DLOG(INFO) << "Sending error response for stream " << id();
2814 SpdyHeaderBlock headers;
2815 headers[":status"] = "500";
2816 headers["content-length"] =
2817 QuicTextUtils::Uint64ToString(response_body_.size());
2818 // This method must call CloseReadSide to cause the test case, StopReading
2819 // is not sufficient.
2820 QuicStreamPeer::CloseReadSide(this);
2821 SendHeadersAndBody(std::move(headers), response_body_);
2822 }
2823
vasilvvc48c8712019-03-11 13:38:16 -07002824 std::string response_body_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002825};
2826
2827class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
2828 public:
vasilvvc48c8712019-03-11 13:38:16 -07002829 explicit StreamWithErrorFactory(std::string response_body)
QUICHE teama6ef0a62019-03-07 20:34:33 -05002830 : response_body_(std::move(response_body)) {}
2831
2832 ~StreamWithErrorFactory() override = default;
2833
2834 QuicSimpleServerStream* CreateStream(
2835 QuicStreamId id,
2836 QuicSpdySession* session,
2837 QuicSimpleServerBackend* quic_simple_server_backend) override {
2838 return new ServerStreamWithErrorResponseBody(
2839 id, session, quic_simple_server_backend, response_body_);
2840 }
2841
2842 private:
vasilvvc48c8712019-03-11 13:38:16 -07002843 std::string response_body_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002844};
2845
2846// A test server stream that drops all received body.
2847class ServerStreamThatDropsBody : public QuicSimpleServerStream {
2848 public:
2849 ServerStreamThatDropsBody(QuicStreamId id,
2850 QuicSpdySession* session,
2851 QuicSimpleServerBackend* quic_simple_server_backend)
2852 : QuicSimpleServerStream(id,
2853 session,
2854 BIDIRECTIONAL,
2855 quic_simple_server_backend) {}
2856
2857 ~ServerStreamThatDropsBody() override = default;
2858
2859 protected:
2860 void OnBodyAvailable() override {
2861 while (HasBytesToRead()) {
2862 struct iovec iov;
2863 if (GetReadableRegions(&iov, 1) == 0) {
2864 // No more data to read.
2865 break;
2866 }
2867 QUIC_DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream "
2868 << id();
2869 MarkConsumed(iov.iov_len);
2870 }
2871
2872 if (!sequencer()->IsClosed()) {
2873 sequencer()->SetUnblocked();
2874 return;
2875 }
2876
2877 // If the sequencer is closed, then all the body, including the fin, has
2878 // been consumed.
2879 OnFinRead();
2880
2881 if (write_side_closed() || fin_buffered()) {
2882 return;
2883 }
2884
2885 SendResponse();
2886 }
2887};
2888
2889class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
2890 public:
2891 ServerStreamThatDropsBodyFactory() = default;
2892
2893 ~ServerStreamThatDropsBodyFactory() override = default;
2894
2895 QuicSimpleServerStream* CreateStream(
2896 QuicStreamId id,
2897 QuicSpdySession* session,
2898 QuicSimpleServerBackend* quic_simple_server_backend) override {
2899 return new ServerStreamThatDropsBody(id, session,
2900 quic_simple_server_backend);
2901 }
2902};
2903
2904// A test server stream that sends response with body size greater than 4GB.
2905class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
2906 public:
2907 ServerStreamThatSendsHugeResponse(
2908 QuicStreamId id,
2909 QuicSpdySession* session,
2910 QuicSimpleServerBackend* quic_simple_server_backend,
2911 int64_t body_bytes)
2912 : QuicSimpleServerStream(id,
2913 session,
2914 BIDIRECTIONAL,
2915 quic_simple_server_backend),
2916 body_bytes_(body_bytes) {}
2917
2918 ~ServerStreamThatSendsHugeResponse() override = default;
2919
2920 protected:
2921 void SendResponse() override {
2922 QuicBackendResponse response;
vasilvvc48c8712019-03-11 13:38:16 -07002923 std::string body(body_bytes_, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002924 response.set_body(body);
2925 SendHeadersAndBodyAndTrailers(response.headers().Clone(), response.body(),
2926 response.trailers().Clone());
2927 }
2928
2929 private:
2930 // Use a explicit int64_t rather than size_t to simulate a 64-bit server
2931 // talking to a 32-bit client.
2932 int64_t body_bytes_;
2933};
2934
2935class ServerStreamThatSendsHugeResponseFactory
2936 : public QuicTestServer::StreamFactory {
2937 public:
2938 explicit ServerStreamThatSendsHugeResponseFactory(int64_t body_bytes)
2939 : body_bytes_(body_bytes) {}
2940
2941 ~ServerStreamThatSendsHugeResponseFactory() override = default;
2942
2943 QuicSimpleServerStream* CreateStream(
2944 QuicStreamId id,
2945 QuicSpdySession* session,
2946 QuicSimpleServerBackend* quic_simple_server_backend) override {
2947 return new ServerStreamThatSendsHugeResponse(
2948 id, session, quic_simple_server_backend, body_bytes_);
2949 }
2950
2951 int64_t body_bytes_;
2952};
2953
2954TEST_P(EndToEndTest, EarlyResponseFinRecording) {
2955 set_smaller_flow_control_receive_window();
2956
2957 // Verify that an incoming FIN is recorded in a stream object even if the read
2958 // side has been closed. This prevents an entry from being made in
2959 // locally_close_streams_highest_offset_ (which will never be deleted).
2960 // To set up the test condition, the server must do the following in order:
2961 // start sending the response and call CloseReadSide
2962 // receive the FIN of the request
2963 // send the FIN of the response
2964
2965 // The response body must be larger than the flow control window so the server
2966 // must receive a window update from the client before it can finish sending
2967 // it.
2968 uint32_t response_body_size =
2969 2 * client_config_.GetInitialStreamFlowControlWindowToSend();
vasilvvc48c8712019-03-11 13:38:16 -07002970 std::string response_body(response_body_size, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002971
2972 StreamWithErrorFactory stream_factory(response_body);
2973 SetSpdyStreamFactory(&stream_factory);
2974
2975 ASSERT_TRUE(Initialize());
2976
2977 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2978
2979 // A POST that gets an early error response, after the headers are received
2980 // and before the body is received, due to invalid content-length.
2981 // Set an invalid content-length, so the request will receive an early 500
2982 // response.
2983 SpdyHeaderBlock headers;
2984 headers[":method"] = "POST";
2985 headers[":path"] = "/garbage";
2986 headers[":scheme"] = "https";
2987 headers[":authority"] = server_hostname_;
2988 headers["content-length"] = "-1";
2989
2990 // The body must be large enough that the FIN will be in a different packet
2991 // than the end of the headers, but short enough to not require a flow control
2992 // update. This allows headers processing to trigger the error response
2993 // before the request FIN is processed but receive the request FIN before the
2994 // response is sent completely.
dschinazi66dea072019-04-09 11:41:06 -07002995 const uint32_t kRequestBodySize = kMaxOutgoingPacketSize + 10;
vasilvvc48c8712019-03-11 13:38:16 -07002996 std::string request_body(kRequestBodySize, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002997
2998 // Send the request.
2999 client_->SendMessage(headers, request_body);
3000 client_->WaitForResponse();
3001 EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
3002
3003 // Pause the server so we can access the server's internals without races.
3004 server_thread_->Pause();
3005
3006 QuicDispatcher* dispatcher =
3007 QuicServerPeer::GetDispatcher(server_thread_->server());
3008 QuicDispatcher::SessionMap const& map =
3009 QuicDispatcherPeer::session_map(dispatcher);
3010 auto it = map.begin();
3011 EXPECT_TRUE(it != map.end());
3012 QuicSession* server_session = it->second.get();
3013
3014 // The stream is not waiting for the arrival of the peer's final offset.
3015 EXPECT_EQ(
3016 0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(server_session)
3017 .size());
3018
3019 server_thread_->Resume();
3020}
3021
3022TEST_P(EndToEndTestWithTls, Trailers) {
3023 // Test sending and receiving HTTP/2 Trailers (trailing HEADERS frames).
3024 ASSERT_TRUE(Initialize());
3025 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3026
3027 // Set reordering to ensure that Trailers arriving before body is ok.
3028 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3029 SetReorderPercentage(30);
3030
3031 // Add a response with headers, body, and trailers.
vasilvvc48c8712019-03-11 13:38:16 -07003032 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003033
3034 SpdyHeaderBlock headers;
3035 headers[":status"] = "200";
3036 headers[":version"] = "HTTP/1.1";
3037 headers["content-length"] = QuicTextUtils::Uint64ToString(kBody.size());
3038
3039 SpdyHeaderBlock trailers;
3040 trailers["some-trailing-header"] = "trailing-header-value";
3041
3042 memory_cache_backend_.AddResponse(server_hostname_, "/trailer_url",
3043 std::move(headers), kBody,
3044 trailers.Clone());
3045
3046 EXPECT_EQ(kBody, client_->SendSynchronousRequest("/trailer_url"));
3047 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3048 EXPECT_EQ(trailers, client_->response_trailers());
3049}
3050
3051class EndToEndTestServerPush : public EndToEndTest {
3052 protected:
3053 const size_t kNumMaxStreams = 10;
3054
3055 EndToEndTestServerPush() : EndToEndTest() {
fkastenholzd3a1de92019-05-15 07:00:07 -07003056 client_config_.SetMaxIncomingBidirectionalStreamsToSend(kNumMaxStreams);
3057 server_config_.SetMaxIncomingBidirectionalStreamsToSend(kNumMaxStreams);
3058 client_config_.SetMaxIncomingUnidirectionalStreamsToSend(kNumMaxStreams);
3059 server_config_.SetMaxIncomingUnidirectionalStreamsToSend(kNumMaxStreams);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003060 support_server_push_ = true;
3061 }
3062
3063 // Add a request with its response and |num_resources| push resources into
3064 // cache.
3065 // If |resource_size| == 0, response body of push resources use default string
3066 // concatenating with resource url. Otherwise, generate a string of
3067 // |resource_size| as body.
vasilvvc48c8712019-03-11 13:38:16 -07003068 void AddRequestAndResponseWithServerPush(std::string host,
3069 std::string path,
3070 std::string response_body,
3071 std::string* push_urls,
QUICHE teama6ef0a62019-03-07 20:34:33 -05003072 const size_t num_resources,
3073 const size_t resource_size) {
3074 bool use_large_response = resource_size != 0;
vasilvvc48c8712019-03-11 13:38:16 -07003075 std::string large_resource;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003076 if (use_large_response) {
3077 // Generate a response common body larger than flow control window for
3078 // push response.
vasilvvc48c8712019-03-11 13:38:16 -07003079 large_resource = std::string(resource_size, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003080 }
3081 std::list<QuicBackendResponse::ServerPushInfo> push_resources;
3082 for (size_t i = 0; i < num_resources; ++i) {
vasilvvc48c8712019-03-11 13:38:16 -07003083 std::string url = push_urls[i];
QUICHE teama6ef0a62019-03-07 20:34:33 -05003084 QuicUrl resource_url(url);
vasilvvc48c8712019-03-11 13:38:16 -07003085 std::string body =
QUICHE teama6ef0a62019-03-07 20:34:33 -05003086 use_large_response
3087 ? large_resource
3088 : QuicStrCat("This is server push response body for ", url);
3089 SpdyHeaderBlock response_headers;
3090 response_headers[":version"] = "HTTP/1.1";
3091 response_headers[":status"] = "200";
3092 response_headers["content-length"] =
3093 QuicTextUtils::Uint64ToString(body.size());
3094 push_resources.push_back(QuicBackendResponse::ServerPushInfo(
3095 resource_url, std::move(response_headers), kV3LowestPriority, body));
3096 }
3097
3098 memory_cache_backend_.AddSimpleResponseWithServerPushResources(
3099 host, path, 200, response_body, push_resources);
3100 }
3101};
3102
3103// Run all server push end to end tests with all supported versions.
3104INSTANTIATE_TEST_SUITE_P(EndToEndTestsServerPush,
3105 EndToEndTestServerPush,
wubbd64c102019-05-13 11:58:17 -07003106 ::testing::ValuesIn(GetTestParams(false)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003107
3108TEST_P(EndToEndTestServerPush, ServerPush) {
3109 ASSERT_TRUE(Initialize());
3110 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3111
3112 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3113 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3114 SetReorderPercentage(30);
3115
3116 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003117 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003118 size_t kNumResources = 4;
vasilvvc48c8712019-03-11 13:38:16 -07003119 std::string push_urls[] = {"https://example.com/font.woff",
3120 "https://example.com/script.js",
3121 "https://fonts.example.com/font.woff",
3122 "https://example.com/logo-hires.jpg"};
QUICHE teama6ef0a62019-03-07 20:34:33 -05003123 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3124 push_urls, kNumResources, 0);
3125
3126 client_->client()->set_response_listener(
3127 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3128 new TestResponseListener));
3129
3130 QUIC_DVLOG(1) << "send request for /push_example";
3131 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
3132 "https://example.com/push_example"));
renjietang3c3dfb72019-07-26 11:55:52 -07003133 QuicStreamSequencer* sequencer;
3134 if (!VersionUsesQpack(client_->client()
3135 ->client_session()
3136 ->connection()
3137 ->transport_version())) {
fkastenholz7591c282019-08-13 12:58:38 -07003138 QuicHeadersStream* headers_stream =
3139 QuicSpdySessionPeer::GetHeadersStream(GetClientSession());
renjietang3c3dfb72019-07-26 11:55:52 -07003140 sequencer = QuicStreamPeer::sequencer(headers_stream);
3141 // Headers stream's sequencer buffer shouldn't be released because server
3142 // push hasn't finished yet.
3143 EXPECT_TRUE(
3144 QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
3145 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05003146
vasilvvc48c8712019-03-11 13:38:16 -07003147 for (const std::string& url : push_urls) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003148 QUIC_DVLOG(1) << "send request for pushed stream on url " << url;
vasilvvc48c8712019-03-11 13:38:16 -07003149 std::string expected_body =
QUICHE teama6ef0a62019-03-07 20:34:33 -05003150 QuicStrCat("This is server push response body for ", url);
vasilvvc48c8712019-03-11 13:38:16 -07003151 std::string response_body = client_->SendSynchronousRequest(url);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003152 QUIC_DVLOG(1) << "response body " << response_body;
3153 EXPECT_EQ(expected_body, response_body);
3154 }
renjietang3c3dfb72019-07-26 11:55:52 -07003155 if (!VersionUsesQpack(client_->client()
3156 ->client_session()
3157 ->connection()
3158 ->transport_version())) {
3159 EXPECT_FALSE(
3160 QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
3161 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05003162}
3163
3164TEST_P(EndToEndTestServerPush, ServerPushUnderLimit) {
3165 // Tests that sending a request which has 4 push resources will trigger server
3166 // to push those 4 resources and client can handle pushed resources and match
3167 // them with requests later.
3168 ASSERT_TRUE(Initialize());
3169
3170 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3171
3172 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3173 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3174 SetReorderPercentage(30);
3175
3176 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003177 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003178 size_t const kNumResources = 4;
vasilvvc48c8712019-03-11 13:38:16 -07003179 std::string push_urls[] = {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003180 "https://example.com/font.woff",
3181 "https://example.com/script.js",
3182 "https://fonts.example.com/font.woff",
3183 "https://example.com/logo-hires.jpg",
3184 };
3185 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3186 push_urls, kNumResources, 0);
3187 client_->client()->set_response_listener(
3188 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3189 new TestResponseListener));
3190
3191 // Send the first request: this will trigger the server to send all the push
3192 // resources associated with this request, and these will be cached by the
3193 // client.
3194 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
3195 "https://example.com/push_example"));
3196
vasilvvc48c8712019-03-11 13:38:16 -07003197 for (const std::string& url : push_urls) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003198 // Sending subsequent requesets will not actually send anything on the wire,
3199 // as the responses are already in the client's cache.
3200 QUIC_DVLOG(1) << "send request for pushed stream on url " << url;
vasilvvc48c8712019-03-11 13:38:16 -07003201 std::string expected_body =
QUICHE teama6ef0a62019-03-07 20:34:33 -05003202 QuicStrCat("This is server push response body for ", url);
vasilvvc48c8712019-03-11 13:38:16 -07003203 std::string response_body = client_->SendSynchronousRequest(url);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003204 QUIC_DVLOG(1) << "response body " << response_body;
3205 EXPECT_EQ(expected_body, response_body);
3206 }
3207 // Expect only original request has been sent and push responses have been
3208 // received as normal response.
3209 EXPECT_EQ(1u, client_->num_requests());
3210 EXPECT_EQ(1u + kNumResources, client_->num_responses());
3211}
3212
3213TEST_P(EndToEndTestServerPush, ServerPushOverLimitNonBlocking) {
3214 // Tests that when streams are not blocked by flow control or congestion
3215 // control, pushing even more resources than max number of open outgoing
3216 // streams should still work because all response streams get closed
3217 // immediately after pushing resources.
3218 ASSERT_TRUE(Initialize());
3219 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3220
3221 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3222 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3223 SetReorderPercentage(30);
3224
3225 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003226 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003227
3228 // One more resource than max number of outgoing stream of this session.
3229 const size_t kNumResources = 1 + kNumMaxStreams; // 11.
vasilvvc48c8712019-03-11 13:38:16 -07003230 std::string push_urls[11];
QUICHE teama6ef0a62019-03-07 20:34:33 -05003231 for (size_t i = 0; i < kNumResources; ++i) {
3232 push_urls[i] = QuicStrCat("https://example.com/push_resources", i);
3233 }
3234 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3235 push_urls, kNumResources, 0);
3236 client_->client()->set_response_listener(
3237 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3238 new TestResponseListener));
3239
3240 // Send the first request: this will trigger the server to send all the push
3241 // resources associated with this request, and these will be cached by the
3242 // client.
3243 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
3244 "https://example.com/push_example"));
3245
vasilvvc48c8712019-03-11 13:38:16 -07003246 for (const std::string& url : push_urls) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003247 // Sending subsequent requesets will not actually send anything on the wire,
3248 // as the responses are already in the client's cache.
3249 EXPECT_EQ(QuicStrCat("This is server push response body for ", url),
3250 client_->SendSynchronousRequest(url));
3251 }
3252
3253 // Only 1 request should have been sent.
3254 EXPECT_EQ(1u, client_->num_requests());
3255 // The responses to the original request and all the promised resources
3256 // should have been received.
3257 EXPECT_EQ(12u, client_->num_responses());
3258}
3259
3260TEST_P(EndToEndTestServerPush, ServerPushOverLimitWithBlocking) {
3261 // Tests that when server tries to send more large resources(large enough to
3262 // be blocked by flow control window or congestion control window) than max
3263 // open outgoing streams , server can open upto max number of outgoing
3264 // streams for them, and the rest will be queued up.
3265
3266 // Reset flow control windows.
3267 size_t kFlowControlWnd = 20 * 1024; // 20KB.
3268 // Response body is larger than 1 flow controlblock window.
3269 size_t kBodySize = kFlowControlWnd * 2;
3270 set_client_initial_stream_flow_control_receive_window(kFlowControlWnd);
3271 // Make sure conntection level flow control window is large enough not to
3272 // block data being sent out though they will be blocked by stream level one.
3273 set_client_initial_session_flow_control_receive_window(
3274 kBodySize * kNumMaxStreams + 1024);
3275
3276 ASSERT_TRUE(Initialize());
3277 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3278
3279 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3280 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3281 SetReorderPercentage(30);
3282
3283 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003284 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003285
3286 const size_t kNumResources = kNumMaxStreams + 1;
vasilvvc48c8712019-03-11 13:38:16 -07003287 std::string push_urls[11];
QUICHE teama6ef0a62019-03-07 20:34:33 -05003288 for (size_t i = 0; i < kNumResources; ++i) {
3289 push_urls[i] = QuicStrCat("http://example.com/push_resources", i);
3290 }
3291 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3292 push_urls, kNumResources, kBodySize);
3293
3294 client_->client()->set_response_listener(
3295 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3296 new TestResponseListener));
3297
3298 client_->SendRequest("https://example.com/push_example");
3299
3300 // Pause after the first response arrives.
3301 while (!client_->response_complete()) {
3302 // Because of priority, the first response arrived should be to original
3303 // request.
3304 client_->WaitForResponse();
3305 }
3306
3307 // Check server session to see if it has max number of outgoing streams opened
3308 // though more resources need to be pushed.
3309 server_thread_->Pause();
3310 EXPECT_EQ(kNumMaxStreams, GetServerSession()->GetNumOpenOutgoingStreams());
3311 server_thread_->Resume();
3312
3313 EXPECT_EQ(1u, client_->num_requests());
3314 EXPECT_EQ(1u, client_->num_responses());
3315 EXPECT_EQ(kBody, client_->response_body());
3316
3317 // "Send" request for a promised resources will not really send out it because
3318 // its response is being pushed(but blocked). And the following ack and
3319 // flow control behavior of SendSynchronousRequests()
3320 // will unblock the stream to finish receiving response.
3321 client_->SendSynchronousRequest(push_urls[0]);
3322 EXPECT_EQ(1u, client_->num_requests());
3323 EXPECT_EQ(2u, client_->num_responses());
3324
3325 // Do same thing for the rest 10 resources.
3326 for (size_t i = 1; i < kNumResources; ++i) {
3327 client_->SendSynchronousRequest(push_urls[i]);
3328 }
3329
3330 // Because of server push, client gets all pushed resources without actually
3331 // sending requests for them.
3332 EXPECT_EQ(1u, client_->num_requests());
3333 // Including response to original request, 12 responses in total were
3334 // received.
3335 EXPECT_EQ(12u, client_->num_responses());
3336}
3337
3338// TODO(fayang): this test seems to cause net_unittests timeouts :|
3339TEST_P(EndToEndTest, DISABLED_TestHugePostWithPacketLoss) {
3340 // This test tests a huge post with introduced packet loss from client to
3341 // server and body size greater than 4GB, making sure QUIC code does not break
3342 // for 32-bit builds.
3343 ServerStreamThatDropsBodyFactory stream_factory;
3344 SetSpdyStreamFactory(&stream_factory);
3345 ASSERT_TRUE(Initialize());
3346 // Set client's epoll server's time out to 0 to make this test be finished
3347 // within a short time.
3348 client_->epoll_server()->set_timeout_in_us(0);
3349
3350 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3351 SetPacketLossPercentage(1);
3352 // To avoid storing the whole request body in memory, use a loop to repeatedly
3353 // send body size of kSizeBytes until the whole request body size is reached.
3354 const int kSizeBytes = 128 * 1024;
3355 // Request body size is 4G plus one more kSizeBytes.
3356 int64_t request_body_size_bytes = pow(2, 32) + kSizeBytes;
3357 ASSERT_LT(INT64_C(4294967296), request_body_size_bytes);
vasilvvc48c8712019-03-11 13:38:16 -07003358 std::string body(kSizeBytes, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003359
3360 SpdyHeaderBlock headers;
3361 headers[":method"] = "POST";
3362 headers[":path"] = "/foo";
3363 headers[":scheme"] = "https";
3364 headers[":authority"] = server_hostname_;
3365 headers["content-length"] =
3366 QuicTextUtils::Uint64ToString(request_body_size_bytes);
3367
3368 client_->SendMessage(headers, "", /*fin=*/false);
3369
3370 for (int i = 0; i < request_body_size_bytes / kSizeBytes; ++i) {
3371 bool fin = (i == request_body_size_bytes - 1);
vasilvvc48c8712019-03-11 13:38:16 -07003372 client_->SendData(std::string(body.data(), kSizeBytes), fin);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003373 client_->client()->WaitForEvents();
3374 }
3375 VerifyCleanConnection(true);
3376}
3377
3378// TODO(fayang): this test seems to cause net_unittests timeouts :|
3379TEST_P(EndToEndTest, DISABLED_TestHugeResponseWithPacketLoss) {
3380 // This test tests a huge response with introduced loss from server to client
3381 // and body size greater than 4GB, making sure QUIC code does not break for
3382 // 32-bit builds.
3383 const int kSizeBytes = 128 * 1024;
3384 int64_t response_body_size_bytes = pow(2, 32) + kSizeBytes;
3385 ASSERT_LT(4294967296, response_body_size_bytes);
3386 ServerStreamThatSendsHugeResponseFactory stream_factory(
3387 response_body_size_bytes);
3388 SetSpdyStreamFactory(&stream_factory);
3389
3390 StartServer();
3391
3392 // Use a quic client that drops received body.
3393 QuicTestClient* client =
3394 new QuicTestClient(server_address_, server_hostname_, client_config_,
3395 client_supported_versions_);
3396 client->client()->set_drop_response_body(true);
3397 client->UseWriter(client_writer_);
3398 client->Connect();
3399 client_.reset(client);
3400 static QuicEpollEvent event(EPOLLOUT);
3401 client_writer_->Initialize(
fkastenholz7591c282019-08-13 12:58:38 -07003402 QuicConnectionPeer::GetHelper(GetClientConnection()),
3403 QuicConnectionPeer::GetAlarmFactory(GetClientConnection()),
QUICHE teama6ef0a62019-03-07 20:34:33 -05003404 QuicMakeUnique<ClientDelegate>(client_->client()));
3405 initialized_ = true;
3406 ASSERT_TRUE(client_->client()->connected());
3407
3408 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3409 SetPacketLossPercentage(1);
3410 client_->SendRequest("/huge_response");
3411 client_->WaitForResponse();
wubbd64c102019-05-13 11:58:17 -07003412 VerifyCleanConnection(true);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003413}
3414
3415// Regression test for b/111515567
3416TEST_P(EndToEndTest, AgreeOnStopWaiting) {
3417 ASSERT_TRUE(Initialize());
3418 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3419
fkastenholz7591c282019-08-13 12:58:38 -07003420 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003421 server_thread_->Pause();
3422 QuicConnection* server_connection = GetServerConnection();
3423 // Verify client and server connections agree on the value of
3424 // no_stop_waiting_frames.
3425 EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
3426 QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
3427 server_thread_->Resume();
3428}
3429
3430// Regression test for b/111515567
3431TEST_P(EndToEndTest, AgreeOnStopWaitingWithNoStopWaitingOption) {
3432 QuicTagVector options;
3433 options.push_back(kNSTP);
3434 client_config_.SetConnectionOptionsToSend(options);
3435 ASSERT_TRUE(Initialize());
3436 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3437
fkastenholz7591c282019-08-13 12:58:38 -07003438 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003439 server_thread_->Pause();
3440 QuicConnection* server_connection = GetServerConnection();
3441 // Verify client and server connections agree on the value of
3442 // no_stop_waiting_frames.
3443 EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
3444 QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
3445 server_thread_->Resume();
3446}
3447
3448TEST_P(EndToEndTest, ReleaseHeadersStreamBufferWhenIdle) {
3449 // Tests that when client side has no active request and no waiting
3450 // PUSH_PROMISE, its headers stream's sequencer buffer should be released.
3451 ASSERT_TRUE(Initialize());
3452 client_->SendSynchronousRequest("/foo");
renjietang118c8ac2019-07-30 11:43:59 -07003453 if (VersionUsesQpack(client_->client()
3454 ->client_session()
3455 ->connection()
3456 ->transport_version())) {
3457 return;
3458 }
fkastenholz7591c282019-08-13 12:58:38 -07003459 QuicHeadersStream* headers_stream =
3460 QuicSpdySessionPeer::GetHeadersStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003461 QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
3462 EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
3463}
3464
3465TEST_P(EndToEndTest, WayTooLongRequestHeaders) {
3466 ASSERT_TRUE(Initialize());
3467 SpdyHeaderBlock headers;
3468 headers[":method"] = "GET";
3469 headers[":path"] = "/foo";
3470 headers[":scheme"] = "https";
3471 headers[":authority"] = server_hostname_;
vasilvvc48c8712019-03-11 13:38:16 -07003472 headers["key"] = std::string(64 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003473
3474 client_->SendMessage(headers, "");
3475 client_->WaitForResponse();
3476 EXPECT_EQ(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
3477 client_->connection_error());
3478}
3479
3480class WindowUpdateObserver : public QuicConnectionDebugVisitor {
3481 public:
3482 WindowUpdateObserver() : num_window_update_frames_(0), num_ping_frames_(0) {}
3483
3484 size_t num_window_update_frames() const { return num_window_update_frames_; }
3485
3486 size_t num_ping_frames() const { return num_ping_frames_; }
3487
dschinazi17d42422019-06-18 16:35:07 -07003488 void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/,
3489 const QuicTime& /*receive_time*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003490 ++num_window_update_frames_;
3491 }
3492
dschinazi17d42422019-06-18 16:35:07 -07003493 void OnPingFrame(const QuicPingFrame& /*frame*/) override {
3494 ++num_ping_frames_;
3495 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05003496
3497 private:
3498 size_t num_window_update_frames_;
3499 size_t num_ping_frames_;
3500};
3501
3502TEST_P(EndToEndTest, WindowUpdateInAck) {
3503 ASSERT_TRUE(Initialize());
3504 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3505 WindowUpdateObserver observer;
fkastenholz7591c282019-08-13 12:58:38 -07003506 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003507 client_connection->set_debug_visitor(&observer);
3508 // 100KB body.
vasilvvc48c8712019-03-11 13:38:16 -07003509 std::string body(100 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003510 SpdyHeaderBlock headers;
3511 headers[":method"] = "POST";
3512 headers[":path"] = "/foo";
3513 headers[":scheme"] = "https";
3514 headers[":authority"] = server_hostname_;
3515
3516 EXPECT_EQ(kFooResponseBody,
3517 client_->SendCustomSynchronousRequest(headers, body));
3518 client_->Disconnect();
3519 EXPECT_LT(0u, observer.num_window_update_frames());
3520 EXPECT_EQ(0u, observer.num_ping_frames());
3521}
3522
dschinazi4e3e6572019-08-02 12:57:17 -07003523TEST_P(EndToEndTestWithTls, SendStatelessResetTokenInShlo) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003524 ASSERT_TRUE(Initialize());
3525 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3526 QuicConfig* config = client_->client()->session()->config();
3527 EXPECT_TRUE(config->HasReceivedStatelessResetToken());
3528 EXPECT_EQ(QuicUtils::GenerateStatelessResetToken(
3529 client_->client()->session()->connection()->connection_id()),
3530 config->ReceivedStatelessResetToken());
3531 client_->Disconnect();
3532}
3533
3534// Regression test for b/116200989.
3535TEST_P(EndToEndTest,
3536 SendStatelessResetIfServerConnectionClosedLocallyDuringHandshake) {
3537 connect_to_server_on_initialize_ = false;
3538 ASSERT_TRUE(Initialize());
3539
3540 server_thread_->Pause();
3541 QuicDispatcher* dispatcher =
3542 QuicServerPeer::GetDispatcher(server_thread_->server());
3543 ASSERT_EQ(0u, dispatcher->session_map().size());
3544 // Note: this writer will only used by the server connection, not the time
3545 // wait list.
3546 QuicDispatcherPeer::UseWriter(
3547 dispatcher,
3548 // This cause the first server-sent packet, a.k.a REJ, to fail.
3549 new BadPacketWriter(/*packet_causing_write_error=*/0, EPERM));
3550 server_thread_->Resume();
3551
3552 client_.reset(CreateQuicClient(client_writer_));
3553 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
fayang51c23732019-06-24 06:59:55 -07003554 EXPECT_EQ(QUIC_HANDSHAKE_FAILED, client_->connection_error());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003555}
3556
3557// Regression test for b/116200989.
3558TEST_P(EndToEndTest,
3559 SendStatelessResetIfServerConnectionClosedLocallyAfterHandshake) {
3560 // Prevent the connection from expiring in the time wait list.
dschinazi552accc2019-06-17 17:07:34 -07003561 SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003562 connect_to_server_on_initialize_ = false;
3563 ASSERT_TRUE(Initialize());
3564
3565 // big_response_body is 64K, which is about 48 full-sized packets.
3566 const size_t kBigResponseBodySize = 65536;
3567 QuicData big_response_body(new char[kBigResponseBodySize](),
3568 kBigResponseBodySize, /*owns_buffer=*/true);
3569 AddToCache("/big_response", 200, big_response_body.AsStringPiece());
3570
3571 server_thread_->Pause();
3572 QuicDispatcher* dispatcher =
3573 QuicServerPeer::GetDispatcher(server_thread_->server());
3574 ASSERT_EQ(0u, dispatcher->session_map().size());
3575 QuicDispatcherPeer::UseWriter(
3576 dispatcher,
3577 // This will cause an server write error with EPERM, while sending the
3578 // response for /big_response.
3579 new BadPacketWriter(/*packet_causing_write_error=*/20, EPERM));
3580 server_thread_->Resume();
3581
3582 client_.reset(CreateQuicClient(client_writer_));
3583
3584 // First, a /foo request with small response should succeed.
3585 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3586 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3587
3588 // Second, a /big_response request with big response should fail.
3589 EXPECT_LT(client_->SendSynchronousRequest("/big_response").length(),
3590 kBigResponseBodySize);
3591 EXPECT_EQ(QUIC_PUBLIC_RESET, client_->connection_error());
3592}
3593
3594// Regression test of b/70782529.
3595TEST_P(EndToEndTest, DoNotCrashOnPacketWriteError) {
3596 ASSERT_TRUE(Initialize());
3597 BadPacketWriter* bad_writer =
3598 new BadPacketWriter(/*packet_causing_write_error=*/5,
3599 /*error_code=*/90);
3600 std::unique_ptr<QuicTestClient> client(CreateQuicClient(bad_writer));
3601
3602 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07003603 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003604 SpdyHeaderBlock headers;
3605 headers[":method"] = "POST";
3606 headers[":path"] = "/foo";
3607 headers[":scheme"] = "https";
3608 headers[":authority"] = server_hostname_;
3609
3610 client->SendCustomSynchronousRequest(headers, body);
3611}
3612
3613// Regression test for b/71711996. This test sends a connectivity probing packet
3614// as its last sent packet, and makes sure the server's ACK of that packet does
3615// not cause the client to fail.
3616TEST_P(EndToEndTest, LastPacketSentIsConnectivityProbing) {
3617 ASSERT_TRUE(Initialize());
3618
3619 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3620 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3621
3622 // Wait for the client's ACK (of the response) to be received by the server.
3623 client_->WaitForDelayedAcks();
3624
3625 // We are sending a connectivity probing packet from an unchanged client
3626 // address, so the server will not respond to us with a connectivity probing
3627 // packet, however the server should send an ack-only packet to us.
3628 client_->SendConnectivityProbing();
3629
3630 // Wait for the server's last ACK to be received by the client.
3631 client_->WaitForDelayedAcks();
3632}
3633
3634TEST_P(EndToEndTest, PreSharedKey) {
3635 client_config_.set_max_time_before_crypto_handshake(
3636 QuicTime::Delta::FromSeconds(1));
3637 client_config_.set_max_idle_time_before_crypto_handshake(
3638 QuicTime::Delta::FromSeconds(1));
3639 pre_shared_key_client_ = "foobar";
3640 pre_shared_key_server_ = "foobar";
3641 ASSERT_TRUE(Initialize());
3642
3643 ASSERT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3644 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3645}
3646
3647// TODO: reenable once we have a way to make this run faster.
3648TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyMismatch)) {
3649 client_config_.set_max_time_before_crypto_handshake(
3650 QuicTime::Delta::FromSeconds(1));
3651 client_config_.set_max_idle_time_before_crypto_handshake(
3652 QuicTime::Delta::FromSeconds(1));
3653 pre_shared_key_client_ = "foo";
3654 pre_shared_key_server_ = "bar";
3655 // One of two things happens when Initialize() returns:
3656 // 1. Crypto handshake has completed, and it is unsuccessful. Initialize()
3657 // returns false.
3658 // 2. Crypto handshake has not completed, Initialize() returns true. The call
3659 // to WaitForCryptoHandshakeConfirmed() will wait for the handshake and
3660 // return whether it is successful.
3661 ASSERT_FALSE(Initialize() &&
3662 client_->client()->WaitForCryptoHandshakeConfirmed());
3663 EXPECT_EQ(QUIC_HANDSHAKE_TIMEOUT, client_->connection_error());
3664}
3665
3666// TODO: reenable once we have a way to make this run faster.
3667TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoClient)) {
3668 client_config_.set_max_time_before_crypto_handshake(
3669 QuicTime::Delta::FromSeconds(1));
3670 client_config_.set_max_idle_time_before_crypto_handshake(
3671 QuicTime::Delta::FromSeconds(1));
3672 pre_shared_key_server_ = "foobar";
3673 ASSERT_FALSE(Initialize() &&
3674 client_->client()->WaitForCryptoHandshakeConfirmed());
3675 EXPECT_EQ(QUIC_HANDSHAKE_TIMEOUT, client_->connection_error());
3676}
3677
3678// TODO: reenable once we have a way to make this run faster.
3679TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoServer)) {
3680 client_config_.set_max_time_before_crypto_handshake(
3681 QuicTime::Delta::FromSeconds(1));
3682 client_config_.set_max_idle_time_before_crypto_handshake(
3683 QuicTime::Delta::FromSeconds(1));
3684 pre_shared_key_client_ = "foobar";
3685 ASSERT_FALSE(Initialize() &&
3686 client_->client()->WaitForCryptoHandshakeConfirmed());
3687 EXPECT_EQ(QUIC_HANDSHAKE_TIMEOUT, client_->connection_error());
3688}
3689
3690TEST_P(EndToEndTest, RequestAndStreamRstInOnePacket) {
3691 // Regression test for b/80234898.
3692 ASSERT_TRUE(Initialize());
3693
3694 // INCOMPLETE_RESPONSE will cause the server to not to send the trailer
3695 // (and the FIN) after the response body.
vasilvvc48c8712019-03-11 13:38:16 -07003696 std::string response_body(1305, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003697 SpdyHeaderBlock response_headers;
3698 response_headers[":status"] = QuicTextUtils::Uint64ToString(200);
3699 response_headers["content-length"] =
3700 QuicTextUtils::Uint64ToString(response_body.length());
3701 memory_cache_backend_.AddSpecialResponse(
3702 server_hostname_, "/test_url", std::move(response_headers), response_body,
3703 QuicBackendResponse::INCOMPLETE_RESPONSE);
3704
3705 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3706 client_->WaitForDelayedAcks();
3707
fkastenholz7591c282019-08-13 12:58:38 -07003708 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003709 const QuicPacketCount packets_sent_before =
3710 session->connection()->GetStats().packets_sent;
3711
3712 client_->SendRequestAndRstTogether("/test_url");
3713
3714 // Expect exactly one packet is sent from the block above.
3715 ASSERT_EQ(packets_sent_before + 1,
3716 session->connection()->GetStats().packets_sent);
3717
3718 // Wait for the connection to become idle.
3719 client_->WaitForDelayedAcks();
3720
3721 // The real expectation is the test does not crash or timeout.
3722 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
3723}
3724
3725TEST_P(EndToEndTest, ResetStreamOnTtlExpires) {
3726 ASSERT_TRUE(Initialize());
3727 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
fkastenholz7591c282019-08-13 12:58:38 -07003728 if (!GetClientSession()->session_decides_what_to_write()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003729 return;
3730 }
3731 SetPacketLossPercentage(30);
3732
3733 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
3734 // Set a TTL which expires immediately.
3735 stream->MaybeSetTtl(QuicTime::Delta::FromMicroseconds(1));
3736
bnc519216c2019-07-09 05:03:48 -07003737 WriteHeadersOnStream(stream);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003738 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07003739 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003740 stream->WriteOrBufferBody(body, true);
3741 client_->WaitForResponse();
3742 EXPECT_EQ(QUIC_STREAM_TTL_EXPIRED, client_->stream_error());
3743}
3744
3745TEST_P(EndToEndTest, SendMessages) {
3746 ASSERT_TRUE(Initialize());
3747 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
fkastenholz7591c282019-08-13 12:58:38 -07003748 QuicSession* client_session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003749 QuicConnection* client_connection = client_session->connection();
fayangd4291e42019-05-30 10:31:21 -07003750 if (!VersionSupportsMessageFrames(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003751 return;
3752 }
3753
3754 SetPacketLossPercentage(30);
dschinazi66dea072019-04-09 11:41:06 -07003755 ASSERT_GT(kMaxOutgoingPacketSize,
3756 client_session->GetCurrentLargestMessagePayload());
ianswettb239f862019-04-05 09:15:06 -07003757 ASSERT_LT(0, client_session->GetCurrentLargestMessagePayload());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003758
dschinazi66dea072019-04-09 11:41:06 -07003759 std::string message_string(kMaxOutgoingPacketSize, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003760 QuicStringPiece message_buffer(message_string);
3761 QuicRandom* random =
3762 QuicConnectionPeer::GetHelper(client_connection)->GetRandomGenerator();
3763 QuicMemSliceStorage storage(nullptr, 0, nullptr, 0);
3764 {
fayanga4b37b22019-06-18 13:37:47 -07003765 QuicConnection::ScopedPacketFlusher flusher(client_session->connection());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003766 // Verify the largest message gets successfully sent.
ianswettb239f862019-04-05 09:15:06 -07003767 EXPECT_EQ(
3768 MessageResult(MESSAGE_STATUS_SUCCESS, 1),
3769 client_session->SendMessage(MakeSpan(
3770 client_session->connection()
3771 ->helper()
3772 ->GetStreamSendBufferAllocator(),
3773 QuicStringPiece(message_buffer.data(),
3774 client_session->GetCurrentLargestMessagePayload()),
3775 &storage)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003776 // Send more messages with size (0, largest_payload] until connection is
3777 // write blocked.
3778 const int kTestMaxNumberOfMessages = 100;
3779 for (size_t i = 2; i <= kTestMaxNumberOfMessages; ++i) {
3780 size_t message_length =
ianswettb239f862019-04-05 09:15:06 -07003781 random->RandUint64() %
3782 client_session->GetCurrentLargestMessagePayload() +
3783 1;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003784 MessageResult result = client_session->SendMessage(MakeSpan(
3785 client_session->connection()
3786 ->helper()
3787 ->GetStreamSendBufferAllocator(),
3788 QuicStringPiece(message_buffer.data(), message_length), &storage));
3789 if (result.status == MESSAGE_STATUS_BLOCKED) {
3790 // Connection is write blocked.
3791 break;
3792 }
3793 EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, i), result);
3794 }
3795 }
3796
3797 client_->WaitForDelayedAcks();
ianswettb239f862019-04-05 09:15:06 -07003798 EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
3799 client_session
3800 ->SendMessage(MakeSpan(
3801 client_session->connection()
3802 ->helper()
3803 ->GetStreamSendBufferAllocator(),
3804 QuicStringPiece(
3805 message_buffer.data(),
3806 client_session->GetCurrentLargestMessagePayload() + 1),
3807 &storage))
3808 .status);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003809 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
3810}
3811
3812class EndToEndPacketReorderingTest : public EndToEndTest {
3813 public:
3814 void CreateClientWithWriter() override {
3815 QUIC_LOG(ERROR) << "create client with reorder_writer_";
3816 reorder_writer_ = new PacketReorderingWriter();
3817 client_.reset(EndToEndTest::CreateQuicClient(reorder_writer_));
3818 }
3819
3820 void SetUp() override {
3821 // Don't initialize client writer in base class.
3822 server_writer_ = new PacketDroppingTestWriter();
3823 }
3824
3825 protected:
3826 PacketReorderingWriter* reorder_writer_;
3827};
3828
3829INSTANTIATE_TEST_SUITE_P(EndToEndPacketReorderingTests,
3830 EndToEndPacketReorderingTest,
wubbd64c102019-05-13 11:58:17 -07003831 testing::ValuesIn(GetTestParams(false)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003832
3833TEST_P(EndToEndPacketReorderingTest, ReorderedConnectivityProbing) {
3834 ASSERT_TRUE(Initialize());
3835
3836 // Finish one request to make sure handshake established.
3837 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3838
3839 // Wait for the connection to become idle, to make sure the packet gets
3840 // delayed is the connectivity probing packet.
3841 client_->WaitForDelayedAcks();
3842
3843 QuicSocketAddress old_addr =
3844 client_->client()->network_helper()->GetLatestClientAddress();
3845
3846 // Migrate socket to the new IP address.
3847 QuicIpAddress new_host = TestLoopback(2);
3848 EXPECT_NE(old_addr.host(), new_host);
3849 ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
3850
3851 // Write a connectivity probing after the next /foo request.
3852 reorder_writer_->SetDelay(1);
3853 client_->SendConnectivityProbing();
3854
3855 ASSERT_TRUE(client_->MigrateSocketWithSpecifiedPort(old_addr.host(),
3856 old_addr.port()));
3857
3858 // The (delayed) connectivity probing will be sent after this request.
3859 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3860
3861 // Send yet another request after the connectivity probing, when this request
3862 // returns, the probing is guaranteed to have been received by the server, and
3863 // the server's response to probing is guaranteed to have been received by the
3864 // client.
3865 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3866
3867 server_thread_->Pause();
3868 QuicConnection* server_connection = GetServerConnection();
3869 EXPECT_EQ(1u,
3870 server_connection->GetStats().num_connectivity_probing_received);
3871 server_thread_->Resume();
3872
fkastenholz7591c282019-08-13 12:58:38 -07003873 EXPECT_EQ(
3874 1u, GetClientConnection()->GetStats().num_connectivity_probing_received);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003875}
3876
3877TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
3878 ASSERT_TRUE(Initialize());
3879 // Finish one request to make sure handshake established.
3880 client_->SendSynchronousRequest("/foo");
3881 // Disconnect for next 0-rtt request.
3882 client_->Disconnect();
3883
3884 // Client get valid STK now. Do a 0-rtt request.
3885 // Buffer a CHLO till another packets sent out.
3886 reorder_writer_->SetDelay(1);
3887 // Only send out a CHLO.
3888 client_->client()->Initialize();
3889 client_->client()->StartConnect();
3890 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3891 ASSERT_TRUE(client_->client()->connected());
3892
3893 // Send a request before handshake finishes.
3894 SpdyHeaderBlock headers;
3895 headers[":method"] = "POST";
3896 headers[":path"] = "/bar";
3897 headers[":scheme"] = "https";
3898 headers[":authority"] = server_hostname_;
3899
3900 client_->SendMessage(headers, "");
3901 client_->WaitForResponse();
3902 EXPECT_EQ(kBarResponseBody, client_->response_body());
fkastenholz7591c282019-08-13 12:58:38 -07003903 QuicConnectionStats client_stats = GetClientConnection()->GetStats();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003904 EXPECT_EQ(0u, client_stats.packets_lost);
3905 if (ServerSendsVersionNegotiation()) {
3906 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
3907 } else {
3908 EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
3909 }
3910}
3911
3912// Test that STOP_SENDING makes it to the other side. Set up a client & server,
3913// create a stream (do not close it), and then send a STOP_SENDING from one
3914// side. The other side should get a call to QuicStream::OnStopSending.
3915// (aside, test cribbed from RequestAndStreamRstInOnePacket)
3916TEST_P(EndToEndTest, SimpleStopSendingTest) {
3917 const uint16_t kStopSendingTestCode = 123;
3918 ASSERT_TRUE(Initialize());
fkastenholz305e1732019-06-18 05:01:22 -07003919 if (!VersionHasIetfQuicFrames(negotiated_version_.transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003920 return;
3921 }
fkastenholz7591c282019-08-13 12:58:38 -07003922 QuicSession* client_session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003923 ASSERT_NE(nullptr, client_session);
3924 QuicConnection* client_connection = client_session->connection();
3925 ASSERT_NE(nullptr, client_connection);
3926
3927 // STOP_SENDING will cause the server to not to send the trailer
3928 // (and the FIN) after the response body. Instead, it sends a STOP_SENDING
3929 // frame for the stream.
vasilvvc48c8712019-03-11 13:38:16 -07003930 std::string response_body(1305, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003931 SpdyHeaderBlock response_headers;
3932 response_headers[":status"] = QuicTextUtils::Uint64ToString(200);
3933 response_headers["content-length"] =
3934 QuicTextUtils::Uint64ToString(response_body.length());
3935 memory_cache_backend_.AddStopSendingResponse(
3936 server_hostname_, "/test_url", std::move(response_headers), response_body,
3937 kStopSendingTestCode);
3938
3939 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3940 client_->WaitForDelayedAcks();
3941
fkastenholz7591c282019-08-13 12:58:38 -07003942 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003943 const QuicPacketCount packets_sent_before =
3944 session->connection()->GetStats().packets_sent;
3945
3946 QuicStreamId stream_id = session->next_outgoing_bidirectional_stream_id();
3947 client_->SendRequest("/test_url");
3948
3949 // Expect exactly one packet is sent from the block above.
3950 ASSERT_EQ(packets_sent_before + 1,
3951 session->connection()->GetStats().packets_sent);
3952
3953 // Wait for the connection to become idle.
3954 client_->WaitForDelayedAcks();
3955
3956 // The real expectation is the test does not crash or timeout.
3957 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
3958 // And that the stop-sending code is received.
3959 QuicSimpleClientStream* client_stream =
3960 static_cast<QuicSimpleClientStream*>(client_->latest_created_stream());
3961 ASSERT_NE(nullptr, client_stream);
3962 // Make sure we have the correct stream
3963 EXPECT_EQ(stream_id, client_stream->id());
3964 EXPECT_EQ(kStopSendingTestCode, client_stream->last_stop_sending_code());
3965}
3966
3967TEST_P(EndToEndTest, SimpleStopSendingRstStreamTest) {
3968 ASSERT_TRUE(Initialize());
3969
3970 // Send a request without a fin, to keep the stream open
3971 SpdyHeaderBlock headers;
3972 headers[":method"] = "POST";
3973 headers[":path"] = "/foo";
3974 headers[":scheme"] = "https";
3975 headers[":authority"] = server_hostname_;
3976 client_->SendMessage(headers, "", /*fin=*/false);
3977 // Stream should be open
3978 ASSERT_NE(nullptr, client_->latest_created_stream());
bncc7d9e0c2019-04-16 10:22:15 -07003979 EXPECT_FALSE(client_->latest_created_stream()->write_side_closed());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003980 EXPECT_FALSE(
3981 QuicStreamPeer::read_side_closed(client_->latest_created_stream()));
3982
3983 // Send a RST_STREAM+STOP_SENDING on the stream
3984 // Code is not important.
3985 client_->latest_created_stream()->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
3986 client_->WaitForResponse();
3987
3988 // Stream should be gone.
3989 ASSERT_EQ(nullptr, client_->latest_created_stream());
3990}
3991
3992class BadShloPacketWriter : public QuicPacketWriterWrapper {
3993 public:
3994 BadShloPacketWriter() : error_returned_(false) {}
3995 ~BadShloPacketWriter() override {}
3996
3997 WriteResult WritePacket(const char* buffer,
3998 size_t buf_len,
3999 const QuicIpAddress& self_address,
4000 const QuicSocketAddress& peer_address,
4001 quic::PerPacketOptions* options) override {
4002 const WriteResult result = QuicPacketWriterWrapper::WritePacket(
4003 buffer, buf_len, self_address, peer_address, options);
4004 const uint8_t type_byte = buffer[0];
4005 if (!error_returned_ && (type_byte & FLAGS_LONG_HEADER) &&
4006 (((type_byte & 0x30) >> 4) == 1 || (type_byte & 0x7F) == 0x7C)) {
4007 QUIC_DVLOG(1) << "Return write error for ZERO_RTT_PACKET";
4008 error_returned_ = true;
4009 return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
4010 }
4011 return result;
4012 }
4013
4014 private:
4015 bool error_returned_;
4016};
4017
4018TEST_P(EndToEndTest, ZeroRttProtectedConnectionClose) {
4019 // This test ensures ZERO_RTT_PROTECTED connection close could close a client
4020 // which has switched to forward secure.
4021 connect_to_server_on_initialize_ =
fayangd4291e42019-05-30 10:31:21 -07004022 !VersionHasIetfInvariantHeader(negotiated_version_.transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -05004023 ASSERT_TRUE(Initialize());
fayangd4291e42019-05-30 10:31:21 -07004024 if (!VersionHasIetfInvariantHeader(negotiated_version_.transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05004025 // Only runs for IETF QUIC header.
4026 return;
4027 }
4028 server_thread_->Pause();
4029 QuicDispatcher* dispatcher =
4030 QuicServerPeer::GetDispatcher(server_thread_->server());
4031 ASSERT_EQ(0u, dispatcher->session_map().size());
4032 // Note: this writer will only used by the server connection, not the time
4033 // wait list.
4034 QuicDispatcherPeer::UseWriter(
4035 dispatcher,
4036 // This causes the first server sent ZERO_RTT_PROTECTED packet (i.e.,
4037 // SHLO) to be sent, but WRITE_ERROR is returned. Such that a
4038 // ZERO_RTT_PROTECTED connection close would be sent to a client with
4039 // encryption level FORWARD_SECURE.
4040 new BadShloPacketWriter());
4041 server_thread_->Resume();
4042
4043 client_.reset(CreateQuicClient(client_writer_));
4044 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
4045 // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
4046 // client which switches to FORWARD_SECURE.
4047 EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, client_->connection_error());
4048}
4049
4050class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
4051 public:
4052 BadShloPacketWriter2() : error_returned_(false) {}
4053 ~BadShloPacketWriter2() override {}
4054
4055 WriteResult WritePacket(const char* buffer,
4056 size_t buf_len,
4057 const QuicIpAddress& self_address,
4058 const QuicSocketAddress& peer_address,
4059 quic::PerPacketOptions* options) override {
4060 const uint8_t type_byte = buffer[0];
4061 if ((type_byte & FLAGS_LONG_HEADER) &&
4062 (((type_byte & 0x30) >> 4) == 1 || (type_byte & 0x7F) == 0x7C)) {
4063 QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
4064 return WriteResult(WRITE_STATUS_OK, buf_len);
4065 }
4066 if (!error_returned_ && !(type_byte & FLAGS_LONG_HEADER)) {
4067 QUIC_DVLOG(1) << "Return write error for short header packet";
4068 error_returned_ = true;
4069 return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
4070 }
4071 return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
4072 peer_address, options);
4073 }
4074
4075 private:
4076 bool error_returned_;
4077};
4078
4079TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
4080 // This test ensures ZERO_RTT_PROTECTED connection close is sent to a client
4081 // which has ZERO_RTT_PROTECTED encryption level.
QUICHE teama6ef0a62019-03-07 20:34:33 -05004082 connect_to_server_on_initialize_ =
fayangd4291e42019-05-30 10:31:21 -07004083 !VersionHasIetfInvariantHeader(negotiated_version_.transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -05004084 ASSERT_TRUE(Initialize());
fayangd4291e42019-05-30 10:31:21 -07004085 if (!VersionHasIetfInvariantHeader(negotiated_version_.transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05004086 // Only runs for IETF QUIC header.
4087 return;
4088 }
4089 server_thread_->Pause();
4090 QuicDispatcher* dispatcher =
4091 QuicServerPeer::GetDispatcher(server_thread_->server());
4092 ASSERT_EQ(0u, dispatcher->session_map().size());
4093 // Note: this writer will only used by the server connection, not the time
4094 // wait list.
4095 QuicDispatcherPeer::UseWriter(
4096 dispatcher,
4097 // This causes the all server sent ZERO_RTT_PROTECTED packets to be
4098 // dropped, and first short header packet causes write error.
4099 new BadShloPacketWriter2());
4100 server_thread_->Resume();
4101 client_.reset(CreateQuicClient(client_writer_));
4102 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
4103 // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
4104 // client.
4105 EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, client_->connection_error());
4106}
4107
fkastenholz3c4eabf2019-04-22 07:49:59 -07004108// Test that the stream id manager closes the connection if a stream
4109// in excess of the allowed maximum.
4110TEST_P(EndToEndTest, TooBigStreamIdClosesConnection) {
4111 // Has to be before version test, see EndToEndTest::TearDown()
4112 ASSERT_TRUE(Initialize());
fkastenholz305e1732019-06-18 05:01:22 -07004113 if (!VersionHasIetfQuicFrames(negotiated_version_.transport_version)) {
fkastenholz3c4eabf2019-04-22 07:49:59 -07004114 // Only runs for IETF QUIC.
4115 return;
4116 }
4117 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
4118
4119 std::string body(kMaxOutgoingPacketSize, 'a');
4120 SpdyHeaderBlock headers;
4121 headers[":method"] = "POST";
4122 headers[":path"] = "/foo";
4123 headers[":scheme"] = "https";
4124 headers[":authority"] = server_hostname_;
4125
4126 // Force the client to write with a stream ID that exceeds the limit.
fkastenholz7591c282019-08-13 12:58:38 -07004127 QuicSpdySession* session = GetClientSession();
fkastenholz3c4eabf2019-04-22 07:49:59 -07004128 QuicStreamIdManager* stream_id_manager =
4129 QuicSessionPeer::v99_bidirectional_stream_id_manager(session);
4130 QuicStreamCount max_number_of_streams =
4131 stream_id_manager->outgoing_max_streams();
4132 QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
4133 session, GetNthClientInitiatedBidirectionalId(max_number_of_streams + 1));
4134 client_->SendCustomSynchronousRequest(headers, body);
4135 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
4136 EXPECT_EQ(QUIC_INVALID_STREAM_ID, client_->connection_error());
4137}
4138
QUICHE teamc258e4f2019-08-14 10:04:58 -07004139TEST_P(EndToEndTest, TestMaxPushId) {
4140 // Has to be before version test, see EndToEndTest::TearDown()
4141 ASSERT_TRUE(Initialize());
4142 if (!VersionHasIetfQuicFrames(negotiated_version_.transport_version)) {
4143 // Only runs for IETF QUIC.
4144 return;
4145 }
4146
4147 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
4148 static_cast<QuicSpdySession*>(client_->client()->session())
4149 ->set_max_allowed_push_id(kMaxQuicStreamId);
4150
4151 client_->SendSynchronousRequest("/foo");
4152
4153 EXPECT_EQ(kMaxQuicStreamId,
4154 static_cast<QuicSpdySession*>(client_->client()->session())
4155 ->max_allowed_push_id());
4156
4157 EXPECT_EQ(
4158 kMaxQuicStreamId,
4159 static_cast<QuicSpdySession*>(GetServerSession())->max_allowed_push_id());
4160}
4161
QUICHE teama6ef0a62019-03-07 20:34:33 -05004162} // namespace
4163} // namespace test
4164} // namespace quic