blob: 9a2f95ff7ec86c4ee0b5b03f9c20bfd54e13548e [file] [log] [blame]
[email protected]dd3fd0e2012-11-04 05:14:401// 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
Ryan Hamiltona3ee93a72018-08-01 22:03:085#include "net/quic/quic_chromium_client_session.h"
[email protected]dd3fd0e2012-11-04 05:14:406
[email protected]5db452202014-08-19 05:22:157#include "base/base64.h"
Sebastien Marchand6d0558fd2019-01-25 16:49:378#include "base/bind.h"
[email protected]f21ec372014-07-02 07:15:129#include "base/files/file_path.h"
danakjad1777e2016-04-16 00:56:4210#include "base/memory/ptr_util.h"
jri9f303712016-09-13 01:10:2211#include "base/run_loop.h"
Ryan Sleevib8d7ea02018-05-07 20:01:0112#include "base/stl_util.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4713#include "base/test/metrics/histogram_tester.h"
Matt Menke26e41542019-06-05 01:09:5114#include "base/test/scoped_feature_list.h"
gabf767595f2016-05-11 18:50:3515#include "base/threading/thread_task_runner_handle.h"
Zhongyi Shic16b4102019-02-12 00:37:4016#include "base/time/default_tick_clock.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0817#include "build/build_config.h"
Matt Menke26e41542019-06-05 01:09:5118#include "net/base/features.h"
19#include "net/base/network_isolation_key.h"
[email protected]8ee611b2012-11-20 01:48:1220#include "net/base/test_completion_callback.h"
[email protected]f21ec372014-07-02 07:15:1221#include "net/cert/cert_verify_result.h"
[email protected]5db452202014-08-19 05:22:1522#include "net/http/transport_security_state.h"
Matt Mueller230996f12018-10-22 19:39:4423#include "net/http/transport_security_state_test_util.h"
mikecironef22f9812016-10-04 03:40:1924#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5125#include "net/log/test_net_log.h"
Victor Vasiliev4f6fb892019-05-31 16:58:3126#include "net/quic/address_utils.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0827#include "net/quic/crypto/proof_verifier_chromium.h"
28#include "net/quic/mock_crypto_client_stream_factory.h"
29#include "net/quic/mock_quic_data.h"
30#include "net/quic/quic_chromium_alarm_factory.h"
31#include "net/quic/quic_chromium_client_session_peer.h"
32#include "net/quic/quic_chromium_connection_helper.h"
33#include "net/quic/quic_chromium_packet_reader.h"
34#include "net/quic/quic_chromium_packet_writer.h"
35#include "net/quic/quic_crypto_client_stream_factory.h"
36#include "net/quic/quic_http_utils.h"
37#include "net/quic/quic_server_info.h"
38#include "net/quic/quic_test_packet_maker.h"
tfarina5dd13c22016-11-16 12:08:2639#include "net/socket/datagram_client_socket.h"
[email protected]4d283b32013-10-17 12:57:2740#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5841#include "net/spdy/spdy_test_util_common.h"
[email protected]f21ec372014-07-02 07:15:1242#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0143#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4344#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4045#include "net/test/test_with_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5146#include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h"
47#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
48#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
49#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
50#include "net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h"
51#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
52#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h"
53#include "net/third_party/quiche/src/quic/core/quic_utils.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5154#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
55#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
56#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
57#include "net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.h"
58#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
59#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
60#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
61#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
62#include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h"
Victor Vasiliev27cc7712019-01-24 11:50:1463#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
Ramin Halavati683bcaa92018-02-14 08:42:3964#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0165#include "testing/gmock/include/gmock/gmock.h"
[email protected]dd3fd0e2012-11-04 05:14:4066
67using testing::_;
68
69namespace net {
70namespace test {
71namespace {
72
eroman36d84e54432016-03-17 03:23:0273const IPEndPoint kIpEndPoint = IPEndPoint(IPAddress::IPv4AllZeros(), 0);
rch1fe2eeb2015-10-26 14:45:5774const char kServerHostname[] = "test.example.com";
Avi Drissman13fc8932015-12-20 04:40:4675const uint16_t kServerPort = 443;
jri7e636642016-01-14 06:57:0876const size_t kMaxReadersPerQuicSession = 5;
77
David Benjamin3cc59772019-04-02 07:33:3178// A subclass of QuicChromiumClientSession that allows OnPathDegrading to be
79// mocked.
Nick Harpere45fe4fc2017-07-13 00:34:5880class TestingQuicChromiumClientSession : public QuicChromiumClientSession {
81 public:
82 using QuicChromiumClientSession::QuicChromiumClientSession;
83
Zhongyi Shi5068bb02018-08-03 02:44:0984 MOCK_METHOD0(OnPathDegrading, void());
Nick Harpere45fe4fc2017-07-13 00:34:5885};
86
ckrasic4f9d88d2015-07-22 22:23:1687class QuicChromiumClientSessionTest
Ryan Hamilton8d9ee76e2018-05-29 23:52:5288 : public ::testing::TestWithParam<
Nick Harper23290b82019-05-02 00:02:5689 std::tuple<quic::ParsedQuicVersion, bool>>,
Gabriel Charette694c3c332019-08-19 14:53:0590 public WithTaskEnvironment {
Ryan Hamilton9883ff62017-08-01 06:07:0591 public:
ckrasic4f9d88d2015-07-22 22:23:1692 QuicChromiumClientSessionTest()
Yixin Wang079ad542018-01-11 04:06:0593 : version_(std::get<0>(GetParam())),
94 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Nick Harpera598fc5f2019-06-21 08:46:5095 crypto_config_(
96 quic::test::crypto_test_utils::ProofVerifierForTesting()),
jri7e636642016-01-14 06:57:0897 default_read_(new MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)),
98 socket_data_(
Ryan Sleevib8d7ea02018-05-07 20:01:0199 new SequencedSocketData(base::make_span(default_read_.get(), 1),
100 base::span<MockWrite>())),
jri7e636642016-01-14 06:57:08101 random_(0),
rch16c74d1d2016-04-22 06:14:07102 helper_(&clock_, &random_),
Paul Jensen8e3c5d32018-02-19 17:06:33103 session_key_(kServerHostname,
104 kServerPort,
105 PRIVACY_MODE_DISABLED,
106 SocketTag()),
Ryan Hamilton6c2a2a82017-12-15 02:06:28107 destination_(kServerHostname, kServerPort),
Yixin Wang079ad542018-01-11 04:06:05108 client_maker_(version_,
David Schinazic8281052019-01-24 06:14:17109 quic::QuicUtils::CreateRandomConnectionId(&random_),
alyssar2adf3ac2016-05-03 17:12:58110 &clock_,
111 kServerHostname,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52112 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05113 client_headers_include_h2_stream_dependency_),
114 server_maker_(version_,
David Schinazic8281052019-01-24 06:14:17115 quic::QuicUtils::CreateRandomConnectionId(&random_),
alyssar2adf3ac2016-05-03 17:12:58116 &clock_,
117 kServerHostname,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52118 quic::Perspective::IS_SERVER,
Yixin Wangf65c4b6d2018-03-08 22:37:40119 false),
120 migrate_session_early_v2_(false) {
Nick Harper057264a82019-09-12 23:33:49121 SetQuicReloadableFlag(quic_supports_tls_handshake, true);
xunjielic70cc862016-02-19 15:29:26122 // Advance the time, because timers do not like uninitialized times.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52123 clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
xunjielic70cc862016-02-19 15:29:26124 }
jri7e636642016-01-14 06:57:08125
Ryan Hamilton9883ff62017-08-01 06:07:05126 void ResetHandleOnError(
127 std::unique_ptr<QuicChromiumClientSession::Handle>* handle,
128 int net_error) {
129 EXPECT_NE(OK, net_error);
130 handle->reset();
131 }
132
133 protected:
jri7e636642016-01-14 06:57:08134 void Initialize() {
rch1baa7472017-04-26 05:43:58135 if (socket_data_)
136 socket_factory_.AddSocketDataProvider(socket_data_.get());
danakjad1777e2016-04-16 00:56:42137 std::unique_ptr<DatagramClientSocket> socket =
jri7e636642016-01-14 06:57:08138 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:19139 &net_log_, NetLogSource());
jri7e636642016-01-14 06:57:08140 socket->Connect(kIpEndPoint);
Ryan Hamilton9edcf1a2017-11-22 05:55:17141 QuicChromiumPacketWriter* writer = new net::QuicChromiumPacketWriter(
142 socket.get(), base::ThreadTaskRunnerHandle::Get().get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52143 quic::QuicConnection* connection = new quic::QuicConnection(
David Schinazic8281052019-01-24 06:14:17144 quic::QuicUtils::CreateRandomConnectionId(&random_),
Victor Vasiliev4f6fb892019-05-31 16:58:31145 ToQuicSocketAddress(kIpEndPoint), &helper_, &alarm_factory_, writer,
146 true, quic::Perspective::IS_CLIENT,
Nick Harper23290b82019-05-02 00:02:56147 quic::test::SupportedVersions(version_));
Nick Harpere45fe4fc2017-07-13 00:34:58148 session_.reset(new TestingQuicChromiumClientSession(
jri7e636642016-01-14 06:57:08149 connection, std::move(socket),
150 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57151 &transport_security_state_, /*ssl_config_service=*/nullptr,
Paul Jensen8e3c5d32018-02-19 17:06:33152 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)), session_key_,
Bence Béky1ceba552019-07-19 17:11:05153 /*require_confirmation=*/false,
154 /*max_allowed_push_id=*/0, migrate_session_early_v2_,
Yixin Wangf65c4b6d2018-03-08 22:37:40155 /*migrate_session_on_network_change_v2=*/false,
Zhongyi Shid672f7542018-06-08 01:03:26156 /*defaulet_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shie01f2db2019-02-22 19:53:23157 quic::QuicTime::Delta::FromMilliseconds(
Ryan Sleevi2e8255b2019-07-17 21:02:21158 kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
Zhongyi Shiaf38c4e42019-08-29 22:49:05159 /*migrate_idle_session=*/false, /*allow_port_migration=*/false,
160 kDefaultIdleSessionMigrationPeriod, kMaxTimeOnNonDefaultNetwork,
Zhongyi Shiee760762018-08-01 00:54:29161 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30162 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17163 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52164 quic::QuicTime::Delta::FromMilliseconds(
165 kQuicYieldAfterDurationMilliseconds),
Zhongyi Shidbce7f412019-02-01 23:16:29166 /*cert_verify_flags=*/0, /*go_away_on_path_degrading*/ false,
167 client_headers_include_h2_stream_dependency_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52168 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
Yixin Wang079ad542018-01-11 04:06:05169 base::TimeTicks::Now(), base::TimeTicks::Now(), &push_promise_index_,
Zhongyi Shic16b4102019-02-12 00:37:40170 &test_push_delegate_, base::DefaultTickClock::GetInstance(),
171 base::ThreadTaskRunnerHandle::Get().get(),
jri7e636642016-01-14 06:57:08172 /*socket_performance_watcher=*/nullptr, &net_log_));
173
174 scoped_refptr<X509Certificate> cert(
175 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
176 verify_details_.cert_verify_result.verified_cert = cert;
177 verify_details_.cert_verify_result.is_issued_by_known_root = true;
jri7e636642016-01-14 06:57:08178 session_->Initialize();
179 session_->StartReading();
jribce3eec2016-09-09 05:41:08180 writer->set_delegate(session_.get());
[email protected]dd3fd0e2012-11-04 05:14:40181 }
182
rtenneti85dcfac22015-03-27 20:22:19183 void TearDown() override {
rchf0b18c8a2017-05-05 19:31:57184 if (session_)
Renjieba55fae2018-09-20 03:05:16185 session_->CloseSessionOnError(
186 ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
187 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]4d283b32013-10-17 12:57:27188 }
189
[email protected]ed3fc15d2013-03-08 18:37:44190 void CompleteCryptoHandshake() {
rch433bf5f2017-02-14 04:10:47191 ASSERT_THAT(session_->CryptoConnect(callback_.callback()), IsOk());
[email protected]ed3fc15d2013-03-08 18:37:44192 }
193
jried79618b2016-07-02 03:18:52194 QuicChromiumPacketWriter* CreateQuicChromiumPacketWriter(
195 DatagramClientSocket* socket,
196 QuicChromiumClientSession* session) const {
danakjad1777e2016-04-16 00:56:42197 std::unique_ptr<QuicChromiumPacketWriter> writer(
Ryan Hamilton9edcf1a2017-11-22 05:55:17198 new QuicChromiumPacketWriter(
199 socket, base::ThreadTaskRunnerHandle::Get().get()));
jribce3eec2016-09-09 05:41:08200 writer->set_delegate(session);
jri7e636642016-01-14 06:57:08201 return writer.release();
202 }
203
Fan Yang32c5a112018-12-10 20:06:33204 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56205 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
206 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36207 }
208
Fan Yang32c5a112018-12-10 20:06:33209 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56210 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
211 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36212 }
213
Fan Yang32c5a112018-12-10 20:06:33214 size_t GetMaxAllowedOutgoingBidirectionalStreams() {
Frank Kastenholzc9b9bea2018-12-03 20:13:47215 quic::QuicSession* quic_session =
216 dynamic_cast<quic::QuicSession*>(&*session_);
Nick Harper23290b82019-05-02 00:02:56217 if (version_.transport_version != quic::QUIC_VERSION_99) {
Frank Kastenholzc9b9bea2018-12-03 20:13:47218 return quic::test::QuicSessionPeer::GetStreamIdManager(quic_session)
219 ->max_open_outgoing_streams();
220 }
David Schinazicc1bc592019-04-24 19:40:31221 // For version99, the count will include both static and dynamic streams.
222 // These tests are only concerned with dynamic streams (that is, the number
Ryan Hamilton4aeec562019-05-17 21:22:52223 // of streams that they can create), so back out the static header stream.
Frank Kastenholzc9b9bea2018-12-03 20:13:47224 return quic::test::QuicSessionPeer::v99_streamid_manager(quic_session)
Fan Yang2330d182019-08-05 14:50:50225 ->max_allowed_outgoing_bidirectional_streams();
Frank Kastenholzc9b9bea2018-12-03 20:13:47226 }
227
Nick Harper23290b82019-05-02 00:02:56228 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05229 const bool client_headers_include_h2_stream_dependency_;
Jana Iyengarf6b13d82017-09-04 02:09:10230 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52231 quic::QuicCryptoClientConfig crypto_config_;
vishal.b62985ca92015-04-17 08:45:51232 TestNetLog net_log_;
tfarina42834112016-09-22 13:38:20233 BoundTestNetLog bound_test_net_log_;
[email protected]4d283b32013-10-17 12:57:27234 MockClientSocketFactory socket_factory_;
danakjad1777e2016-04-16 00:56:42235 std::unique_ptr<MockRead> default_read_;
236 std::unique_ptr<SequencedSocketData> socket_data_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52237 quic::MockClock clock_;
238 quic::test::MockRandom random_;
rch12fef552016-01-15 16:26:31239 QuicChromiumConnectionHelper helper_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52240 quic::test::MockAlarmFactory alarm_factory_;
jri7e636642016-01-14 06:57:08241 TransportSecurityState transport_security_state_;
242 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52243 quic::QuicClientPushPromiseIndex push_promise_index_;
Paul Jensen8e3c5d32018-02-19 17:06:33244 QuicSessionKey session_key_;
Ryan Hamilton6c2a2a82017-12-15 02:06:28245 HostPortPair destination_;
Nick Harpere45fe4fc2017-07-13 00:34:58246 std::unique_ptr<TestingQuicChromiumClientSession> session_;
zhongyi0009f3e2016-11-11 19:47:50247 TestServerPushDelegate test_push_delegate_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52248 quic::QuicConnectionVisitorInterface* visitor_;
[email protected]8ee611b2012-11-20 01:48:12249 TestCompletionCallback callback_;
alyssar2adf3ac2016-05-03 17:12:58250 QuicTestPacketMaker client_maker_;
251 QuicTestPacketMaker server_maker_;
jri7e636642016-01-14 06:57:08252 ProofVerifyDetailsChromium verify_details_;
Yixin Wangf65c4b6d2018-03-08 22:37:40253 bool migrate_session_early_v2_;
[email protected]dd3fd0e2012-11-04 05:14:40254};
255
Victor Costane635086f2019-01-27 05:20:30256INSTANTIATE_TEST_SUITE_P(
Bence Békyce380cb2018-04-26 23:39:55257 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05258 QuicChromiumClientSessionTest,
Ryan Hamilton93424eb82019-08-23 04:28:40259 ::testing::Combine(::testing::ValuesIn(quic::AllSupportedVersions()),
Nick Harper23290b82019-05-02 00:02:56260 ::testing::Bool()));
[email protected]4d640792013-12-18 22:21:08261
Shivani Sharma8ae506c2019-07-21 21:08:27262// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
263// kAppendInitiatingFrameOriginToNetworkIsolationKey.
264
Carlos IL81133382017-12-06 17:18:45265TEST_P(QuicChromiumClientSessionTest, IsFatalErrorNotSetForNonFatalError) {
Renjie Tangaadb84b2019-08-31 01:00:23266 MockQuicData quic_data(version_);
267 if (VersionUsesQpack(version_.transport_version))
268 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
269 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
270 quic_data.AddRead(ASYNC, OK); // EOF
271 quic_data.AddSocketDataToFactory(&socket_factory_);
272
Carlos IL81133382017-12-06 17:18:45273 Initialize();
274
275 SSLInfo ssl_info;
276 ProofVerifyDetailsChromium details;
277 details.cert_verify_result.verified_cert =
278 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
279 details.cert_verify_result.cert_status =
280 MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
281 details.is_fatal_cert_error = false;
282 CompleteCryptoHandshake();
283 session_->OnProofVerifyDetailsAvailable(details);
284
285 ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
286 EXPECT_FALSE(ssl_info.is_fatal_cert_error);
287}
288
289TEST_P(QuicChromiumClientSessionTest, IsFatalErrorSetForFatalError) {
Renjie Tangaadb84b2019-08-31 01:00:23290 MockQuicData quic_data(version_);
291 if (VersionUsesQpack(version_.transport_version))
292 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
293 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
294 quic_data.AddRead(ASYNC, OK); // EOF
295 quic_data.AddSocketDataToFactory(&socket_factory_);
Carlos IL81133382017-12-06 17:18:45296 Initialize();
297
298 SSLInfo ssl_info;
299 ProofVerifyDetailsChromium details;
300 details.cert_verify_result.verified_cert =
301 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
302 details.cert_verify_result.cert_status =
303 MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
304 details.is_fatal_cert_error = true;
305 CompleteCryptoHandshake();
306 session_->OnProofVerifyDetailsAvailable(details);
307 ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
308 EXPECT_TRUE(ssl_info.is_fatal_cert_error);
309}
310
ckrasic4f9d88d2015-07-22 22:23:16311TEST_P(QuicChromiumClientSessionTest, CryptoConnect) {
Renjie Tangaadb84b2019-08-31 01:00:23312 MockQuicData quic_data(version_);
313 if (VersionUsesQpack(version_.transport_version))
314 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
315 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
316 quic_data.AddRead(ASYNC, OK); // EOF
317 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:08318 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44319 CompleteCryptoHandshake();
[email protected]8ee611b2012-11-20 01:48:12320}
321
rchf0b18c8a2017-05-05 19:31:57322TEST_P(QuicChromiumClientSessionTest, Handle) {
Ryan Hamiltonabad59e2019-06-06 04:02:59323 MockQuicData quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:23324 if (VersionUsesQpack(version_.transport_version))
325 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
rchf0b18c8a2017-05-05 19:31:57326 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
327 quic_data.AddRead(ASYNC, OK); // EOF
328 quic_data.AddSocketDataToFactory(&socket_factory_);
329
330 Initialize();
331
332 NetLogWithSource session_net_log = session_->net_log();
333 EXPECT_EQ(NetLogSourceType::QUIC_SESSION, session_net_log.source().type);
334 EXPECT_EQ(&net_log_, session_net_log.net_log());
335
336 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28337 session_->CreateHandle(destination_);
rchf0b18c8a2017-05-05 19:31:57338 EXPECT_TRUE(handle->IsConnected());
339 EXPECT_FALSE(handle->IsCryptoHandshakeConfirmed());
Nick Harper23290b82019-05-02 00:02:56340 EXPECT_EQ(version_.transport_version, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33341 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57342 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
343 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
344 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
345 IPEndPoint address;
346 EXPECT_EQ(OK, handle->GetPeerAddress(&address));
347 EXPECT_EQ(kIpEndPoint, address);
Bin Wuae74d8b2019-06-19 23:55:07348 EXPECT_TRUE(handle->CreatePacketBundler().get() != nullptr);
rchf0b18c8a2017-05-05 19:31:57349
350 CompleteCryptoHandshake();
351
352 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
353
354 // Request a stream and verify that a stream was created.
355 TestCompletionCallback callback;
356 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39357 callback.callback(),
358 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29359 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchf0b18c8a2017-05-05 19:31:57360
361 quic_data.Resume();
362 EXPECT_TRUE(quic_data.AllReadDataConsumed());
363 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
364
365 // Veirfy that the handle works correctly after the session is closed.
366 EXPECT_FALSE(handle->IsConnected());
367 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
Nick Harper23290b82019-05-02 00:02:56368 EXPECT_EQ(version_.transport_version, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33369 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57370 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
371 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
372 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
373 EXPECT_EQ(ERR_CONNECTION_CLOSED, handle->GetPeerAddress(&address));
Bin Wuae74d8b2019-06-19 23:55:07374 EXPECT_TRUE(handle->CreatePacketBundler().get() == nullptr);
rchf0b18c8a2017-05-05 19:31:57375 {
376 // Verify that CreateHandle() works even after the session is closed.
377 std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
Ryan Hamilton6c2a2a82017-12-15 02:06:28378 session_->CreateHandle(destination_);
rchf0b18c8a2017-05-05 19:31:57379 EXPECT_FALSE(handle2->IsConnected());
380 EXPECT_TRUE(handle2->IsCryptoHandshakeConfirmed());
381 ASSERT_EQ(ERR_CONNECTION_CLOSED,
382 handle2->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39383 callback.callback(),
384 TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57385 }
386
387 session_.reset();
388
389 // Veirfy that the handle works correctly after the session is deleted.
390 EXPECT_FALSE(handle->IsConnected());
391 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
Nick Harper23290b82019-05-02 00:02:56392 EXPECT_EQ(version_.transport_version, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33393 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57394 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
395 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
396 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
397 EXPECT_EQ(ERR_CONNECTION_CLOSED, handle->GetPeerAddress(&address));
Bin Wuae74d8b2019-06-19 23:55:07398 EXPECT_TRUE(handle->CreatePacketBundler().get() == nullptr);
Ramin Halavati683bcaa92018-02-14 08:42:39399 ASSERT_EQ(
400 ERR_CONNECTION_CLOSED,
401 handle->RequestStream(/*requires_confirmation=*/false,
402 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57403}
404
rch1baa7472017-04-26 05:43:58405TEST_P(QuicChromiumClientSessionTest, StreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59406 MockQuicData quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:23407 if (VersionUsesQpack(version_.transport_version))
408 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
rch1baa7472017-04-26 05:43:58409 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
410 quic_data.AddRead(ASYNC, OK); // EOF
411 quic_data.AddSocketDataToFactory(&socket_factory_);
412
413 Initialize();
414 CompleteCryptoHandshake();
415
416 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57417 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28418 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58419 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57420 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39421 callback.callback(),
422 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29423 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rch1baa7472017-04-26 05:43:58424
425 quic_data.Resume();
426 EXPECT_TRUE(quic_data.AllReadDataConsumed());
427 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
428}
429
rchd606b6c32017-05-02 17:32:57430TEST_P(QuicChromiumClientSessionTest, ConfirmationRequiredStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59431 MockQuicData quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:23432 if (VersionUsesQpack(version_.transport_version))
433 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
rchd606b6c32017-05-02 17:32:57434 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
435 quic_data.AddRead(ASYNC, OK); // EOF
436 quic_data.AddSocketDataToFactory(&socket_factory_);
437
438 Initialize();
439 CompleteCryptoHandshake();
440
441 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57442 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28443 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57444 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57445 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/true,
Ramin Halavati683bcaa92018-02-14 08:42:39446 callback.callback(),
447 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29448 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchd606b6c32017-05-02 17:32:57449
450 quic_data.Resume();
451 EXPECT_TRUE(quic_data.AllReadDataConsumed());
452 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
453}
454
455TEST_P(QuicChromiumClientSessionTest, StreamRequestBeforeConfirmation) {
Ryan Hamiltonabad59e2019-06-06 04:02:59456 MockQuicData quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:23457 if (VersionUsesQpack(version_.transport_version))
458 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
rchd606b6c32017-05-02 17:32:57459 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
460 quic_data.AddRead(ASYNC, OK); // EOF
461 quic_data.AddSocketDataToFactory(&socket_factory_);
462
463 Initialize();
464
465 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57466 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28467 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57468 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39469 ASSERT_EQ(
470 ERR_IO_PENDING,
471 handle->RequestStream(/*requires_confirmation=*/true, callback.callback(),
472 TRAFFIC_ANNOTATION_FOR_TESTS));
rchd606b6c32017-05-02 17:32:57473
474 CompleteCryptoHandshake();
475
476 EXPECT_THAT(callback.WaitForResult(), IsOk());
477
rch1bcfddf22017-06-03 00:26:29478 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchd606b6c32017-05-02 17:32:57479
480 quic_data.Resume();
481 EXPECT_TRUE(quic_data.AllReadDataConsumed());
482 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
483}
484
rch1baa7472017-04-26 05:43:58485TEST_P(QuicChromiumClientSessionTest, CancelStreamRequestBeforeRelease) {
Ryan Hamiltonabad59e2019-06-06 04:02:59486 MockQuicData quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:23487 int packet_num = 1;
488 if (VersionUsesQpack(version_.transport_version)) {
489 quic_data.AddWrite(SYNCHRONOUS,
490 client_maker_.MakeInitialSettingsPacket(packet_num++));
491 }
492 quic_data.AddWrite(
493 SYNCHRONOUS,
494 client_maker_.MakeRstPacket(packet_num++, true,
495 GetNthClientInitiatedBidirectionalStreamId(0),
496 quic::QUIC_STREAM_CANCELLED));
rch1baa7472017-04-26 05:43:58497 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
498 quic_data.AddRead(ASYNC, OK); // EOF
499 quic_data.AddSocketDataToFactory(&socket_factory_);
500
501 Initialize();
502 CompleteCryptoHandshake();
503
504 // Request a stream and cancel it without releasing the stream.
rchf0b18c8a2017-05-05 19:31:57505 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28506 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58507 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57508 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39509 callback.callback(),
510 TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57511 handle.reset();
rch1baa7472017-04-26 05:43:58512
513 quic_data.Resume();
514 EXPECT_TRUE(quic_data.AllReadDataConsumed());
515 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
516}
517
518TEST_P(QuicChromiumClientSessionTest, AsyncStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59519 MockQuicData quic_data(version_);
Nick Harper23290b82019-05-02 00:02:56520 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjie Tangaadb84b2019-08-31 01:00:23521 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Frank Kastenholz878763bf2018-11-28 19:14:48522 // The open stream limit is set to 50 by
523 // MockCryptoClientStream::SetConfigNegotiated() so when the 51st stream is
David Schinazicc1bc592019-04-24 19:40:31524 // requested, a STREAMS_BLOCKED will be sent, indicating that it's blocked
Fan Yang2330d182019-08-05 14:50:50525 // at the limit of 50.
David Schinazicc1bc592019-04-24 19:40:31526 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Fan Yang2330d182019-08-05 14:50:50527 2, true, 50,
David Schinazicc1bc592019-04-24 19:40:31528 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:33529 quic_data.AddWrite(
530 SYNCHRONOUS, client_maker_.MakeRstPacket(
531 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41532 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:18533 /*include_stop_sending_if_v99=*/false));
David Schinazicc1bc592019-04-24 19:40:31534 // After the STREAMS_BLOCKED is sent, receive a MAX_STREAMS to increase
Fan Yang2330d182019-08-05 14:50:50535 // the limit to 52.
Fan Yang32c5a112018-12-10 20:06:33536 quic_data.AddRead(
Fan Yang2330d182019-08-05 14:50:50537 ASYNC, server_maker_.MakeMaxStreamsPacket(1, true, 52,
David Schinazicc1bc592019-04-24 19:40:31538 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47539 } else {
540 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33541 SYNCHRONOUS, client_maker_.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:23542 1, true, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:33543 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:48544 }
rch1baa7472017-04-26 05:43:58545 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
546 quic_data.AddRead(ASYNC, OK); // EOF
547 quic_data.AddSocketDataToFactory(&socket_factory_);
rch1baa7472017-04-26 05:43:58548 Initialize();
549 CompleteCryptoHandshake();
550
551 // Open the maximum number of streams so that a subsequent request
552 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33553 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch1baa7472017-04-26 05:43:58554 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50555 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch1baa7472017-04-26 05:43:58556 }
557 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
558
559 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57560 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28561 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58562 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39563 ASSERT_EQ(
564 ERR_IO_PENDING,
565 handle->RequestStream(/*requires_confirmation=*/false,
566 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch1baa7472017-04-26 05:43:58567
568 // Close a stream and ensure the stream request completes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52569 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
Fan Yang32c5a112018-12-10 20:06:33570 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52571 quic::QUIC_STREAM_CANCELLED, 0);
rch1baa7472017-04-26 05:43:58572 session_->OnRstStream(rst);
Nick Harper23290b82019-05-02 00:02:56573 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz684ea412019-02-13 18:48:18574 // For version99, to close the stream completely, we also must receive a
575 // STOP_SENDING frame:
576 quic::QuicStopSendingFrame stop_sending(
577 quic::kInvalidControlFrameId,
578 GetNthClientInitiatedBidirectionalStreamId(0),
579 quic::QUIC_STREAM_CANCELLED);
580 session_->OnStopSendingFrame(stop_sending);
581 }
Frank Kastenholz878763bf2018-11-28 19:14:48582 // Pump the message loop to read the max stream id packet.
583 base::RunLoop().RunUntilIdle();
584
rch1baa7472017-04-26 05:43:58585 ASSERT_TRUE(callback.have_result());
586 EXPECT_THAT(callback.WaitForResult(), IsOk());
rch1bcfddf22017-06-03 00:26:29587 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rch1baa7472017-04-26 05:43:58588
589 quic_data.Resume();
590 EXPECT_TRUE(quic_data.AllReadDataConsumed());
591 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
592}
593
Ryan Hamilton9883ff62017-08-01 06:07:05594TEST_P(QuicChromiumClientSessionTest, ClosedWithAsyncStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59595 MockQuicData quic_data(version_);
Nick Harper23290b82019-05-02 00:02:56596 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjie Tangaadb84b2019-08-31 01:00:23597 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Frank Kastenholzc9b9bea2018-12-03 20:13:47598 // The open stream limit is set to 50 by
599 // MockCryptoClientStream::SetConfigNegotiated() so when the 51st stream is
David Schinazicc1bc592019-04-24 19:40:31600 // requested, a STREAMS_BLOCKED will be sent, indicating that it's blocked
Fan Yang2330d182019-08-05 14:50:50601 // at the limit of 50.
David Schinazicc1bc592019-04-24 19:40:31602 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Fan Yang2330d182019-08-05 14:50:50603 2, true, 50,
David Schinazicc1bc592019-04-24 19:40:31604 /*unidirectional=*/false));
605 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Fan Yang2330d182019-08-05 14:50:50606 3, true, 50,
David Schinazicc1bc592019-04-24 19:40:31607 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47608 }
Ryan Hamilton9883ff62017-08-01 06:07:05609 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
610 quic_data.AddRead(ASYNC, OK); // EOF
611 quic_data.AddSocketDataToFactory(&socket_factory_);
612
613 Initialize();
614 CompleteCryptoHandshake();
615
616 // Open the maximum number of streams so that a subsequent request
617 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33618 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
Ryan Hamilton9883ff62017-08-01 06:07:05619 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50620 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
Ryan Hamilton9883ff62017-08-01 06:07:05621 }
622 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
623
624 // Request two streams which will both be pending.
Frank Kastenholzc9b9bea2018-12-03 20:13:47625 // In V99 each will generate a max stream id for each attempt.
Ryan Hamilton9883ff62017-08-01 06:07:05626 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28627 session_->CreateHandle(destination_);
Ryan Hamilton9883ff62017-08-01 06:07:05628 std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
Ryan Hamilton6c2a2a82017-12-15 02:06:28629 session_->CreateHandle(destination_);
Ryan Hamilton9883ff62017-08-01 06:07:05630
Yannic Bonenberger3c96beb2019-09-03 20:41:37631 ASSERT_EQ(
632 ERR_IO_PENDING,
633 handle->RequestStream(
634 /*requires_confirmation=*/false,
635 base::BindOnce(&QuicChromiumClientSessionTest::ResetHandleOnError,
636 base::Unretained(this), &handle2),
637 TRAFFIC_ANNOTATION_FOR_TESTS));
Ryan Hamilton9883ff62017-08-01 06:07:05638
639 TestCompletionCallback callback2;
640 ASSERT_EQ(ERR_IO_PENDING,
641 handle2->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39642 callback2.callback(),
643 TRAFFIC_ANNOTATION_FOR_TESTS));
Ryan Hamilton9883ff62017-08-01 06:07:05644
645 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52646 quic::QUIC_NETWORK_IDLE_TIMEOUT, "Timed out",
647 quic::ConnectionCloseBehavior::SILENT_CLOSE);
Ryan Hamilton9883ff62017-08-01 06:07:05648
649 // Pump the message loop to read the connection close packet.
650 base::RunLoop().RunUntilIdle();
651 EXPECT_FALSE(handle2.get());
652 quic_data.Resume();
653 EXPECT_TRUE(quic_data.AllReadDataConsumed());
654 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
655}
656
rch1baa7472017-04-26 05:43:58657TEST_P(QuicChromiumClientSessionTest, CancelPendingStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59658 MockQuicData quic_data(version_);
Nick Harper23290b82019-05-02 00:02:56659 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjie Tangaadb84b2019-08-31 01:00:23660 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Frank Kastenholz878763bf2018-11-28 19:14:48661 // The open stream limit is set to 50 by
662 // MockCryptoClientStream::SetConfigNegotiated() so when the 51st stream is
David Schinazicc1bc592019-04-24 19:40:31663 // requested, a STREAMS_BLOCKED will be sent.
664 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Fan Yang2330d182019-08-05 14:50:50665 2, true, 50,
David Schinazicc1bc592019-04-24 19:40:31666 /*unidirectional=*/false));
Frank Kastenholz684ea412019-02-13 18:48:18667 // This node receives the RST_STREAM+STOP_SENDING, it responds
668 // with only a RST_STREAM.
Fan Yang32c5a112018-12-10 20:06:33669 quic_data.AddWrite(
670 SYNCHRONOUS, client_maker_.MakeRstPacket(
671 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41672 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:18673 /*include_stop_sending_if_v99=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47674 } else {
675 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33676 SYNCHRONOUS, client_maker_.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:23677 1, true, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:33678 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:48679 }
rch1baa7472017-04-26 05:43:58680 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
681 quic_data.AddRead(ASYNC, OK); // EOF
682 quic_data.AddSocketDataToFactory(&socket_factory_);
683
684 Initialize();
685 CompleteCryptoHandshake();
686
687 // Open the maximum number of streams so that a subsequent request
688 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33689 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch1baa7472017-04-26 05:43:58690 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50691 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch1baa7472017-04-26 05:43:58692 }
693 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
694
695 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57696 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28697 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58698 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39699 ASSERT_EQ(
700 ERR_IO_PENDING,
701 handle->RequestStream(/*requires_confirmation=*/false,
702 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch1baa7472017-04-26 05:43:58703
704 // Cancel the pending stream request.
rchf0b18c8a2017-05-05 19:31:57705 handle.reset();
rch1baa7472017-04-26 05:43:58706
707 // Close a stream and ensure that no new stream is created.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52708 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
Fan Yang32c5a112018-12-10 20:06:33709 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52710 quic::QUIC_STREAM_CANCELLED, 0);
rch1baa7472017-04-26 05:43:58711 session_->OnRstStream(rst);
Nick Harper23290b82019-05-02 00:02:56712 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz684ea412019-02-13 18:48:18713 // For version99, we require a STOP_SENDING as well as a RESET_STREAM to
714 // fully close the stream.
715 quic::QuicStopSendingFrame stop_sending(
716 quic::kInvalidControlFrameId,
717 GetNthClientInitiatedBidirectionalStreamId(0),
718 quic::QUIC_STREAM_CANCELLED);
719 session_->OnStopSendingFrame(stop_sending);
720 }
rch1baa7472017-04-26 05:43:58721 EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
722
723 quic_data.Resume();
724 EXPECT_TRUE(quic_data.AllReadDataConsumed());
725 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
726}
727
rch94c26d682017-04-29 02:49:27728TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59729 MockQuicData quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:23730 int packet_num = 1;
731 if (VersionUsesQpack(version_.transport_version)) {
732 quic_data.AddWrite(SYNCHRONOUS,
733 client_maker_.MakeInitialSettingsPacket(packet_num++));
734 }
735 quic_data.AddWrite(SYNCHRONOUS,
736 client_maker_.MakePingPacket(packet_num++, true));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52737 quic_data.AddRead(
738 ASYNC,
739 server_maker_.MakeConnectionClosePacket(
740 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
Renjie Tangaadb84b2019-08-31 01:00:23741
rch94c26d682017-04-29 02:49:27742 quic_data.AddSocketDataToFactory(&socket_factory_);
743
744 Initialize();
745 CompleteCryptoHandshake();
746
Renjie Tangaadb84b2019-08-31 01:00:23747 // Send a ping so that client has outgoing traffic before receiving packets.
748 session_->SendPing();
749
rch94c26d682017-04-29 02:49:27750 // Pump the message loop to read the connection close packet.
751 base::RunLoop().RunUntilIdle();
752
753 // Request a stream and verify that it failed.
rchf0b18c8a2017-05-05 19:31:57754 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28755 session_->CreateHandle(destination_);
rch94c26d682017-04-29 02:49:27756 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39757 ASSERT_EQ(
758 ERR_CONNECTION_CLOSED,
759 handle->RequestStream(/*requires_confirmation=*/false,
760 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch94c26d682017-04-29 02:49:27761
762 EXPECT_TRUE(quic_data.AllReadDataConsumed());
763 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
764}
765
rchd606b6c32017-05-02 17:32:57766TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeHandshakeConfirmed) {
Ryan Hamilton8380c652019-06-04 02:25:06767 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
768 // TODO(nharper, b/112643533): Figure out why this test fails when TLS is
769 // enabled and fix it.
770 return;
771 }
772
David Schinazic8281052019-01-24 06:14:17773 // Force the connection close packet to use long headers with connection ID.
Ryan Hamilton840358c2019-03-19 19:00:35774 server_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
David Schinazic8281052019-01-24 06:14:17775
Ryan Hamiltonabad59e2019-06-06 04:02:59776 MockQuicData quic_data(version_);
rchd606b6c32017-05-02 17:32:57777 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52778 quic_data.AddRead(
779 ASYNC,
780 server_maker_.MakeConnectionClosePacket(
781 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rchd606b6c32017-05-02 17:32:57782 quic_data.AddSocketDataToFactory(&socket_factory_);
783
784 Initialize();
785
786 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57787 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28788 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57789 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39790 ASSERT_EQ(
791 ERR_IO_PENDING,
792 handle->RequestStream(/*requires_confirmation=*/true, callback.callback(),
793 TRAFFIC_ANNOTATION_FOR_TESTS));
rchd606b6c32017-05-02 17:32:57794
795 // Close the connection and verify that the StreamRequest completes with
796 // an error.
797 quic_data.Resume();
798 base::RunLoop().RunUntilIdle();
799
800 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
801
802 EXPECT_TRUE(quic_data.AllReadDataConsumed());
803 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
804}
805
rch94c26d682017-04-29 02:49:27806TEST_P(QuicChromiumClientSessionTest, ConnectionCloseWithPendingStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59807 MockQuicData quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:23808 int packet_num = 1;
809 if (version_.transport_version == quic::QUIC_VERSION_99) {
810 quic_data.AddWrite(SYNCHRONOUS,
811 client_maker_.MakeInitialSettingsPacket(packet_num++));
812 }
813 quic_data.AddWrite(SYNCHRONOUS,
814 client_maker_.MakePingPacket(packet_num++, true));
Nick Harper23290b82019-05-02 00:02:56815 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:31816 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Renjie Tangaadb84b2019-08-31 01:00:23817 packet_num++, true, 50,
David Schinazicc1bc592019-04-24 19:40:31818 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47819 }
rch94c26d682017-04-29 02:49:27820 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52821 quic_data.AddRead(
822 ASYNC,
823 server_maker_.MakeConnectionClosePacket(
824 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rch94c26d682017-04-29 02:49:27825 quic_data.AddSocketDataToFactory(&socket_factory_);
826
827 Initialize();
828 CompleteCryptoHandshake();
829
Renjie Tangaadb84b2019-08-31 01:00:23830 // Send a ping so that client has outgoing traffic before receiving packets.
831 session_->SendPing();
832
rch94c26d682017-04-29 02:49:27833 // Open the maximum number of streams so that a subsequent request
834 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33835 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch94c26d682017-04-29 02:49:27836 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50837 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch94c26d682017-04-29 02:49:27838 }
839 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
840
841 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57842 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28843 session_->CreateHandle(destination_);
rch94c26d682017-04-29 02:49:27844 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39845 ASSERT_EQ(
846 ERR_IO_PENDING,
847 handle->RequestStream(/*requires_confirmation=*/false,
848 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch94c26d682017-04-29 02:49:27849
850 // Close the connection and verify that the StreamRequest completes with
851 // an error.
852 quic_data.Resume();
853 base::RunLoop().RunUntilIdle();
854
855 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
856
857 EXPECT_TRUE(quic_data.AllReadDataConsumed());
858 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
859}
860
ckrasic4f9d88d2015-07-22 22:23:16861TEST_P(QuicChromiumClientSessionTest, MaxNumStreams) {
Ryan Hamiltonabad59e2019-06-06 04:02:59862 MockQuicData quic_data(version_);
Nick Harper23290b82019-05-02 00:02:56863 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjie Tangaadb84b2019-08-31 01:00:23864 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
David Schinazicc1bc592019-04-24 19:40:31865 // Initial configuration is 50 dynamic streams. Taking into account
Ryan Hamilton4aeec562019-05-17 21:22:52866 // the static stream (headers), expect to block on when hitting the limit
Fan Yang2330d182019-08-05 14:50:50867 // of 50 streams
David Schinazicc1bc592019-04-24 19:40:31868 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Fan Yang2330d182019-08-05 14:50:50869 2, true, 50,
David Schinazicc1bc592019-04-24 19:40:31870 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:33871 quic_data.AddWrite(
872 SYNCHRONOUS, client_maker_.MakeRstPacket(
873 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
874 quic::QUIC_RST_ACKNOWLEDGEMENT));
David Schinazicc1bc592019-04-24 19:40:31875 // For the second CreateOutgoingStream that fails because of hitting the
876 // stream count limit.
877 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Fan Yang2330d182019-08-05 14:50:50878 4, true, 50,
David Schinazicc1bc592019-04-24 19:40:31879 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:33880 quic_data.AddRead(
Ryan Hamilton4aeec562019-05-17 21:22:52881 ASYNC, server_maker_.MakeMaxStreamsPacket(1, true, 50 + 2,
David Schinazicc1bc592019-04-24 19:40:31882 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47883 } else {
884 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33885 SYNCHRONOUS, client_maker_.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:23886 1, true, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:33887 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:48888 }
889 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
890 quic_data.AddRead(ASYNC, OK); // EOF
891 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:08892
893 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44894 CompleteCryptoHandshake();
Fan Yang32c5a112018-12-10 20:06:33895 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
[email protected]dd3fd0e2012-11-04 05:14:40896
rch12fef552016-01-15 16:26:31897 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:08898 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:57899 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50900 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
[email protected]dd3fd0e2012-11-04 05:14:40901 EXPECT_TRUE(stream);
[email protected]f702d572012-12-04 15:56:20902 streams.push_back(stream);
[email protected]dd3fd0e2012-11-04 05:14:40903 }
David Schinazicc1bc592019-04-24 19:40:31904 // This stream, the 51st dynamic stream, can not be opened.
Fan Yang5a3bddf2018-10-12 10:05:50905 EXPECT_FALSE(
906 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
[email protected]dd3fd0e2012-11-04 05:14:40907
jri7e636642016-01-14 06:57:08908 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
rtennetiac06c2f2015-11-05 18:12:35909
[email protected]dd3fd0e2012-11-04 05:14:40910 // Close a stream and ensure I can now open a new one.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52911 quic::QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:08912 session_->CloseStream(stream_id);
rtennetiac06c2f2015-11-05 18:12:35913
Frank Kastenholzc9b9bea2018-12-03 20:13:47914 // Pump data, bringing in the max-stream-id
915 base::RunLoop().RunUntilIdle();
916
Fan Yang5a3bddf2018-10-12 10:05:50917 EXPECT_FALSE(
918 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52919 quic::QuicRstStreamFrame rst1(quic::kInvalidControlFrameId, stream_id,
920 quic::QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:08921 session_->OnRstStream(rst1);
922 EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
Frank Kastenholz878763bf2018-11-28 19:14:48923 base::RunLoop().RunUntilIdle();
Fan Yang5a3bddf2018-10-12 10:05:50924 EXPECT_TRUE(
925 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
[email protected]dd3fd0e2012-11-04 05:14:40926}
927
zhongyie34c035662016-10-19 22:26:02928TEST_P(QuicChromiumClientSessionTest, PushStreamTimedOutNoResponse) {
929 base::HistogramTester histogram_tester;
Renjie Tangaadb84b2019-08-31 01:00:23930 MockQuicData quic_data(version_);
931 int packet_num = 1;
932 if (VersionUsesQpack(version_.transport_version)) {
933 quic_data.AddWrite(ASYNC,
934 client_maker_.MakeInitialSettingsPacket(packet_num++));
935 }
936 quic_data.AddWrite(ASYNC, client_maker_.MakeRstPacket(
937 packet_num++, true,
938 GetNthServerInitiatedUnidirectionalStreamId(0),
939 quic::QUIC_PUSH_STREAM_TIMED_OUT));
940 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
941 quic_data.AddRead(ASYNC, OK); // EOF
942 quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyie34c035662016-10-19 22:26:02943 Initialize();
944
945 ProofVerifyDetailsChromium details;
946 details.cert_verify_result.verified_cert =
947 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
948 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
949
950 CompleteCryptoHandshake();
951 session_->OnProofVerifyDetailsAvailable(details);
952
Ramin Halavatif7788ea2018-02-26 07:02:57953 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50954 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyie34c035662016-10-19 22:26:02955 EXPECT_TRUE(stream);
956
Ryan Hamilton0239aac2018-05-19 00:03:13957 spdy::SpdyHeaderBlock promise_headers;
zhongyie34c035662016-10-19 22:26:02958 promise_headers[":method"] = "GET";
959 promise_headers[":authority"] = "www.example.org";
960 promise_headers[":scheme"] = "https";
961 promise_headers[":path"] = "/pushed.jpg";
962
963 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36964 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:33965 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
966 promise_headers));
zhongyie34c035662016-10-19 22:26:02967
Ryan Hamilton8d9ee76e2018-05-29 23:52:52968 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:33969 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyie34c035662016-10-19 22:26:02970 EXPECT_TRUE(promised);
971 // Fire alarm to time out the push stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52972 alarm_factory_.FireAlarm(
973 quic::test::QuicClientPromisedInfoPeer::GetAlarm(promised));
zhongyie34c035662016-10-19 22:26:02974 EXPECT_FALSE(
975 session_->GetPromisedByUrl("https://www.example.org/pushed.jpg"));
976 EXPECT_EQ(0u,
977 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
978 EXPECT_EQ(0u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
979 session_.get()));
980}
981
982TEST_P(QuicChromiumClientSessionTest, PushStreamTimedOutWithResponse) {
983 base::HistogramTester histogram_tester;
Renjie Tangaadb84b2019-08-31 01:00:23984 MockQuicData quic_data(version_);
985 int packet_num = 1;
986 if (VersionUsesQpack(version_.transport_version)) {
987 quic_data.AddWrite(ASYNC,
988 client_maker_.MakeInitialSettingsPacket(packet_num++));
989 }
990 quic_data.AddWrite(ASYNC, client_maker_.MakeRstPacket(
991 packet_num++, true,
992 GetNthServerInitiatedUnidirectionalStreamId(0),
993 quic::QUIC_PUSH_STREAM_TIMED_OUT));
994 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
995 quic_data.AddRead(ASYNC, OK); // EOF
996 quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyie34c035662016-10-19 22:26:02997 Initialize();
998
999 ProofVerifyDetailsChromium details;
1000 details.cert_verify_result.verified_cert =
1001 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1002 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1003
1004 CompleteCryptoHandshake();
1005 session_->OnProofVerifyDetailsAvailable(details);
1006
Ramin Halavatif7788ea2018-02-26 07:02:571007 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501008 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyie34c035662016-10-19 22:26:021009 EXPECT_TRUE(stream);
1010
Ryan Hamilton0239aac2018-05-19 00:03:131011 spdy::SpdyHeaderBlock promise_headers;
zhongyie34c035662016-10-19 22:26:021012 promise_headers[":method"] = "GET";
1013 promise_headers[":authority"] = "www.example.org";
1014 promise_headers[":scheme"] = "https";
1015 promise_headers[":path"] = "/pushed.jpg";
1016
Fan Yang32c5a112018-12-10 20:06:331017 session_->GetOrCreateStream(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyie34c035662016-10-19 22:26:021018 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361019 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:331020 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
1021 promise_headers));
1022 session_->OnInitialHeadersComplete(
1023 GetNthServerInitiatedUnidirectionalStreamId(0), spdy::SpdyHeaderBlock());
zhongyie34c035662016-10-19 22:26:021024 // Read data on the pushed stream.
Fan Yang32c5a112018-12-10 20:06:331025 quic::QuicStreamFrame data(GetNthServerInitiatedUnidirectionalStreamId(0),
1026 false, 0, quic::QuicStringPiece("SP"));
zhongyie34c035662016-10-19 22:26:021027 session_->OnStreamFrame(data);
1028
Ryan Hamilton8d9ee76e2018-05-29 23:52:521029 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:331030 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyie34c035662016-10-19 22:26:021031 EXPECT_TRUE(promised);
1032 // Fire alarm to time out the push stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521033 alarm_factory_.FireAlarm(
1034 quic::test::QuicClientPromisedInfoPeer::GetAlarm(promised));
zhongyie34c035662016-10-19 22:26:021035 EXPECT_EQ(2u,
1036 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
1037 EXPECT_EQ(2u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
1038 session_.get()));
1039}
1040
Renjie7f5894b2019-05-31 03:41:311041// Regression test for crbug.com/968621.
1042TEST_P(QuicChromiumClientSessionTest, PendingStreamOnRst) {
1043 if (!quic::VersionHasStreamType(version_.transport_version))
1044 return;
1045
Renjie Tangaadb84b2019-08-31 01:00:231046 MockQuicData quic_data(version_);
1047 int packet_num = 1;
1048 if (VersionUsesQpack(version_.transport_version)) {
1049 quic_data.AddWrite(ASYNC,
1050 client_maker_.MakeInitialSettingsPacket(packet_num++));
1051 }
1052 quic_data.AddWrite(ASYNC, client_maker_.MakeRstPacket(
1053 packet_num++, true,
1054 GetNthServerInitiatedUnidirectionalStreamId(0),
1055 quic::QUIC_RST_ACKNOWLEDGEMENT));
1056 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1057 quic_data.AddRead(ASYNC, OK); // EOF
1058 quic_data.AddSocketDataToFactory(&socket_factory_);
Renjie7f5894b2019-05-31 03:41:311059
1060 Initialize();
1061 CompleteCryptoHandshake();
1062
1063 quic::QuicStreamFrame data(GetNthServerInitiatedUnidirectionalStreamId(0),
1064 false, 1, quic::QuicStringPiece("SP"));
1065 session_->OnStreamFrame(data);
1066 EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
1067 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
1068 GetNthServerInitiatedUnidirectionalStreamId(0),
1069 quic::QUIC_STREAM_CANCELLED, 0);
1070 session_->OnRstStream(rst);
1071}
1072
Renjie82ddaf42019-06-07 23:40:311073// Regression test for crbug.com/971361.
1074TEST_P(QuicChromiumClientSessionTest, ClosePendingStream) {
1075 if (!quic::VersionHasStreamType(version_.transport_version))
1076 return;
1077
Renjie Tangaadb84b2019-08-31 01:00:231078 MockQuicData quic_data(version_);
1079 int packet_num = 1;
1080 if (VersionUsesQpack(version_.transport_version)) {
1081 quic_data.AddWrite(ASYNC,
1082 client_maker_.MakeInitialSettingsPacket(packet_num++));
1083 }
1084 quic_data.AddWrite(ASYNC, client_maker_.MakeRstPacket(
1085 packet_num++, true,
1086 GetNthServerInitiatedUnidirectionalStreamId(0),
1087 quic::QUIC_RST_ACKNOWLEDGEMENT));
1088 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1089 quic_data.AddRead(ASYNC, OK); // EOF
1090 quic_data.AddSocketDataToFactory(&socket_factory_);
Renjie82ddaf42019-06-07 23:40:311091
1092 Initialize();
1093 CompleteCryptoHandshake();
1094
1095 quic::QuicStreamId id = GetNthServerInitiatedUnidirectionalStreamId(0);
1096 quic::QuicStreamFrame data(id, false, 1, quic::QuicStringPiece("SP"));
1097 session_->OnStreamFrame(data);
1098 EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
1099 session_->CloseStream(id);
1100}
1101
zhongyi7465c1b2016-11-11 01:38:051102TEST_P(QuicChromiumClientSessionTest, CancelPushWhenPendingValidation) {
Renjie Tangaadb84b2019-08-31 01:00:231103 MockQuicData quic_data(version_);
1104 int packet_num = 1;
1105 if (VersionUsesQpack(version_.transport_version)) {
1106 quic_data.AddWrite(ASYNC,
1107 client_maker_.MakeInitialSettingsPacket(packet_num++));
1108 }
1109 quic_data.AddWrite(ASYNC, client_maker_.MakeRstPacket(
1110 packet_num++, true,
1111 GetNthClientInitiatedBidirectionalStreamId(0),
1112 quic::QUIC_RST_ACKNOWLEDGEMENT));
1113 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1114 quic_data.AddRead(ASYNC, OK); // EOF
1115 quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi7465c1b2016-11-11 01:38:051116 Initialize();
1117
1118 ProofVerifyDetailsChromium details;
1119 details.cert_verify_result.verified_cert =
1120 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1121 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1122
1123 CompleteCryptoHandshake();
1124 session_->OnProofVerifyDetailsAvailable(details);
1125
Ramin Halavatif7788ea2018-02-26 07:02:571126 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501127 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyi7465c1b2016-11-11 01:38:051128 EXPECT_TRUE(stream);
1129
Ryan Hamilton0239aac2018-05-19 00:03:131130 spdy::SpdyHeaderBlock promise_headers;
zhongyi7465c1b2016-11-11 01:38:051131 promise_headers[":method"] = "GET";
1132 promise_headers[":authority"] = "www.example.org";
1133 promise_headers[":scheme"] = "https";
1134 promise_headers[":path"] = "/pushed.jpg";
1135
1136 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361137 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:331138 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
1139 promise_headers));
zhongyi7465c1b2016-11-11 01:38:051140
Ryan Hamilton8d9ee76e2018-05-29 23:52:521141 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:331142 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi7465c1b2016-11-11 01:38:051143 EXPECT_TRUE(promised);
1144
1145 // Initiate rendezvous.
Ryan Hamilton0239aac2018-05-19 00:03:131146 spdy::SpdyHeaderBlock client_request = promise_headers.Clone();
Ryan Hamilton8d9ee76e2018-05-29 23:52:521147 quic::test::TestPushPromiseDelegate delegate(/*match=*/true);
zhongyi7465c1b2016-11-11 01:38:051148 promised->HandleClientRequest(client_request, &delegate);
1149
1150 // Cancel the push before receiving the response to the pushed request.
1151 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:501152 test_push_delegate_.CancelPush(pushed_url);
zhongyi7465c1b2016-11-11 01:38:051153 EXPECT_TRUE(session_->GetPromisedByUrl(pushed_url.spec()));
1154
1155 // Reset the stream now before tear down.
Fan Yang32c5a112018-12-10 20:06:331156 session_->CloseStream(GetNthClientInitiatedBidirectionalStreamId(0));
zhongyi7465c1b2016-11-11 01:38:051157}
1158
zhongyi18bb2d92016-10-27 19:38:501159TEST_P(QuicChromiumClientSessionTest, CancelPushBeforeReceivingResponse) {
1160 base::HistogramTester histogram_tester;
Renjie Tangaadb84b2019-08-31 01:00:231161 MockQuicData quic_data(version_);
1162 int packet_num = 1;
1163 if (VersionUsesQpack(version_.transport_version)) {
1164 quic_data.AddWrite(ASYNC,
1165 client_maker_.MakeInitialSettingsPacket(packet_num++));
1166 }
1167 quic_data.AddWrite(ASYNC, client_maker_.MakeRstPacket(
1168 packet_num++, true,
1169 GetNthServerInitiatedUnidirectionalStreamId(0),
1170 quic::QUIC_STREAM_CANCELLED));
1171 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1172 quic_data.AddRead(ASYNC, OK); // EOF
1173 quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi18bb2d92016-10-27 19:38:501174 Initialize();
1175
1176 ProofVerifyDetailsChromium details;
1177 details.cert_verify_result.verified_cert =
1178 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1179 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1180
1181 CompleteCryptoHandshake();
1182 session_->OnProofVerifyDetailsAvailable(details);
1183
Ramin Halavatif7788ea2018-02-26 07:02:571184 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501185 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyi18bb2d92016-10-27 19:38:501186 EXPECT_TRUE(stream);
1187
Ryan Hamilton0239aac2018-05-19 00:03:131188 spdy::SpdyHeaderBlock promise_headers;
zhongyi18bb2d92016-10-27 19:38:501189 promise_headers[":method"] = "GET";
1190 promise_headers[":authority"] = "www.example.org";
1191 promise_headers[":scheme"] = "https";
1192 promise_headers[":path"] = "/pushed.jpg";
1193
1194 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361195 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:331196 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
1197 promise_headers));
zhongyi18bb2d92016-10-27 19:38:501198
Ryan Hamilton8d9ee76e2018-05-29 23:52:521199 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:331200 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501201 EXPECT_TRUE(promised);
1202 // Cancel the push before receiving the response to the pushed request.
1203 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:501204 test_push_delegate_.CancelPush(pushed_url);
zhongyi18bb2d92016-10-27 19:38:501205
1206 EXPECT_FALSE(session_->GetPromisedByUrl(pushed_url.spec()));
1207 EXPECT_EQ(0u,
1208 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
1209 EXPECT_EQ(0u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
1210 session_.get()));
1211}
1212
1213TEST_P(QuicChromiumClientSessionTest, CancelPushAfterReceivingResponse) {
1214 base::HistogramTester histogram_tester;
Renjie Tangaadb84b2019-08-31 01:00:231215 MockQuicData quic_data(version_);
1216 int packet_num = 1;
1217 if (VersionUsesQpack(version_.transport_version)) {
1218 quic_data.AddWrite(ASYNC,
1219 client_maker_.MakeInitialSettingsPacket(packet_num++));
1220 }
1221 quic_data.AddWrite(ASYNC, client_maker_.MakeRstPacket(
1222 packet_num++, true,
1223 GetNthServerInitiatedUnidirectionalStreamId(0),
1224 quic::QUIC_STREAM_CANCELLED));
1225 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1226 quic_data.AddRead(ASYNC, OK); // EOF
1227 quic_data.AddSocketDataToFactory(&socket_factory_);
1228
zhongyi18bb2d92016-10-27 19:38:501229 Initialize();
1230
1231 ProofVerifyDetailsChromium details;
1232 details.cert_verify_result.verified_cert =
1233 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1234 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1235
1236 CompleteCryptoHandshake();
1237 session_->OnProofVerifyDetailsAvailable(details);
1238
Ramin Halavatif7788ea2018-02-26 07:02:571239 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501240 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyi18bb2d92016-10-27 19:38:501241 EXPECT_TRUE(stream);
1242
Ryan Hamilton0239aac2018-05-19 00:03:131243 spdy::SpdyHeaderBlock promise_headers;
zhongyi18bb2d92016-10-27 19:38:501244 promise_headers[":method"] = "GET";
1245 promise_headers[":authority"] = "www.example.org";
1246 promise_headers[":scheme"] = "https";
1247 promise_headers[":path"] = "/pushed.jpg";
1248
Fan Yang32c5a112018-12-10 20:06:331249 session_->GetOrCreateStream(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501250 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361251 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:331252 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
1253 promise_headers));
1254 session_->OnInitialHeadersComplete(
1255 GetNthServerInitiatedUnidirectionalStreamId(0), spdy::SpdyHeaderBlock());
zhongyi18bb2d92016-10-27 19:38:501256 // Read data on the pushed stream.
Fan Yang32c5a112018-12-10 20:06:331257 quic::QuicStreamFrame data(GetNthServerInitiatedUnidirectionalStreamId(0),
1258 false, 0, quic::QuicStringPiece("SP"));
zhongyi18bb2d92016-10-27 19:38:501259 session_->OnStreamFrame(data);
1260
Ryan Hamilton8d9ee76e2018-05-29 23:52:521261 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:331262 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501263 EXPECT_TRUE(promised);
1264 // Cancel the push after receiving data on the push stream.
1265 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:501266 test_push_delegate_.CancelPush(pushed_url);
zhongyi18bb2d92016-10-27 19:38:501267
1268 EXPECT_FALSE(session_->GetPromisedByUrl(pushed_url.spec()));
1269 EXPECT_EQ(2u,
1270 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
1271 EXPECT_EQ(2u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
1272 session_.get()));
1273}
1274
ckrasic4f9d88d2015-07-22 22:23:161275TEST_P(QuicChromiumClientSessionTest, MaxNumStreamsViaRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:591276 MockQuicData quic_data(version_);
Nick Harper23290b82019-05-02 00:02:561277 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjie Tangaadb84b2019-08-31 01:00:231278 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
David Schinazicc1bc592019-04-24 19:40:311279 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Fan Yang2330d182019-08-05 14:50:501280 2, true, 50,
David Schinazicc1bc592019-04-24 19:40:311281 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:331282 quic_data.AddWrite(
1283 SYNCHRONOUS, client_maker_.MakeRstPacket(
1284 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
1285 quic::QUIC_RST_ACKNOWLEDGEMENT));
1286 quic_data.AddRead(
Fan Yang2330d182019-08-05 14:50:501287 ASYNC, server_maker_.MakeMaxStreamsPacket(1, true, 52,
David Schinazicc1bc592019-04-24 19:40:311288 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471289 } else {
1290 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331291 SYNCHRONOUS, client_maker_.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231292 1, true, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:331293 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:481294 }
1295 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1296 quic_data.AddRead(ASYNC, OK); // EOF
1297 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:081298
1299 Initialize();
[email protected]0b2294d32013-08-02 00:46:361300 CompleteCryptoHandshake();
Fan Yang32c5a112018-12-10 20:06:331301 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch12fef552016-01-15 16:26:311302 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:081303 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:571304 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501305 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
[email protected]0b2294d32013-08-02 00:46:361306 EXPECT_TRUE(stream);
1307 streams.push_back(stream);
1308 }
1309
rchf0b18c8a2017-05-05 19:31:571310 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:281311 session_->CreateHandle(destination_);
[email protected]0b2294d32013-08-02 00:46:361312 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:391313 ASSERT_EQ(
1314 ERR_IO_PENDING,
1315 handle->RequestStream(/*requires_confirmation=*/false,
1316 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]0b2294d32013-08-02 00:46:361317
1318 // Close a stream and ensure I can now open a new one.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521319 quic::QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:081320 session_->CloseStream(stream_id);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521321 quic::QuicRstStreamFrame rst1(quic::kInvalidControlFrameId, stream_id,
1322 quic::QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:081323 session_->OnRstStream(rst1);
Frank Kastenholz878763bf2018-11-28 19:14:481324 // Pump data, bringing in the max-stream-id
1325 base::RunLoop().RunUntilIdle();
[email protected]0b2294d32013-08-02 00:46:361326 ASSERT_TRUE(callback.have_result());
robpercival214763f2016-07-01 23:27:011327 EXPECT_THAT(callback.WaitForResult(), IsOk());
rch1bcfddf22017-06-03 00:26:291328 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
[email protected]0b2294d32013-08-02 00:46:361329}
1330
ckrasic4f9d88d2015-07-22 22:23:161331TEST_P(QuicChromiumClientSessionTest, GoAwayReceived) {
Renjie Tangaadb84b2019-08-31 01:00:231332 MockQuicData quic_data(version_);
1333 if (VersionUsesQpack(version_.transport_version))
1334 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
1335 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1336 quic_data.AddRead(ASYNC, OK); // EOF
1337 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:081338 Initialize();
[email protected]8ba81212013-05-03 13:11:481339 CompleteCryptoHandshake();
[email protected]9db443912013-02-25 05:27:031340
1341 // After receiving a GoAway, I should no longer be able to create outgoing
1342 // streams.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521343 session_->connection()->OnGoAwayFrame(
1344 quic::QuicGoAwayFrame(quic::kInvalidControlFrameId,
1345 quic::QUIC_PEER_GOING_AWAY, 1u, "Going away."));
Fan Yang5a3bddf2018-10-12 10:05:501346 EXPECT_EQ(nullptr, QuicChromiumClientSessionPeer::CreateOutgoingStream(
Ramin Halavatif7788ea2018-02-26 07:02:571347 session_.get()));
[email protected]9db443912013-02-25 05:27:031348}
1349
ckrasic4f9d88d2015-07-22 22:23:161350TEST_P(QuicChromiumClientSessionTest, CanPool) {
Renjie Tangaadb84b2019-08-31 01:00:231351 MockQuicData quic_data(version_);
1352 if (VersionUsesQpack(version_.transport_version))
1353 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
1354 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1355 quic_data.AddRead(ASYNC, OK); // EOF
1356 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:081357 Initialize();
[email protected]f21ec372014-07-02 07:15:121358 // Load a cert that is valid for:
1359 // www.example.org
1360 // mail.example.org
1361 // www.example.com
[email protected]f21ec372014-07-02 07:15:121362
[email protected]f21ec372014-07-02 07:15:121363 ProofVerifyDetailsChromium details;
1364 details.cert_verify_result.verified_cert =
[email protected]5db452202014-08-19 05:22:151365 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
dcheng4227c6d2014-08-25 23:58:181366 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]f21ec372014-07-02 07:15:121367
[email protected]f21ec372014-07-02 07:15:121368 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081369 session_->OnProofVerifyDetailsAvailable(details);
[email protected]f21ec372014-07-02 07:15:121370
Matt Menke26e41542019-06-05 01:09:511371 EXPECT_TRUE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED,
1372 SocketTag(), NetworkIsolationKey()));
1373 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_ENABLED,
1374 SocketTag(), NetworkIsolationKey()));
Paul Jensen8e3c5d32018-02-19 17:06:331375#if defined(OS_ANDROID)
1376 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
1377 SocketTag tag2(getuid(), 0x87654321);
Matt Menke26e41542019-06-05 01:09:511378 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag1,
1379 NetworkIsolationKey()));
1380 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag2,
1381 NetworkIsolationKey()));
Paul Jensen8e3c5d32018-02-19 17:06:331382#endif
1383 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
Matt Menke26e41542019-06-05 01:09:511384 SocketTag(), NetworkIsolationKey()));
Paul Jensen8e3c5d32018-02-19 17:06:331385 EXPECT_TRUE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
Matt Menke26e41542019-06-05 01:09:511386 SocketTag(), NetworkIsolationKey()));
1387 EXPECT_FALSE(session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED,
1388 SocketTag(), NetworkIsolationKey()));
1389
Shivani Sharma8ae506c2019-07-21 21:08:271390 const auto kOriginFoo = url::Origin::Create(GURL("http://foo.test/"));
1391
Matt Menke26e41542019-06-05 01:09:511392 // Check that NetworkIsolationKey is respected when feature is enabled.
1393 {
1394 base::test::ScopedFeatureList feature_list;
1395 feature_list.InitAndDisableFeature(
1396 features::kPartitionConnectionsByNetworkIsolationKey);
Shivani Sharma8ae506c2019-07-21 21:08:271397 EXPECT_TRUE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1398 SocketTag(),
1399 NetworkIsolationKey(kOriginFoo, kOriginFoo)));
Matt Menke26e41542019-06-05 01:09:511400 }
1401 {
1402 base::test::ScopedFeatureList feature_list;
1403 feature_list.InitAndEnableFeature(
1404 features::kPartitionConnectionsByNetworkIsolationKey);
1405 EXPECT_FALSE(session_->CanPool(
1406 "mail.example.com", PRIVACY_MODE_DISABLED, SocketTag(),
Shivani Sharma8ae506c2019-07-21 21:08:271407 NetworkIsolationKey(kOriginFoo, kOriginFoo)));
Matt Menke26e41542019-06-05 01:09:511408 }
1409}
1410
1411// Much as above, but uses a non-empty NetworkIsolationKey.
1412TEST_P(QuicChromiumClientSessionTest, CanPoolWithNetworkIsolationKey) {
1413 base::test::ScopedFeatureList feature_list;
1414 feature_list.InitAndEnableFeature(
1415 features::kPartitionConnectionsByNetworkIsolationKey);
1416
Shivani Sharma8ae506c2019-07-21 21:08:271417 const auto kOriginFoo = url::Origin::Create(GURL("http://foo.test/"));
1418 const auto kOriginBar = url::Origin::Create(GURL("http://bar.test/"));
1419 const NetworkIsolationKey kNetworkIsolationKey1(kOriginFoo, kOriginFoo);
1420 const NetworkIsolationKey kNetworkIsolationKey2(kOriginBar, kOriginBar);
Matt Menke26e41542019-06-05 01:09:511421
1422 session_key_ =
1423 QuicSessionKey(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED,
1424 SocketTag(), kNetworkIsolationKey1);
1425
Renjie Tangaadb84b2019-08-31 01:00:231426 MockQuicData quic_data(version_);
1427 if (VersionUsesQpack(version_.transport_version))
1428 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
1429 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1430 quic_data.AddRead(ASYNC, OK); // EOF
1431 quic_data.AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:511432 Initialize();
1433 // Load a cert that is valid for:
1434 // www.example.org
1435 // mail.example.org
1436 // www.example.com
1437
1438 ProofVerifyDetailsChromium details;
1439 details.cert_verify_result.verified_cert =
1440 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1441 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1442
1443 CompleteCryptoHandshake();
1444 session_->OnProofVerifyDetailsAvailable(details);
1445
1446 EXPECT_TRUE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED,
1447 SocketTag(), kNetworkIsolationKey1));
1448 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_ENABLED,
1449 SocketTag(), kNetworkIsolationKey1));
1450#if defined(OS_ANDROID)
1451 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
1452 SocketTag tag2(getuid(), 0x87654321);
1453 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag1,
1454 kNetworkIsolationKey1));
1455 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag2,
1456 kNetworkIsolationKey1));
1457#endif
1458 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1459 SocketTag(), kNetworkIsolationKey1));
1460 EXPECT_TRUE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1461 SocketTag(), kNetworkIsolationKey1));
1462 EXPECT_FALSE(session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED,
1463 SocketTag(), kNetworkIsolationKey1));
1464
1465 EXPECT_FALSE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1466 SocketTag(), kNetworkIsolationKey2));
1467 EXPECT_FALSE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1468 SocketTag(), NetworkIsolationKey()));
[email protected]f21ec372014-07-02 07:15:121469}
1470
ckrasic4f9d88d2015-07-22 22:23:161471TEST_P(QuicChromiumClientSessionTest, ConnectionNotPooledWithDifferentPin) {
Matt Mueller230996f12018-10-22 19:39:441472 // Configure the TransportSecurityStateSource so that kPreloadedPKPHost will
1473 // have static PKP pins set.
1474 ScopedTransportSecurityStateSource scoped_security_state_source;
1475
1476 // |net::test_default::kHSTSSource| defines pins for kPreloadedPKPHost.
1477 // (This hostname must be in the spdy_pooling.pem SAN.)
1478 const char kPreloadedPKPHost[] = "www.example.org";
1479 // A hostname without any static state. (This hostname isn't in
1480 // spdy_pooling.pem SAN, but that's okay because the
1481 // ProofVerifyDetailsChromium are faked.)
1482 const char kNoPinsHost[] = "no-pkp.example.org";
1483
Renjie Tangaadb84b2019-08-31 01:00:231484 MockQuicData quic_data(version_);
1485 if (VersionUsesQpack(version_.transport_version))
1486 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
1487 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1488 quic_data.AddRead(ASYNC, OK); // EOF
1489 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:081490 Initialize();
1491
Matt Mueller230996f12018-10-22 19:39:441492 transport_security_state_.EnableStaticPinsForTesting();
[email protected]5db452202014-08-19 05:22:151493
1494 ProofVerifyDetailsChromium details;
1495 details.cert_verify_result.verified_cert =
1496 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1497 details.cert_verify_result.is_issued_by_known_root = true;
Matt Mueller230996f12018-10-22 19:39:441498 uint8_t bad_pin = 3;
[email protected]5db452202014-08-19 05:22:151499 details.cert_verify_result.public_key_hashes.push_back(
1500 GetTestHashValue(bad_pin));
1501
dcheng4227c6d2014-08-25 23:58:181502 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:151503
[email protected]5db452202014-08-19 05:22:151504 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081505 session_->OnProofVerifyDetailsAvailable(details);
Matt Mueller230996f12018-10-22 19:39:441506 QuicChromiumClientSessionPeer::SetHostname(session_.get(), kNoPinsHost);
[email protected]5db452202014-08-19 05:22:151507
Matt Menke26e41542019-06-05 01:09:511508 EXPECT_FALSE(session_->CanPool(kPreloadedPKPHost, PRIVACY_MODE_DISABLED,
1509 SocketTag(), NetworkIsolationKey()));
[email protected]5db452202014-08-19 05:22:151510}
1511
ckrasic4f9d88d2015-07-22 22:23:161512TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithMatchingPin) {
Matt Mueller230996f12018-10-22 19:39:441513 ScopedTransportSecurityStateSource scoped_security_state_source;
1514
Renjie Tangaadb84b2019-08-31 01:00:231515 MockQuicData quic_data(version_);
1516 if (VersionUsesQpack(version_.transport_version))
1517 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
1518 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1519 quic_data.AddRead(ASYNC, OK); // EOF
1520 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:081521 Initialize();
1522
Matt Mueller230996f12018-10-22 19:39:441523 transport_security_state_.EnableStaticPinsForTesting();
[email protected]5db452202014-08-19 05:22:151524
1525 ProofVerifyDetailsChromium details;
1526 details.cert_verify_result.verified_cert =
1527 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1528 details.cert_verify_result.is_issued_by_known_root = true;
Matt Mueller230996f12018-10-22 19:39:441529 HashValue primary_pin(HASH_VALUE_SHA256);
1530 EXPECT_TRUE(primary_pin.FromString(
1531 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
1532 details.cert_verify_result.public_key_hashes.push_back(primary_pin);
[email protected]5db452202014-08-19 05:22:151533
dcheng4227c6d2014-08-25 23:58:181534 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:151535
[email protected]5db452202014-08-19 05:22:151536 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081537 session_->OnProofVerifyDetailsAvailable(details);
1538 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
[email protected]5db452202014-08-19 05:22:151539
Paul Jensen8e3c5d32018-02-19 17:06:331540 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
Matt Menke26e41542019-06-05 01:09:511541 SocketTag(), NetworkIsolationKey()));
jri7e636642016-01-14 06:57:081542}
1543
1544TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) {
Renjie Tangaadb84b2019-08-31 01:00:231545 MockQuicData quic_data(version_);
1546 int packet_num = 1;
1547 socket_data_.reset();
1548 if (VersionUsesQpack(version_.transport_version)) {
1549 quic_data.AddWrite(SYNCHRONOUS,
1550 client_maker_.MakeInitialSettingsPacket(packet_num++));
1551 }
1552 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1553 quic_data.AddRead(ASYNC, OK); // EOF
1554 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:081555 Initialize();
1556 CompleteCryptoHandshake();
1557
1558 char data[] = "ABCD";
Ryan Hamilton8d9ee76e2018-05-29 23:52:521559 std::unique_ptr<quic::QuicEncryptedPacket> client_ping;
1560 std::unique_ptr<quic::QuicEncryptedPacket> ack_and_data_out;
Renjie Tangaadb84b2019-08-31 01:00:231561 if (VersionUsesQpack(version_.transport_version)) {
1562 client_ping =
1563 client_maker_.MakeAckAndPingPacket(packet_num++, false, 1, 1, 1);
1564 } else {
1565 client_ping = client_maker_.MakePingPacket(packet_num++, true);
1566 }
Fan Yang32c5a112018-12-10 20:06:331567 ack_and_data_out = client_maker_.MakeDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:231568 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
Fan Yang32c5a112018-12-10 20:06:331569 quic::QuicStringPiece(data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521570 std::unique_ptr<quic::QuicEncryptedPacket> server_ping(
alyssar2adf3ac2016-05-03 17:12:581571 server_maker_.MakePingPacket(1, /*include_version=*/false));
alyssar2adf3ac2016-05-03 17:12:581572 MockRead reads[] = {
1573 MockRead(SYNCHRONOUS, server_ping->data(), server_ping->length(), 0),
1574 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
1575 MockWrite writes[] = {
1576 MockWrite(SYNCHRONOUS, client_ping->data(), client_ping->length(), 2),
1577 MockWrite(SYNCHRONOUS, ack_and_data_out->data(),
1578 ack_and_data_out->length(), 3)};
Ryan Sleevib8d7ea02018-05-07 20:01:011579 StaticSocketDataProvider socket_data(reads, writes);
jri7e636642016-01-14 06:57:081580 socket_factory_.AddSocketDataProvider(&socket_data);
jri7e636642016-01-14 06:57:081581 // Create connected socket.
danakjad1777e2016-04-16 00:56:421582 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081583 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191584 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011585 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081586
1587 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421588 std::unique_ptr<QuicChromiumPacketReader> new_reader(
1589 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1590 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521591 quic::QuicTime::Delta::FromMilliseconds(
danakjad1777e2016-04-16 00:56:421592 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201593 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221594 new_reader->StartReading();
jried79618b2016-07-02 03:18:521595 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1596 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081597
1598 // Migrate session.
jri9f303712016-09-13 01:10:221599 EXPECT_TRUE(session_->MigrateToSocket(
1600 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1601 // Spin message loop to complete migration.
1602 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081603
1604 // Write data to session.
Ramin Halavatif7788ea2018-02-26 07:02:571605 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501606 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
jri7e636642016-01-14 06:57:081607 struct iovec iov[1];
1608 iov[0].iov_base = data;
1609 iov[0].iov_len = 4;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521610 quic::test::QuicStreamPeer::SendBuffer(stream).SaveStreamData(iov, 1, 0, 4);
1611 quic::test::QuicStreamPeer::SetStreamBytesWritten(4, stream);
1612 session_->WritevData(stream, stream->id(), 4, 0, quic::NO_FIN);
jri7e636642016-01-14 06:57:081613
1614 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1615 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1616}
1617
1618TEST_P(QuicChromiumClientSessionTest, MigrateToSocketMaxReaders) {
Renjie Tangaadb84b2019-08-31 01:00:231619 MockQuicData quic_data(version_);
1620 socket_data_.reset();
1621 int packet_num = 1;
1622 if (VersionUsesQpack(version_.transport_version)) {
1623 quic_data.AddWrite(SYNCHRONOUS,
1624 client_maker_.MakeInitialSettingsPacket(packet_num++));
1625 }
1626 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1627 quic_data.AddRead(ASYNC, OK); // EOF
1628 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:081629 Initialize();
1630 CompleteCryptoHandshake();
1631
1632 for (size_t i = 0; i < kMaxReadersPerQuicSession; ++i) {
1633 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521634 std::unique_ptr<quic::QuicEncryptedPacket> ping_out(
Renjie Tangaadb84b2019-08-31 01:00:231635 client_maker_.MakePingPacket(i + packet_num, /*include_version=*/true));
jri7e636642016-01-14 06:57:081636 MockWrite writes[] = {
1637 MockWrite(SYNCHRONOUS, ping_out->data(), ping_out->length(), i + 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011638 StaticSocketDataProvider socket_data(reads, writes);
jri7e636642016-01-14 06:57:081639 socket_factory_.AddSocketDataProvider(&socket_data);
1640
1641 // Create connected socket.
danakjad1777e2016-04-16 00:56:421642 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081643 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191644 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011645 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081646
1647 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421648 std::unique_ptr<QuicChromiumPacketReader> new_reader(
rcha02807b42016-01-29 21:56:151649 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1650 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521651 quic::QuicTime::Delta::FromMilliseconds(
rcha02807b42016-01-29 21:56:151652 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201653 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221654 new_reader->StartReading();
jried79618b2016-07-02 03:18:521655 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1656 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081657
1658 // Migrate session.
1659 if (i < kMaxReadersPerQuicSession - 1) {
jri9f303712016-09-13 01:10:221660 EXPECT_TRUE(session_->MigrateToSocket(
1661 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1662 // Spin message loop to complete migration.
1663 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081664 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1665 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1666 } else {
1667 // Max readers exceeded.
jri9f303712016-09-13 01:10:221668 EXPECT_FALSE(session_->MigrateToSocket(
1669 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
Zhongyi Shid3d5f502018-08-10 00:22:221670 EXPECT_TRUE(socket_data.AllReadDataConsumed());
jri7e636642016-01-14 06:57:081671 EXPECT_FALSE(socket_data.AllWriteDataConsumed());
1672 }
1673 }
1674}
1675
Renjie Tang786df912019-09-03 23:17:131676TEST_P(QuicChromiumClientSessionTest, MigrateToSocketReadError) {
Renjie Tangaadb84b2019-08-31 01:00:231677 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet;
1678 std::unique_ptr<quic::QuicEncryptedPacket> client_ping =
1679 client_maker_.MakeAckAndPingPacket(2, false, 1, 1, 1);
1680 std::unique_ptr<quic::QuicEncryptedPacket> initial_ping;
Renjie Tang786df912019-09-03 23:17:131681 std::vector<MockWrite> old_writes;
1682 std::vector<MockRead> old_reads;
Renjie Tangaadb84b2019-08-31 01:00:231683 if (VersionUsesQpack(version_.transport_version)) {
1684 settings_packet = client_maker_.MakeInitialSettingsPacket(1);
Renjie Tang786df912019-09-03 23:17:131685 old_writes.push_back(MockWrite(ASYNC, settings_packet->data(),
1686 settings_packet->length(), 0));
Renjie Tangaadb84b2019-08-31 01:00:231687 } else {
1688 initial_ping = client_maker_.MakePingPacket(1, true);
Renjie Tang786df912019-09-03 23:17:131689 old_writes.push_back(
1690 MockWrite(ASYNC, initial_ping->data(), initial_ping->length(), 0));
Renjie Tangaadb84b2019-08-31 01:00:231691 }
Renjie Tang786df912019-09-03 23:17:131692 old_reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 1));
1693 old_reads.push_back(MockRead(ASYNC, ERR_NETWORK_CHANGED, 2));
1694
1695 socket_data_.reset(new SequencedSocketData(
1696 base::span<const MockRead>(old_reads.data(), old_reads.size()),
1697 base::span<const MockWrite>(old_writes.data(), old_writes.size())));
Renjie Tangaadb84b2019-08-31 01:00:231698
Ryan Hamilton8d9ee76e2018-05-29 23:52:521699 std::unique_ptr<quic::QuicEncryptedPacket> server_ping(
alyssar2adf3ac2016-05-03 17:12:581700 server_maker_.MakePingPacket(1, /*include_version=*/false));
jri7e636642016-01-14 06:57:081701 Initialize();
1702 CompleteCryptoHandshake();
Renjie Tangaadb84b2019-08-31 01:00:231703
1704 if (!VersionUsesQpack(version_.transport_version))
1705 session_->SendPing();
jri7e636642016-01-14 06:57:081706 MockWrite writes[] = {
alyssar2adf3ac2016-05-03 17:12:581707 MockWrite(SYNCHRONOUS, client_ping->data(), client_ping->length(), 1)};
jri7e636642016-01-14 06:57:081708 MockRead new_reads[] = {
alyssar2adf3ac2016-05-03 17:12:581709 MockRead(SYNCHRONOUS, server_ping->data(), server_ping->length(), 0),
jri7e636642016-01-14 06:57:081710 MockRead(ASYNC, ERR_IO_PENDING, 2), // pause reading.
alyssar2adf3ac2016-05-03 17:12:581711 MockRead(ASYNC, server_ping->data(), server_ping->length(), 3),
jri7e636642016-01-14 06:57:081712 MockRead(ASYNC, ERR_IO_PENDING, 4), // pause reading
1713 MockRead(ASYNC, ERR_NETWORK_CHANGED, 5)};
Ryan Sleevib8d7ea02018-05-07 20:01:011714 SequencedSocketData new_socket_data(new_reads, writes);
jri7e636642016-01-14 06:57:081715 socket_factory_.AddSocketDataProvider(&new_socket_data);
1716
1717 // Create connected socket.
danakjad1777e2016-04-16 00:56:421718 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081719 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191720 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011721 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081722
1723 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421724 std::unique_ptr<QuicChromiumPacketReader> new_reader(
1725 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1726 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521727 quic::QuicTime::Delta::FromMilliseconds(
danakjad1777e2016-04-16 00:56:421728 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201729 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221730 new_reader->StartReading();
jried79618b2016-07-02 03:18:521731 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1732 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081733
1734 // Store old socket and migrate session.
jri9f303712016-09-13 01:10:221735 EXPECT_TRUE(session_->MigrateToSocket(
1736 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1737 // Spin message loop to complete migration.
1738 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081739
1740 // Read error on old socket does not impact session.
1741 EXPECT_TRUE(socket_data_->IsPaused());
1742 socket_data_->Resume();
1743 EXPECT_TRUE(session_->connection()->connected());
1744 EXPECT_TRUE(new_socket_data.IsPaused());
1745 new_socket_data.Resume();
1746
1747 // Read error on new socket causes session close.
1748 EXPECT_TRUE(new_socket_data.IsPaused());
1749 EXPECT_TRUE(session_->connection()->connected());
1750 new_socket_data.Resume();
1751 EXPECT_FALSE(session_->connection()->connected());
1752
1753 EXPECT_TRUE(socket_data_->AllReadDataConsumed());
1754 EXPECT_TRUE(socket_data_->AllWriteDataConsumed());
1755 EXPECT_TRUE(new_socket_data.AllReadDataConsumed());
1756 EXPECT_TRUE(new_socket_data.AllWriteDataConsumed());
1757}
1758
Zhongyi Shi5068bb02018-08-03 02:44:091759TEST_P(QuicChromiumClientSessionTest, DetectPathDegradingDuringHandshake) {
Ryan Hamilton8380c652019-06-04 02:25:061760 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
1761 // TODO(nharper, b/112643533): Figure out why this test fails when TLS is
1762 // enabled and fix it.
1763 return;
1764 }
Zhongyi Shi5068bb02018-08-03 02:44:091765 migrate_session_early_v2_ = true;
1766
Ryan Hamiltonabad59e2019-06-06 04:02:591767 MockQuicData quic_data(version_);
Zhongyi Shi5068bb02018-08-03 02:44:091768 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
1769 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
1770 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(2));
1771 quic_data.AddSocketDataToFactory(&socket_factory_);
1772
1773 // Set the crypto handshake mode to cold start and send CHLO packets.
1774 crypto_client_stream_factory_.set_handshake_mode(
1775 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
1776 Initialize();
1777
1778 session_->CryptoConnect(callback_.callback());
1779
1780 // Check retransmission alarm is set after sending the initial CHLO packet.
1781 quic::QuicAlarm* retransmission_alarm =
1782 quic::test::QuicConnectionPeer::GetRetransmissionAlarm(
1783 session_->connection());
1784 EXPECT_TRUE(retransmission_alarm->IsSet());
1785 quic::QuicTime retransmission_time = retransmission_alarm->deadline();
1786
1787 // Check path degrading alarm is set after sending the initial CHLO packet.
1788 quic::QuicAlarm* path_degrading_alarm =
1789 quic::test::QuicConnectionPeer::GetPathDegradingAlarm(
1790 session_->connection());
1791 EXPECT_TRUE(path_degrading_alarm->IsSet());
1792 quic::QuicTime path_degrading_time = path_degrading_alarm->deadline();
1793 EXPECT_LE(retransmission_time, path_degrading_time);
1794
1795 // Do not create outgoing stream since encryption is not established.
1796 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
1797 session_->CreateHandle(destination_);
1798 TestCompletionCallback callback;
1799 EXPECT_TRUE(handle->IsConnected());
1800 EXPECT_FALSE(handle->IsCryptoHandshakeConfirmed());
1801 EXPECT_EQ(
1802 ERR_IO_PENDING,
1803 handle->RequestStream(/*require_handshake_confirmation=*/true,
1804 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
1805
1806 // Fire the retransmission alarm to retransmit the crypto packet.
1807 quic::QuicTime::Delta delay = retransmission_time - clock_.ApproximateNow();
1808 clock_.AdvanceTime(delay);
1809 alarm_factory_.FireAlarm(retransmission_alarm);
1810
1811 // Fire the path degrading alarm to notify session that path is degrading
1812 // during crypto handshake.
1813 delay = path_degrading_time - clock_.ApproximateNow();
1814 clock_.AdvanceTime(delay);
1815 EXPECT_CALL(*session_.get(), OnPathDegrading());
1816 alarm_factory_.FireAlarm(path_degrading_alarm);
1817
1818 EXPECT_TRUE(session_->connection()->IsPathDegrading());
1819 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1820 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
1821}
1822
Yixin Wangf65c4b6d2018-03-08 22:37:401823TEST_P(QuicChromiumClientSessionTest, RetransmittableOnWireTimeout) {
1824 migrate_session_early_v2_ = true;
1825
Ryan Hamiltonabad59e2019-06-06 04:02:591826 MockQuicData quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231827 int packet_num = 1;
1828 if (VersionUsesQpack(version_.transport_version)) {
1829 quic_data.AddWrite(SYNCHRONOUS,
1830 client_maker_.MakeInitialSettingsPacket(packet_num++));
1831 }
1832 quic_data.AddWrite(SYNCHRONOUS,
1833 client_maker_.MakePingPacket(packet_num++, true));
Yixin Wangf65c4b6d2018-03-08 22:37:401834
Renjie Tangaadb84b2019-08-31 01:00:231835 quic_data.AddRead(
1836 ASYNC, server_maker_.MakeAckPacket(1, packet_num - 1, 1, 1, false));
1837
1838 quic_data.AddWrite(SYNCHRONOUS,
1839 client_maker_.MakePingPacket(packet_num++, false));
Yixin Wangf65c4b6d2018-03-08 22:37:401840 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1841 quic_data.AddRead(ASYNC, OK); // EOF
1842 quic_data.AddSocketDataToFactory(&socket_factory_);
1843
1844 Initialize();
1845 CompleteCryptoHandshake();
1846
Ryan Hamilton8d9ee76e2018-05-29 23:52:521847 EXPECT_EQ(quic::QuicTime::Delta::FromMilliseconds(100),
Yixin Wangf65c4b6d2018-03-08 22:37:401848 session_->connection()->retransmittable_on_wire_timeout());
1849
1850 // Open a stream since the connection only sends PINGs to keep a
1851 // retransmittable packet on the wire if there's an open stream.
Fan Yang5a3bddf2018-10-12 10:05:501852 EXPECT_TRUE(
1853 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
Yixin Wangf65c4b6d2018-03-08 22:37:401854
Ryan Hamilton8d9ee76e2018-05-29 23:52:521855 quic::QuicAlarm* alarm =
Zhongyi Shi4bd7bf42018-11-06 21:05:101856 quic::test::QuicConnectionPeer::GetPingAlarm(session_->connection());
Yixin Wangf65c4b6d2018-03-08 22:37:401857 EXPECT_FALSE(alarm->IsSet());
1858
1859 // Send PING, which will be ACKed by the server. After the ACK, there will be
1860 // no retransmittable packets on the wire, so the alarm should be set.
1861 session_->SendPing();
1862 base::RunLoop().RunUntilIdle();
1863 EXPECT_TRUE(alarm->IsSet());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521864 EXPECT_EQ(
1865 clock_.ApproximateNow() + quic::QuicTime::Delta::FromMilliseconds(100),
1866 alarm->deadline());
Yixin Wangf65c4b6d2018-03-08 22:37:401867
1868 // Advance clock and simulate the alarm firing. This should cause a PING to be
1869 // sent.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521870 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(100));
Yixin Wangf65c4b6d2018-03-08 22:37:401871 alarm_factory_.FireAlarm(alarm);
1872 base::RunLoop().RunUntilIdle();
1873
1874 quic_data.Resume();
1875 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1876 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
1877}
1878
[email protected]dd3fd0e2012-11-04 05:14:401879} // namespace
1880} // namespace test
1881} // namespace net