blob: 236fbdbb16c173d1ed19d91d3a70cacff3321625 [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),
rch13cfcae2019-08-26 14:48:08 -0700228 server_address_(QuicSocketAddress(TestLoopback(),
229 QuicPickServerPortForTestsOrDie())),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500230 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);
nharper8c8f74f2019-08-26 22:23:14 -0700239 SetQuicReloadableFlag(quic_simplify_stop_waiting, true);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500240 client_supported_versions_ = GetParam().client_supported_versions;
241 server_supported_versions_ = GetParam().server_supported_versions;
242 negotiated_version_ = GetParam().negotiated_version;
243
244 QUIC_LOG(INFO) << "Using Configuration: " << GetParam();
245
246 // Use different flow control windows for client/server.
247 client_config_.SetInitialStreamFlowControlWindowToSend(
248 2 * kInitialStreamFlowControlWindowForTest);
249 client_config_.SetInitialSessionFlowControlWindowToSend(
250 2 * kInitialSessionFlowControlWindowForTest);
251 server_config_.SetInitialStreamFlowControlWindowToSend(
252 3 * kInitialStreamFlowControlWindowForTest);
253 server_config_.SetInitialSessionFlowControlWindowToSend(
254 3 * kInitialSessionFlowControlWindowForTest);
255
256 // The default idle timeouts can be too strict when running on a busy
257 // machine.
258 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(30);
259 client_config_.set_max_time_before_crypto_handshake(timeout);
260 client_config_.set_max_idle_time_before_crypto_handshake(timeout);
261 server_config_.set_max_time_before_crypto_handshake(timeout);
262 server_config_.set_max_idle_time_before_crypto_handshake(timeout);
263
264 AddToCache("/foo", 200, kFooResponseBody);
265 AddToCache("/bar", 200, kBarResponseBody);
266 }
267
268 ~EndToEndTest() override { QuicRecyclePort(server_address_.port()); }
269
270 virtual void CreateClientWithWriter() {
271 client_.reset(CreateQuicClient(client_writer_));
272 }
273
274 QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) {
275 QuicTestClient* client =
276 new QuicTestClient(server_address_, server_hostname_, client_config_,
277 client_supported_versions_,
278 crypto_test_utils::ProofVerifierForTesting());
279 client->UseWriter(writer);
280 if (!pre_shared_key_client_.empty()) {
281 client->client()->SetPreSharedKey(pre_shared_key_client_);
282 }
dschinazic8579862019-07-24 18:20:20 -0700283 client->UseConnectionIdLength(override_server_connection_id_length_);
284 client->UseClientConnectionIdLength(override_client_connection_id_length_);
QUICHE teamc258e4f2019-08-14 10:04:58 -0700285 if (support_server_push_) {
286 client->client()->set_max_allowed_push_id(kMaxQuicStreamId);
287 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500288 client->Connect();
289 return client;
290 }
291
292 void set_smaller_flow_control_receive_window() {
293 const uint32_t kClientIFCW = 64 * 1024;
294 const uint32_t kServerIFCW = 1024 * 1024;
295 set_client_initial_stream_flow_control_receive_window(kClientIFCW);
296 set_client_initial_session_flow_control_receive_window(
297 kSessionToStreamRatio * kClientIFCW);
298 set_server_initial_stream_flow_control_receive_window(kServerIFCW);
299 set_server_initial_session_flow_control_receive_window(
300 kSessionToStreamRatio * kServerIFCW);
301 }
302
303 void set_client_initial_stream_flow_control_receive_window(uint32_t window) {
304 CHECK(client_ == nullptr);
305 QUIC_DLOG(INFO) << "Setting client initial stream flow control window: "
306 << window;
307 client_config_.SetInitialStreamFlowControlWindowToSend(window);
308 }
309
310 void set_client_initial_session_flow_control_receive_window(uint32_t window) {
311 CHECK(client_ == nullptr);
312 QUIC_DLOG(INFO) << "Setting client initial session flow control window: "
313 << window;
314 client_config_.SetInitialSessionFlowControlWindowToSend(window);
315 }
316
317 void set_server_initial_stream_flow_control_receive_window(uint32_t window) {
318 CHECK(server_thread_ == nullptr);
319 QUIC_DLOG(INFO) << "Setting server initial stream flow control window: "
320 << window;
321 server_config_.SetInitialStreamFlowControlWindowToSend(window);
322 }
323
324 void set_server_initial_session_flow_control_receive_window(uint32_t window) {
325 CHECK(server_thread_ == nullptr);
326 QUIC_DLOG(INFO) << "Setting server initial session flow control window: "
327 << window;
328 server_config_.SetInitialSessionFlowControlWindowToSend(window);
329 }
330
331 const QuicSentPacketManager* GetSentPacketManagerFromFirstServerSession() {
332 return &GetServerConnection()->sent_packet_manager();
333 }
334
fkastenholz7591c282019-08-13 12:58:38 -0700335 QuicSpdyClientSession* GetClientSession() {
336 return client_->client()->client_session();
337 }
338
339 QuicConnection* GetClientConnection() {
340 return GetClientSession()->connection();
341 }
342
QUICHE teama6ef0a62019-03-07 20:34:33 -0500343 QuicConnection* GetServerConnection() {
344 return GetServerSession()->connection();
345 }
346
renjietange01b3eb2019-08-20 11:04:54 -0700347 QuicSpdySession* GetServerSession() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500348 QuicDispatcher* dispatcher =
349 QuicServerPeer::GetDispatcher(server_thread_->server());
350 EXPECT_EQ(1u, dispatcher->session_map().size());
renjietange01b3eb2019-08-20 11:04:54 -0700351 return static_cast<QuicSpdySession*>(
352 dispatcher->session_map().begin()->second.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500353 }
354
355 bool Initialize() {
356 QuicTagVector copt;
357 server_config_.SetConnectionOptionsToSend(copt);
358 copt = client_extra_copts_;
359
360 // TODO(nimia): Consider setting the congestion control algorithm for the
361 // client as well according to the test parameter.
362 copt.push_back(GetParam().congestion_control_tag);
363 if (GetParam().congestion_control_tag == kTPCC &&
364 GetQuicReloadableFlag(quic_enable_pcc3)) {
365 copt.push_back(kTPCC);
366 }
fayange606e0c2019-08-05 06:56:05 -0700367 copt.push_back(GetParam().priority_tag);
fayangce0a3162019-08-15 09:05:36 -0700368 if (GetQuicReloadableFlag(quic_enable_pto)) {
369 copt.push_back(k2PTO);
370 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500371 client_config_.SetConnectionOptionsToSend(copt);
372
373 // Start the server first, because CreateQuicClient() attempts
374 // to connect to the server.
375 StartServer();
376
377 if (!connect_to_server_on_initialize_) {
378 initialized_ = true;
379 return true;
380 }
381
382 CreateClientWithWriter();
383 static QuicEpollEvent event(EPOLLOUT);
384 if (client_writer_ != nullptr) {
385 client_writer_->Initialize(
fkastenholz7591c282019-08-13 12:58:38 -0700386 QuicConnectionPeer::GetHelper(GetClientConnection()),
387 QuicConnectionPeer::GetAlarmFactory(GetClientConnection()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500388 QuicMakeUnique<ClientDelegate>(client_->client()));
389 }
390 initialized_ = true;
391 return client_->client()->connected();
392 }
393
394 void SetUp() override {
395 // The ownership of these gets transferred to the QuicPacketWriterWrapper
396 // when Initialize() is executed.
397 client_writer_ = new PacketDroppingTestWriter();
398 server_writer_ = new PacketDroppingTestWriter();
399 }
400
401 void TearDown() override {
402 ASSERT_TRUE(initialized_) << "You must call Initialize() in every test "
403 << "case. Otherwise, your test will leak memory.";
404 StopServer();
405 }
406
407 void StartServer() {
QUICHE team8e2e4532019-03-14 14:37:56 -0700408 auto* test_server = new QuicTestServer(
409 crypto_test_utils::ProofSourceForTesting(), server_config_,
410 server_supported_versions_, &memory_cache_backend_,
dschinazi8ff74822019-05-28 16:37:20 -0700411 expected_server_connection_id_length_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500412 server_thread_ = QuicMakeUnique<ServerThread>(test_server, server_address_);
413 if (chlo_multiplier_ != 0) {
414 server_thread_->server()->SetChloMultiplier(chlo_multiplier_);
415 }
416 if (!pre_shared_key_server_.empty()) {
417 server_thread_->server()->SetPreSharedKey(pre_shared_key_server_);
418 }
419 server_thread_->Initialize();
rch13cfcae2019-08-26 14:48:08 -0700420 server_address_ =
421 QuicSocketAddress(server_address_.host(), server_thread_->GetPort());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500422 QuicDispatcher* dispatcher =
423 QuicServerPeer::GetDispatcher(server_thread_->server());
424 QuicDispatcherPeer::UseWriter(dispatcher, server_writer_);
425
QUICHE teama6ef0a62019-03-07 20:34:33 -0500426 server_writer_->Initialize(QuicDispatcherPeer::GetHelper(dispatcher),
427 QuicDispatcherPeer::GetAlarmFactory(dispatcher),
428 QuicMakeUnique<ServerDelegate>(dispatcher));
429 if (stream_factory_ != nullptr) {
430 static_cast<QuicTestServer*>(server_thread_->server())
431 ->SetSpdyStreamFactory(stream_factory_);
432 }
433
434 server_thread_->Start();
435 }
436
437 void StopServer() {
438 if (server_thread_) {
439 server_thread_->Quit();
440 server_thread_->Join();
441 }
442 }
443
444 void AddToCache(QuicStringPiece path,
445 int response_code,
446 QuicStringPiece body) {
447 memory_cache_backend_.AddSimpleResponse(server_hostname_, path,
448 response_code, body);
449 }
450
451 void SetPacketLossPercentage(int32_t loss) {
452 client_writer_->set_fake_packet_loss_percentage(loss);
453 server_writer_->set_fake_packet_loss_percentage(loss);
454 }
455
456 void SetPacketSendDelay(QuicTime::Delta delay) {
457 client_writer_->set_fake_packet_delay(delay);
458 server_writer_->set_fake_packet_delay(delay);
459 }
460
461 void SetReorderPercentage(int32_t reorder) {
462 client_writer_->set_fake_reorder_percentage(reorder);
463 server_writer_->set_fake_reorder_percentage(reorder);
464 }
465
466 // Verifies that the client and server connections were both free of packets
467 // being discarded, based on connection stats.
468 // Calls server_thread_ Pause() and Resume(), which may only be called once
469 // per test.
470 void VerifyCleanConnection(bool had_packet_loss) {
fkastenholz7591c282019-08-13 12:58:38 -0700471 QuicConnectionStats client_stats = GetClientConnection()->GetStats();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500472 // TODO(ianswett): Determine why this becomes even more flaky with BBR
473 // enabled. b/62141144
474 if (!had_packet_loss && !GetQuicReloadableFlag(quic_default_to_bbr)) {
475 EXPECT_EQ(0u, client_stats.packets_lost);
476 }
477 EXPECT_EQ(0u, client_stats.packets_discarded);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500478 // When client starts with an unsupported version, the version negotiation
479 // packet sent by server for the old connection (respond for the connection
480 // close packet) will be dropped by the client.
wubbd64c102019-05-13 11:58:17 -0700481 if (!ServerSendsVersionNegotiation()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500482 EXPECT_EQ(0u, client_stats.packets_dropped);
483 }
484 if (!ClientSupportsIetfQuicNotSupportedByServer()) {
485 // In this case, if client sends 0-RTT POST with v99, receives IETF
486 // version negotiation packet and speaks a GQUIC version. Server processes
487 // this connection in time wait list and keeps sending IETF version
488 // negotiation packet for incoming packets. But these version negotiation
489 // packets cannot be processed by the client speaking GQUIC.
490 EXPECT_EQ(client_stats.packets_received, client_stats.packets_processed);
491 }
492
QUICHE teama6ef0a62019-03-07 20:34:33 -0500493 server_thread_->Pause();
494 QuicConnectionStats server_stats = GetServerConnection()->GetStats();
495 if (!had_packet_loss) {
496 EXPECT_EQ(0u, server_stats.packets_lost);
497 }
498 EXPECT_EQ(0u, server_stats.packets_discarded);
499 // TODO(ianswett): Restore the check for packets_dropped equals 0.
500 // The expect for packets received is equal to packets processed fails
501 // due to version negotiation packets.
502 server_thread_->Resume();
503 }
504
QUICHE teama6ef0a62019-03-07 20:34:33 -0500505 // Client supports IETF QUIC, while it is not supported by server.
506 bool ClientSupportsIetfQuicNotSupportedByServer() {
fayangd4291e42019-05-30 10:31:21 -0700507 return VersionHasIetfInvariantHeader(
508 client_supported_versions_[0].transport_version) &&
509 !VersionHasIetfInvariantHeader(
510 FilterSupportedVersions(GetParam().server_supported_versions)[0]
511 .transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500512 }
513
514 // Returns true when client starts with an unsupported version, and client
515 // closes connection when version negotiation is received.
516 bool ServerSendsVersionNegotiation() {
fayang9ed391a2019-06-20 11:16:59 -0700517 return client_supported_versions_[0] != GetParam().negotiated_version;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500518 }
519
520 bool SupportsIetfQuicWithTls(ParsedQuicVersion version) {
fayangd4291e42019-05-30 10:31:21 -0700521 return VersionHasIetfInvariantHeader(version.transport_version) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500522 version.handshake_protocol == PROTOCOL_TLS1_3;
523 }
524
525 void ExpectFlowControlsSynced(QuicFlowController* client,
526 QuicFlowController* server) {
527 EXPECT_EQ(QuicFlowControllerPeer::SendWindowSize(client),
528 QuicFlowControllerPeer::ReceiveWindowSize(server));
529 EXPECT_EQ(QuicFlowControllerPeer::ReceiveWindowSize(client),
530 QuicFlowControllerPeer::SendWindowSize(server));
531 }
532
533 // Must be called before Initialize to have effect.
534 void SetSpdyStreamFactory(QuicTestServer::StreamFactory* factory) {
535 stream_factory_ = factory;
536 }
537
538 QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
539 return GetNthClientInitiatedBidirectionalStreamId(
fkastenholz7591c282019-08-13 12:58:38 -0700540 GetClientConnection()->transport_version(), n);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500541 }
542
543 QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
544 return GetNthServerInitiatedBidirectionalStreamId(
fkastenholz7591c282019-08-13 12:58:38 -0700545 GetClientConnection()->transport_version(), n);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500546 }
547
548 ScopedEnvironmentForThreads environment_;
549 bool initialized_;
550 // If true, the Initialize() function will create |client_| and starts to
551 // connect to the server.
552 // Default is true.
553 bool connect_to_server_on_initialize_;
554 QuicSocketAddress server_address_;
vasilvvc48c8712019-03-11 13:38:16 -0700555 std::string server_hostname_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500556 QuicMemoryCacheBackend memory_cache_backend_;
557 std::unique_ptr<ServerThread> server_thread_;
558 std::unique_ptr<QuicTestClient> client_;
559 PacketDroppingTestWriter* client_writer_;
560 PacketDroppingTestWriter* server_writer_;
561 QuicConfig client_config_;
562 QuicConfig server_config_;
563 ParsedQuicVersionVector client_supported_versions_;
564 ParsedQuicVersionVector server_supported_versions_;
565 QuicTagVector client_extra_copts_;
566 ParsedQuicVersion negotiated_version_;
567 size_t chlo_multiplier_;
568 QuicTestServer::StreamFactory* stream_factory_;
569 bool support_server_push_;
vasilvvc48c8712019-03-11 13:38:16 -0700570 std::string pre_shared_key_client_;
571 std::string pre_shared_key_server_;
dschinazic8579862019-07-24 18:20:20 -0700572 int override_server_connection_id_length_ = -1;
573 int override_client_connection_id_length_ = -1;
dschinazi8ff74822019-05-28 16:37:20 -0700574 uint8_t expected_server_connection_id_length_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500575};
576
577// Run all end to end tests with all supported versions.
578INSTANTIATE_TEST_SUITE_P(EndToEndTests,
579 EndToEndTest,
wubbd64c102019-05-13 11:58:17 -0700580 ::testing::ValuesIn(GetTestParams(false)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500581
582class EndToEndTestWithTls : public EndToEndTest {};
583
584INSTANTIATE_TEST_SUITE_P(EndToEndTestsWithTls,
585 EndToEndTestWithTls,
wubbd64c102019-05-13 11:58:17 -0700586 ::testing::ValuesIn(GetTestParams(true)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500587
588TEST_P(EndToEndTestWithTls, HandshakeSuccessful) {
589 ASSERT_TRUE(Initialize());
590 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
591 server_thread_->WaitForCryptoHandshakeConfirmed();
592 // There have been occasions where it seemed that negotiated_version_ and the
593 // version in the connection are not in sync. If it is happening, it has not
594 // been recreatable; this assert is here just to check and raise a flag if it
595 // happens.
fkastenholz7591c282019-08-13 12:58:38 -0700596 ASSERT_EQ(GetClientConnection()->transport_version(),
597 negotiated_version_.transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500598
fkastenholz7591c282019-08-13 12:58:38 -0700599 QuicCryptoStream* crypto_stream =
600 QuicSessionPeer::GetMutableCryptoStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500601 QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(crypto_stream);
602 EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
603 server_thread_->Pause();
604 crypto_stream = QuicSessionPeer::GetMutableCryptoStream(GetServerSession());
605 sequencer = QuicStreamPeer::sequencer(crypto_stream);
606 EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
607}
608
QUICHE teama6ef0a62019-03-07 20:34:33 -0500609TEST_P(EndToEndTest, SimpleRequestResponse) {
610 ASSERT_TRUE(Initialize());
611
612 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
613 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
614 int expected_num_client_hellos = 2;
615 if (ServerSendsVersionNegotiation()) {
616 ++expected_num_client_hellos;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500617 }
618 EXPECT_EQ(expected_num_client_hellos,
619 client_->client()->GetNumSentClientHellos());
renjietange01b3eb2019-08-20 11:04:54 -0700620 if (VersionUsesQpack(GetClientConnection()->transport_version())) {
621 EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(GetClientSession()));
622 EXPECT_TRUE(
623 QuicSpdySessionPeer::GetReceiveControlStream(GetClientSession()));
624 EXPECT_TRUE(QuicSpdySessionPeer::GetSendControlStream(GetServerSession()));
625 EXPECT_TRUE(
626 QuicSpdySessionPeer::GetReceiveControlStream(GetServerSession()));
627 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500628}
629
dschinazi24e7ae82019-07-11 13:07:41 -0700630TEST_P(EndToEndTestWithTls, SimpleRequestResponse) {
631 ASSERT_TRUE(Initialize());
632 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
633 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
634}
635
fkastenholz4c7303c2019-07-29 08:17:07 -0700636// Simple transaction, but set a non-default ack delay at the client
637// and ensure it gets to the server.
638TEST_P(EndToEndTest, SimpleRequestResponseWithAckDelayChange) {
639 // Force the ACK delay to be something other than the default.
640 // Note that it is sent only if doing IETF QUIC.
641 client_config_.SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs + 100u);
642 ASSERT_TRUE(Initialize());
643
644 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
645 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
646 int expected_num_client_hellos = 2;
647 if (ServerSendsVersionNegotiation()) {
648 ++expected_num_client_hellos;
649 }
650 EXPECT_EQ(expected_num_client_hellos,
651 client_->client()->GetNumSentClientHellos());
652 if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
653 EXPECT_EQ(kDefaultDelayedAckTimeMs + 100u,
654 GetSentPacketManagerFromFirstServerSession()
655 ->peer_max_ack_delay()
656 .ToMilliseconds());
657 } else {
658 EXPECT_EQ(kDefaultDelayedAckTimeMs,
659 GetSentPacketManagerFromFirstServerSession()
660 ->peer_max_ack_delay()
661 .ToMilliseconds());
662 }
663}
664
fkastenholz4dc4ba32019-07-30 09:55:25 -0700665// Simple transaction, but set a non-default ack exponent at the client
666// and ensure it gets to the server.
667TEST_P(EndToEndTest, SimpleRequestResponseWithAckExponentChange) {
668 const uint32_t kClientAckDelayExponent = kDefaultAckDelayExponent + 100u;
669 // Force the ACK exponent to be something other than the default.
670 // Note that it is sent only if doing IETF QUIC.
671 client_config_.SetAckDelayExponentToSend(kClientAckDelayExponent);
672 ASSERT_TRUE(Initialize());
673
674 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
675 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
676 int expected_num_client_hellos = 2;
677 if (ServerSendsVersionNegotiation()) {
678 ++expected_num_client_hellos;
679 }
680
681 EXPECT_EQ(expected_num_client_hellos,
682 client_->client()->GetNumSentClientHellos());
683 if (VersionHasIetfQuicFrames(
684 GetParam().negotiated_version.transport_version)) {
685 // Should be only for IETF QUIC.
686 EXPECT_EQ(kClientAckDelayExponent,
687 GetServerConnection()->framer().peer_ack_delay_exponent());
688 } else {
689 // No change for Google QUIC.
690 EXPECT_EQ(kDefaultAckDelayExponent,
691 GetServerConnection()->framer().peer_ack_delay_exponent());
692 }
693 // No change, regardless of version.
694 EXPECT_EQ(kDefaultAckDelayExponent,
695 GetServerConnection()->framer().local_ack_delay_exponent());
696}
697
dschinazi5a354c92019-05-09 12:18:53 -0700698TEST_P(EndToEndTest, SimpleRequestResponseForcedVersionNegotiation) {
dschinazi48ac9192019-07-31 00:07:26 -0700699 SetQuicReloadableFlag(quic_use_parse_public_header, true);
dschinazi5a354c92019-05-09 12:18:53 -0700700 client_supported_versions_.insert(client_supported_versions_.begin(),
701 QuicVersionReservedForNegotiation());
702 ASSERT_TRUE(Initialize());
703 ASSERT_TRUE(ServerSendsVersionNegotiation());
704
705 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
706 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
707
wubbd64c102019-05-13 11:58:17 -0700708 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
dschinazi5a354c92019-05-09 12:18:53 -0700709}
710
dschinazi24e7ae82019-07-11 13:07:41 -0700711TEST_P(EndToEndTestWithTls, ForcedVersionNegotiation) {
dschinazi48ac9192019-07-31 00:07:26 -0700712 SetQuicReloadableFlag(quic_use_parse_public_header, true);
dschinazi24e7ae82019-07-11 13:07:41 -0700713 client_supported_versions_.insert(client_supported_versions_.begin(),
714 QuicVersionReservedForNegotiation());
715 ASSERT_TRUE(Initialize());
716 ASSERT_TRUE(ServerSendsVersionNegotiation());
717
718 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
719 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
720}
721
QUICHE teama6ef0a62019-03-07 20:34:33 -0500722TEST_P(EndToEndTest, SimpleRequestResponseZeroConnectionID) {
dschinazic8579862019-07-24 18:20:20 -0700723 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
724 GetParam().negotiated_version.transport_version)) {
725 ASSERT_TRUE(Initialize());
726 return;
727 }
728 override_server_connection_id_length_ = 0;
729 expected_server_connection_id_length_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500730 ASSERT_TRUE(Initialize());
731
732 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
733 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
734 int expected_num_client_hellos = 2;
735 if (ServerSendsVersionNegotiation()) {
736 ++expected_num_client_hellos;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500737 }
738 EXPECT_EQ(expected_num_client_hellos,
739 client_->client()->GetNumSentClientHellos());
fkastenholz7591c282019-08-13 12:58:38 -0700740 EXPECT_EQ(GetClientConnection()->connection_id(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500741 QuicUtils::CreateZeroConnectionId(
742 GetParam().negotiated_version.transport_version));
743}
744
dschinazi5c030852019-07-11 15:45:53 -0700745TEST_P(EndToEndTestWithTls, ZeroConnectionID) {
dschinazic8579862019-07-24 18:20:20 -0700746 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
747 GetParam().negotiated_version.transport_version)) {
748 ASSERT_TRUE(Initialize());
749 return;
750 }
751 override_server_connection_id_length_ = 0;
752 expected_server_connection_id_length_ = 0;
dschinazi5c030852019-07-11 15:45:53 -0700753 ASSERT_TRUE(Initialize());
754
755 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
756 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -0700757 EXPECT_EQ(GetClientConnection()->connection_id(),
dschinazi5c030852019-07-11 15:45:53 -0700758 QuicUtils::CreateZeroConnectionId(
759 GetParam().negotiated_version.transport_version));
760}
761
762TEST_P(EndToEndTestWithTls, BadConnectionIdLength) {
QUICHE team8e2e4532019-03-14 14:37:56 -0700763 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
764 GetParam().negotiated_version.transport_version)) {
765 ASSERT_TRUE(Initialize());
766 return;
767 }
dschinazic8579862019-07-24 18:20:20 -0700768 override_server_connection_id_length_ = 9;
QUICHE teamc65d1d12019-03-19 20:58:04 -0700769 ASSERT_TRUE(Initialize());
770 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
771 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
772 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
773 ->client_session()
774 ->connection()
775 ->connection_id()
776 .length());
QUICHE team8e2e4532019-03-14 14:37:56 -0700777}
778
dschinazi5c030852019-07-11 15:45:53 -0700779// Tests a very long (16-byte) initial destination connection ID to make
780// sure the dispatcher properly replaces it with an 8-byte one.
781TEST_P(EndToEndTestWithTls, LongBadConnectionIdLength) {
782 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
783 GetParam().negotiated_version.transport_version)) {
784 ASSERT_TRUE(Initialize());
785 return;
786 }
dschinazic8579862019-07-24 18:20:20 -0700787 override_server_connection_id_length_ = 16;
dschinazi5c030852019-07-11 15:45:53 -0700788 ASSERT_TRUE(Initialize());
789 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
790 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
791 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
792 ->client_session()
793 ->connection()
794 ->connection_id()
795 .length());
796}
797
798TEST_P(EndToEndTestWithTls, ClientConnectionId) {
dschinazi346b7ce2019-06-05 01:38:18 -0700799 if (!GetParam().negotiated_version.SupportsClientConnectionIds()) {
800 ASSERT_TRUE(Initialize());
801 return;
802 }
dschinazic8579862019-07-24 18:20:20 -0700803 override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
dschinazi346b7ce2019-06-05 01:38:18 -0700804 ASSERT_TRUE(Initialize());
805 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
806 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
dschinazic8579862019-07-24 18:20:20 -0700807 EXPECT_EQ(override_client_connection_id_length_, client_->client()
808 ->client_session()
809 ->connection()
810 ->client_connection_id()
811 .length());
dschinazi346b7ce2019-06-05 01:38:18 -0700812}
813
dschinazi5c030852019-07-11 15:45:53 -0700814TEST_P(EndToEndTestWithTls, ForcedVersionNegotiationAndClientConnectionId) {
dschinazi346b7ce2019-06-05 01:38:18 -0700815 if (!GetParam().negotiated_version.SupportsClientConnectionIds()) {
816 ASSERT_TRUE(Initialize());
817 return;
818 }
dschinazi8c79ac82019-07-31 12:23:05 -0700819 SetQuicReloadableFlag(quic_use_parse_public_header, true);
dschinazi346b7ce2019-06-05 01:38:18 -0700820 client_supported_versions_.insert(client_supported_versions_.begin(),
821 QuicVersionReservedForNegotiation());
dschinazic8579862019-07-24 18:20:20 -0700822 override_client_connection_id_length_ = kQuicDefaultConnectionIdLength;
dschinazi346b7ce2019-06-05 01:38:18 -0700823 ASSERT_TRUE(Initialize());
824 ASSERT_TRUE(ServerSendsVersionNegotiation());
825 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
826 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
dschinazic8579862019-07-24 18:20:20 -0700827 EXPECT_EQ(override_client_connection_id_length_, client_->client()
828 ->client_session()
829 ->connection()
830 ->client_connection_id()
831 .length());
dschinazi346b7ce2019-06-05 01:38:18 -0700832}
833
dschinazi5c030852019-07-11 15:45:53 -0700834TEST_P(EndToEndTestWithTls, ForcedVersionNegotiationAndBadConnectionIdLength) {
dschinazi8eb45e92019-05-10 11:36:15 -0700835 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
836 GetParam().negotiated_version.transport_version)) {
837 ASSERT_TRUE(Initialize());
838 return;
839 }
dschinazi8c79ac82019-07-31 12:23:05 -0700840 SetQuicReloadableFlag(quic_use_parse_public_header, true);
dschinazi8eb45e92019-05-10 11:36:15 -0700841 client_supported_versions_.insert(client_supported_versions_.begin(),
842 QuicVersionReservedForNegotiation());
dschinazic8579862019-07-24 18:20:20 -0700843 override_server_connection_id_length_ = 9;
dschinazi8eb45e92019-05-10 11:36:15 -0700844 ASSERT_TRUE(Initialize());
845 ASSERT_TRUE(ServerSendsVersionNegotiation());
846 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
847 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
848 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
849 ->client_session()
850 ->connection()
851 ->connection_id()
852 .length());
853}
854
dschinazi5c030852019-07-11 15:45:53 -0700855// Forced Version Negotiation with a client connection ID and a long
856// connection ID.
857TEST_P(EndToEndTestWithTls, ForcedVersNegoAndClientCIDAndLongCID) {
858 if (!GetParam().negotiated_version.SupportsClientConnectionIds() ||
859 !QuicUtils::VariableLengthConnectionIdAllowedForVersion(
860 GetParam().negotiated_version.transport_version)) {
861 ASSERT_TRUE(Initialize());
862 return;
863 }
864 client_supported_versions_.insert(client_supported_versions_.begin(),
865 QuicVersionReservedForNegotiation());
dschinazic8579862019-07-24 18:20:20 -0700866 override_server_connection_id_length_ = 16;
867 override_client_connection_id_length_ = 18;
dschinazi5c030852019-07-11 15:45:53 -0700868 ASSERT_TRUE(Initialize());
869 ASSERT_TRUE(ServerSendsVersionNegotiation());
870 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
871 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
872 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
873 ->client_session()
874 ->connection()
875 ->connection_id()
876 .length());
dschinazic8579862019-07-24 18:20:20 -0700877 EXPECT_EQ(override_client_connection_id_length_, client_->client()
878 ->client_session()
879 ->connection()
880 ->client_connection_id()
881 .length());
dschinazi5c030852019-07-11 15:45:53 -0700882}
883
QUICHE team8e2e4532019-03-14 14:37:56 -0700884TEST_P(EndToEndTest, MixGoodAndBadConnectionIdLengths) {
885 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
886 GetParam().negotiated_version.transport_version)) {
887 ASSERT_TRUE(Initialize());
888 return;
889 }
890
QUICHE teamc65d1d12019-03-19 20:58:04 -0700891 // Start client_ which will use a bad connection ID length.
dschinazic8579862019-07-24 18:20:20 -0700892 override_server_connection_id_length_ = 9;
QUICHE teamc65d1d12019-03-19 20:58:04 -0700893 ASSERT_TRUE(Initialize());
dschinazic8579862019-07-24 18:20:20 -0700894 override_server_connection_id_length_ = -1;
QUICHE team8e2e4532019-03-14 14:37:56 -0700895
QUICHE teamc65d1d12019-03-19 20:58:04 -0700896 // Start client2 which will use a good connection ID length.
QUICHE team8e2e4532019-03-14 14:37:56 -0700897 std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
898 SpdyHeaderBlock headers;
899 headers[":method"] = "POST";
900 headers[":path"] = "/foo";
901 headers[":scheme"] = "https";
902 headers[":authority"] = server_hostname_;
903 headers["content-length"] = "3";
904 client2->SendMessage(headers, "", /*fin=*/false);
905 client2->SendData("eep", true);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700906
907 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
908 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
909 EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
910 ->client_session()
911 ->connection()
912 ->connection_id()
913 .length());
914
QUICHE team8e2e4532019-03-14 14:37:56 -0700915 client2->WaitForResponse();
916 EXPECT_EQ(kFooResponseBody, client2->response_body());
917 EXPECT_EQ("200", client2->response_headers()->find(":status")->second);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700918 EXPECT_EQ(kQuicDefaultConnectionIdLength, client2->client()
919 ->client_session()
920 ->connection()
921 ->connection_id()
922 .length());
QUICHE team8e2e4532019-03-14 14:37:56 -0700923}
924
dschinazi552accc2019-06-17 17:07:34 -0700925TEST_P(EndToEndTestWithTls, SimpleRequestResponseWithIetfDraftSupport) {
926 if (GetParam().negotiated_version.transport_version != QUIC_VERSION_99 ||
927 GetParam().negotiated_version.handshake_protocol != PROTOCOL_TLS1_3) {
928 ASSERT_TRUE(Initialize());
929 return;
930 }
931 QuicVersionInitializeSupportForIetfDraft(1);
932 ASSERT_TRUE(Initialize());
933
934 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
935 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
936}
937
QUICHE teama6ef0a62019-03-07 20:34:33 -0500938TEST_P(EndToEndTest, SimpleRequestResponseWithLargeReject) {
939 chlo_multiplier_ = 1;
940 ASSERT_TRUE(Initialize());
941
942 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
943 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
944 if (ServerSendsVersionNegotiation()) {
945 EXPECT_EQ(4, client_->client()->GetNumSentClientHellos());
946 } else {
947 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
948 }
949}
950
951TEST_P(EndToEndTestWithTls, SimpleRequestResponsev6) {
952 server_address_ =
953 QuicSocketAddress(QuicIpAddress::Loopback6(), server_address_.port());
954 ASSERT_TRUE(Initialize());
955
956 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
957 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
958}
959
dschinazi6ece5002019-05-22 06:35:49 -0700960TEST_P(EndToEndTestWithTls, NoUndecryptablePackets) {
961 ASSERT_TRUE(Initialize());
962
963 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
964 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
965
fkastenholz7591c282019-08-13 12:58:38 -0700966 QuicConnectionStats client_stats = GetClientConnection()->GetStats();
dschinazi6ece5002019-05-22 06:35:49 -0700967 EXPECT_EQ(0u, client_stats.undecryptable_packets_received);
dschinazi02208652019-05-28 02:57:47 -0700968
969 server_thread_->Pause();
970 QuicConnectionStats server_stats = GetServerConnection()->GetStats();
dschinazi6ece5002019-05-22 06:35:49 -0700971 EXPECT_EQ(0u, server_stats.undecryptable_packets_received);
dschinazi02208652019-05-28 02:57:47 -0700972 server_thread_->Resume();
dschinazi6ece5002019-05-22 06:35:49 -0700973}
974
QUICHE teama6ef0a62019-03-07 20:34:33 -0500975TEST_P(EndToEndTestWithTls, SeparateFinPacket) {
976 ASSERT_TRUE(Initialize());
977
978 // Send a request in two parts: the request and then an empty packet with FIN.
979 SpdyHeaderBlock headers;
980 headers[":method"] = "POST";
981 headers[":path"] = "/foo";
982 headers[":scheme"] = "https";
983 headers[":authority"] = server_hostname_;
984 client_->SendMessage(headers, "", /*fin=*/false);
985 client_->SendData("", true);
986 client_->WaitForResponse();
987 EXPECT_EQ(kFooResponseBody, client_->response_body());
988 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
989
990 // Now do the same thing but with a content length.
991 headers["content-length"] = "3";
992 client_->SendMessage(headers, "", /*fin=*/false);
993 client_->SendData("foo", true);
994 client_->WaitForResponse();
995 EXPECT_EQ(kFooResponseBody, client_->response_body());
996 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
997}
998
999TEST_P(EndToEndTestWithTls, MultipleRequestResponse) {
1000 ASSERT_TRUE(Initialize());
1001
1002 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1003 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1004 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
1005 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1006}
1007
1008TEST_P(EndToEndTest, MultipleRequestResponseZeroConnectionID) {
dschinazic8579862019-07-24 18:20:20 -07001009 if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
1010 GetParam().negotiated_version.transport_version)) {
1011 ASSERT_TRUE(Initialize());
1012 return;
1013 }
1014 override_server_connection_id_length_ = 0;
1015 expected_server_connection_id_length_ = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001016 ASSERT_TRUE(Initialize());
1017
1018 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1019 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1020 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
1021 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1022}
1023
1024TEST_P(EndToEndTestWithTls, MultipleStreams) {
1025 // Verifies quic_test_client can track responses of all active streams.
1026 ASSERT_TRUE(Initialize());
1027
1028 const int kNumRequests = 10;
1029
1030 SpdyHeaderBlock headers;
1031 headers[":method"] = "POST";
1032 headers[":path"] = "/foo";
1033 headers[":scheme"] = "https";
1034 headers[":authority"] = server_hostname_;
1035 headers["content-length"] = "3";
1036
1037 for (int i = 0; i < kNumRequests; ++i) {
1038 client_->SendMessage(headers, "bar", /*fin=*/true);
1039 }
1040
1041 while (kNumRequests > client_->num_responses()) {
1042 client_->ClearPerRequestState();
1043 client_->WaitForResponse();
1044 EXPECT_EQ(kFooResponseBody, client_->response_body());
1045 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1046 }
1047}
1048
1049TEST_P(EndToEndTestWithTls, MultipleClients) {
1050 ASSERT_TRUE(Initialize());
1051 std::unique_ptr<QuicTestClient> client2(CreateQuicClient(nullptr));
1052
1053 SpdyHeaderBlock headers;
1054 headers[":method"] = "POST";
1055 headers[":path"] = "/foo";
1056 headers[":scheme"] = "https";
1057 headers[":authority"] = server_hostname_;
1058 headers["content-length"] = "3";
1059
1060 client_->SendMessage(headers, "", /*fin=*/false);
1061 client2->SendMessage(headers, "", /*fin=*/false);
1062
1063 client_->SendData("bar", true);
1064 client_->WaitForResponse();
1065 EXPECT_EQ(kFooResponseBody, client_->response_body());
1066 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1067
1068 client2->SendData("eep", true);
1069 client2->WaitForResponse();
1070 EXPECT_EQ(kFooResponseBody, client2->response_body());
1071 EXPECT_EQ("200", client2->response_headers()->find(":status")->second);
1072}
1073
1074TEST_P(EndToEndTestWithTls, RequestOverMultiplePackets) {
1075 // Send a large enough request to guarantee fragmentation.
vasilvvc48c8712019-03-11 13:38:16 -07001076 std::string huge_request =
dschinazi66dea072019-04-09 11:41:06 -07001077 "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001078 AddToCache(huge_request, 200, kBarResponseBody);
1079
1080 ASSERT_TRUE(Initialize());
1081
1082 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
1083 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1084}
1085
1086TEST_P(EndToEndTestWithTls, MultiplePacketsRandomOrder) {
1087 // Send a large enough request to guarantee fragmentation.
vasilvvc48c8712019-03-11 13:38:16 -07001088 std::string huge_request =
dschinazi66dea072019-04-09 11:41:06 -07001089 "/some/path?query=" + std::string(kMaxOutgoingPacketSize, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001090 AddToCache(huge_request, 200, kBarResponseBody);
1091
1092 ASSERT_TRUE(Initialize());
1093 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
1094 SetReorderPercentage(50);
1095
1096 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest(huge_request));
1097 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1098}
1099
1100TEST_P(EndToEndTestWithTls, PostMissingBytes) {
1101 ASSERT_TRUE(Initialize());
1102
1103 // Add a content length header with no body.
1104 SpdyHeaderBlock headers;
1105 headers[":method"] = "POST";
1106 headers[":path"] = "/foo";
1107 headers[":scheme"] = "https";
1108 headers[":authority"] = server_hostname_;
1109 headers["content-length"] = "3";
1110
1111 // This should be detected as stream fin without complete request,
1112 // triggering an error response.
1113 client_->SendCustomSynchronousRequest(headers, "");
1114 EXPECT_EQ(QuicSimpleServerStream::kErrorResponseBody,
1115 client_->response_body());
1116 EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
1117}
1118
1119TEST_P(EndToEndTest, LargePostNoPacketLoss) {
1120 ASSERT_TRUE(Initialize());
1121
1122 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1123
1124 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07001125 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001126 SpdyHeaderBlock headers;
1127 headers[":method"] = "POST";
1128 headers[":path"] = "/foo";
1129 headers[":scheme"] = "https";
1130 headers[":authority"] = server_hostname_;
1131
1132 EXPECT_EQ(kFooResponseBody,
1133 client_->SendCustomSynchronousRequest(headers, body));
1134 // TODO(ianswett): There should not be packet loss in this test, but on some
1135 // platforms the receive buffer overflows.
1136 VerifyCleanConnection(true);
1137}
1138
1139TEST_P(EndToEndTest, LargePostNoPacketLoss1sRTT) {
1140 ASSERT_TRUE(Initialize());
1141 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(1000));
1142
1143 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1144
1145 // 100 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001146 std::string body(100 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001147 SpdyHeaderBlock headers;
1148 headers[":method"] = "POST";
1149 headers[":path"] = "/foo";
1150 headers[":scheme"] = "https";
1151 headers[":authority"] = server_hostname_;
1152
1153 EXPECT_EQ(kFooResponseBody,
1154 client_->SendCustomSynchronousRequest(headers, body));
1155 VerifyCleanConnection(false);
1156}
1157
1158TEST_P(EndToEndTest, LargePostWithPacketLoss) {
wubbd64c102019-05-13 11:58:17 -07001159 // Connect with lower fake packet loss than we'd like to test.
1160 // Until b/10126687 is fixed, losing handshake packets is pretty
1161 // brutal.
1162 SetPacketLossPercentage(5);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001163 ASSERT_TRUE(Initialize());
1164
1165 // Wait for the server SHLO before upping the packet loss.
1166 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1167 SetPacketLossPercentage(30);
1168
1169 // 10 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001170 std::string body(1024 * 10, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001171 SpdyHeaderBlock headers;
1172 headers[":method"] = "POST";
1173 headers[":path"] = "/foo";
1174 headers[":scheme"] = "https";
1175 headers[":authority"] = server_hostname_;
1176
1177 EXPECT_EQ(kFooResponseBody,
1178 client_->SendCustomSynchronousRequest(headers, body));
1179 VerifyCleanConnection(true);
1180}
1181
1182// Regression test for b/80090281.
1183TEST_P(EndToEndTest, LargePostWithPacketLossAndAlwaysBundleWindowUpdates) {
1184 ASSERT_TRUE(Initialize());
1185
1186 // Wait for the server SHLO before upping the packet loss.
1187 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1188 server_thread_->WaitForCryptoHandshakeConfirmed();
1189
1190 // Normally server only bundles a retransmittable frame once every other
1191 // kMaxConsecutiveNonRetransmittablePackets ack-only packets. Setting the max
1192 // to 0 to reliably reproduce b/80090281.
1193 server_thread_->Schedule([this]() {
1194 QuicConnectionPeer::SetMaxConsecutiveNumPacketsWithNoRetransmittableFrames(
1195 GetServerConnection(), 0);
1196 });
1197
1198 SetPacketLossPercentage(30);
1199
1200 // 10 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001201 std::string body(1024 * 10, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001202 SpdyHeaderBlock headers;
1203 headers[":method"] = "POST";
1204 headers[":path"] = "/foo";
1205 headers[":scheme"] = "https";
1206 headers[":authority"] = server_hostname_;
1207
1208 EXPECT_EQ(kFooResponseBody,
1209 client_->SendCustomSynchronousRequest(headers, body));
1210 VerifyCleanConnection(true);
1211}
1212
1213TEST_P(EndToEndTest, LargePostWithPacketLossAndBlockedSocket) {
wubbd64c102019-05-13 11:58:17 -07001214 // Connect with lower fake packet loss than we'd like to test. Until
1215 // b/10126687 is fixed, losing handshake packets is pretty brutal.
1216 SetPacketLossPercentage(5);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001217 ASSERT_TRUE(Initialize());
1218
1219 // Wait for the server SHLO before upping the packet loss.
1220 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1221 SetPacketLossPercentage(10);
1222 client_writer_->set_fake_blocked_socket_percentage(10);
1223
1224 // 10 KB body.
vasilvvc48c8712019-03-11 13:38:16 -07001225 std::string body(1024 * 10, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001226 SpdyHeaderBlock headers;
1227 headers[":method"] = "POST";
1228 headers[":path"] = "/foo";
1229 headers[":scheme"] = "https";
1230 headers[":authority"] = server_hostname_;
1231
1232 EXPECT_EQ(kFooResponseBody,
1233 client_->SendCustomSynchronousRequest(headers, body));
1234}
1235
1236TEST_P(EndToEndTest, LargePostNoPacketLossWithDelayAndReordering) {
1237 ASSERT_TRUE(Initialize());
1238
1239 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1240 // Both of these must be called when the writer is not actively used.
1241 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
1242 SetReorderPercentage(30);
1243
1244 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07001245 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001246 SpdyHeaderBlock headers;
1247 headers[":method"] = "POST";
1248 headers[":path"] = "/foo";
1249 headers[":scheme"] = "https";
1250 headers[":authority"] = server_hostname_;
1251
1252 EXPECT_EQ(kFooResponseBody,
1253 client_->SendCustomSynchronousRequest(headers, body));
1254}
1255
1256TEST_P(EndToEndTest, LargePostZeroRTTFailure) {
1257 // Send a request and then disconnect. This prepares the client to attempt
1258 // a 0-RTT handshake for the next request.
1259 ASSERT_TRUE(Initialize());
1260
vasilvvc48c8712019-03-11 13:38:16 -07001261 std::string body(20480, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001262 SpdyHeaderBlock headers;
1263 headers[":method"] = "POST";
1264 headers[":path"] = "/foo";
1265 headers[":scheme"] = "https";
1266 headers[":authority"] = server_hostname_;
1267
1268 EXPECT_EQ(kFooResponseBody,
1269 client_->SendCustomSynchronousRequest(headers, body));
wubbd64c102019-05-13 11:58:17 -07001270 // The same session is used for both hellos, so the number of hellos sent on
1271 // that session is 2.
fkastenholz7591c282019-08-13 12:58:38 -07001272 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001273 if (ServerSendsVersionNegotiation()) {
1274 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1275 } else {
1276 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1277 }
1278
1279 client_->Disconnect();
1280
1281 // The 0-RTT handshake should succeed.
1282 client_->Connect();
1283 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1284 ASSERT_TRUE(client_->client()->connected());
1285 EXPECT_EQ(kFooResponseBody,
1286 client_->SendCustomSynchronousRequest(headers, body));
1287
fkastenholz7591c282019-08-13 12:58:38 -07001288 EXPECT_EQ(1, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001289 if (ServerSendsVersionNegotiation()) {
1290 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1291 } else {
1292 EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
1293 }
1294
1295 client_->Disconnect();
1296
1297 // Restart the server so that the 0-RTT handshake will take 1 RTT.
1298 StopServer();
1299 server_writer_ = new PacketDroppingTestWriter();
1300 StartServer();
1301
1302 client_->Connect();
1303 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1304 ASSERT_TRUE(client_->client()->connected());
1305 EXPECT_EQ(kFooResponseBody,
1306 client_->SendCustomSynchronousRequest(headers, body));
wubbd64c102019-05-13 11:58:17 -07001307 // The same session is used for both hellos, so the number of hellos sent on
1308 // that session is 2.
fkastenholz7591c282019-08-13 12:58:38 -07001309 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001310 if (ServerSendsVersionNegotiation()) {
1311 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1312 } else {
1313 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1314 }
1315
1316 VerifyCleanConnection(false);
1317}
1318
1319TEST_P(EndToEndTest, SynchronousRequestZeroRTTFailure) {
1320 // Send a request and then disconnect. This prepares the client to attempt
1321 // a 0-RTT handshake for the next request.
1322 ASSERT_TRUE(Initialize());
1323
1324 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
wubbd64c102019-05-13 11:58:17 -07001325 // The same session is used for both hellos, so the number of hellos sent on
1326 // that session is 2.
fkastenholz7591c282019-08-13 12:58:38 -07001327 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001328 if (ServerSendsVersionNegotiation()) {
1329 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1330 } else {
1331 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1332 }
1333
1334 client_->Disconnect();
1335
1336 // The 0-RTT handshake should succeed.
1337 client_->Connect();
1338 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1339 ASSERT_TRUE(client_->client()->connected());
1340 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1341
fkastenholz7591c282019-08-13 12:58:38 -07001342 EXPECT_EQ(1, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001343 if (ServerSendsVersionNegotiation()) {
1344 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1345 } else {
1346 EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
1347 }
1348
1349 client_->Disconnect();
1350
1351 // Restart the server so that the 0-RTT handshake will take 1 RTT.
1352 StopServer();
1353 server_writer_ = new PacketDroppingTestWriter();
1354 StartServer();
1355
1356 client_->Connect();
1357 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1358 ASSERT_TRUE(client_->client()->connected());
1359 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
wubbd64c102019-05-13 11:58:17 -07001360
fkastenholz7591c282019-08-13 12:58:38 -07001361 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001362 if (ServerSendsVersionNegotiation()) {
1363 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1364 } else {
1365 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1366 }
1367
1368 VerifyCleanConnection(false);
1369}
1370
1371TEST_P(EndToEndTest, LargePostSynchronousRequest) {
1372 // Send a request and then disconnect. This prepares the client to attempt
1373 // a 0-RTT handshake for the next request.
1374 ASSERT_TRUE(Initialize());
1375
vasilvvc48c8712019-03-11 13:38:16 -07001376 std::string body(20480, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001377 SpdyHeaderBlock headers;
1378 headers[":method"] = "POST";
1379 headers[":path"] = "/foo";
1380 headers[":scheme"] = "https";
1381 headers[":authority"] = server_hostname_;
1382
1383 EXPECT_EQ(kFooResponseBody,
1384 client_->SendCustomSynchronousRequest(headers, body));
wubbd64c102019-05-13 11:58:17 -07001385 // The same session is used for both hellos, so the number of hellos sent on
1386 // that session is 2.
fkastenholz7591c282019-08-13 12:58:38 -07001387 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001388 if (ServerSendsVersionNegotiation()) {
1389 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1390 } else {
1391 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1392 }
1393
1394 client_->Disconnect();
1395
1396 // The 0-RTT handshake should succeed.
1397 client_->Connect();
1398 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1399 ASSERT_TRUE(client_->client()->connected());
1400 EXPECT_EQ(kFooResponseBody,
1401 client_->SendCustomSynchronousRequest(headers, body));
1402
fkastenholz7591c282019-08-13 12:58:38 -07001403 EXPECT_EQ(1, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001404 if (ServerSendsVersionNegotiation()) {
1405 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1406 } else {
1407 EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
1408 }
1409
1410 client_->Disconnect();
1411
1412 // Restart the server so that the 0-RTT handshake will take 1 RTT.
1413 StopServer();
1414 server_writer_ = new PacketDroppingTestWriter();
1415 StartServer();
1416
1417 client_->Connect();
1418 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1419 ASSERT_TRUE(client_->client()->connected());
1420 EXPECT_EQ(kFooResponseBody,
1421 client_->SendCustomSynchronousRequest(headers, body));
wubbd64c102019-05-13 11:58:17 -07001422
fkastenholz7591c282019-08-13 12:58:38 -07001423 EXPECT_EQ(2, GetClientSession()->GetNumSentClientHellos());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001424 if (ServerSendsVersionNegotiation()) {
1425 EXPECT_EQ(3, client_->client()->GetNumSentClientHellos());
1426 } else {
1427 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
1428 }
1429
1430 VerifyCleanConnection(false);
1431}
1432
wubbd64c102019-05-13 11:58:17 -07001433TEST_P(EndToEndTest, RejectWithPacketLoss) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001434 // In this test, we intentionally drop the first packet from the
wubbd64c102019-05-13 11:58:17 -07001435 // server, which corresponds with the initial REJ response from
QUICHE teama6ef0a62019-03-07 20:34:33 -05001436 // the server.
1437 server_writer_->set_fake_drop_first_n_packets(1);
1438 ASSERT_TRUE(Initialize());
1439}
1440
1441TEST_P(EndToEndTest, SetInitialReceivedConnectionOptions) {
1442 QuicTagVector initial_received_options;
1443 initial_received_options.push_back(kTBBR);
1444 initial_received_options.push_back(kIW10);
1445 initial_received_options.push_back(kPRST);
1446 EXPECT_TRUE(server_config_.SetInitialReceivedConnectionOptions(
1447 initial_received_options));
1448
1449 ASSERT_TRUE(Initialize());
1450 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1451 server_thread_->WaitForCryptoHandshakeConfirmed();
1452
1453 EXPECT_FALSE(server_config_.SetInitialReceivedConnectionOptions(
1454 initial_received_options));
1455
1456 // Verify that server's configuration is correct.
1457 server_thread_->Pause();
1458 EXPECT_TRUE(server_config_.HasReceivedConnectionOptions());
1459 EXPECT_TRUE(
1460 ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kTBBR));
1461 EXPECT_TRUE(
1462 ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kIW10));
1463 EXPECT_TRUE(
1464 ContainsQuicTag(server_config_.ReceivedConnectionOptions(), kPRST));
1465}
1466
1467TEST_P(EndToEndTest, LargePostSmallBandwidthLargeBuffer) {
1468 ASSERT_TRUE(Initialize());
1469 SetPacketSendDelay(QuicTime::Delta::FromMicroseconds(1));
1470 // 256KB per second with a 256KB buffer from server to client. Wireless
1471 // clients commonly have larger buffers, but our max CWND is 200.
1472 server_writer_->set_max_bandwidth_and_buffer_size(
1473 QuicBandwidth::FromBytesPerSecond(256 * 1024), 256 * 1024);
1474
1475 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1476
1477 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07001478 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001479 SpdyHeaderBlock headers;
1480 headers[":method"] = "POST";
1481 headers[":path"] = "/foo";
1482 headers[":scheme"] = "https";
1483 headers[":authority"] = server_hostname_;
1484
1485 EXPECT_EQ(kFooResponseBody,
1486 client_->SendCustomSynchronousRequest(headers, body));
1487 // This connection may drop packets, because the buffer is smaller than the
1488 // max CWND.
1489 VerifyCleanConnection(true);
1490}
1491
1492TEST_P(EndToEndTestWithTls, DoNotSetSendAlarmIfConnectionFlowControlBlocked) {
1493 // Regression test for b/14677858.
1494 // Test that the resume write alarm is not set in QuicConnection::OnCanWrite
1495 // if currently connection level flow control blocked. If set, this results in
1496 // an infinite loop in the EpollServer, as the alarm fires and is immediately
1497 // rescheduled.
1498 ASSERT_TRUE(Initialize());
1499 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1500
1501 // Ensure both stream and connection level are flow control blocked by setting
1502 // the send window offset to 0.
1503 const uint64_t flow_control_window =
1504 server_config_.GetInitialStreamFlowControlWindowToSend();
1505 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
fkastenholz7591c282019-08-13 12:58:38 -07001506 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001507 QuicFlowControllerPeer::SetSendWindowOffset(stream->flow_controller(), 0);
1508 QuicFlowControllerPeer::SetSendWindowOffset(session->flow_controller(), 0);
1509 EXPECT_TRUE(stream->flow_controller()->IsBlocked());
1510 EXPECT_TRUE(session->flow_controller()->IsBlocked());
1511
1512 // Make sure that the stream has data pending so that it will be marked as
1513 // write blocked when it receives a stream level WINDOW_UPDATE.
1514 stream->WriteOrBufferBody("hello", false);
1515
1516 // The stream now attempts to write, fails because it is still connection
1517 // level flow control blocked, and is added to the write blocked list.
1518 QuicWindowUpdateFrame window_update(kInvalidControlFrameId, stream->id(),
1519 2 * flow_control_window);
1520 stream->OnWindowUpdateFrame(window_update);
1521
1522 // Prior to fixing b/14677858 this call would result in an infinite loop in
1523 // Chromium. As a proxy for detecting this, we now check whether the
1524 // send alarm is set after OnCanWrite. It should not be, as the
1525 // connection is still flow control blocked.
1526 session->connection()->OnCanWrite();
1527
1528 QuicAlarm* send_alarm =
1529 QuicConnectionPeer::GetSendAlarm(session->connection());
1530 EXPECT_FALSE(send_alarm->IsSet());
1531}
1532
1533// TODO(nharper): Needs to get turned back to EndToEndTestWithTls
1534// when we figure out why the test doesn't work on chrome.
1535TEST_P(EndToEndTest, InvalidStream) {
1536 ASSERT_TRUE(Initialize());
1537 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1538
dschinazi66dea072019-04-09 11:41:06 -07001539 std::string body(kMaxOutgoingPacketSize, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001540 SpdyHeaderBlock headers;
1541 headers[":method"] = "POST";
1542 headers[":path"] = "/foo";
1543 headers[":scheme"] = "https";
1544 headers[":authority"] = server_hostname_;
1545
1546 // Force the client to write with a stream ID belonging to a nonexistent
1547 // server-side stream.
fkastenholz7591c282019-08-13 12:58:38 -07001548 QuicSpdySession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001549 QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
1550 session, GetNthServerInitiatedBidirectionalId(0));
1551
1552 client_->SendCustomSynchronousRequest(headers, body);
1553 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
1554 EXPECT_EQ(QUIC_INVALID_STREAM_ID, client_->connection_error());
1555}
1556
1557// Test that if the server will close the connection if the client attempts
1558// to send a request with overly large headers.
1559TEST_P(EndToEndTest, LargeHeaders) {
1560 ASSERT_TRUE(Initialize());
1561 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1562
dschinazi66dea072019-04-09 11:41:06 -07001563 std::string body(kMaxOutgoingPacketSize, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001564 SpdyHeaderBlock headers;
1565 headers[":method"] = "POST";
1566 headers[":path"] = "/foo";
1567 headers[":scheme"] = "https";
1568 headers[":authority"] = server_hostname_;
vasilvvc48c8712019-03-11 13:38:16 -07001569 headers["key1"] = std::string(15 * 1024, 'a');
1570 headers["key2"] = std::string(15 * 1024, 'a');
1571 headers["key3"] = std::string(15 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001572
1573 client_->SendCustomSynchronousRequest(headers, body);
renjietang2abedac2019-05-20 14:04:50 -07001574
1575 if (VersionUsesQpack(client_->client()
1576 ->client_session()
1577 ->connection()
1578 ->transport_version())) {
1579 EXPECT_EQ(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
1580 client_->connection_error());
1581 } else {
1582 EXPECT_EQ(QUIC_HEADERS_TOO_LARGE, client_->stream_error());
1583 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
1584 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001585}
1586
1587TEST_P(EndToEndTest, EarlyResponseWithQuicStreamNoError) {
1588 ASSERT_TRUE(Initialize());
1589 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1590
vasilvvc48c8712019-03-11 13:38:16 -07001591 std::string large_body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001592 SpdyHeaderBlock headers;
1593 headers[":method"] = "POST";
1594 headers[":path"] = "/foo";
1595 headers[":scheme"] = "https";
1596 headers[":authority"] = server_hostname_;
1597 // Insert an invalid content_length field in request to trigger an early
1598 // response from server.
1599 headers["content-length"] = "-3";
1600
1601 client_->SendCustomSynchronousRequest(headers, large_body);
1602 EXPECT_EQ("bad", client_->response_body());
1603 EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
1604 EXPECT_EQ(QUIC_STREAM_NO_ERROR, client_->stream_error());
1605 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
1606}
1607
1608// TODO(rch): this test seems to cause net_unittests timeouts :|
1609TEST_P(EndToEndTestWithTls, QUIC_TEST_DISABLED_IN_CHROME(MultipleTermination)) {
1610 ASSERT_TRUE(Initialize());
1611
1612 // Set the offset so we won't frame. Otherwise when we pick up termination
1613 // before HTTP framing is complete, we send an error and close the stream,
1614 // and the second write is picked up as writing on a closed stream.
1615 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
1616 ASSERT_TRUE(stream != nullptr);
1617 QuicStreamPeer::SetStreamBytesWritten(3, stream);
1618
1619 client_->SendData("bar", true);
1620 client_->WaitForWriteToFlush();
1621
1622 // By default the stream protects itself from writes after terminte is set.
1623 // Override this to test the server handling buggy clients.
1624 QuicStreamPeer::SetWriteSideClosed(false, client_->GetOrCreateStream());
1625
1626 EXPECT_QUIC_BUG(client_->SendData("eep", true), "Fin already buffered");
1627}
1628
1629// TODO(nharper): Needs to get turned back to EndToEndTestWithTls
1630// when we figure out why the test doesn't work on chrome.
1631TEST_P(EndToEndTest, Timeout) {
1632 client_config_.SetIdleNetworkTimeout(QuicTime::Delta::FromMicroseconds(500),
1633 QuicTime::Delta::FromMicroseconds(500));
1634 // Note: we do NOT ASSERT_TRUE: we may time out during initial handshake:
1635 // that's enough to validate timeout in this case.
1636 Initialize();
1637 while (client_->client()->connected()) {
1638 client_->client()->WaitForEvents();
1639 }
1640}
1641
1642TEST_P(EndToEndTestWithTls, MaxIncomingDynamicStreamsLimitRespected) {
1643 // Set a limit on maximum number of incoming dynamic streams.
1644 // Make sure the limit is respected.
1645 const uint32_t kServerMaxIncomingDynamicStreams = 1;
fkastenholzd3a1de92019-05-15 07:00:07 -07001646 server_config_.SetMaxIncomingBidirectionalStreamsToSend(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001647 kServerMaxIncomingDynamicStreams);
1648 ASSERT_TRUE(Initialize());
fkastenholz305e1732019-06-18 05:01:22 -07001649 if (VersionHasIetfQuicFrames(
1650 GetParam().negotiated_version.transport_version)) {
1651 // Do not run this test for /IETF QUIC. Note that the test needs
fkastenholz3c4eabf2019-04-22 07:49:59 -07001652 // to be here, after calling Initialize(), because all tests end up calling
1653 // EndToEndTest::TearDown(), which asserts that Initialize has been called
1654 // and then proceeds to tear things down -- which fails if they are not
1655 // properly set up.
1656 return;
1657 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001658 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001659
1660 // Make the client misbehave after negotiation.
1661 const int kServerMaxStreams = kMaxStreamsMinimumIncrement + 1;
fkastenholz7591c282019-08-13 12:58:38 -07001662 QuicSessionPeer::SetMaxOpenOutgoingStreams(GetClientSession(),
1663 kServerMaxStreams + 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001664
1665 SpdyHeaderBlock headers;
1666 headers[":method"] = "POST";
1667 headers[":path"] = "/foo";
1668 headers[":scheme"] = "https";
1669 headers[":authority"] = server_hostname_;
1670 headers["content-length"] = "3";
1671
1672 // The server supports a small number of additional streams beyond the
1673 // negotiated limit. Open enough streams to go beyond that limit.
1674 for (int i = 0; i < kServerMaxStreams + 1; ++i) {
1675 client_->SendMessage(headers, "", /*fin=*/false);
1676 }
1677 client_->WaitForResponse();
fkastenholz3c4eabf2019-04-22 07:49:59 -07001678
1679 EXPECT_TRUE(client_->connected());
1680 EXPECT_EQ(QUIC_REFUSED_STREAM, client_->stream_error());
1681 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001682}
1683
1684TEST_P(EndToEndTest, SetIndependentMaxIncomingDynamicStreamsLimits) {
1685 // Each endpoint can set max incoming dynamic streams independently.
renjietang87cd7de2019-08-16 08:35:10 -07001686 const uint32_t kClientMaxIncomingDynamicStreams = 4;
1687 const uint32_t kServerMaxIncomingDynamicStreams = 3;
fkastenholzd3a1de92019-05-15 07:00:07 -07001688 client_config_.SetMaxIncomingBidirectionalStreamsToSend(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001689 kClientMaxIncomingDynamicStreams);
fkastenholzd3a1de92019-05-15 07:00:07 -07001690 server_config_.SetMaxIncomingBidirectionalStreamsToSend(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001691 kServerMaxIncomingDynamicStreams);
fkastenholzd3a1de92019-05-15 07:00:07 -07001692 client_config_.SetMaxIncomingUnidirectionalStreamsToSend(
1693 kClientMaxIncomingDynamicStreams);
1694 server_config_.SetMaxIncomingUnidirectionalStreamsToSend(
1695 kServerMaxIncomingDynamicStreams);
1696
QUICHE teama6ef0a62019-03-07 20:34:33 -05001697 ASSERT_TRUE(Initialize());
1698 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1699
1700 // The client has received the server's limit and vice versa.
fkastenholz7591c282019-08-13 12:58:38 -07001701 QuicSpdyClientSession* client_session = GetClientSession();
fkastenholz3c4eabf2019-04-22 07:49:59 -07001702 // The value returned by max_allowed... includes the Crypto and Header
1703 // stream (created as a part of initialization). The config. values,
1704 // above, are treated as "number of requests/responses" - that is, they do
1705 // not include the static Crypto and Header streams. Reduce the value
1706 // returned by max_allowed... by 2 to remove the static streams from the
1707 // count.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001708 size_t client_max_open_outgoing_bidirectional_streams =
fkastenholz305e1732019-06-18 05:01:22 -07001709 VersionHasIetfQuicFrames(
1710 client_session->connection()->transport_version())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001711 ? QuicSessionPeer::v99_streamid_manager(client_session)
renjietang216dc012019-08-27 11:28:27 -07001712 ->max_allowed_outgoing_bidirectional_streams()
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() -
renjietang216dc012019-08-27 11:28:27 -07001720 client_session->num_expected_unidirectional_static_streams()
QUICHE teama6ef0a62019-03-07 20:34:33 -05001721 : QuicSessionPeer::GetStreamIdManager(client_session)
1722 ->max_open_outgoing_streams();
1723 EXPECT_EQ(kServerMaxIncomingDynamicStreams,
1724 client_max_open_outgoing_bidirectional_streams);
1725 EXPECT_EQ(kServerMaxIncomingDynamicStreams,
1726 client_max_open_outgoing_unidirectional_streams);
1727 server_thread_->Pause();
1728 QuicSession* server_session = GetServerSession();
1729 size_t server_max_open_outgoing_bidirectional_streams =
fkastenholz305e1732019-06-18 05:01:22 -07001730 VersionHasIetfQuicFrames(
1731 server_session->connection()->transport_version())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001732 ? QuicSessionPeer::v99_streamid_manager(server_session)
1733 ->max_allowed_outgoing_bidirectional_streams()
1734 : QuicSessionPeer::GetStreamIdManager(server_session)
1735 ->max_open_outgoing_streams();
1736 size_t server_max_open_outgoing_unidirectional_streams =
fkastenholz305e1732019-06-18 05:01:22 -07001737 VersionHasIetfQuicFrames(
1738 server_session->connection()->transport_version())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001739 ? QuicSessionPeer::v99_streamid_manager(server_session)
renjietang3a1bb802019-06-11 10:42:41 -07001740 ->max_allowed_outgoing_unidirectional_streams() -
renjietang216dc012019-08-27 11:28:27 -07001741 server_session->num_expected_unidirectional_static_streams()
QUICHE teama6ef0a62019-03-07 20:34:33 -05001742 : QuicSessionPeer::GetStreamIdManager(server_session)
1743 ->max_open_outgoing_streams();
1744 EXPECT_EQ(kClientMaxIncomingDynamicStreams,
1745 server_max_open_outgoing_bidirectional_streams);
1746 EXPECT_EQ(kClientMaxIncomingDynamicStreams,
1747 server_max_open_outgoing_unidirectional_streams);
renjietang87cd7de2019-08-16 08:35:10 -07001748
QUICHE teama6ef0a62019-03-07 20:34:33 -05001749 server_thread_->Resume();
1750}
1751
1752TEST_P(EndToEndTest, NegotiateCongestionControl) {
1753 ASSERT_TRUE(Initialize());
1754
1755 // For PCC, the underlying implementation may be a stub with a
1756 // different name-tag. Skip the rest of this test.
1757 if (GetParam().congestion_control_tag == kTPCC) {
1758 return;
1759 }
1760
1761 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1762
1763 CongestionControlType expected_congestion_control_type = kRenoBytes;
1764 switch (GetParam().congestion_control_tag) {
1765 case kRENO:
1766 expected_congestion_control_type = kRenoBytes;
1767 break;
1768 case kTBBR:
1769 expected_congestion_control_type = kBBR;
1770 break;
1771 case kQBIC:
1772 expected_congestion_control_type = kCubicBytes;
1773 break;
wuba9a43cb2019-07-17 15:22:42 -07001774 case kB2ON:
1775 expected_congestion_control_type = kBBRv2;
1776 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001777 default:
1778 QUIC_DLOG(FATAL) << "Unexpected congestion control tag";
1779 }
1780
1781 server_thread_->Pause();
1782 EXPECT_EQ(expected_congestion_control_type,
1783 QuicSentPacketManagerPeer::GetSendAlgorithm(
1784 *GetSentPacketManagerFromFirstServerSession())
1785 ->GetCongestionControlType());
1786 server_thread_->Resume();
1787}
1788
1789TEST_P(EndToEndTest, ClientSuggestsRTT) {
1790 // Client suggests initial RTT, verify it is used.
1791 const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
1792 client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
1793
1794 ASSERT_TRUE(Initialize());
1795 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1796 server_thread_->WaitForCryptoHandshakeConfirmed();
1797
1798 // Pause the server so we can access the server's internals without races.
1799 server_thread_->Pause();
1800 QuicDispatcher* dispatcher =
1801 QuicServerPeer::GetDispatcher(server_thread_->server());
1802 ASSERT_EQ(1u, dispatcher->session_map().size());
1803 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001804 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001805 const QuicSentPacketManager* server_sent_packet_manager =
1806 GetSentPacketManagerFromFirstServerSession();
1807
1808 EXPECT_EQ(kInitialRTT,
1809 client_sent_packet_manager.GetRttStats()->initial_rtt());
1810 EXPECT_EQ(kInitialRTT,
1811 server_sent_packet_manager->GetRttStats()->initial_rtt());
1812 server_thread_->Resume();
1813}
1814
1815TEST_P(EndToEndTest, ClientSuggestsIgnoredRTT) {
1816 // Client suggests initial RTT, but also specifies NRTT, so it's not used.
1817 const QuicTime::Delta kInitialRTT = QuicTime::Delta::FromMicroseconds(20000);
1818 client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT.ToMicroseconds());
1819 QuicTagVector options;
1820 options.push_back(kNRTT);
1821 client_config_.SetConnectionOptionsToSend(options);
1822
1823 ASSERT_TRUE(Initialize());
1824 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1825 server_thread_->WaitForCryptoHandshakeConfirmed();
1826
1827 // Pause the server so we can access the server's internals without races.
1828 server_thread_->Pause();
1829 QuicDispatcher* dispatcher =
1830 QuicServerPeer::GetDispatcher(server_thread_->server());
1831 ASSERT_EQ(1u, dispatcher->session_map().size());
1832 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001833 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001834 const QuicSentPacketManager* server_sent_packet_manager =
1835 GetSentPacketManagerFromFirstServerSession();
1836
1837 EXPECT_EQ(kInitialRTT,
1838 client_sent_packet_manager.GetRttStats()->initial_rtt());
1839 EXPECT_EQ(kInitialRTT,
1840 server_sent_packet_manager->GetRttStats()->initial_rtt());
1841 server_thread_->Resume();
1842}
1843
1844TEST_P(EndToEndTest, MaxInitialRTT) {
1845 // Client tries to suggest twice the server's max initial rtt and the server
1846 // uses the max.
1847 client_config_.SetInitialRoundTripTimeUsToSend(2 *
1848 kMaxInitialRoundTripTimeUs);
1849
1850 ASSERT_TRUE(Initialize());
1851 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1852 server_thread_->WaitForCryptoHandshakeConfirmed();
1853
1854 // Pause the server so we can access the server's internals without races.
1855 server_thread_->Pause();
1856 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001857 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001858
1859 // Now that acks have been exchanged, the RTT estimate has decreased on the
1860 // server and is not infinite on the client.
1861 EXPECT_FALSE(
1862 client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
1863 const RttStats& server_rtt_stats =
1864 *GetServerConnection()->sent_packet_manager().GetRttStats();
1865 EXPECT_EQ(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
1866 server_rtt_stats.initial_rtt().ToMicroseconds());
1867 EXPECT_GE(static_cast<int64_t>(kMaxInitialRoundTripTimeUs),
1868 server_rtt_stats.smoothed_rtt().ToMicroseconds());
1869 server_thread_->Resume();
1870}
1871
1872TEST_P(EndToEndTest, MinInitialRTT) {
1873 // Client tries to suggest 0 and the server uses the default.
1874 client_config_.SetInitialRoundTripTimeUsToSend(0);
1875
1876 ASSERT_TRUE(Initialize());
1877 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1878 server_thread_->WaitForCryptoHandshakeConfirmed();
1879
1880 // Pause the server so we can access the server's internals without races.
1881 server_thread_->Pause();
1882 const QuicSentPacketManager& client_sent_packet_manager =
fkastenholz7591c282019-08-13 12:58:38 -07001883 GetClientConnection()->sent_packet_manager();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001884 const QuicSentPacketManager& server_sent_packet_manager =
1885 GetServerConnection()->sent_packet_manager();
1886
1887 // Now that acks have been exchanged, the RTT estimate has decreased on the
1888 // server and is not infinite on the client.
1889 EXPECT_FALSE(
1890 client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
1891 // Expect the default rtt of 100ms.
1892 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100),
1893 server_sent_packet_manager.GetRttStats()->initial_rtt());
1894 // Ensure the bandwidth is valid.
1895 client_sent_packet_manager.BandwidthEstimate();
1896 server_sent_packet_manager.BandwidthEstimate();
1897 server_thread_->Resume();
1898}
1899
1900TEST_P(EndToEndTest, 0ByteConnectionId) {
fayangd4291e42019-05-30 10:31:21 -07001901 if (VersionHasIetfInvariantHeader(
1902 GetParam().negotiated_version.transport_version)) {
dschinazi6dc83682019-05-28 16:46:47 -07001903 // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
1904 ASSERT_TRUE(Initialize());
1905 return;
1906 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001907 client_config_.SetBytesForConnectionIdToSend(0);
1908 ASSERT_TRUE(Initialize());
1909
1910 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1911 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -07001912 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001913 QuicPacketHeader* header =
1914 QuicConnectionPeer::GetLastHeader(client_connection);
dschinazi5e1a7b22019-07-31 12:23:21 -07001915 EXPECT_EQ(CONNECTION_ID_ABSENT, header->source_connection_id_included);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001916}
1917
1918TEST_P(EndToEndTestWithTls, 8ByteConnectionId) {
fayangd4291e42019-05-30 10:31:21 -07001919 if (VersionHasIetfInvariantHeader(
1920 GetParam().negotiated_version.transport_version)) {
dschinazi6dc83682019-05-28 16:46:47 -07001921 // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
1922 ASSERT_TRUE(Initialize());
1923 return;
1924 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001925 client_config_.SetBytesForConnectionIdToSend(8);
1926 ASSERT_TRUE(Initialize());
1927
1928 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1929 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -07001930 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001931 QuicPacketHeader* header =
1932 QuicConnectionPeer::GetLastHeader(client_connection);
dschinazi6dc83682019-05-28 16:46:47 -07001933 EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001934}
1935
1936TEST_P(EndToEndTestWithTls, 15ByteConnectionId) {
fayangd4291e42019-05-30 10:31:21 -07001937 if (VersionHasIetfInvariantHeader(
1938 GetParam().negotiated_version.transport_version)) {
dschinazi6dc83682019-05-28 16:46:47 -07001939 // SetBytesForConnectionIdToSend only applies to Google QUIC encoding.
1940 ASSERT_TRUE(Initialize());
1941 return;
1942 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001943 client_config_.SetBytesForConnectionIdToSend(15);
1944 ASSERT_TRUE(Initialize());
1945
1946 // Our server is permissive and allows for out of bounds values.
1947 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1948 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
fkastenholz7591c282019-08-13 12:58:38 -07001949 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001950 QuicPacketHeader* header =
1951 QuicConnectionPeer::GetLastHeader(client_connection);
dschinazi6dc83682019-05-28 16:46:47 -07001952 EXPECT_EQ(CONNECTION_ID_PRESENT, header->destination_connection_id_included);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001953}
1954
1955TEST_P(EndToEndTestWithTls, ResetConnection) {
1956 ASSERT_TRUE(Initialize());
1957
1958 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
1959 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1960 client_->ResetConnection();
1961 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1962 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
1963 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
1964}
1965
1966// TODO(nharper): Needs to get turned back to EndToEndTestWithTls
1967// when we figure out why the test doesn't work on chrome.
1968TEST_P(EndToEndTest, MaxStreamsUberTest) {
wubbd64c102019-05-13 11:58:17 -07001969 // Connect with lower fake packet loss than we'd like to test. Until
1970 // b/10126687 is fixed, losing handshake packets is pretty brutal.
1971 SetPacketLossPercentage(1);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001972 ASSERT_TRUE(Initialize());
vasilvvc48c8712019-03-11 13:38:16 -07001973 std::string large_body(10240, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001974 int max_streams = 100;
1975
1976 AddToCache("/large_response", 200, large_body);
1977
1978 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1979 SetPacketLossPercentage(10);
1980
1981 for (int i = 0; i < max_streams; ++i) {
1982 EXPECT_LT(0, client_->SendRequest("/large_response"));
1983 }
1984
1985 // WaitForEvents waits 50ms and returns true if there are outstanding
1986 // requests.
1987 while (client_->client()->WaitForEvents() == true) {
1988 }
1989}
1990
1991TEST_P(EndToEndTestWithTls, StreamCancelErrorTest) {
1992 ASSERT_TRUE(Initialize());
vasilvvc48c8712019-03-11 13:38:16 -07001993 std::string small_body(256, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05001994
1995 AddToCache("/small_response", 200, small_body);
1996
1997 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
1998
fkastenholz7591c282019-08-13 12:58:38 -07001999 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002000 // Lose the request.
2001 SetPacketLossPercentage(100);
2002 EXPECT_LT(0, client_->SendRequest("/small_response"));
2003 client_->client()->WaitForEvents();
2004 // Transmit the cancel, and ensure the connection is torn down properly.
2005 SetPacketLossPercentage(0);
2006 QuicStreamId stream_id = GetNthClientInitiatedBidirectionalId(0);
2007 session->SendRstStream(stream_id, QUIC_STREAM_CANCELLED, 0);
2008
2009 // WaitForEvents waits 50ms and returns true if there are outstanding
2010 // requests.
2011 while (client_->client()->WaitForEvents() == true) {
2012 }
2013 // It should be completely fine to RST a stream before any data has been
2014 // received for that stream.
2015 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
2016}
2017
2018TEST_P(EndToEndTest, ConnectionMigrationClientIPChanged) {
2019 ASSERT_TRUE(Initialize());
2020 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2021 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2022
2023 // Store the client IP address which was used to send the first request.
2024 QuicIpAddress old_host =
2025 client_->client()->network_helper()->GetLatestClientAddress().host();
2026
2027 // Migrate socket to the new IP address.
2028 QuicIpAddress new_host = TestLoopback(2);
2029 EXPECT_NE(old_host, new_host);
2030 ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
2031
2032 // Send a request using the new socket.
2033 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
2034 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2035}
2036
2037TEST_P(EndToEndTest, ConnectionMigrationClientPortChanged) {
2038 // Tests that the client's port can change during an established QUIC
2039 // connection, and that doing so does not result in the connection being
2040 // closed by the server.
2041 ASSERT_TRUE(Initialize());
2042
2043 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2044 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2045
2046 // Store the client address which was used to send the first request.
2047 QuicSocketAddress old_address =
2048 client_->client()->network_helper()->GetLatestClientAddress();
2049 int old_fd = client_->client()->GetLatestFD();
2050
2051 // Create a new socket before closing the old one, which will result in a new
2052 // ephemeral port.
2053 QuicClientPeer::CreateUDPSocketAndBind(client_->client());
2054
2055 // Stop listening and close the old FD.
2056 QuicClientPeer::CleanUpUDPSocket(client_->client(), old_fd);
2057
2058 // The packet writer needs to be updated to use the new FD.
2059 client_->client()->network_helper()->CreateQuicPacketWriter();
2060
2061 // Change the internal state of the client and connection to use the new port,
2062 // this is done because in a real NAT rebinding the client wouldn't see any
2063 // port change, and so expects no change to incoming port.
2064 // This is kind of ugly, but needed as we are simply swapping out the client
2065 // FD rather than any more complex NAT rebinding simulation.
2066 int new_port =
2067 client_->client()->network_helper()->GetLatestClientAddress().port();
2068 QuicClientPeer::SetClientPort(client_->client(), new_port);
fkastenholz7591c282019-08-13 12:58:38 -07002069 QuicConnectionPeer::SetSelfAddress(GetClientConnection(),
2070 QuicSocketAddress(client_->client()
2071 ->client_session()
2072 ->connection()
2073 ->self_address()
2074 .host(),
2075 new_port));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002076
2077 // Register the new FD for epoll events.
2078 int new_fd = client_->client()->GetLatestFD();
2079 QuicEpollServer* eps = client_->epoll_server();
2080 eps->RegisterFD(new_fd, client_->client()->epoll_network_helper(),
2081 EPOLLIN | EPOLLOUT | EPOLLET);
2082
2083 // Send a second request, using the new FD.
2084 EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
2085 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2086
2087 // Verify that the client's ephemeral port is different.
2088 QuicSocketAddress new_address =
2089 client_->client()->network_helper()->GetLatestClientAddress();
2090 EXPECT_EQ(old_address.host(), new_address.host());
2091 EXPECT_NE(old_address.port(), new_address.port());
2092}
2093
2094TEST_P(EndToEndTest, NegotiatedInitialCongestionWindow) {
2095 SetQuicReloadableFlag(quic_unified_iw_options, true);
2096 client_extra_copts_.push_back(kIW03);
2097
2098 ASSERT_TRUE(Initialize());
2099
2100 // Values are exchanged during crypto handshake, so wait for that to finish.
2101 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2102 server_thread_->WaitForCryptoHandshakeConfirmed();
2103 server_thread_->Pause();
2104
2105 QuicPacketCount cwnd =
2106 GetServerConnection()->sent_packet_manager().initial_congestion_window();
2107 EXPECT_EQ(3u, cwnd);
2108}
2109
2110TEST_P(EndToEndTest, DifferentFlowControlWindows) {
2111 // Client and server can set different initial flow control receive windows.
2112 // These are sent in CHLO/SHLO. Tests that these values are exchanged properly
2113 // in the crypto handshake.
2114 const uint32_t kClientStreamIFCW = 123456;
2115 const uint32_t kClientSessionIFCW = 234567;
2116 set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
2117 set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
2118
2119 uint32_t kServerStreamIFCW = 32 * 1024;
2120 uint32_t kServerSessionIFCW = 48 * 1024;
2121 set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
2122 set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
2123
2124 ASSERT_TRUE(Initialize());
2125
2126 // Values are exchanged during crypto handshake, so wait for that to finish.
2127 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2128 server_thread_->WaitForCryptoHandshakeConfirmed();
2129
2130 // Open a data stream to make sure the stream level flow control is updated.
2131 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
bnc519216c2019-07-09 05:03:48 -07002132 WriteHeadersOnStream(stream);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002133 stream->WriteOrBufferBody("hello", false);
2134
2135 // Client should have the right values for server's receive window.
2136 EXPECT_EQ(kServerStreamIFCW,
2137 client_->client()
2138 ->client_session()
2139 ->config()
2140 ->ReceivedInitialStreamFlowControlWindowBytes());
2141 EXPECT_EQ(kServerSessionIFCW,
2142 client_->client()
2143 ->client_session()
2144 ->config()
2145 ->ReceivedInitialSessionFlowControlWindowBytes());
2146 EXPECT_EQ(kServerStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
2147 stream->flow_controller()));
fkastenholz7591c282019-08-13 12:58:38 -07002148 EXPECT_EQ(kServerSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
2149 GetClientSession()->flow_controller()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002150
2151 // Server should have the right values for client's receive window.
2152 server_thread_->Pause();
2153 QuicSession* session = GetServerSession();
2154 EXPECT_EQ(kClientStreamIFCW,
2155 session->config()->ReceivedInitialStreamFlowControlWindowBytes());
2156 EXPECT_EQ(kClientSessionIFCW,
2157 session->config()->ReceivedInitialSessionFlowControlWindowBytes());
2158 EXPECT_EQ(kClientSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
2159 session->flow_controller()));
2160 server_thread_->Resume();
2161}
2162
2163// Test negotiation of IFWA connection option.
2164TEST_P(EndToEndTest, NegotiatedServerInitialFlowControlWindow) {
2165 const uint32_t kClientStreamIFCW = 123456;
2166 const uint32_t kClientSessionIFCW = 234567;
2167 set_client_initial_stream_flow_control_receive_window(kClientStreamIFCW);
2168 set_client_initial_session_flow_control_receive_window(kClientSessionIFCW);
2169
2170 uint32_t kServerStreamIFCW = 32 * 1024;
2171 uint32_t kServerSessionIFCW = 48 * 1024;
2172 set_server_initial_stream_flow_control_receive_window(kServerStreamIFCW);
2173 set_server_initial_session_flow_control_receive_window(kServerSessionIFCW);
2174
2175 // Bump the window.
2176 const uint32_t kExpectedStreamIFCW = 1024 * 1024;
2177 const uint32_t kExpectedSessionIFCW = 1.5 * 1024 * 1024;
2178 client_extra_copts_.push_back(kIFWA);
2179
2180 ASSERT_TRUE(Initialize());
2181
2182 // Values are exchanged during crypto handshake, so wait for that to finish.
2183 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2184 server_thread_->WaitForCryptoHandshakeConfirmed();
2185
2186 // Open a data stream to make sure the stream level flow control is updated.
2187 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
bnc519216c2019-07-09 05:03:48 -07002188 WriteHeadersOnStream(stream);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002189 stream->WriteOrBufferBody("hello", false);
2190
2191 // Client should have the right values for server's receive window.
2192 EXPECT_EQ(kExpectedStreamIFCW,
2193 client_->client()
2194 ->client_session()
2195 ->config()
2196 ->ReceivedInitialStreamFlowControlWindowBytes());
2197 EXPECT_EQ(kExpectedSessionIFCW,
2198 client_->client()
2199 ->client_session()
2200 ->config()
2201 ->ReceivedInitialSessionFlowControlWindowBytes());
2202 EXPECT_EQ(kExpectedStreamIFCW, QuicFlowControllerPeer::SendWindowOffset(
2203 stream->flow_controller()));
fkastenholz7591c282019-08-13 12:58:38 -07002204 EXPECT_EQ(kExpectedSessionIFCW, QuicFlowControllerPeer::SendWindowOffset(
2205 GetClientSession()->flow_controller()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002206}
2207
2208TEST_P(EndToEndTest, HeadersAndCryptoStreamsNoConnectionFlowControl) {
2209 // The special headers and crypto streams should be subject to per-stream flow
2210 // control limits, but should not be subject to connection level flow control
2211 const uint32_t kStreamIFCW = 32 * 1024;
2212 const uint32_t kSessionIFCW = 48 * 1024;
2213 set_client_initial_stream_flow_control_receive_window(kStreamIFCW);
2214 set_client_initial_session_flow_control_receive_window(kSessionIFCW);
2215 set_server_initial_stream_flow_control_receive_window(kStreamIFCW);
2216 set_server_initial_session_flow_control_receive_window(kSessionIFCW);
2217
2218 ASSERT_TRUE(Initialize());
2219
2220 // Wait for crypto handshake to finish. This should have contributed to the
2221 // crypto stream flow control window, but not affected the session flow
2222 // control window.
2223 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2224 server_thread_->WaitForCryptoHandshakeConfirmed();
2225
fkastenholz7591c282019-08-13 12:58:38 -07002226 QuicCryptoStream* crypto_stream =
2227 QuicSessionPeer::GetMutableCryptoStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002228 // In v47 and later, the crypto handshake (sent in CRYPTO frames) is not
2229 // subject to flow control.
renjietang2abedac2019-05-20 14:04:50 -07002230 const QuicTransportVersion transport_version =
fkastenholz7591c282019-08-13 12:58:38 -07002231 GetClientConnection()->transport_version();
renjietang2abedac2019-05-20 14:04:50 -07002232 if (!QuicVersionUsesCryptoFrames(transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002233 EXPECT_LT(QuicFlowControllerPeer::SendWindowSize(
2234 crypto_stream->flow_controller()),
2235 kStreamIFCW);
2236 }
renjietang3a1bb802019-06-11 10:42:41 -07002237 // When stream type is enabled, control streams will send settings and
2238 // contribute to flow control windows, so this expectation is no longer valid.
2239 if (!VersionHasStreamType(transport_version)) {
fkastenholz7591c282019-08-13 12:58:38 -07002240 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
2241 GetClientSession()->flow_controller()));
renjietang3a1bb802019-06-11 10:42:41 -07002242 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002243
2244 // Send a request with no body, and verify that the connection level window
2245 // has not been affected.
2246 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2247
renjietang2abedac2019-05-20 14:04:50 -07002248 // No headers stream in IETF QUIC.
2249 if (VersionUsesQpack(transport_version)) {
2250 return;
2251 }
2252
fkastenholz7591c282019-08-13 12:58:38 -07002253 QuicHeadersStream* headers_stream =
2254 QuicSpdySessionPeer::GetHeadersStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002255 EXPECT_LT(
2256 QuicFlowControllerPeer::SendWindowSize(headers_stream->flow_controller()),
2257 kStreamIFCW);
fkastenholz7591c282019-08-13 12:58:38 -07002258 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize(
2259 GetClientSession()->flow_controller()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002260
2261 // Server should be in a similar state: connection flow control window should
2262 // not have any bytes marked as received.
2263 server_thread_->Pause();
2264 QuicSession* session = GetServerSession();
2265 QuicFlowController* server_connection_flow_controller =
2266 session->flow_controller();
2267 EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::ReceiveWindowSize(
2268 server_connection_flow_controller));
2269 server_thread_->Resume();
2270}
2271
2272TEST_P(EndToEndTest, FlowControlsSynced) {
2273 set_smaller_flow_control_receive_window();
2274
2275 ASSERT_TRUE(Initialize());
2276
2277 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2278 server_thread_->WaitForCryptoHandshakeConfirmed();
2279
2280 server_thread_->Pause();
fkastenholz7591c282019-08-13 12:58:38 -07002281 QuicSpdySession* const client_session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002282 auto* server_session = static_cast<QuicSpdySession*>(GetServerSession());
renjietang3a1bb802019-06-11 10:42:41 -07002283
renjietang118c8ac2019-07-30 11:43:59 -07002284 if (VersionHasStreamType(server_session->connection()->transport_version())) {
renjietang3a1bb802019-06-11 10:42:41 -07002285 // Settings frame will be sent through control streams, which contribute
2286 // to the session's flow controller. And due to the timing issue described
2287 // below, the settings frame might not be received.
2288 HttpEncoder encoder;
2289 SettingsFrame settings;
renjietang87cd7de2019-08-16 08:35:10 -07002290 settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] =
2291 kDefaultMaxUncompressedHeaderSize;
2292 settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
2293 kDefaultQpackMaxDynamicTableCapacity;
renjietang3a1bb802019-06-11 10:42:41 -07002294 std::unique_ptr<char[]> buffer;
2295 auto header_length = encoder.SerializeSettingsFrame(settings, &buffer);
2296 QuicByteCount win_difference1 = QuicFlowControllerPeer::ReceiveWindowSize(
2297 server_session->flow_controller()) -
2298 QuicFlowControllerPeer::SendWindowSize(
2299 client_session->flow_controller());
2300 QuicByteCount win_difference2 = QuicFlowControllerPeer::ReceiveWindowSize(
2301 client_session->flow_controller()) -
2302 QuicFlowControllerPeer::SendWindowSize(
2303 server_session->flow_controller());
2304 EXPECT_TRUE(win_difference1 == 0 ||
2305 win_difference1 ==
2306 header_length +
renjietang87cd7de2019-08-16 08:35:10 -07002307 QuicDataWriter::GetVarInt62Len(kControlStream) +
2308 QuicDataWriter::GetVarInt62Len(kQpackEncoderStream) +
2309 QuicDataWriter::GetVarInt62Len(kQpackDecoderStream));
renjietang3a1bb802019-06-11 10:42:41 -07002310 EXPECT_TRUE(win_difference2 == 0 ||
2311 win_difference2 ==
2312 header_length +
renjietang87cd7de2019-08-16 08:35:10 -07002313 QuicDataWriter::GetVarInt62Len(kControlStream) +
2314 QuicDataWriter::GetVarInt62Len(kQpackEncoderStream) +
2315 QuicDataWriter::GetVarInt62Len(kQpackDecoderStream));
renjietang3a1bb802019-06-11 10:42:41 -07002316 // The test returns early because in this version, headers stream no longer
2317 // sends settings.
2318 return;
2319 }
2320
QUICHE teama6ef0a62019-03-07 20:34:33 -05002321 ExpectFlowControlsSynced(client_session->flow_controller(),
2322 server_session->flow_controller());
nharperd5c4a932019-05-13 13:58:49 -07002323 if (!QuicVersionUsesCryptoFrames(client_->client()
2324 ->client_session()
2325 ->connection()
2326 ->transport_version())) {
2327 ExpectFlowControlsSynced(
2328 QuicSessionPeer::GetMutableCryptoStream(client_session)
2329 ->flow_controller(),
2330 QuicSessionPeer::GetMutableCryptoStream(server_session)
2331 ->flow_controller());
2332 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05002333 SpdyFramer spdy_framer(SpdyFramer::ENABLE_COMPRESSION);
2334 SpdySettingsIR settings_frame;
2335 settings_frame.AddSetting(SETTINGS_MAX_HEADER_LIST_SIZE,
2336 kDefaultMaxUncompressedHeaderSize);
2337 SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame));
2338 QuicFlowController* client_header_stream_flow_controller =
2339 QuicSpdySessionPeer::GetHeadersStream(client_session)->flow_controller();
2340 QuicFlowController* server_header_stream_flow_controller =
2341 QuicSpdySessionPeer::GetHeadersStream(server_session)->flow_controller();
2342 // Both client and server are sending this SETTINGS frame, and the send
2343 // window is consumed. But because of timing issue, the server may send or
2344 // not send the frame, and the client may send/ not send / receive / not
2345 // receive the frame.
2346 // TODO(fayang): Rewrite this part because it is hacky.
2347 QuicByteCount win_difference1 = QuicFlowControllerPeer::ReceiveWindowSize(
2348 server_header_stream_flow_controller) -
2349 QuicFlowControllerPeer::SendWindowSize(
2350 client_header_stream_flow_controller);
2351 QuicByteCount win_difference2 = QuicFlowControllerPeer::ReceiveWindowSize(
2352 client_header_stream_flow_controller) -
2353 QuicFlowControllerPeer::SendWindowSize(
2354 server_header_stream_flow_controller);
2355 EXPECT_TRUE(win_difference1 == 0 || win_difference1 == frame.size());
2356 EXPECT_TRUE(win_difference2 == 0 || win_difference2 == frame.size());
2357
2358 // Client *may* have received the SETTINGs frame.
2359 // TODO(fayang): Rewrite this part because it is hacky.
2360 float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
2361 client_session->flow_controller())) /
2362 QuicFlowControllerPeer::ReceiveWindowSize(
2363 QuicSpdySessionPeer::GetHeadersStream(client_session)
2364 ->flow_controller());
2365 float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize(
2366 client_session->flow_controller())) /
2367 (QuicFlowControllerPeer::ReceiveWindowSize(
2368 QuicSpdySessionPeer::GetHeadersStream(client_session)
2369 ->flow_controller()) +
2370 frame.size());
2371 EXPECT_TRUE(ratio1 == kSessionToStreamRatio ||
2372 ratio2 == kSessionToStreamRatio);
2373
2374 server_thread_->Resume();
2375}
2376
2377TEST_P(EndToEndTestWithTls, RequestWithNoBodyWillNeverSendStreamFrameWithFIN) {
2378 // A stream created on receipt of a simple request with no body will never get
2379 // a stream frame with a FIN. Verify that we don't keep track of the stream in
2380 // the locally closed streams map: it will never be removed if so.
2381 ASSERT_TRUE(Initialize());
2382
2383 // Send a simple headers only request, and receive response.
2384 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2385 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2386
2387 // Now verify that the server is not waiting for a final FIN or RST.
2388 server_thread_->Pause();
2389 QuicSession* session = GetServerSession();
2390 EXPECT_EQ(
2391 0u,
2392 QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(session).size());
2393 server_thread_->Resume();
2394}
2395
2396// A TestAckListener verifies that its OnAckNotification method has been
2397// called exactly once on destruction.
2398class TestAckListener : public QuicAckListenerInterface {
2399 public:
2400 explicit TestAckListener(int bytes_to_ack) : bytes_to_ack_(bytes_to_ack) {}
2401
2402 void OnPacketAcked(int acked_bytes,
2403 QuicTime::Delta /*delta_largest_observed*/) override {
2404 ASSERT_LE(acked_bytes, bytes_to_ack_);
2405 bytes_to_ack_ -= acked_bytes;
2406 }
2407
2408 void OnPacketRetransmitted(int /*retransmitted_bytes*/) override {}
2409
2410 bool has_been_notified() const { return bytes_to_ack_ == 0; }
2411
2412 protected:
2413 // Object is ref counted.
2414 ~TestAckListener() override { EXPECT_EQ(0, bytes_to_ack_); }
2415
2416 private:
2417 int bytes_to_ack_;
2418};
2419
2420class TestResponseListener : public QuicSpdyClientBase::ResponseListener {
2421 public:
2422 void OnCompleteResponse(QuicStreamId id,
2423 const SpdyHeaderBlock& response_headers,
vasilvvc48c8712019-03-11 13:38:16 -07002424 const std::string& response_body) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002425 QUIC_DVLOG(1) << "response for stream " << id << " "
2426 << response_headers.DebugString() << "\n"
2427 << response_body;
2428 }
2429};
2430
2431TEST_P(EndToEndTest, AckNotifierWithPacketLossAndBlockedSocket) {
2432 // Verify that even in the presence of packet loss and occasionally blocked
2433 // socket, an AckNotifierDelegate will get informed that the data it is
2434 // interested in has been ACKed. This tests end-to-end ACK notification, and
2435 // demonstrates that retransmissions do not break this functionality.
wubbd64c102019-05-13 11:58:17 -07002436
2437 SetPacketLossPercentage(5);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002438 ASSERT_TRUE(Initialize());
2439
2440 // Wait for the server SHLO before upping the packet loss.
2441 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2442 SetPacketLossPercentage(30);
2443 client_writer_->set_fake_blocked_socket_percentage(10);
2444
2445 // Create a POST request and send the headers only.
2446 SpdyHeaderBlock headers;
2447 headers[":method"] = "POST";
2448 headers[":path"] = "/foo";
2449 headers[":scheme"] = "https";
2450 headers[":authority"] = server_hostname_;
2451
2452 client_->SendMessage(headers, "", /*fin=*/false);
2453
renjietang2abedac2019-05-20 14:04:50 -07002454 // Size of headers on the request stream. Zero if headers are sent on the
2455 // header stream.
2456 size_t header_size = 0;
2457 if (VersionUsesQpack(client_->client()
2458 ->client_session()
2459 ->connection()
2460 ->transport_version())) {
2461 // Determine size of compressed headers.
2462 NoopDecoderStreamErrorDelegate decoder_stream_error_delegate;
renjietangc2aa5cb2019-06-20 12:22:53 -07002463 NoopQpackStreamSenderDelegate encoder_stream_sender_delegate;
renjietang8a2df8f2019-08-07 10:43:52 -07002464 QpackEncoder qpack_encoder(&decoder_stream_error_delegate);
2465 qpack_encoder.set_qpack_stream_sender_delegate(
2466 &encoder_stream_sender_delegate);
bncf21c1ad2019-06-20 20:09:50 -07002467 std::string encoded_headers =
bnc8c016222019-08-22 04:43:41 -07002468 qpack_encoder.EncodeHeaderList(/* stream_id = */ 0, headers);
renjietang2abedac2019-05-20 14:04:50 -07002469 header_size = encoded_headers.size();
2470 }
2471
QUICHE teama6ef0a62019-03-07 20:34:33 -05002472 // Test the AckNotifier's ability to track multiple packets by making the
2473 // request body exceed the size of a single packet.
vasilvvc48c8712019-03-11 13:38:16 -07002474 std::string request_string = "a request body bigger than one packet" +
dschinazi66dea072019-04-09 11:41:06 -07002475 std::string(kMaxOutgoingPacketSize, '.');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002476
2477 // The TestAckListener will cause a failure if not notified.
2478 QuicReferenceCountedPointer<TestAckListener> ack_listener(
renjietang2abedac2019-05-20 14:04:50 -07002479 new TestAckListener(header_size + request_string.length()));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002480
2481 // Send the request, and register the delegate for ACKs.
2482 client_->SendData(request_string, true, ack_listener);
2483 client_->WaitForResponse();
2484 EXPECT_EQ(kFooResponseBody, client_->response_body());
2485 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2486
2487 // Send another request to flush out any pending ACKs on the server.
2488 client_->SendSynchronousRequest("/bar");
2489
2490 // Make sure the delegate does get the notification it expects.
2491 while (!ack_listener->has_been_notified()) {
2492 // Waits for up to 50 ms.
2493 client_->client()->WaitForEvents();
2494 }
2495}
2496
2497// Send a public reset from the server.
2498TEST_P(EndToEndTestWithTls, ServerSendPublicReset) {
2499 ASSERT_TRUE(Initialize());
2500
2501 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
fkastenholz7591c282019-08-13 12:58:38 -07002502 QuicConnection* client_connection = GetClientConnection();
dschinazi82884662019-08-02 13:25:15 -07002503 QuicConfig* config = client_->client()->session()->config();
2504 EXPECT_TRUE(config->HasReceivedStatelessResetToken());
2505 QuicUint128 stateless_reset_token = config->ReceivedStatelessResetToken();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002506
2507 // Send the public reset.
2508 QuicConnectionId connection_id = client_connection->connection_id();
2509 QuicPublicResetPacket header;
2510 header.connection_id = connection_id;
2511 QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
2512 Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
2513 std::unique_ptr<QuicEncryptedPacket> packet;
fayangd4291e42019-05-30 10:31:21 -07002514 if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002515 packet = framer.BuildIetfStatelessResetPacket(connection_id,
2516 stateless_reset_token);
2517 } else {
2518 packet = framer.BuildPublicResetPacket(header);
2519 }
2520 // We must pause the server's thread in order to call WritePacket without
2521 // race conditions.
2522 server_thread_->Pause();
2523 server_writer_->WritePacket(
2524 packet->data(), packet->length(), server_address_.host(),
2525 client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
2526 server_thread_->Resume();
2527
2528 // The request should fail.
2529 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
2530 EXPECT_TRUE(client_->response_headers()->empty());
2531 EXPECT_EQ(QUIC_PUBLIC_RESET, client_->connection_error());
2532}
2533
2534// Send a public reset from the server for a different connection ID.
2535// It should be ignored.
2536TEST_P(EndToEndTestWithTls, ServerSendPublicResetWithDifferentConnectionId) {
2537 ASSERT_TRUE(Initialize());
2538
2539 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
fkastenholz7591c282019-08-13 12:58:38 -07002540 QuicConnection* client_connection = GetClientConnection();
dschinazi82884662019-08-02 13:25:15 -07002541 QuicConfig* config = client_->client()->session()->config();
2542 EXPECT_TRUE(config->HasReceivedStatelessResetToken());
2543 QuicUint128 stateless_reset_token = config->ReceivedStatelessResetToken();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002544 // Send the public reset.
2545 QuicConnectionId incorrect_connection_id = TestConnectionId(
2546 TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
2547 QuicPublicResetPacket header;
2548 header.connection_id = incorrect_connection_id;
2549 QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
2550 Perspective::IS_SERVER, kQuicDefaultConnectionIdLength);
2551 std::unique_ptr<QuicEncryptedPacket> packet;
2552 testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
fkastenholz7591c282019-08-13 12:58:38 -07002553 GetClientConnection()->set_debug_visitor(&visitor);
fayangd4291e42019-05-30 10:31:21 -07002554 if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002555 packet = framer.BuildIetfStatelessResetPacket(incorrect_connection_id,
2556 stateless_reset_token);
2557 EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
2558 .Times(0);
2559 } else {
2560 packet = framer.BuildPublicResetPacket(header);
2561 EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
2562 .Times(1);
2563 }
2564 // We must pause the server's thread in order to call WritePacket without
2565 // race conditions.
2566 server_thread_->Pause();
2567 server_writer_->WritePacket(
2568 packet->data(), packet->length(), server_address_.host(),
2569 client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
2570 server_thread_->Resume();
2571
fayangd4291e42019-05-30 10:31:21 -07002572 if (VersionHasIetfInvariantHeader(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05002573 // The request should fail. IETF stateless reset does not include connection
2574 // ID.
2575 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
2576 EXPECT_TRUE(client_->response_headers()->empty());
2577 EXPECT_EQ(QUIC_PUBLIC_RESET, client_->connection_error());
2578 return;
2579 }
2580 // The connection should be unaffected.
2581 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2582 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2583
fkastenholz7591c282019-08-13 12:58:38 -07002584 GetClientConnection()->set_debug_visitor(nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002585}
2586
2587// Send a public reset from the client for a different connection ID.
2588// It should be ignored.
2589TEST_P(EndToEndTestWithTls, ClientSendPublicResetWithDifferentConnectionId) {
2590 ASSERT_TRUE(Initialize());
2591
2592 // Send the public reset.
2593 QuicConnectionId incorrect_connection_id = TestConnectionId(
fkastenholz7591c282019-08-13 12:58:38 -07002594 TestConnectionIdToUInt64(GetClientConnection()->connection_id()) + 1);
QUICHE teama6ef0a62019-03-07 20:34:33 -05002595 QuicPublicResetPacket header;
2596 header.connection_id = incorrect_connection_id;
2597 QuicFramer framer(server_supported_versions_, QuicTime::Zero(),
2598 Perspective::IS_CLIENT, kQuicDefaultConnectionIdLength);
2599 std::unique_ptr<QuicEncryptedPacket> packet(
2600 framer.BuildPublicResetPacket(header));
2601 client_writer_->WritePacket(
2602 packet->data(), packet->length(),
2603 client_->client()->network_helper()->GetLatestClientAddress().host(),
2604 server_address_, nullptr);
2605
2606 // The connection should be unaffected.
2607 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2608 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2609}
2610
2611// Send a version negotiation packet from the server for a different
2612// connection ID. It should be ignored.
2613TEST_P(EndToEndTestWithTls,
2614 ServerSendVersionNegotiationWithDifferentConnectionId) {
2615 ASSERT_TRUE(Initialize());
2616
2617 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2618
2619 // Send the version negotiation packet.
fkastenholz7591c282019-08-13 12:58:38 -07002620 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002621 QuicConnectionId incorrect_connection_id = TestConnectionId(
2622 TestConnectionIdToUInt64(client_connection->connection_id()) + 1);
2623 std::unique_ptr<QuicEncryptedPacket> packet(
2624 QuicFramer::BuildVersionNegotiationPacket(
dschinazib417d602019-05-29 13:08:45 -07002625 incorrect_connection_id, EmptyQuicConnectionId(),
fayangd4291e42019-05-30 10:31:21 -07002626 VersionHasIetfInvariantHeader(client_connection->transport_version()),
dschinazi48ac9192019-07-31 00:07:26 -07002627 client_connection->version().HasLengthPrefixedConnectionIds(),
QUICHE teama6ef0a62019-03-07 20:34:33 -05002628 server_supported_versions_));
2629 testing::NiceMock<MockQuicConnectionDebugVisitor> visitor;
2630 client_connection->set_debug_visitor(&visitor);
2631 EXPECT_CALL(visitor, OnIncorrectConnectionId(incorrect_connection_id))
2632 .Times(1);
2633 // We must pause the server's thread in order to call WritePacket without
2634 // race conditions.
2635 server_thread_->Pause();
2636 server_writer_->WritePacket(
2637 packet->data(), packet->length(), server_address_.host(),
2638 client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
2639 server_thread_->Resume();
2640
2641 // The connection should be unaffected.
2642 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2643 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2644
2645 client_connection->set_debug_visitor(nullptr);
2646}
2647
2648// A bad header shouldn't tear down the connection, because the receiver can't
2649// tell the connection ID.
2650TEST_P(EndToEndTestWithTls, BadPacketHeaderTruncated) {
2651 ASSERT_TRUE(Initialize());
2652
2653 // Start the connection.
2654 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2655 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2656
2657 // Packet with invalid public flags.
2658 char packet[] = {// public flags (8 byte connection_id)
2659 0x3C,
2660 // truncated connection ID
2661 0x11};
2662 client_writer_->WritePacket(
2663 &packet[0], sizeof(packet),
2664 client_->client()->network_helper()->GetLatestClientAddress().host(),
2665 server_address_, nullptr);
2666 // Give the server time to process the packet.
2667 QuicSleep(QuicTime::Delta::FromMilliseconds(100));
2668 // Pause the server so we can access the server's internals without races.
2669 server_thread_->Pause();
2670 QuicDispatcher* dispatcher =
2671 QuicServerPeer::GetDispatcher(server_thread_->server());
2672 EXPECT_EQ(QUIC_INVALID_PACKET_HEADER,
2673 QuicDispatcherPeer::GetAndClearLastError(dispatcher));
2674 server_thread_->Resume();
2675
2676 // The connection should not be terminated.
2677 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2678 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2679}
2680
2681// A bad header shouldn't tear down the connection, because the receiver can't
2682// tell the connection ID.
2683TEST_P(EndToEndTestWithTls, BadPacketHeaderFlags) {
2684 ASSERT_TRUE(Initialize());
2685
2686 // Start the connection.
2687 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2688 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2689
2690 // Packet with invalid public flags.
2691 char packet[] = {
2692 // invalid public flags
2693 0xFF,
2694 // connection_id
2695 0x10,
2696 0x32,
2697 0x54,
2698 0x76,
2699 0x98,
2700 0xBA,
2701 0xDC,
2702 0xFE,
2703 // packet sequence number
2704 0xBC,
2705 0x9A,
2706 0x78,
2707 0x56,
2708 0x34,
2709 0x12,
2710 // private flags
2711 0x00,
2712 };
2713 client_writer_->WritePacket(
2714 &packet[0], sizeof(packet),
2715 client_->client()->network_helper()->GetLatestClientAddress().host(),
2716 server_address_, nullptr);
2717 // Give the server time to process the packet.
2718 QuicSleep(QuicTime::Delta::FromMilliseconds(100));
2719 // Pause the server so we can access the server's internals without races.
2720 server_thread_->Pause();
2721 QuicDispatcher* dispatcher =
2722 QuicServerPeer::GetDispatcher(server_thread_->server());
2723 EXPECT_EQ(QUIC_INVALID_PACKET_HEADER,
2724 QuicDispatcherPeer::GetAndClearLastError(dispatcher));
2725 server_thread_->Resume();
2726
2727 // The connection should not be terminated.
2728 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2729 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2730}
2731
2732// Send a packet from the client with bad encrypted data. The server should not
2733// tear down the connection.
2734TEST_P(EndToEndTestWithTls, BadEncryptedData) {
2735 ASSERT_TRUE(Initialize());
2736
2737 // Start the connection.
2738 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2739 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2740
2741 std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
fkastenholz7591c282019-08-13 12:58:38 -07002742 GetClientConnection()->connection_id(), EmptyQuicConnectionId(), false,
2743 false, 1, "At least 20 characters.", CONNECTION_ID_PRESENT,
2744 CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER));
QUICHE teama6ef0a62019-03-07 20:34:33 -05002745 // Damage the encrypted data.
vasilvvc48c8712019-03-11 13:38:16 -07002746 std::string damaged_packet(packet->data(), packet->length());
QUICHE teama6ef0a62019-03-07 20:34:33 -05002747 damaged_packet[30] ^= 0x01;
2748 QUIC_DLOG(INFO) << "Sending bad packet.";
2749 client_writer_->WritePacket(
2750 damaged_packet.data(), damaged_packet.length(),
2751 client_->client()->network_helper()->GetLatestClientAddress().host(),
2752 server_address_, nullptr);
2753 // Give the server time to process the packet.
2754 QuicSleep(QuicTime::Delta::FromMilliseconds(100));
2755 // This error is sent to the connection's OnError (which ignores it), so the
2756 // dispatcher doesn't see it.
2757 // Pause the server so we can access the server's internals without races.
2758 server_thread_->Pause();
2759 QuicDispatcher* dispatcher =
2760 QuicServerPeer::GetDispatcher(server_thread_->server());
2761 EXPECT_EQ(QUIC_NO_ERROR,
2762 QuicDispatcherPeer::GetAndClearLastError(dispatcher));
2763 server_thread_->Resume();
2764
2765 // The connection should not be terminated.
2766 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
2767 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
2768}
2769
2770TEST_P(EndToEndTestWithTls, CanceledStreamDoesNotBecomeZombie) {
2771 ASSERT_TRUE(Initialize());
2772 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2773 // Lose the request.
2774 SetPacketLossPercentage(100);
2775 SpdyHeaderBlock headers;
2776 headers[":method"] = "POST";
2777 headers[":path"] = "/foo";
2778 headers[":scheme"] = "https";
2779 headers[":authority"] = server_hostname_;
2780 client_->SendMessage(headers, "test_body", /*fin=*/false);
2781 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
2782
2783 // Cancel the stream.
2784 stream->Reset(QUIC_STREAM_CANCELLED);
fkastenholz7591c282019-08-13 12:58:38 -07002785 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05002786 // Verify canceled stream does not become zombie.
2787 EXPECT_TRUE(QuicSessionPeer::zombie_streams(session).empty());
2788 EXPECT_EQ(1u, QuicSessionPeer::closed_streams(session).size());
2789}
2790
2791// A test stream that gives |response_body_| as an error response body.
2792class ServerStreamWithErrorResponseBody : public QuicSimpleServerStream {
2793 public:
2794 ServerStreamWithErrorResponseBody(
2795 QuicStreamId id,
2796 QuicSpdySession* session,
2797 QuicSimpleServerBackend* quic_simple_server_backend,
vasilvvc48c8712019-03-11 13:38:16 -07002798 std::string response_body)
QUICHE teama6ef0a62019-03-07 20:34:33 -05002799 : QuicSimpleServerStream(id,
2800 session,
2801 BIDIRECTIONAL,
2802 quic_simple_server_backend),
2803 response_body_(std::move(response_body)) {}
2804
2805 ~ServerStreamWithErrorResponseBody() override = default;
2806
2807 protected:
2808 void SendErrorResponse() override {
2809 QUIC_DLOG(INFO) << "Sending error response for stream " << id();
2810 SpdyHeaderBlock headers;
2811 headers[":status"] = "500";
2812 headers["content-length"] =
2813 QuicTextUtils::Uint64ToString(response_body_.size());
2814 // This method must call CloseReadSide to cause the test case, StopReading
2815 // is not sufficient.
2816 QuicStreamPeer::CloseReadSide(this);
2817 SendHeadersAndBody(std::move(headers), response_body_);
2818 }
2819
vasilvvc48c8712019-03-11 13:38:16 -07002820 std::string response_body_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002821};
2822
2823class StreamWithErrorFactory : public QuicTestServer::StreamFactory {
2824 public:
vasilvvc48c8712019-03-11 13:38:16 -07002825 explicit StreamWithErrorFactory(std::string response_body)
QUICHE teama6ef0a62019-03-07 20:34:33 -05002826 : response_body_(std::move(response_body)) {}
2827
2828 ~StreamWithErrorFactory() override = default;
2829
2830 QuicSimpleServerStream* CreateStream(
2831 QuicStreamId id,
2832 QuicSpdySession* session,
2833 QuicSimpleServerBackend* quic_simple_server_backend) override {
2834 return new ServerStreamWithErrorResponseBody(
2835 id, session, quic_simple_server_backend, response_body_);
2836 }
2837
2838 private:
vasilvvc48c8712019-03-11 13:38:16 -07002839 std::string response_body_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05002840};
2841
2842// A test server stream that drops all received body.
2843class ServerStreamThatDropsBody : public QuicSimpleServerStream {
2844 public:
2845 ServerStreamThatDropsBody(QuicStreamId id,
2846 QuicSpdySession* session,
2847 QuicSimpleServerBackend* quic_simple_server_backend)
2848 : QuicSimpleServerStream(id,
2849 session,
2850 BIDIRECTIONAL,
2851 quic_simple_server_backend) {}
2852
2853 ~ServerStreamThatDropsBody() override = default;
2854
2855 protected:
2856 void OnBodyAvailable() override {
2857 while (HasBytesToRead()) {
2858 struct iovec iov;
2859 if (GetReadableRegions(&iov, 1) == 0) {
2860 // No more data to read.
2861 break;
2862 }
2863 QUIC_DVLOG(1) << "Processed " << iov.iov_len << " bytes for stream "
2864 << id();
2865 MarkConsumed(iov.iov_len);
2866 }
2867
2868 if (!sequencer()->IsClosed()) {
2869 sequencer()->SetUnblocked();
2870 return;
2871 }
2872
2873 // If the sequencer is closed, then all the body, including the fin, has
2874 // been consumed.
2875 OnFinRead();
2876
2877 if (write_side_closed() || fin_buffered()) {
2878 return;
2879 }
2880
2881 SendResponse();
2882 }
2883};
2884
2885class ServerStreamThatDropsBodyFactory : public QuicTestServer::StreamFactory {
2886 public:
2887 ServerStreamThatDropsBodyFactory() = default;
2888
2889 ~ServerStreamThatDropsBodyFactory() override = default;
2890
2891 QuicSimpleServerStream* CreateStream(
2892 QuicStreamId id,
2893 QuicSpdySession* session,
2894 QuicSimpleServerBackend* quic_simple_server_backend) override {
2895 return new ServerStreamThatDropsBody(id, session,
2896 quic_simple_server_backend);
2897 }
2898};
2899
2900// A test server stream that sends response with body size greater than 4GB.
2901class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
2902 public:
2903 ServerStreamThatSendsHugeResponse(
2904 QuicStreamId id,
2905 QuicSpdySession* session,
2906 QuicSimpleServerBackend* quic_simple_server_backend,
2907 int64_t body_bytes)
2908 : QuicSimpleServerStream(id,
2909 session,
2910 BIDIRECTIONAL,
2911 quic_simple_server_backend),
2912 body_bytes_(body_bytes) {}
2913
2914 ~ServerStreamThatSendsHugeResponse() override = default;
2915
2916 protected:
2917 void SendResponse() override {
2918 QuicBackendResponse response;
vasilvvc48c8712019-03-11 13:38:16 -07002919 std::string body(body_bytes_, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002920 response.set_body(body);
2921 SendHeadersAndBodyAndTrailers(response.headers().Clone(), response.body(),
2922 response.trailers().Clone());
2923 }
2924
2925 private:
2926 // Use a explicit int64_t rather than size_t to simulate a 64-bit server
2927 // talking to a 32-bit client.
2928 int64_t body_bytes_;
2929};
2930
2931class ServerStreamThatSendsHugeResponseFactory
2932 : public QuicTestServer::StreamFactory {
2933 public:
2934 explicit ServerStreamThatSendsHugeResponseFactory(int64_t body_bytes)
2935 : body_bytes_(body_bytes) {}
2936
2937 ~ServerStreamThatSendsHugeResponseFactory() override = default;
2938
2939 QuicSimpleServerStream* CreateStream(
2940 QuicStreamId id,
2941 QuicSpdySession* session,
2942 QuicSimpleServerBackend* quic_simple_server_backend) override {
2943 return new ServerStreamThatSendsHugeResponse(
2944 id, session, quic_simple_server_backend, body_bytes_);
2945 }
2946
2947 int64_t body_bytes_;
2948};
2949
2950TEST_P(EndToEndTest, EarlyResponseFinRecording) {
2951 set_smaller_flow_control_receive_window();
2952
2953 // Verify that an incoming FIN is recorded in a stream object even if the read
2954 // side has been closed. This prevents an entry from being made in
2955 // locally_close_streams_highest_offset_ (which will never be deleted).
2956 // To set up the test condition, the server must do the following in order:
2957 // start sending the response and call CloseReadSide
2958 // receive the FIN of the request
2959 // send the FIN of the response
2960
2961 // The response body must be larger than the flow control window so the server
2962 // must receive a window update from the client before it can finish sending
2963 // it.
2964 uint32_t response_body_size =
2965 2 * client_config_.GetInitialStreamFlowControlWindowToSend();
vasilvvc48c8712019-03-11 13:38:16 -07002966 std::string response_body(response_body_size, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002967
2968 StreamWithErrorFactory stream_factory(response_body);
2969 SetSpdyStreamFactory(&stream_factory);
2970
2971 ASSERT_TRUE(Initialize());
2972
2973 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
2974
2975 // A POST that gets an early error response, after the headers are received
2976 // and before the body is received, due to invalid content-length.
2977 // Set an invalid content-length, so the request will receive an early 500
2978 // response.
2979 SpdyHeaderBlock headers;
2980 headers[":method"] = "POST";
2981 headers[":path"] = "/garbage";
2982 headers[":scheme"] = "https";
2983 headers[":authority"] = server_hostname_;
2984 headers["content-length"] = "-1";
2985
2986 // The body must be large enough that the FIN will be in a different packet
2987 // than the end of the headers, but short enough to not require a flow control
2988 // update. This allows headers processing to trigger the error response
2989 // before the request FIN is processed but receive the request FIN before the
2990 // response is sent completely.
dschinazi66dea072019-04-09 11:41:06 -07002991 const uint32_t kRequestBodySize = kMaxOutgoingPacketSize + 10;
vasilvvc48c8712019-03-11 13:38:16 -07002992 std::string request_body(kRequestBodySize, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05002993
2994 // Send the request.
2995 client_->SendMessage(headers, request_body);
2996 client_->WaitForResponse();
2997 EXPECT_EQ("500", client_->response_headers()->find(":status")->second);
2998
2999 // Pause the server so we can access the server's internals without races.
3000 server_thread_->Pause();
3001
3002 QuicDispatcher* dispatcher =
3003 QuicServerPeer::GetDispatcher(server_thread_->server());
3004 QuicDispatcher::SessionMap const& map =
3005 QuicDispatcherPeer::session_map(dispatcher);
3006 auto it = map.begin();
3007 EXPECT_TRUE(it != map.end());
3008 QuicSession* server_session = it->second.get();
3009
3010 // The stream is not waiting for the arrival of the peer's final offset.
3011 EXPECT_EQ(
3012 0u, QuicSessionPeer::GetLocallyClosedStreamsHighestOffset(server_session)
3013 .size());
3014
3015 server_thread_->Resume();
3016}
3017
3018TEST_P(EndToEndTestWithTls, Trailers) {
3019 // Test sending and receiving HTTP/2 Trailers (trailing HEADERS frames).
3020 ASSERT_TRUE(Initialize());
3021 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3022
3023 // Set reordering to ensure that Trailers arriving before body is ok.
3024 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3025 SetReorderPercentage(30);
3026
3027 // Add a response with headers, body, and trailers.
vasilvvc48c8712019-03-11 13:38:16 -07003028 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003029
3030 SpdyHeaderBlock headers;
3031 headers[":status"] = "200";
3032 headers[":version"] = "HTTP/1.1";
3033 headers["content-length"] = QuicTextUtils::Uint64ToString(kBody.size());
3034
3035 SpdyHeaderBlock trailers;
3036 trailers["some-trailing-header"] = "trailing-header-value";
3037
3038 memory_cache_backend_.AddResponse(server_hostname_, "/trailer_url",
3039 std::move(headers), kBody,
3040 trailers.Clone());
3041
3042 EXPECT_EQ(kBody, client_->SendSynchronousRequest("/trailer_url"));
3043 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3044 EXPECT_EQ(trailers, client_->response_trailers());
3045}
3046
3047class EndToEndTestServerPush : public EndToEndTest {
3048 protected:
3049 const size_t kNumMaxStreams = 10;
3050
3051 EndToEndTestServerPush() : EndToEndTest() {
fkastenholzd3a1de92019-05-15 07:00:07 -07003052 client_config_.SetMaxIncomingBidirectionalStreamsToSend(kNumMaxStreams);
3053 server_config_.SetMaxIncomingBidirectionalStreamsToSend(kNumMaxStreams);
3054 client_config_.SetMaxIncomingUnidirectionalStreamsToSend(kNumMaxStreams);
3055 server_config_.SetMaxIncomingUnidirectionalStreamsToSend(kNumMaxStreams);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003056 support_server_push_ = true;
3057 }
3058
3059 // Add a request with its response and |num_resources| push resources into
3060 // cache.
3061 // If |resource_size| == 0, response body of push resources use default string
3062 // concatenating with resource url. Otherwise, generate a string of
3063 // |resource_size| as body.
vasilvvc48c8712019-03-11 13:38:16 -07003064 void AddRequestAndResponseWithServerPush(std::string host,
3065 std::string path,
3066 std::string response_body,
3067 std::string* push_urls,
QUICHE teama6ef0a62019-03-07 20:34:33 -05003068 const size_t num_resources,
3069 const size_t resource_size) {
3070 bool use_large_response = resource_size != 0;
vasilvvc48c8712019-03-11 13:38:16 -07003071 std::string large_resource;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003072 if (use_large_response) {
3073 // Generate a response common body larger than flow control window for
3074 // push response.
vasilvvc48c8712019-03-11 13:38:16 -07003075 large_resource = std::string(resource_size, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003076 }
3077 std::list<QuicBackendResponse::ServerPushInfo> push_resources;
3078 for (size_t i = 0; i < num_resources; ++i) {
vasilvvc48c8712019-03-11 13:38:16 -07003079 std::string url = push_urls[i];
QUICHE teama6ef0a62019-03-07 20:34:33 -05003080 QuicUrl resource_url(url);
vasilvvc48c8712019-03-11 13:38:16 -07003081 std::string body =
QUICHE teama6ef0a62019-03-07 20:34:33 -05003082 use_large_response
3083 ? large_resource
3084 : QuicStrCat("This is server push response body for ", url);
3085 SpdyHeaderBlock response_headers;
3086 response_headers[":version"] = "HTTP/1.1";
3087 response_headers[":status"] = "200";
3088 response_headers["content-length"] =
3089 QuicTextUtils::Uint64ToString(body.size());
3090 push_resources.push_back(QuicBackendResponse::ServerPushInfo(
3091 resource_url, std::move(response_headers), kV3LowestPriority, body));
3092 }
3093
3094 memory_cache_backend_.AddSimpleResponseWithServerPushResources(
3095 host, path, 200, response_body, push_resources);
3096 }
3097};
3098
3099// Run all server push end to end tests with all supported versions.
3100INSTANTIATE_TEST_SUITE_P(EndToEndTestsServerPush,
3101 EndToEndTestServerPush,
wubbd64c102019-05-13 11:58:17 -07003102 ::testing::ValuesIn(GetTestParams(false)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003103
3104TEST_P(EndToEndTestServerPush, ServerPush) {
3105 ASSERT_TRUE(Initialize());
3106 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3107
3108 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3109 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3110 SetReorderPercentage(30);
3111
3112 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003113 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003114 size_t kNumResources = 4;
vasilvvc48c8712019-03-11 13:38:16 -07003115 std::string push_urls[] = {"https://example.com/font.woff",
3116 "https://example.com/script.js",
3117 "https://fonts.example.com/font.woff",
3118 "https://example.com/logo-hires.jpg"};
QUICHE teama6ef0a62019-03-07 20:34:33 -05003119 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3120 push_urls, kNumResources, 0);
3121
3122 client_->client()->set_response_listener(
3123 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3124 new TestResponseListener));
3125
3126 QUIC_DVLOG(1) << "send request for /push_example";
3127 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
3128 "https://example.com/push_example"));
renjietang3c3dfb72019-07-26 11:55:52 -07003129 QuicStreamSequencer* sequencer;
3130 if (!VersionUsesQpack(client_->client()
3131 ->client_session()
3132 ->connection()
3133 ->transport_version())) {
fkastenholz7591c282019-08-13 12:58:38 -07003134 QuicHeadersStream* headers_stream =
3135 QuicSpdySessionPeer::GetHeadersStream(GetClientSession());
renjietang3c3dfb72019-07-26 11:55:52 -07003136 sequencer = QuicStreamPeer::sequencer(headers_stream);
3137 // Headers stream's sequencer buffer shouldn't be released because server
3138 // push hasn't finished yet.
3139 EXPECT_TRUE(
3140 QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
3141 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05003142
vasilvvc48c8712019-03-11 13:38:16 -07003143 for (const std::string& url : push_urls) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003144 QUIC_DVLOG(1) << "send request for pushed stream on url " << url;
vasilvvc48c8712019-03-11 13:38:16 -07003145 std::string expected_body =
QUICHE teama6ef0a62019-03-07 20:34:33 -05003146 QuicStrCat("This is server push response body for ", url);
vasilvvc48c8712019-03-11 13:38:16 -07003147 std::string response_body = client_->SendSynchronousRequest(url);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003148 QUIC_DVLOG(1) << "response body " << response_body;
3149 EXPECT_EQ(expected_body, response_body);
3150 }
renjietang3c3dfb72019-07-26 11:55:52 -07003151 if (!VersionUsesQpack(client_->client()
3152 ->client_session()
3153 ->connection()
3154 ->transport_version())) {
3155 EXPECT_FALSE(
3156 QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
3157 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05003158}
3159
3160TEST_P(EndToEndTestServerPush, ServerPushUnderLimit) {
3161 // Tests that sending a request which has 4 push resources will trigger server
3162 // to push those 4 resources and client can handle pushed resources and match
3163 // them with requests later.
3164 ASSERT_TRUE(Initialize());
3165
3166 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3167
3168 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3169 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3170 SetReorderPercentage(30);
3171
3172 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003173 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003174 size_t const kNumResources = 4;
vasilvvc48c8712019-03-11 13:38:16 -07003175 std::string push_urls[] = {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003176 "https://example.com/font.woff",
3177 "https://example.com/script.js",
3178 "https://fonts.example.com/font.woff",
3179 "https://example.com/logo-hires.jpg",
3180 };
3181 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3182 push_urls, kNumResources, 0);
3183 client_->client()->set_response_listener(
3184 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3185 new TestResponseListener));
3186
3187 // Send the first request: this will trigger the server to send all the push
3188 // resources associated with this request, and these will be cached by the
3189 // client.
3190 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
3191 "https://example.com/push_example"));
3192
vasilvvc48c8712019-03-11 13:38:16 -07003193 for (const std::string& url : push_urls) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003194 // Sending subsequent requesets will not actually send anything on the wire,
3195 // as the responses are already in the client's cache.
3196 QUIC_DVLOG(1) << "send request for pushed stream on url " << url;
vasilvvc48c8712019-03-11 13:38:16 -07003197 std::string expected_body =
QUICHE teama6ef0a62019-03-07 20:34:33 -05003198 QuicStrCat("This is server push response body for ", url);
vasilvvc48c8712019-03-11 13:38:16 -07003199 std::string response_body = client_->SendSynchronousRequest(url);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003200 QUIC_DVLOG(1) << "response body " << response_body;
3201 EXPECT_EQ(expected_body, response_body);
3202 }
3203 // Expect only original request has been sent and push responses have been
3204 // received as normal response.
3205 EXPECT_EQ(1u, client_->num_requests());
3206 EXPECT_EQ(1u + kNumResources, client_->num_responses());
3207}
3208
3209TEST_P(EndToEndTestServerPush, ServerPushOverLimitNonBlocking) {
3210 // Tests that when streams are not blocked by flow control or congestion
3211 // control, pushing even more resources than max number of open outgoing
3212 // streams should still work because all response streams get closed
3213 // immediately after pushing resources.
3214 ASSERT_TRUE(Initialize());
3215 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3216
3217 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3218 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3219 SetReorderPercentage(30);
3220
3221 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003222 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003223
3224 // One more resource than max number of outgoing stream of this session.
3225 const size_t kNumResources = 1 + kNumMaxStreams; // 11.
vasilvvc48c8712019-03-11 13:38:16 -07003226 std::string push_urls[11];
QUICHE teama6ef0a62019-03-07 20:34:33 -05003227 for (size_t i = 0; i < kNumResources; ++i) {
3228 push_urls[i] = QuicStrCat("https://example.com/push_resources", i);
3229 }
3230 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3231 push_urls, kNumResources, 0);
3232 client_->client()->set_response_listener(
3233 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3234 new TestResponseListener));
3235
3236 // Send the first request: this will trigger the server to send all the push
3237 // resources associated with this request, and these will be cached by the
3238 // client.
3239 EXPECT_EQ(kBody, client_->SendSynchronousRequest(
3240 "https://example.com/push_example"));
3241
vasilvvc48c8712019-03-11 13:38:16 -07003242 for (const std::string& url : push_urls) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003243 // Sending subsequent requesets will not actually send anything on the wire,
3244 // as the responses are already in the client's cache.
3245 EXPECT_EQ(QuicStrCat("This is server push response body for ", url),
3246 client_->SendSynchronousRequest(url));
3247 }
3248
3249 // Only 1 request should have been sent.
3250 EXPECT_EQ(1u, client_->num_requests());
3251 // The responses to the original request and all the promised resources
3252 // should have been received.
3253 EXPECT_EQ(12u, client_->num_responses());
3254}
3255
3256TEST_P(EndToEndTestServerPush, ServerPushOverLimitWithBlocking) {
3257 // Tests that when server tries to send more large resources(large enough to
3258 // be blocked by flow control window or congestion control window) than max
3259 // open outgoing streams , server can open upto max number of outgoing
3260 // streams for them, and the rest will be queued up.
3261
3262 // Reset flow control windows.
3263 size_t kFlowControlWnd = 20 * 1024; // 20KB.
3264 // Response body is larger than 1 flow controlblock window.
3265 size_t kBodySize = kFlowControlWnd * 2;
3266 set_client_initial_stream_flow_control_receive_window(kFlowControlWnd);
3267 // Make sure conntection level flow control window is large enough not to
3268 // block data being sent out though they will be blocked by stream level one.
3269 set_client_initial_session_flow_control_receive_window(
3270 kBodySize * kNumMaxStreams + 1024);
3271
3272 ASSERT_TRUE(Initialize());
3273 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3274
3275 // Set reordering to ensure that body arriving before PUSH_PROMISE is ok.
3276 SetPacketSendDelay(QuicTime::Delta::FromMilliseconds(2));
3277 SetReorderPercentage(30);
3278
3279 // Add a response with headers, body, and push resources.
vasilvvc48c8712019-03-11 13:38:16 -07003280 const std::string kBody = "body content";
QUICHE teama6ef0a62019-03-07 20:34:33 -05003281
3282 const size_t kNumResources = kNumMaxStreams + 1;
vasilvvc48c8712019-03-11 13:38:16 -07003283 std::string push_urls[11];
QUICHE teama6ef0a62019-03-07 20:34:33 -05003284 for (size_t i = 0; i < kNumResources; ++i) {
3285 push_urls[i] = QuicStrCat("http://example.com/push_resources", i);
3286 }
3287 AddRequestAndResponseWithServerPush("example.com", "/push_example", kBody,
3288 push_urls, kNumResources, kBodySize);
3289
3290 client_->client()->set_response_listener(
3291 std::unique_ptr<QuicSpdyClientBase::ResponseListener>(
3292 new TestResponseListener));
3293
3294 client_->SendRequest("https://example.com/push_example");
3295
3296 // Pause after the first response arrives.
3297 while (!client_->response_complete()) {
3298 // Because of priority, the first response arrived should be to original
3299 // request.
3300 client_->WaitForResponse();
3301 }
3302
3303 // Check server session to see if it has max number of outgoing streams opened
3304 // though more resources need to be pushed.
3305 server_thread_->Pause();
3306 EXPECT_EQ(kNumMaxStreams, GetServerSession()->GetNumOpenOutgoingStreams());
3307 server_thread_->Resume();
3308
3309 EXPECT_EQ(1u, client_->num_requests());
3310 EXPECT_EQ(1u, client_->num_responses());
3311 EXPECT_EQ(kBody, client_->response_body());
3312
3313 // "Send" request for a promised resources will not really send out it because
3314 // its response is being pushed(but blocked). And the following ack and
3315 // flow control behavior of SendSynchronousRequests()
3316 // will unblock the stream to finish receiving response.
3317 client_->SendSynchronousRequest(push_urls[0]);
3318 EXPECT_EQ(1u, client_->num_requests());
3319 EXPECT_EQ(2u, client_->num_responses());
3320
3321 // Do same thing for the rest 10 resources.
3322 for (size_t i = 1; i < kNumResources; ++i) {
3323 client_->SendSynchronousRequest(push_urls[i]);
3324 }
3325
3326 // Because of server push, client gets all pushed resources without actually
3327 // sending requests for them.
3328 EXPECT_EQ(1u, client_->num_requests());
3329 // Including response to original request, 12 responses in total were
3330 // received.
3331 EXPECT_EQ(12u, client_->num_responses());
3332}
3333
3334// TODO(fayang): this test seems to cause net_unittests timeouts :|
3335TEST_P(EndToEndTest, DISABLED_TestHugePostWithPacketLoss) {
3336 // This test tests a huge post with introduced packet loss from client to
3337 // server and body size greater than 4GB, making sure QUIC code does not break
3338 // for 32-bit builds.
3339 ServerStreamThatDropsBodyFactory stream_factory;
3340 SetSpdyStreamFactory(&stream_factory);
3341 ASSERT_TRUE(Initialize());
3342 // Set client's epoll server's time out to 0 to make this test be finished
3343 // within a short time.
3344 client_->epoll_server()->set_timeout_in_us(0);
3345
3346 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3347 SetPacketLossPercentage(1);
3348 // To avoid storing the whole request body in memory, use a loop to repeatedly
3349 // send body size of kSizeBytes until the whole request body size is reached.
3350 const int kSizeBytes = 128 * 1024;
3351 // Request body size is 4G plus one more kSizeBytes.
3352 int64_t request_body_size_bytes = pow(2, 32) + kSizeBytes;
3353 ASSERT_LT(INT64_C(4294967296), request_body_size_bytes);
vasilvvc48c8712019-03-11 13:38:16 -07003354 std::string body(kSizeBytes, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003355
3356 SpdyHeaderBlock headers;
3357 headers[":method"] = "POST";
3358 headers[":path"] = "/foo";
3359 headers[":scheme"] = "https";
3360 headers[":authority"] = server_hostname_;
3361 headers["content-length"] =
3362 QuicTextUtils::Uint64ToString(request_body_size_bytes);
3363
3364 client_->SendMessage(headers, "", /*fin=*/false);
3365
3366 for (int i = 0; i < request_body_size_bytes / kSizeBytes; ++i) {
3367 bool fin = (i == request_body_size_bytes - 1);
vasilvvc48c8712019-03-11 13:38:16 -07003368 client_->SendData(std::string(body.data(), kSizeBytes), fin);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003369 client_->client()->WaitForEvents();
3370 }
3371 VerifyCleanConnection(true);
3372}
3373
3374// TODO(fayang): this test seems to cause net_unittests timeouts :|
3375TEST_P(EndToEndTest, DISABLED_TestHugeResponseWithPacketLoss) {
3376 // This test tests a huge response with introduced loss from server to client
3377 // and body size greater than 4GB, making sure QUIC code does not break for
3378 // 32-bit builds.
3379 const int kSizeBytes = 128 * 1024;
3380 int64_t response_body_size_bytes = pow(2, 32) + kSizeBytes;
3381 ASSERT_LT(4294967296, response_body_size_bytes);
3382 ServerStreamThatSendsHugeResponseFactory stream_factory(
3383 response_body_size_bytes);
3384 SetSpdyStreamFactory(&stream_factory);
3385
3386 StartServer();
3387
3388 // Use a quic client that drops received body.
3389 QuicTestClient* client =
3390 new QuicTestClient(server_address_, server_hostname_, client_config_,
3391 client_supported_versions_);
3392 client->client()->set_drop_response_body(true);
3393 client->UseWriter(client_writer_);
3394 client->Connect();
3395 client_.reset(client);
3396 static QuicEpollEvent event(EPOLLOUT);
3397 client_writer_->Initialize(
fkastenholz7591c282019-08-13 12:58:38 -07003398 QuicConnectionPeer::GetHelper(GetClientConnection()),
3399 QuicConnectionPeer::GetAlarmFactory(GetClientConnection()),
QUICHE teama6ef0a62019-03-07 20:34:33 -05003400 QuicMakeUnique<ClientDelegate>(client_->client()));
3401 initialized_ = true;
3402 ASSERT_TRUE(client_->client()->connected());
3403
3404 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3405 SetPacketLossPercentage(1);
3406 client_->SendRequest("/huge_response");
3407 client_->WaitForResponse();
wubbd64c102019-05-13 11:58:17 -07003408 VerifyCleanConnection(true);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003409}
3410
3411// Regression test for b/111515567
3412TEST_P(EndToEndTest, AgreeOnStopWaiting) {
3413 ASSERT_TRUE(Initialize());
3414 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3415
fkastenholz7591c282019-08-13 12:58:38 -07003416 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003417 server_thread_->Pause();
3418 QuicConnection* server_connection = GetServerConnection();
3419 // Verify client and server connections agree on the value of
3420 // no_stop_waiting_frames.
3421 EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
3422 QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
3423 server_thread_->Resume();
3424}
3425
3426// Regression test for b/111515567
3427TEST_P(EndToEndTest, AgreeOnStopWaitingWithNoStopWaitingOption) {
3428 QuicTagVector options;
3429 options.push_back(kNSTP);
3430 client_config_.SetConnectionOptionsToSend(options);
3431 ASSERT_TRUE(Initialize());
3432 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3433
fkastenholz7591c282019-08-13 12:58:38 -07003434 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003435 server_thread_->Pause();
3436 QuicConnection* server_connection = GetServerConnection();
3437 // Verify client and server connections agree on the value of
3438 // no_stop_waiting_frames.
3439 EXPECT_EQ(QuicConnectionPeer::GetNoStopWaitingFrames(client_connection),
3440 QuicConnectionPeer::GetNoStopWaitingFrames(server_connection));
3441 server_thread_->Resume();
3442}
3443
3444TEST_P(EndToEndTest, ReleaseHeadersStreamBufferWhenIdle) {
3445 // Tests that when client side has no active request and no waiting
3446 // PUSH_PROMISE, its headers stream's sequencer buffer should be released.
3447 ASSERT_TRUE(Initialize());
3448 client_->SendSynchronousRequest("/foo");
renjietang118c8ac2019-07-30 11:43:59 -07003449 if (VersionUsesQpack(client_->client()
3450 ->client_session()
3451 ->connection()
3452 ->transport_version())) {
3453 return;
3454 }
fkastenholz7591c282019-08-13 12:58:38 -07003455 QuicHeadersStream* headers_stream =
3456 QuicSpdySessionPeer::GetHeadersStream(GetClientSession());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003457 QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
3458 EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
3459}
3460
3461TEST_P(EndToEndTest, WayTooLongRequestHeaders) {
3462 ASSERT_TRUE(Initialize());
3463 SpdyHeaderBlock headers;
3464 headers[":method"] = "GET";
3465 headers[":path"] = "/foo";
3466 headers[":scheme"] = "https";
3467 headers[":authority"] = server_hostname_;
vasilvvc48c8712019-03-11 13:38:16 -07003468 headers["key"] = std::string(64 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003469
3470 client_->SendMessage(headers, "");
3471 client_->WaitForResponse();
3472 EXPECT_EQ(QUIC_HEADERS_STREAM_DATA_DECOMPRESS_FAILURE,
3473 client_->connection_error());
3474}
3475
3476class WindowUpdateObserver : public QuicConnectionDebugVisitor {
3477 public:
3478 WindowUpdateObserver() : num_window_update_frames_(0), num_ping_frames_(0) {}
3479
3480 size_t num_window_update_frames() const { return num_window_update_frames_; }
3481
3482 size_t num_ping_frames() const { return num_ping_frames_; }
3483
dschinazi17d42422019-06-18 16:35:07 -07003484 void OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/,
3485 const QuicTime& /*receive_time*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003486 ++num_window_update_frames_;
3487 }
3488
dschinazi17d42422019-06-18 16:35:07 -07003489 void OnPingFrame(const QuicPingFrame& /*frame*/) override {
3490 ++num_ping_frames_;
3491 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05003492
3493 private:
3494 size_t num_window_update_frames_;
3495 size_t num_ping_frames_;
3496};
3497
3498TEST_P(EndToEndTest, WindowUpdateInAck) {
3499 ASSERT_TRUE(Initialize());
3500 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3501 WindowUpdateObserver observer;
fkastenholz7591c282019-08-13 12:58:38 -07003502 QuicConnection* client_connection = GetClientConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003503 client_connection->set_debug_visitor(&observer);
3504 // 100KB body.
vasilvvc48c8712019-03-11 13:38:16 -07003505 std::string body(100 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003506 SpdyHeaderBlock headers;
3507 headers[":method"] = "POST";
3508 headers[":path"] = "/foo";
3509 headers[":scheme"] = "https";
3510 headers[":authority"] = server_hostname_;
3511
3512 EXPECT_EQ(kFooResponseBody,
3513 client_->SendCustomSynchronousRequest(headers, body));
3514 client_->Disconnect();
3515 EXPECT_LT(0u, observer.num_window_update_frames());
3516 EXPECT_EQ(0u, observer.num_ping_frames());
3517}
3518
dschinazi4e3e6572019-08-02 12:57:17 -07003519TEST_P(EndToEndTestWithTls, SendStatelessResetTokenInShlo) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003520 ASSERT_TRUE(Initialize());
3521 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3522 QuicConfig* config = client_->client()->session()->config();
3523 EXPECT_TRUE(config->HasReceivedStatelessResetToken());
3524 EXPECT_EQ(QuicUtils::GenerateStatelessResetToken(
3525 client_->client()->session()->connection()->connection_id()),
3526 config->ReceivedStatelessResetToken());
3527 client_->Disconnect();
3528}
3529
3530// Regression test for b/116200989.
3531TEST_P(EndToEndTest,
3532 SendStatelessResetIfServerConnectionClosedLocallyDuringHandshake) {
3533 connect_to_server_on_initialize_ = false;
3534 ASSERT_TRUE(Initialize());
3535
3536 server_thread_->Pause();
3537 QuicDispatcher* dispatcher =
3538 QuicServerPeer::GetDispatcher(server_thread_->server());
3539 ASSERT_EQ(0u, dispatcher->session_map().size());
3540 // Note: this writer will only used by the server connection, not the time
3541 // wait list.
3542 QuicDispatcherPeer::UseWriter(
3543 dispatcher,
3544 // This cause the first server-sent packet, a.k.a REJ, to fail.
3545 new BadPacketWriter(/*packet_causing_write_error=*/0, EPERM));
3546 server_thread_->Resume();
3547
3548 client_.reset(CreateQuicClient(client_writer_));
3549 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
fayang51c23732019-06-24 06:59:55 -07003550 EXPECT_EQ(QUIC_HANDSHAKE_FAILED, client_->connection_error());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003551}
3552
3553// Regression test for b/116200989.
3554TEST_P(EndToEndTest,
3555 SendStatelessResetIfServerConnectionClosedLocallyAfterHandshake) {
3556 // Prevent the connection from expiring in the time wait list.
dschinazi552accc2019-06-17 17:07:34 -07003557 SetQuicFlag(FLAGS_quic_time_wait_list_seconds, 10000);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003558 connect_to_server_on_initialize_ = false;
3559 ASSERT_TRUE(Initialize());
3560
3561 // big_response_body is 64K, which is about 48 full-sized packets.
3562 const size_t kBigResponseBodySize = 65536;
3563 QuicData big_response_body(new char[kBigResponseBodySize](),
3564 kBigResponseBodySize, /*owns_buffer=*/true);
3565 AddToCache("/big_response", 200, big_response_body.AsStringPiece());
3566
3567 server_thread_->Pause();
3568 QuicDispatcher* dispatcher =
3569 QuicServerPeer::GetDispatcher(server_thread_->server());
3570 ASSERT_EQ(0u, dispatcher->session_map().size());
3571 QuicDispatcherPeer::UseWriter(
3572 dispatcher,
3573 // This will cause an server write error with EPERM, while sending the
3574 // response for /big_response.
3575 new BadPacketWriter(/*packet_causing_write_error=*/20, EPERM));
3576 server_thread_->Resume();
3577
3578 client_.reset(CreateQuicClient(client_writer_));
3579
3580 // First, a /foo request with small response should succeed.
3581 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3582 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3583
3584 // Second, a /big_response request with big response should fail.
3585 EXPECT_LT(client_->SendSynchronousRequest("/big_response").length(),
3586 kBigResponseBodySize);
3587 EXPECT_EQ(QUIC_PUBLIC_RESET, client_->connection_error());
3588}
3589
3590// Regression test of b/70782529.
3591TEST_P(EndToEndTest, DoNotCrashOnPacketWriteError) {
3592 ASSERT_TRUE(Initialize());
3593 BadPacketWriter* bad_writer =
3594 new BadPacketWriter(/*packet_causing_write_error=*/5,
3595 /*error_code=*/90);
3596 std::unique_ptr<QuicTestClient> client(CreateQuicClient(bad_writer));
3597
3598 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07003599 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003600 SpdyHeaderBlock headers;
3601 headers[":method"] = "POST";
3602 headers[":path"] = "/foo";
3603 headers[":scheme"] = "https";
3604 headers[":authority"] = server_hostname_;
3605
3606 client->SendCustomSynchronousRequest(headers, body);
3607}
3608
3609// Regression test for b/71711996. This test sends a connectivity probing packet
3610// as its last sent packet, and makes sure the server's ACK of that packet does
3611// not cause the client to fail.
3612TEST_P(EndToEndTest, LastPacketSentIsConnectivityProbing) {
3613 ASSERT_TRUE(Initialize());
3614
3615 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3616 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3617
3618 // Wait for the client's ACK (of the response) to be received by the server.
3619 client_->WaitForDelayedAcks();
3620
3621 // We are sending a connectivity probing packet from an unchanged client
3622 // address, so the server will not respond to us with a connectivity probing
3623 // packet, however the server should send an ack-only packet to us.
3624 client_->SendConnectivityProbing();
3625
3626 // Wait for the server's last ACK to be received by the client.
3627 client_->WaitForDelayedAcks();
3628}
3629
3630TEST_P(EndToEndTest, PreSharedKey) {
3631 client_config_.set_max_time_before_crypto_handshake(
3632 QuicTime::Delta::FromSeconds(1));
3633 client_config_.set_max_idle_time_before_crypto_handshake(
3634 QuicTime::Delta::FromSeconds(1));
3635 pre_shared_key_client_ = "foobar";
3636 pre_shared_key_server_ = "foobar";
3637 ASSERT_TRUE(Initialize());
3638
3639 ASSERT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3640 EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
3641}
3642
3643// TODO: reenable once we have a way to make this run faster.
3644TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyMismatch)) {
3645 client_config_.set_max_time_before_crypto_handshake(
3646 QuicTime::Delta::FromSeconds(1));
3647 client_config_.set_max_idle_time_before_crypto_handshake(
3648 QuicTime::Delta::FromSeconds(1));
3649 pre_shared_key_client_ = "foo";
3650 pre_shared_key_server_ = "bar";
3651 // One of two things happens when Initialize() returns:
3652 // 1. Crypto handshake has completed, and it is unsuccessful. Initialize()
3653 // returns false.
3654 // 2. Crypto handshake has not completed, Initialize() returns true. The call
3655 // to WaitForCryptoHandshakeConfirmed() will wait for the handshake and
3656 // return whether it is successful.
3657 ASSERT_FALSE(Initialize() &&
3658 client_->client()->WaitForCryptoHandshakeConfirmed());
3659 EXPECT_EQ(QUIC_HANDSHAKE_TIMEOUT, client_->connection_error());
3660}
3661
3662// TODO: reenable once we have a way to make this run faster.
3663TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoClient)) {
3664 client_config_.set_max_time_before_crypto_handshake(
3665 QuicTime::Delta::FromSeconds(1));
3666 client_config_.set_max_idle_time_before_crypto_handshake(
3667 QuicTime::Delta::FromSeconds(1));
3668 pre_shared_key_server_ = "foobar";
3669 ASSERT_FALSE(Initialize() &&
3670 client_->client()->WaitForCryptoHandshakeConfirmed());
3671 EXPECT_EQ(QUIC_HANDSHAKE_TIMEOUT, client_->connection_error());
3672}
3673
3674// TODO: reenable once we have a way to make this run faster.
3675TEST_P(EndToEndTest, QUIC_TEST_DISABLED_IN_CHROME(PreSharedKeyNoServer)) {
3676 client_config_.set_max_time_before_crypto_handshake(
3677 QuicTime::Delta::FromSeconds(1));
3678 client_config_.set_max_idle_time_before_crypto_handshake(
3679 QuicTime::Delta::FromSeconds(1));
3680 pre_shared_key_client_ = "foobar";
3681 ASSERT_FALSE(Initialize() &&
3682 client_->client()->WaitForCryptoHandshakeConfirmed());
3683 EXPECT_EQ(QUIC_HANDSHAKE_TIMEOUT, client_->connection_error());
3684}
3685
3686TEST_P(EndToEndTest, RequestAndStreamRstInOnePacket) {
3687 // Regression test for b/80234898.
3688 ASSERT_TRUE(Initialize());
3689
3690 // INCOMPLETE_RESPONSE will cause the server to not to send the trailer
3691 // (and the FIN) after the response body.
vasilvvc48c8712019-03-11 13:38:16 -07003692 std::string response_body(1305, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003693 SpdyHeaderBlock response_headers;
3694 response_headers[":status"] = QuicTextUtils::Uint64ToString(200);
3695 response_headers["content-length"] =
3696 QuicTextUtils::Uint64ToString(response_body.length());
3697 memory_cache_backend_.AddSpecialResponse(
3698 server_hostname_, "/test_url", std::move(response_headers), response_body,
3699 QuicBackendResponse::INCOMPLETE_RESPONSE);
3700
3701 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3702 client_->WaitForDelayedAcks();
3703
fkastenholz7591c282019-08-13 12:58:38 -07003704 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003705 const QuicPacketCount packets_sent_before =
3706 session->connection()->GetStats().packets_sent;
3707
3708 client_->SendRequestAndRstTogether("/test_url");
3709
3710 // Expect exactly one packet is sent from the block above.
3711 ASSERT_EQ(packets_sent_before + 1,
3712 session->connection()->GetStats().packets_sent);
3713
3714 // Wait for the connection to become idle.
3715 client_->WaitForDelayedAcks();
3716
3717 // The real expectation is the test does not crash or timeout.
3718 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
3719}
3720
3721TEST_P(EndToEndTest, ResetStreamOnTtlExpires) {
3722 ASSERT_TRUE(Initialize());
3723 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
fkastenholz7591c282019-08-13 12:58:38 -07003724 if (!GetClientSession()->session_decides_what_to_write()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003725 return;
3726 }
3727 SetPacketLossPercentage(30);
3728
3729 QuicSpdyClientStream* stream = client_->GetOrCreateStream();
3730 // Set a TTL which expires immediately.
3731 stream->MaybeSetTtl(QuicTime::Delta::FromMicroseconds(1));
3732
bnc519216c2019-07-09 05:03:48 -07003733 WriteHeadersOnStream(stream);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003734 // 1 MB body.
vasilvvc48c8712019-03-11 13:38:16 -07003735 std::string body(1024 * 1024, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003736 stream->WriteOrBufferBody(body, true);
3737 client_->WaitForResponse();
3738 EXPECT_EQ(QUIC_STREAM_TTL_EXPIRED, client_->stream_error());
3739}
3740
3741TEST_P(EndToEndTest, SendMessages) {
3742 ASSERT_TRUE(Initialize());
3743 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
fkastenholz7591c282019-08-13 12:58:38 -07003744 QuicSession* client_session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003745 QuicConnection* client_connection = client_session->connection();
fayangd4291e42019-05-30 10:31:21 -07003746 if (!VersionSupportsMessageFrames(client_connection->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003747 return;
3748 }
3749
3750 SetPacketLossPercentage(30);
dschinazi66dea072019-04-09 11:41:06 -07003751 ASSERT_GT(kMaxOutgoingPacketSize,
3752 client_session->GetCurrentLargestMessagePayload());
ianswettb239f862019-04-05 09:15:06 -07003753 ASSERT_LT(0, client_session->GetCurrentLargestMessagePayload());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003754
dschinazi66dea072019-04-09 11:41:06 -07003755 std::string message_string(kMaxOutgoingPacketSize, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003756 QuicStringPiece message_buffer(message_string);
3757 QuicRandom* random =
3758 QuicConnectionPeer::GetHelper(client_connection)->GetRandomGenerator();
3759 QuicMemSliceStorage storage(nullptr, 0, nullptr, 0);
3760 {
fayanga4b37b22019-06-18 13:37:47 -07003761 QuicConnection::ScopedPacketFlusher flusher(client_session->connection());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003762 // Verify the largest message gets successfully sent.
ianswettb239f862019-04-05 09:15:06 -07003763 EXPECT_EQ(
3764 MessageResult(MESSAGE_STATUS_SUCCESS, 1),
3765 client_session->SendMessage(MakeSpan(
3766 client_session->connection()
3767 ->helper()
3768 ->GetStreamSendBufferAllocator(),
3769 QuicStringPiece(message_buffer.data(),
3770 client_session->GetCurrentLargestMessagePayload()),
3771 &storage)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003772 // Send more messages with size (0, largest_payload] until connection is
3773 // write blocked.
3774 const int kTestMaxNumberOfMessages = 100;
3775 for (size_t i = 2; i <= kTestMaxNumberOfMessages; ++i) {
3776 size_t message_length =
ianswettb239f862019-04-05 09:15:06 -07003777 random->RandUint64() %
3778 client_session->GetCurrentLargestMessagePayload() +
3779 1;
QUICHE teama6ef0a62019-03-07 20:34:33 -05003780 MessageResult result = client_session->SendMessage(MakeSpan(
3781 client_session->connection()
3782 ->helper()
3783 ->GetStreamSendBufferAllocator(),
3784 QuicStringPiece(message_buffer.data(), message_length), &storage));
3785 if (result.status == MESSAGE_STATUS_BLOCKED) {
3786 // Connection is write blocked.
3787 break;
3788 }
3789 EXPECT_EQ(MessageResult(MESSAGE_STATUS_SUCCESS, i), result);
3790 }
3791 }
3792
3793 client_->WaitForDelayedAcks();
ianswettb239f862019-04-05 09:15:06 -07003794 EXPECT_EQ(MESSAGE_STATUS_TOO_LARGE,
3795 client_session
3796 ->SendMessage(MakeSpan(
3797 client_session->connection()
3798 ->helper()
3799 ->GetStreamSendBufferAllocator(),
3800 QuicStringPiece(
3801 message_buffer.data(),
3802 client_session->GetCurrentLargestMessagePayload() + 1),
3803 &storage))
3804 .status);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003805 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
3806}
3807
3808class EndToEndPacketReorderingTest : public EndToEndTest {
3809 public:
3810 void CreateClientWithWriter() override {
3811 QUIC_LOG(ERROR) << "create client with reorder_writer_";
3812 reorder_writer_ = new PacketReorderingWriter();
3813 client_.reset(EndToEndTest::CreateQuicClient(reorder_writer_));
3814 }
3815
3816 void SetUp() override {
3817 // Don't initialize client writer in base class.
3818 server_writer_ = new PacketDroppingTestWriter();
3819 }
3820
3821 protected:
3822 PacketReorderingWriter* reorder_writer_;
3823};
3824
3825INSTANTIATE_TEST_SUITE_P(EndToEndPacketReorderingTests,
3826 EndToEndPacketReorderingTest,
wubbd64c102019-05-13 11:58:17 -07003827 testing::ValuesIn(GetTestParams(false)));
QUICHE teama6ef0a62019-03-07 20:34:33 -05003828
3829TEST_P(EndToEndPacketReorderingTest, ReorderedConnectivityProbing) {
3830 ASSERT_TRUE(Initialize());
3831
3832 // Finish one request to make sure handshake established.
3833 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3834
3835 // Wait for the connection to become idle, to make sure the packet gets
3836 // delayed is the connectivity probing packet.
3837 client_->WaitForDelayedAcks();
3838
3839 QuicSocketAddress old_addr =
3840 client_->client()->network_helper()->GetLatestClientAddress();
3841
3842 // Migrate socket to the new IP address.
3843 QuicIpAddress new_host = TestLoopback(2);
3844 EXPECT_NE(old_addr.host(), new_host);
3845 ASSERT_TRUE(client_->client()->MigrateSocket(new_host));
3846
3847 // Write a connectivity probing after the next /foo request.
3848 reorder_writer_->SetDelay(1);
3849 client_->SendConnectivityProbing();
3850
3851 ASSERT_TRUE(client_->MigrateSocketWithSpecifiedPort(old_addr.host(),
3852 old_addr.port()));
3853
3854 // The (delayed) connectivity probing will be sent after this request.
3855 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3856
3857 // Send yet another request after the connectivity probing, when this request
3858 // returns, the probing is guaranteed to have been received by the server, and
3859 // the server's response to probing is guaranteed to have been received by the
3860 // client.
3861 EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
3862
3863 server_thread_->Pause();
3864 QuicConnection* server_connection = GetServerConnection();
3865 EXPECT_EQ(1u,
3866 server_connection->GetStats().num_connectivity_probing_received);
3867 server_thread_->Resume();
3868
fkastenholz7591c282019-08-13 12:58:38 -07003869 EXPECT_EQ(
3870 1u, GetClientConnection()->GetStats().num_connectivity_probing_received);
QUICHE teama6ef0a62019-03-07 20:34:33 -05003871}
3872
3873TEST_P(EndToEndPacketReorderingTest, Buffer0RttRequest) {
3874 ASSERT_TRUE(Initialize());
3875 // Finish one request to make sure handshake established.
3876 client_->SendSynchronousRequest("/foo");
3877 // Disconnect for next 0-rtt request.
3878 client_->Disconnect();
3879
3880 // Client get valid STK now. Do a 0-rtt request.
3881 // Buffer a CHLO till another packets sent out.
3882 reorder_writer_->SetDelay(1);
3883 // Only send out a CHLO.
3884 client_->client()->Initialize();
3885 client_->client()->StartConnect();
3886 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3887 ASSERT_TRUE(client_->client()->connected());
3888
3889 // Send a request before handshake finishes.
3890 SpdyHeaderBlock headers;
3891 headers[":method"] = "POST";
3892 headers[":path"] = "/bar";
3893 headers[":scheme"] = "https";
3894 headers[":authority"] = server_hostname_;
3895
3896 client_->SendMessage(headers, "");
3897 client_->WaitForResponse();
3898 EXPECT_EQ(kBarResponseBody, client_->response_body());
fkastenholz7591c282019-08-13 12:58:38 -07003899 QuicConnectionStats client_stats = GetClientConnection()->GetStats();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003900 EXPECT_EQ(0u, client_stats.packets_lost);
3901 if (ServerSendsVersionNegotiation()) {
3902 EXPECT_EQ(2, client_->client()->GetNumSentClientHellos());
3903 } else {
3904 EXPECT_EQ(1, client_->client()->GetNumSentClientHellos());
3905 }
3906}
3907
3908// Test that STOP_SENDING makes it to the other side. Set up a client & server,
3909// create a stream (do not close it), and then send a STOP_SENDING from one
3910// side. The other side should get a call to QuicStream::OnStopSending.
3911// (aside, test cribbed from RequestAndStreamRstInOnePacket)
3912TEST_P(EndToEndTest, SimpleStopSendingTest) {
3913 const uint16_t kStopSendingTestCode = 123;
3914 ASSERT_TRUE(Initialize());
fkastenholz305e1732019-06-18 05:01:22 -07003915 if (!VersionHasIetfQuicFrames(negotiated_version_.transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05003916 return;
3917 }
fkastenholz7591c282019-08-13 12:58:38 -07003918 QuicSession* client_session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003919 ASSERT_NE(nullptr, client_session);
3920 QuicConnection* client_connection = client_session->connection();
3921 ASSERT_NE(nullptr, client_connection);
3922
3923 // STOP_SENDING will cause the server to not to send the trailer
3924 // (and the FIN) after the response body. Instead, it sends a STOP_SENDING
3925 // frame for the stream.
vasilvvc48c8712019-03-11 13:38:16 -07003926 std::string response_body(1305, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -05003927 SpdyHeaderBlock response_headers;
3928 response_headers[":status"] = QuicTextUtils::Uint64ToString(200);
3929 response_headers["content-length"] =
3930 QuicTextUtils::Uint64ToString(response_body.length());
3931 memory_cache_backend_.AddStopSendingResponse(
3932 server_hostname_, "/test_url", std::move(response_headers), response_body,
3933 kStopSendingTestCode);
3934
3935 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
3936 client_->WaitForDelayedAcks();
3937
fkastenholz7591c282019-08-13 12:58:38 -07003938 QuicSession* session = GetClientSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -05003939 const QuicPacketCount packets_sent_before =
3940 session->connection()->GetStats().packets_sent;
3941
3942 QuicStreamId stream_id = session->next_outgoing_bidirectional_stream_id();
3943 client_->SendRequest("/test_url");
3944
3945 // Expect exactly one packet is sent from the block above.
3946 ASSERT_EQ(packets_sent_before + 1,
3947 session->connection()->GetStats().packets_sent);
3948
3949 // Wait for the connection to become idle.
3950 client_->WaitForDelayedAcks();
3951
3952 // The real expectation is the test does not crash or timeout.
3953 EXPECT_EQ(QUIC_NO_ERROR, client_->connection_error());
3954 // And that the stop-sending code is received.
3955 QuicSimpleClientStream* client_stream =
3956 static_cast<QuicSimpleClientStream*>(client_->latest_created_stream());
3957 ASSERT_NE(nullptr, client_stream);
3958 // Make sure we have the correct stream
3959 EXPECT_EQ(stream_id, client_stream->id());
3960 EXPECT_EQ(kStopSendingTestCode, client_stream->last_stop_sending_code());
3961}
3962
3963TEST_P(EndToEndTest, SimpleStopSendingRstStreamTest) {
3964 ASSERT_TRUE(Initialize());
3965
3966 // Send a request without a fin, to keep the stream open
3967 SpdyHeaderBlock headers;
3968 headers[":method"] = "POST";
3969 headers[":path"] = "/foo";
3970 headers[":scheme"] = "https";
3971 headers[":authority"] = server_hostname_;
3972 client_->SendMessage(headers, "", /*fin=*/false);
3973 // Stream should be open
3974 ASSERT_NE(nullptr, client_->latest_created_stream());
bncc7d9e0c2019-04-16 10:22:15 -07003975 EXPECT_FALSE(client_->latest_created_stream()->write_side_closed());
QUICHE teama6ef0a62019-03-07 20:34:33 -05003976 EXPECT_FALSE(
3977 QuicStreamPeer::read_side_closed(client_->latest_created_stream()));
3978
3979 // Send a RST_STREAM+STOP_SENDING on the stream
3980 // Code is not important.
3981 client_->latest_created_stream()->Reset(QUIC_BAD_APPLICATION_PAYLOAD);
3982 client_->WaitForResponse();
3983
3984 // Stream should be gone.
3985 ASSERT_EQ(nullptr, client_->latest_created_stream());
3986}
3987
3988class BadShloPacketWriter : public QuicPacketWriterWrapper {
3989 public:
3990 BadShloPacketWriter() : error_returned_(false) {}
3991 ~BadShloPacketWriter() override {}
3992
3993 WriteResult WritePacket(const char* buffer,
3994 size_t buf_len,
3995 const QuicIpAddress& self_address,
3996 const QuicSocketAddress& peer_address,
3997 quic::PerPacketOptions* options) override {
3998 const WriteResult result = QuicPacketWriterWrapper::WritePacket(
3999 buffer, buf_len, self_address, peer_address, options);
4000 const uint8_t type_byte = buffer[0];
4001 if (!error_returned_ && (type_byte & FLAGS_LONG_HEADER) &&
4002 (((type_byte & 0x30) >> 4) == 1 || (type_byte & 0x7F) == 0x7C)) {
4003 QUIC_DVLOG(1) << "Return write error for ZERO_RTT_PACKET";
4004 error_returned_ = true;
4005 return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
4006 }
4007 return result;
4008 }
4009
4010 private:
4011 bool error_returned_;
4012};
4013
4014TEST_P(EndToEndTest, ZeroRttProtectedConnectionClose) {
4015 // This test ensures ZERO_RTT_PROTECTED connection close could close a client
4016 // which has switched to forward secure.
4017 connect_to_server_on_initialize_ =
fayangd4291e42019-05-30 10:31:21 -07004018 !VersionHasIetfInvariantHeader(negotiated_version_.transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -05004019 ASSERT_TRUE(Initialize());
fayangd4291e42019-05-30 10:31:21 -07004020 if (!VersionHasIetfInvariantHeader(negotiated_version_.transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05004021 // Only runs for IETF QUIC header.
4022 return;
4023 }
4024 server_thread_->Pause();
4025 QuicDispatcher* dispatcher =
4026 QuicServerPeer::GetDispatcher(server_thread_->server());
4027 ASSERT_EQ(0u, dispatcher->session_map().size());
4028 // Note: this writer will only used by the server connection, not the time
4029 // wait list.
4030 QuicDispatcherPeer::UseWriter(
4031 dispatcher,
4032 // This causes the first server sent ZERO_RTT_PROTECTED packet (i.e.,
4033 // SHLO) to be sent, but WRITE_ERROR is returned. Such that a
4034 // ZERO_RTT_PROTECTED connection close would be sent to a client with
4035 // encryption level FORWARD_SECURE.
4036 new BadShloPacketWriter());
4037 server_thread_->Resume();
4038
4039 client_.reset(CreateQuicClient(client_writer_));
4040 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
4041 // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
4042 // client which switches to FORWARD_SECURE.
4043 EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, client_->connection_error());
4044}
4045
4046class BadShloPacketWriter2 : public QuicPacketWriterWrapper {
4047 public:
4048 BadShloPacketWriter2() : error_returned_(false) {}
4049 ~BadShloPacketWriter2() override {}
4050
4051 WriteResult WritePacket(const char* buffer,
4052 size_t buf_len,
4053 const QuicIpAddress& self_address,
4054 const QuicSocketAddress& peer_address,
4055 quic::PerPacketOptions* options) override {
4056 const uint8_t type_byte = buffer[0];
4057 if ((type_byte & FLAGS_LONG_HEADER) &&
4058 (((type_byte & 0x30) >> 4) == 1 || (type_byte & 0x7F) == 0x7C)) {
4059 QUIC_DVLOG(1) << "Dropping ZERO_RTT_PACKET packet";
4060 return WriteResult(WRITE_STATUS_OK, buf_len);
4061 }
4062 if (!error_returned_ && !(type_byte & FLAGS_LONG_HEADER)) {
4063 QUIC_DVLOG(1) << "Return write error for short header packet";
4064 error_returned_ = true;
4065 return WriteResult(WRITE_STATUS_ERROR, QUIC_EMSGSIZE);
4066 }
4067 return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
4068 peer_address, options);
4069 }
4070
4071 private:
4072 bool error_returned_;
4073};
4074
4075TEST_P(EndToEndTest, ForwardSecureConnectionClose) {
4076 // This test ensures ZERO_RTT_PROTECTED connection close is sent to a client
4077 // which has ZERO_RTT_PROTECTED encryption level.
QUICHE teama6ef0a62019-03-07 20:34:33 -05004078 connect_to_server_on_initialize_ =
fayangd4291e42019-05-30 10:31:21 -07004079 !VersionHasIetfInvariantHeader(negotiated_version_.transport_version);
QUICHE teama6ef0a62019-03-07 20:34:33 -05004080 ASSERT_TRUE(Initialize());
fayangd4291e42019-05-30 10:31:21 -07004081 if (!VersionHasIetfInvariantHeader(negotiated_version_.transport_version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05004082 // Only runs for IETF QUIC header.
4083 return;
4084 }
4085 server_thread_->Pause();
4086 QuicDispatcher* dispatcher =
4087 QuicServerPeer::GetDispatcher(server_thread_->server());
4088 ASSERT_EQ(0u, dispatcher->session_map().size());
4089 // Note: this writer will only used by the server connection, not the time
4090 // wait list.
4091 QuicDispatcherPeer::UseWriter(
4092 dispatcher,
4093 // This causes the all server sent ZERO_RTT_PROTECTED packets to be
4094 // dropped, and first short header packet causes write error.
4095 new BadShloPacketWriter2());
4096 server_thread_->Resume();
4097 client_.reset(CreateQuicClient(client_writer_));
4098 EXPECT_EQ("", client_->SendSynchronousRequest("/foo"));
4099 // Verify ZERO_RTT_PROTECTED connection close is successfully processed by
4100 // client.
4101 EXPECT_EQ(QUIC_PACKET_WRITE_ERROR, client_->connection_error());
4102}
4103
fkastenholz3c4eabf2019-04-22 07:49:59 -07004104// Test that the stream id manager closes the connection if a stream
4105// in excess of the allowed maximum.
4106TEST_P(EndToEndTest, TooBigStreamIdClosesConnection) {
4107 // Has to be before version test, see EndToEndTest::TearDown()
4108 ASSERT_TRUE(Initialize());
fkastenholz305e1732019-06-18 05:01:22 -07004109 if (!VersionHasIetfQuicFrames(negotiated_version_.transport_version)) {
fkastenholz3c4eabf2019-04-22 07:49:59 -07004110 // Only runs for IETF QUIC.
4111 return;
4112 }
4113 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
4114
4115 std::string body(kMaxOutgoingPacketSize, 'a');
4116 SpdyHeaderBlock headers;
4117 headers[":method"] = "POST";
4118 headers[":path"] = "/foo";
4119 headers[":scheme"] = "https";
4120 headers[":authority"] = server_hostname_;
4121
4122 // Force the client to write with a stream ID that exceeds the limit.
fkastenholz7591c282019-08-13 12:58:38 -07004123 QuicSpdySession* session = GetClientSession();
fkastenholz3c4eabf2019-04-22 07:49:59 -07004124 QuicStreamIdManager* stream_id_manager =
4125 QuicSessionPeer::v99_bidirectional_stream_id_manager(session);
4126 QuicStreamCount max_number_of_streams =
4127 stream_id_manager->outgoing_max_streams();
4128 QuicSessionPeer::SetNextOutgoingBidirectionalStreamId(
4129 session, GetNthClientInitiatedBidirectionalId(max_number_of_streams + 1));
4130 client_->SendCustomSynchronousRequest(headers, body);
4131 EXPECT_EQ(QUIC_STREAM_CONNECTION_ERROR, client_->stream_error());
4132 EXPECT_EQ(QUIC_INVALID_STREAM_ID, client_->connection_error());
4133}
4134
QUICHE teamc258e4f2019-08-14 10:04:58 -07004135TEST_P(EndToEndTest, TestMaxPushId) {
4136 // Has to be before version test, see EndToEndTest::TearDown()
4137 ASSERT_TRUE(Initialize());
4138 if (!VersionHasIetfQuicFrames(negotiated_version_.transport_version)) {
4139 // Only runs for IETF QUIC.
4140 return;
4141 }
4142
4143 EXPECT_TRUE(client_->client()->WaitForCryptoHandshakeConfirmed());
4144 static_cast<QuicSpdySession*>(client_->client()->session())
4145 ->set_max_allowed_push_id(kMaxQuicStreamId);
4146
4147 client_->SendSynchronousRequest("/foo");
4148
4149 EXPECT_EQ(kMaxQuicStreamId,
4150 static_cast<QuicSpdySession*>(client_->client()->session())
4151 ->max_allowed_push_id());
4152
4153 EXPECT_EQ(
4154 kMaxQuicStreamId,
4155 static_cast<QuicSpdySession*>(GetServerSession())->max_allowed_push_id());
4156}
4157
QUICHE teama6ef0a62019-03-07 20:34:33 -05004158} // namespace
4159} // namespace test
4160} // namespace quic