blob: 744f46200dda9fb745d174339280179a4703bb07 [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"
Bence Béky98447b12018-05-08 03:14:0145#include "net/test/test_with_scoped_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"
54#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
55#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
56#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
57#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
58#include "net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.h"
59#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
60#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
61#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
62#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
63#include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h"
Victor Vasiliev27cc7712019-01-24 11:50:1464#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
Ramin Halavati683bcaa92018-02-14 08:42:3965#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0166#include "testing/gmock/include/gmock/gmock.h"
[email protected]dd3fd0e2012-11-04 05:14:4067
68using testing::_;
69
70namespace net {
71namespace test {
72namespace {
73
eroman36d84e54432016-03-17 03:23:0274const IPEndPoint kIpEndPoint = IPEndPoint(IPAddress::IPv4AllZeros(), 0);
rch1fe2eeb2015-10-26 14:45:5775const char kServerHostname[] = "test.example.com";
Avi Drissman13fc8932015-12-20 04:40:4676const uint16_t kServerPort = 443;
jri7e636642016-01-14 06:57:0877const size_t kMaxReadersPerQuicSession = 5;
78
David Benjamin3cc59772019-04-02 07:33:3179// A subclass of QuicChromiumClientSession that allows OnPathDegrading to be
80// mocked.
Nick Harpere45fe4fc2017-07-13 00:34:5881class TestingQuicChromiumClientSession : public QuicChromiumClientSession {
82 public:
83 using QuicChromiumClientSession::QuicChromiumClientSession;
84
Zhongyi Shi5068bb02018-08-03 02:44:0985 MOCK_METHOD0(OnPathDegrading, void());
Nick Harpere45fe4fc2017-07-13 00:34:5886};
87
ckrasic4f9d88d2015-07-22 22:23:1688class QuicChromiumClientSessionTest
Ryan Hamilton8d9ee76e2018-05-29 23:52:5289 : public ::testing::TestWithParam<
Nick Harper23290b82019-05-02 00:02:5690 std::tuple<quic::ParsedQuicVersion, bool>>,
Bence Béky98447b12018-05-08 03:14:0191 public WithScopedTaskEnvironment {
Ryan Hamilton9883ff62017-08-01 06:07:0592 public:
ckrasic4f9d88d2015-07-22 22:23:1693 QuicChromiumClientSessionTest()
Yixin Wang079ad542018-01-11 04:06:0594 : version_(std::get<0>(GetParam())),
95 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Nick Harpera598fc5f2019-06-21 08:46:5096 crypto_config_(
97 quic::test::crypto_test_utils::ProofVerifierForTesting()),
jri7e636642016-01-14 06:57:0898 default_read_(new MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)),
99 socket_data_(
Ryan Sleevib8d7ea02018-05-07 20:01:01100 new SequencedSocketData(base::make_span(default_read_.get(), 1),
101 base::span<MockWrite>())),
jri7e636642016-01-14 06:57:08102 random_(0),
rch16c74d1d2016-04-22 06:14:07103 helper_(&clock_, &random_),
Paul Jensen8e3c5d32018-02-19 17:06:33104 session_key_(kServerHostname,
105 kServerPort,
106 PRIVACY_MODE_DISABLED,
107 SocketTag()),
Ryan Hamilton6c2a2a82017-12-15 02:06:28108 destination_(kServerHostname, kServerPort),
Yixin Wang079ad542018-01-11 04:06:05109 client_maker_(version_,
David Schinazic8281052019-01-24 06:14:17110 quic::QuicUtils::CreateRandomConnectionId(&random_),
alyssar2adf3ac2016-05-03 17:12:58111 &clock_,
112 kServerHostname,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52113 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05114 client_headers_include_h2_stream_dependency_),
115 server_maker_(version_,
David Schinazic8281052019-01-24 06:14:17116 quic::QuicUtils::CreateRandomConnectionId(&random_),
alyssar2adf3ac2016-05-03 17:12:58117 &clock_,
118 kServerHostname,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52119 quic::Perspective::IS_SERVER,
Yixin Wangf65c4b6d2018-03-08 22:37:40120 false),
121 migrate_session_early_v2_(false) {
Ryan Hamilton8380c652019-06-04 02:25:06122 SetQuicFlag(FLAGS_quic_supports_tls_handshake, true);
xunjielic70cc862016-02-19 15:29:26123 // Advance the time, because timers do not like uninitialized times.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52124 clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
xunjielic70cc862016-02-19 15:29:26125 }
jri7e636642016-01-14 06:57:08126
Ryan Hamilton9883ff62017-08-01 06:07:05127 void ResetHandleOnError(
128 std::unique_ptr<QuicChromiumClientSession::Handle>* handle,
129 int net_error) {
130 EXPECT_NE(OK, net_error);
131 handle->reset();
132 }
133
134 protected:
jri7e636642016-01-14 06:57:08135 void Initialize() {
rch1baa7472017-04-26 05:43:58136 if (socket_data_)
137 socket_factory_.AddSocketDataProvider(socket_data_.get());
danakjad1777e2016-04-16 00:56:42138 std::unique_ptr<DatagramClientSocket> socket =
jri7e636642016-01-14 06:57:08139 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:19140 &net_log_, NetLogSource());
jri7e636642016-01-14 06:57:08141 socket->Connect(kIpEndPoint);
Ryan Hamilton9edcf1a2017-11-22 05:55:17142 QuicChromiumPacketWriter* writer = new net::QuicChromiumPacketWriter(
143 socket.get(), base::ThreadTaskRunnerHandle::Get().get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52144 quic::QuicConnection* connection = new quic::QuicConnection(
David Schinazic8281052019-01-24 06:14:17145 quic::QuicUtils::CreateRandomConnectionId(&random_),
Victor Vasiliev4f6fb892019-05-31 16:58:31146 ToQuicSocketAddress(kIpEndPoint), &helper_, &alarm_factory_, writer,
147 true, quic::Perspective::IS_CLIENT,
Nick Harper23290b82019-05-02 00:02:56148 quic::test::SupportedVersions(version_));
Nick Harpere45fe4fc2017-07-13 00:34:58149 session_.reset(new TestingQuicChromiumClientSession(
jri7e636642016-01-14 06:57:08150 connection, std::move(socket),
151 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57152 &transport_security_state_, /*ssl_config_service=*/nullptr,
Paul Jensen8e3c5d32018-02-19 17:06:33153 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)), session_key_,
Zhongyi Shi757fcce2018-06-27 05:41:27154 /*require_confirmation=*/false, 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(
158 kDefaultRetransmittableOnWireTimeoutMillisecs),
Zhongyi Shi32fe14d42019-02-28 00:25:36159 /*migrate_idle_session=*/false,
Zhongyi Shic16b4102019-02-12 00:37:40160 base::TimeDelta::FromSeconds(kDefaultIdleSessionMigrationPeriodSeconds),
Zhongyi Shi73f23ca872017-12-13 18:37:13161 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29162 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30163 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17164 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52165 quic::QuicTime::Delta::FromMilliseconds(
166 kQuicYieldAfterDurationMilliseconds),
Zhongyi Shidbce7f412019-02-01 23:16:29167 /*cert_verify_flags=*/0, /*go_away_on_path_degrading*/ false,
168 client_headers_include_h2_stream_dependency_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52169 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
Yixin Wang079ad542018-01-11 04:06:05170 base::TimeTicks::Now(), base::TimeTicks::Now(), &push_promise_index_,
Zhongyi Shic16b4102019-02-12 00:37:40171 &test_push_delegate_, base::DefaultTickClock::GetInstance(),
172 base::ThreadTaskRunnerHandle::Get().get(),
jri7e636642016-01-14 06:57:08173 /*socket_performance_watcher=*/nullptr, &net_log_));
174
175 scoped_refptr<X509Certificate> cert(
176 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
177 verify_details_.cert_verify_result.verified_cert = cert;
178 verify_details_.cert_verify_result.is_issued_by_known_root = true;
jri7e636642016-01-14 06:57:08179 session_->Initialize();
180 session_->StartReading();
jribce3eec2016-09-09 05:41:08181 writer->set_delegate(session_.get());
[email protected]dd3fd0e2012-11-04 05:14:40182 }
183
rtenneti85dcfac22015-03-27 20:22:19184 void TearDown() override {
rchf0b18c8a2017-05-05 19:31:57185 if (session_)
Renjieba55fae2018-09-20 03:05:16186 session_->CloseSessionOnError(
187 ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
188 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]4d283b32013-10-17 12:57:27189 }
190
[email protected]ed3fc15d2013-03-08 18:37:44191 void CompleteCryptoHandshake() {
rch433bf5f2017-02-14 04:10:47192 ASSERT_THAT(session_->CryptoConnect(callback_.callback()), IsOk());
[email protected]ed3fc15d2013-03-08 18:37:44193 }
194
jried79618b2016-07-02 03:18:52195 QuicChromiumPacketWriter* CreateQuicChromiumPacketWriter(
196 DatagramClientSocket* socket,
197 QuicChromiumClientSession* session) const {
danakjad1777e2016-04-16 00:56:42198 std::unique_ptr<QuicChromiumPacketWriter> writer(
Ryan Hamilton9edcf1a2017-11-22 05:55:17199 new QuicChromiumPacketWriter(
200 socket, base::ThreadTaskRunnerHandle::Get().get()));
jribce3eec2016-09-09 05:41:08201 writer->set_delegate(session);
jri7e636642016-01-14 06:57:08202 return writer.release();
203 }
204
Fan Yang32c5a112018-12-10 20:06:33205 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56206 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
207 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36208 }
209
Fan Yang32c5a112018-12-10 20:06:33210 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56211 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
212 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36213 }
214
Fan Yang32c5a112018-12-10 20:06:33215 size_t GetMaxAllowedOutgoingBidirectionalStreams() {
Frank Kastenholzc9b9bea2018-12-03 20:13:47216 quic::QuicSession* quic_session =
217 dynamic_cast<quic::QuicSession*>(&*session_);
Nick Harper23290b82019-05-02 00:02:56218 if (version_.transport_version != quic::QUIC_VERSION_99) {
Frank Kastenholzc9b9bea2018-12-03 20:13:47219 return quic::test::QuicSessionPeer::GetStreamIdManager(quic_session)
220 ->max_open_outgoing_streams();
221 }
David Schinazicc1bc592019-04-24 19:40:31222 // For version99, the count will include both static and dynamic streams.
223 // These tests are only concerned with dynamic streams (that is, the number
Ryan Hamilton4aeec562019-05-17 21:22:52224 // of streams that they can create), so back out the static header stream.
Frank Kastenholzc9b9bea2018-12-03 20:13:47225 return quic::test::QuicSessionPeer::v99_streamid_manager(quic_session)
David Schinazicc1bc592019-04-24 19:40:31226 ->max_allowed_outgoing_bidirectional_streams() -
Ryan Hamilton4aeec562019-05-17 21:22:52227 1;
Frank Kastenholzc9b9bea2018-12-03 20:13:47228 }
229
Nick Harper23290b82019-05-02 00:02:56230 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05231 const bool client_headers_include_h2_stream_dependency_;
Jana Iyengarf6b13d82017-09-04 02:09:10232 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52233 quic::QuicCryptoClientConfig crypto_config_;
vishal.b62985ca92015-04-17 08:45:51234 TestNetLog net_log_;
tfarina42834112016-09-22 13:38:20235 BoundTestNetLog bound_test_net_log_;
[email protected]4d283b32013-10-17 12:57:27236 MockClientSocketFactory socket_factory_;
danakjad1777e2016-04-16 00:56:42237 std::unique_ptr<MockRead> default_read_;
238 std::unique_ptr<SequencedSocketData> socket_data_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52239 quic::MockClock clock_;
240 quic::test::MockRandom random_;
rch12fef552016-01-15 16:26:31241 QuicChromiumConnectionHelper helper_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52242 quic::test::MockAlarmFactory alarm_factory_;
jri7e636642016-01-14 06:57:08243 TransportSecurityState transport_security_state_;
244 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52245 quic::QuicClientPushPromiseIndex push_promise_index_;
Paul Jensen8e3c5d32018-02-19 17:06:33246 QuicSessionKey session_key_;
Ryan Hamilton6c2a2a82017-12-15 02:06:28247 HostPortPair destination_;
Nick Harpere45fe4fc2017-07-13 00:34:58248 std::unique_ptr<TestingQuicChromiumClientSession> session_;
zhongyi0009f3e2016-11-11 19:47:50249 TestServerPushDelegate test_push_delegate_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52250 quic::QuicConnectionVisitorInterface* visitor_;
[email protected]8ee611b2012-11-20 01:48:12251 TestCompletionCallback callback_;
alyssar2adf3ac2016-05-03 17:12:58252 QuicTestPacketMaker client_maker_;
253 QuicTestPacketMaker server_maker_;
jri7e636642016-01-14 06:57:08254 ProofVerifyDetailsChromium verify_details_;
Yixin Wangf65c4b6d2018-03-08 22:37:40255 bool migrate_session_early_v2_;
[email protected]dd3fd0e2012-11-04 05:14:40256};
257
Victor Costane635086f2019-01-27 05:20:30258INSTANTIATE_TEST_SUITE_P(
Bence Békyce380cb2018-04-26 23:39:55259 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05260 QuicChromiumClientSessionTest,
Nick Harper23290b82019-05-02 00:02:56261 ::testing::Combine(::testing::ValuesIn(quic::AllSupportedVersions()),
262 ::testing::Bool()));
[email protected]4d640792013-12-18 22:21:08263
Carlos IL81133382017-12-06 17:18:45264TEST_P(QuicChromiumClientSessionTest, IsFatalErrorNotSetForNonFatalError) {
265 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52266 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:02267 client_maker_.MakeInitialSettingsPacket(1));
Carlos IL81133382017-12-06 17:18:45268 MockWrite writes[] = {
269 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01270 socket_data_.reset(new SequencedSocketData(reads, writes));
Carlos IL81133382017-12-06 17:18:45271 Initialize();
272
273 SSLInfo ssl_info;
274 ProofVerifyDetailsChromium details;
275 details.cert_verify_result.verified_cert =
276 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
277 details.cert_verify_result.cert_status =
278 MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
279 details.is_fatal_cert_error = false;
280 CompleteCryptoHandshake();
281 session_->OnProofVerifyDetailsAvailable(details);
282
283 ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
284 EXPECT_FALSE(ssl_info.is_fatal_cert_error);
285}
286
287TEST_P(QuicChromiumClientSessionTest, IsFatalErrorSetForFatalError) {
288 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52289 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:02290 client_maker_.MakeInitialSettingsPacket(1));
Carlos IL81133382017-12-06 17:18:45291 MockWrite writes[] = {
292 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01293 socket_data_.reset(new SequencedSocketData(reads, writes));
Carlos IL81133382017-12-06 17:18:45294 Initialize();
295
296 SSLInfo ssl_info;
297 ProofVerifyDetailsChromium details;
298 details.cert_verify_result.verified_cert =
299 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
300 details.cert_verify_result.cert_status =
301 MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
302 details.is_fatal_cert_error = true;
303 CompleteCryptoHandshake();
304 session_->OnProofVerifyDetailsAvailable(details);
305 ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
306 EXPECT_TRUE(ssl_info.is_fatal_cert_error);
307}
308
ckrasic4f9d88d2015-07-22 22:23:16309TEST_P(QuicChromiumClientSessionTest, CryptoConnect) {
fayang3bcb8b502016-12-07 21:44:37310 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52311 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:02312 client_maker_.MakeInitialSettingsPacket(1));
fayang3bcb8b502016-12-07 21:44:37313 MockWrite writes[] = {
314 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01315 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:08316 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44317 CompleteCryptoHandshake();
[email protected]8ee611b2012-11-20 01:48:12318}
319
rchf0b18c8a2017-05-05 19:31:57320TEST_P(QuicChromiumClientSessionTest, Handle) {
Ryan Hamiltonabad59e2019-06-06 04:02:59321 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02322 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
rchf0b18c8a2017-05-05 19:31:57323 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
324 quic_data.AddRead(ASYNC, OK); // EOF
325 quic_data.AddSocketDataToFactory(&socket_factory_);
326
327 Initialize();
328
329 NetLogWithSource session_net_log = session_->net_log();
330 EXPECT_EQ(NetLogSourceType::QUIC_SESSION, session_net_log.source().type);
331 EXPECT_EQ(&net_log_, session_net_log.net_log());
332
333 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28334 session_->CreateHandle(destination_);
rchf0b18c8a2017-05-05 19:31:57335 EXPECT_TRUE(handle->IsConnected());
336 EXPECT_FALSE(handle->IsCryptoHandshakeConfirmed());
Nick Harper23290b82019-05-02 00:02:56337 EXPECT_EQ(version_.transport_version, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33338 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57339 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
340 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
341 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
342 IPEndPoint address;
343 EXPECT_EQ(OK, handle->GetPeerAddress(&address));
344 EXPECT_EQ(kIpEndPoint, address);
Bin Wuae74d8b2019-06-19 23:55:07345 EXPECT_TRUE(handle->CreatePacketBundler().get() != nullptr);
rchf0b18c8a2017-05-05 19:31:57346
347 CompleteCryptoHandshake();
348
349 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
350
351 // Request a stream and verify that a stream was created.
352 TestCompletionCallback callback;
353 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39354 callback.callback(),
355 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29356 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchf0b18c8a2017-05-05 19:31:57357
358 quic_data.Resume();
359 EXPECT_TRUE(quic_data.AllReadDataConsumed());
360 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
361
362 // Veirfy that the handle works correctly after the session is closed.
363 EXPECT_FALSE(handle->IsConnected());
364 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
Nick Harper23290b82019-05-02 00:02:56365 EXPECT_EQ(version_.transport_version, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33366 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57367 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
368 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
369 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
370 EXPECT_EQ(ERR_CONNECTION_CLOSED, handle->GetPeerAddress(&address));
Bin Wuae74d8b2019-06-19 23:55:07371 EXPECT_TRUE(handle->CreatePacketBundler().get() == nullptr);
rchf0b18c8a2017-05-05 19:31:57372 {
373 // Verify that CreateHandle() works even after the session is closed.
374 std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
Ryan Hamilton6c2a2a82017-12-15 02:06:28375 session_->CreateHandle(destination_);
rchf0b18c8a2017-05-05 19:31:57376 EXPECT_FALSE(handle2->IsConnected());
377 EXPECT_TRUE(handle2->IsCryptoHandshakeConfirmed());
378 ASSERT_EQ(ERR_CONNECTION_CLOSED,
379 handle2->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39380 callback.callback(),
381 TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57382 }
383
384 session_.reset();
385
386 // Veirfy that the handle works correctly after the session is deleted.
387 EXPECT_FALSE(handle->IsConnected());
388 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
Nick Harper23290b82019-05-02 00:02:56389 EXPECT_EQ(version_.transport_version, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33390 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57391 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
392 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
393 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
394 EXPECT_EQ(ERR_CONNECTION_CLOSED, handle->GetPeerAddress(&address));
Bin Wuae74d8b2019-06-19 23:55:07395 EXPECT_TRUE(handle->CreatePacketBundler().get() == nullptr);
Ramin Halavati683bcaa92018-02-14 08:42:39396 ASSERT_EQ(
397 ERR_CONNECTION_CLOSED,
398 handle->RequestStream(/*requires_confirmation=*/false,
399 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57400}
401
rch1baa7472017-04-26 05:43:58402TEST_P(QuicChromiumClientSessionTest, StreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59403 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02404 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
rch1baa7472017-04-26 05:43:58405 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
406 quic_data.AddRead(ASYNC, OK); // EOF
407 quic_data.AddSocketDataToFactory(&socket_factory_);
408
409 Initialize();
410 CompleteCryptoHandshake();
411
412 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57413 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28414 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58415 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57416 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39417 callback.callback(),
418 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29419 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rch1baa7472017-04-26 05:43:58420
421 quic_data.Resume();
422 EXPECT_TRUE(quic_data.AllReadDataConsumed());
423 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
424}
425
rchd606b6c32017-05-02 17:32:57426TEST_P(QuicChromiumClientSessionTest, ConfirmationRequiredStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59427 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02428 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
rchd606b6c32017-05-02 17:32:57429 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
430 quic_data.AddRead(ASYNC, OK); // EOF
431 quic_data.AddSocketDataToFactory(&socket_factory_);
432
433 Initialize();
434 CompleteCryptoHandshake();
435
436 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57437 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28438 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57439 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57440 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/true,
Ramin Halavati683bcaa92018-02-14 08:42:39441 callback.callback(),
442 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29443 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchd606b6c32017-05-02 17:32:57444
445 quic_data.Resume();
446 EXPECT_TRUE(quic_data.AllReadDataConsumed());
447 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
448}
449
450TEST_P(QuicChromiumClientSessionTest, StreamRequestBeforeConfirmation) {
Ryan Hamiltonabad59e2019-06-06 04:02:59451 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02452 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
rchd606b6c32017-05-02 17:32:57453 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
454 quic_data.AddRead(ASYNC, OK); // EOF
455 quic_data.AddSocketDataToFactory(&socket_factory_);
456
457 Initialize();
458
459 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57460 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28461 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57462 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39463 ASSERT_EQ(
464 ERR_IO_PENDING,
465 handle->RequestStream(/*requires_confirmation=*/true, callback.callback(),
466 TRAFFIC_ANNOTATION_FOR_TESTS));
rchd606b6c32017-05-02 17:32:57467
468 CompleteCryptoHandshake();
469
470 EXPECT_THAT(callback.WaitForResult(), IsOk());
471
rch1bcfddf22017-06-03 00:26:29472 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchd606b6c32017-05-02 17:32:57473
474 quic_data.Resume();
475 EXPECT_TRUE(quic_data.AllReadDataConsumed());
476 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
477}
478
rch1baa7472017-04-26 05:43:58479TEST_P(QuicChromiumClientSessionTest, CancelStreamRequestBeforeRelease) {
Ryan Hamiltonabad59e2019-06-06 04:02:59480 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02481 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Fan Yang32c5a112018-12-10 20:06:33482 quic_data.AddWrite(SYNCHRONOUS,
483 client_maker_.MakeRstPacket(
484 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
485 quic::QUIC_STREAM_CANCELLED));
rch1baa7472017-04-26 05:43:58486 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
487 quic_data.AddRead(ASYNC, OK); // EOF
488 quic_data.AddSocketDataToFactory(&socket_factory_);
489
490 Initialize();
491 CompleteCryptoHandshake();
492
493 // Request a stream and cancel it without releasing the stream.
rchf0b18c8a2017-05-05 19:31:57494 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28495 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58496 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57497 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39498 callback.callback(),
499 TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57500 handle.reset();
rch1baa7472017-04-26 05:43:58501
502 quic_data.Resume();
503 EXPECT_TRUE(quic_data.AllReadDataConsumed());
504 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
505}
506
507TEST_P(QuicChromiumClientSessionTest, AsyncStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59508 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02509 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Nick Harper23290b82019-05-02 00:02:56510 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz878763bf2018-11-28 19:14:48511 // The open stream limit is set to 50 by
512 // MockCryptoClientStream::SetConfigNegotiated() so when the 51st stream is
David Schinazicc1bc592019-04-24 19:40:31513 // requested, a STREAMS_BLOCKED will be sent, indicating that it's blocked
Ryan Hamilton4aeec562019-05-17 21:22:52514 // at the limit of 50. The +1 accounts for the header stream.
David Schinazicc1bc592019-04-24 19:40:31515 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52516 2, true, 50 + 1,
David Schinazicc1bc592019-04-24 19:40:31517 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:33518 quic_data.AddWrite(
519 SYNCHRONOUS, client_maker_.MakeRstPacket(
520 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:18521 quic::QUIC_STREAM_CANCELLED, 0,
522 /*include_stop_sending_if_v99=*/false));
David Schinazicc1bc592019-04-24 19:40:31523 // After the STREAMS_BLOCKED is sent, receive a MAX_STREAMS to increase
524 // the limit to 53.
Fan Yang32c5a112018-12-10 20:06:33525 quic_data.AddRead(
David Schinazicc1bc592019-04-24 19:40:31526 ASYNC, server_maker_.MakeMaxStreamsPacket(1, true, 53,
527 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47528 } else {
529 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33530 SYNCHRONOUS, client_maker_.MakeRstPacket(
531 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
532 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:48533 }
rch1baa7472017-04-26 05:43:58534 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
535 quic_data.AddRead(ASYNC, OK); // EOF
536 quic_data.AddSocketDataToFactory(&socket_factory_);
rch1baa7472017-04-26 05:43:58537 Initialize();
538 CompleteCryptoHandshake();
539
540 // Open the maximum number of streams so that a subsequent request
541 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33542 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch1baa7472017-04-26 05:43:58543 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50544 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch1baa7472017-04-26 05:43:58545 }
546 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
547
548 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57549 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28550 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58551 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39552 ASSERT_EQ(
553 ERR_IO_PENDING,
554 handle->RequestStream(/*requires_confirmation=*/false,
555 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch1baa7472017-04-26 05:43:58556
557 // Close a stream and ensure the stream request completes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52558 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
Fan Yang32c5a112018-12-10 20:06:33559 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52560 quic::QUIC_STREAM_CANCELLED, 0);
rch1baa7472017-04-26 05:43:58561 session_->OnRstStream(rst);
Nick Harper23290b82019-05-02 00:02:56562 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz684ea412019-02-13 18:48:18563 // For version99, to close the stream completely, we also must receive a
564 // STOP_SENDING frame:
565 quic::QuicStopSendingFrame stop_sending(
566 quic::kInvalidControlFrameId,
567 GetNthClientInitiatedBidirectionalStreamId(0),
568 quic::QUIC_STREAM_CANCELLED);
569 session_->OnStopSendingFrame(stop_sending);
570 }
Frank Kastenholz878763bf2018-11-28 19:14:48571 // Pump the message loop to read the max stream id packet.
572 base::RunLoop().RunUntilIdle();
573
rch1baa7472017-04-26 05:43:58574 ASSERT_TRUE(callback.have_result());
575 EXPECT_THAT(callback.WaitForResult(), IsOk());
rch1bcfddf22017-06-03 00:26:29576 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rch1baa7472017-04-26 05:43:58577
578 quic_data.Resume();
579 EXPECT_TRUE(quic_data.AllReadDataConsumed());
580 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
581}
582
Ryan Hamilton9883ff62017-08-01 06:07:05583TEST_P(QuicChromiumClientSessionTest, ClosedWithAsyncStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59584 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02585 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Nick Harper23290b82019-05-02 00:02:56586 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholzc9b9bea2018-12-03 20:13:47587 // The open stream limit is set to 50 by
588 // MockCryptoClientStream::SetConfigNegotiated() so when the 51st stream is
David Schinazicc1bc592019-04-24 19:40:31589 // requested, a STREAMS_BLOCKED will be sent, indicating that it's blocked
Ryan Hamilton4aeec562019-05-17 21:22:52590 // at the limit of 50. The +1 accounts for the header streams.
David Schinazicc1bc592019-04-24 19:40:31591 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52592 2, true, 50 + 1,
David Schinazicc1bc592019-04-24 19:40:31593 /*unidirectional=*/false));
594 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52595 3, true, 50 + 1,
David Schinazicc1bc592019-04-24 19:40:31596 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47597 }
Ryan Hamilton9883ff62017-08-01 06:07:05598 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
599 quic_data.AddRead(ASYNC, OK); // EOF
600 quic_data.AddSocketDataToFactory(&socket_factory_);
601
602 Initialize();
603 CompleteCryptoHandshake();
604
605 // Open the maximum number of streams so that a subsequent request
606 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33607 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
Ryan Hamilton9883ff62017-08-01 06:07:05608 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50609 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
Ryan Hamilton9883ff62017-08-01 06:07:05610 }
611 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
612
613 // Request two streams which will both be pending.
Frank Kastenholzc9b9bea2018-12-03 20:13:47614 // In V99 each will generate a max stream id for each attempt.
Ryan Hamilton9883ff62017-08-01 06:07:05615 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28616 session_->CreateHandle(destination_);
Ryan Hamilton9883ff62017-08-01 06:07:05617 std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
Ryan Hamilton6c2a2a82017-12-15 02:06:28618 session_->CreateHandle(destination_);
Ryan Hamilton9883ff62017-08-01 06:07:05619
620 ASSERT_EQ(ERR_IO_PENDING,
621 handle->RequestStream(
622 /*requires_confirmation=*/false,
623 base::Bind(&QuicChromiumClientSessionTest::ResetHandleOnError,
Ramin Halavati683bcaa92018-02-14 08:42:39624 base::Unretained(this), &handle2),
625 TRAFFIC_ANNOTATION_FOR_TESTS));
Ryan Hamilton9883ff62017-08-01 06:07:05626
627 TestCompletionCallback callback2;
628 ASSERT_EQ(ERR_IO_PENDING,
629 handle2->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39630 callback2.callback(),
631 TRAFFIC_ANNOTATION_FOR_TESTS));
Ryan Hamilton9883ff62017-08-01 06:07:05632
633 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52634 quic::QUIC_NETWORK_IDLE_TIMEOUT, "Timed out",
635 quic::ConnectionCloseBehavior::SILENT_CLOSE);
Ryan Hamilton9883ff62017-08-01 06:07:05636
637 // Pump the message loop to read the connection close packet.
638 base::RunLoop().RunUntilIdle();
639 EXPECT_FALSE(handle2.get());
640 quic_data.Resume();
641 EXPECT_TRUE(quic_data.AllReadDataConsumed());
642 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
643}
644
rch1baa7472017-04-26 05:43:58645TEST_P(QuicChromiumClientSessionTest, CancelPendingStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59646 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02647 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Nick Harper23290b82019-05-02 00:02:56648 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz878763bf2018-11-28 19:14:48649 // The open stream limit is set to 50 by
650 // MockCryptoClientStream::SetConfigNegotiated() so when the 51st stream is
David Schinazicc1bc592019-04-24 19:40:31651 // requested, a STREAMS_BLOCKED will be sent.
652 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52653 2, true, 51,
David Schinazicc1bc592019-04-24 19:40:31654 /*unidirectional=*/false));
Frank Kastenholz684ea412019-02-13 18:48:18655 // This node receives the RST_STREAM+STOP_SENDING, it responds
656 // with only a RST_STREAM.
Fan Yang32c5a112018-12-10 20:06:33657 quic_data.AddWrite(
658 SYNCHRONOUS, client_maker_.MakeRstPacket(
659 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:18660 quic::QUIC_STREAM_CANCELLED, 0,
661 /*include_stop_sending_if_v99=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47662 } else {
663 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33664 SYNCHRONOUS, client_maker_.MakeRstPacket(
665 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
666 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:48667 }
rch1baa7472017-04-26 05:43:58668 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
669 quic_data.AddRead(ASYNC, OK); // EOF
670 quic_data.AddSocketDataToFactory(&socket_factory_);
671
672 Initialize();
673 CompleteCryptoHandshake();
674
675 // Open the maximum number of streams so that a subsequent request
676 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33677 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch1baa7472017-04-26 05:43:58678 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50679 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch1baa7472017-04-26 05:43:58680 }
681 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
682
683 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57684 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28685 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58686 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39687 ASSERT_EQ(
688 ERR_IO_PENDING,
689 handle->RequestStream(/*requires_confirmation=*/false,
690 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch1baa7472017-04-26 05:43:58691
692 // Cancel the pending stream request.
rchf0b18c8a2017-05-05 19:31:57693 handle.reset();
rch1baa7472017-04-26 05:43:58694
695 // Close a stream and ensure that no new stream is created.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52696 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
Fan Yang32c5a112018-12-10 20:06:33697 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52698 quic::QUIC_STREAM_CANCELLED, 0);
rch1baa7472017-04-26 05:43:58699 session_->OnRstStream(rst);
Nick Harper23290b82019-05-02 00:02:56700 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz684ea412019-02-13 18:48:18701 // For version99, we require a STOP_SENDING as well as a RESET_STREAM to
702 // fully close the stream.
703 quic::QuicStopSendingFrame stop_sending(
704 quic::kInvalidControlFrameId,
705 GetNthClientInitiatedBidirectionalStreamId(0),
706 quic::QUIC_STREAM_CANCELLED);
707 session_->OnStopSendingFrame(stop_sending);
708 }
rch1baa7472017-04-26 05:43:58709 EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
710
711 quic_data.Resume();
712 EXPECT_TRUE(quic_data.AllReadDataConsumed());
713 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
714}
715
rch94c26d682017-04-29 02:49:27716TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59717 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02718 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52719 quic_data.AddRead(
720 ASYNC,
721 server_maker_.MakeConnectionClosePacket(
722 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rch94c26d682017-04-29 02:49:27723 quic_data.AddSocketDataToFactory(&socket_factory_);
724
725 Initialize();
726 CompleteCryptoHandshake();
727
728 // Pump the message loop to read the connection close packet.
729 base::RunLoop().RunUntilIdle();
730
731 // Request a stream and verify that it failed.
rchf0b18c8a2017-05-05 19:31:57732 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28733 session_->CreateHandle(destination_);
rch94c26d682017-04-29 02:49:27734 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39735 ASSERT_EQ(
736 ERR_CONNECTION_CLOSED,
737 handle->RequestStream(/*requires_confirmation=*/false,
738 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch94c26d682017-04-29 02:49:27739
740 EXPECT_TRUE(quic_data.AllReadDataConsumed());
741 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
742}
743
rchd606b6c32017-05-02 17:32:57744TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeHandshakeConfirmed) {
Ryan Hamilton8380c652019-06-04 02:25:06745 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
746 // TODO(nharper, b/112643533): Figure out why this test fails when TLS is
747 // enabled and fix it.
748 return;
749 }
750
David Schinazic8281052019-01-24 06:14:17751 // Force the connection close packet to use long headers with connection ID.
Ryan Hamilton840358c2019-03-19 19:00:35752 server_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
David Schinazic8281052019-01-24 06:14:17753
Ryan Hamiltonabad59e2019-06-06 04:02:59754 MockQuicData quic_data(version_);
rchd606b6c32017-05-02 17:32:57755 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52756 quic_data.AddRead(
757 ASYNC,
758 server_maker_.MakeConnectionClosePacket(
759 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rchd606b6c32017-05-02 17:32:57760 quic_data.AddSocketDataToFactory(&socket_factory_);
761
762 Initialize();
763
764 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57765 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28766 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57767 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39768 ASSERT_EQ(
769 ERR_IO_PENDING,
770 handle->RequestStream(/*requires_confirmation=*/true, callback.callback(),
771 TRAFFIC_ANNOTATION_FOR_TESTS));
rchd606b6c32017-05-02 17:32:57772
773 // Close the connection and verify that the StreamRequest completes with
774 // an error.
775 quic_data.Resume();
776 base::RunLoop().RunUntilIdle();
777
778 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
779
780 EXPECT_TRUE(quic_data.AllReadDataConsumed());
781 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
782}
783
rch94c26d682017-04-29 02:49:27784TEST_P(QuicChromiumClientSessionTest, ConnectionCloseWithPendingStreamRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:59785 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02786 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Nick Harper23290b82019-05-02 00:02:56787 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:31788 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52789 2, true, 51,
David Schinazicc1bc592019-04-24 19:40:31790 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47791 }
rch94c26d682017-04-29 02:49:27792 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52793 quic_data.AddRead(
794 ASYNC,
795 server_maker_.MakeConnectionClosePacket(
796 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rch94c26d682017-04-29 02:49:27797 quic_data.AddSocketDataToFactory(&socket_factory_);
798
799 Initialize();
800 CompleteCryptoHandshake();
801
802 // Open the maximum number of streams so that a subsequent request
803 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33804 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch94c26d682017-04-29 02:49:27805 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50806 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch94c26d682017-04-29 02:49:27807 }
808 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
809
810 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57811 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28812 session_->CreateHandle(destination_);
rch94c26d682017-04-29 02:49:27813 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39814 ASSERT_EQ(
815 ERR_IO_PENDING,
816 handle->RequestStream(/*requires_confirmation=*/false,
817 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch94c26d682017-04-29 02:49:27818
819 // Close the connection and verify that the StreamRequest completes with
820 // an error.
821 quic_data.Resume();
822 base::RunLoop().RunUntilIdle();
823
824 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
825
826 EXPECT_TRUE(quic_data.AllReadDataConsumed());
827 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
828}
829
ckrasic4f9d88d2015-07-22 22:23:16830TEST_P(QuicChromiumClientSessionTest, MaxNumStreams) {
Ryan Hamiltonabad59e2019-06-06 04:02:59831 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:02832 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Nick Harper23290b82019-05-02 00:02:56833 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:31834 // Initial configuration is 50 dynamic streams. Taking into account
Ryan Hamilton4aeec562019-05-17 21:22:52835 // the static stream (headers), expect to block on when hitting the limit
836 // of 51 streams
David Schinazicc1bc592019-04-24 19:40:31837 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52838 2, true, 50 + 1,
David Schinazicc1bc592019-04-24 19:40:31839 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:33840 quic_data.AddWrite(
841 SYNCHRONOUS, client_maker_.MakeRstPacket(
842 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
843 quic::QUIC_RST_ACKNOWLEDGEMENT));
David Schinazicc1bc592019-04-24 19:40:31844 // For the second CreateOutgoingStream that fails because of hitting the
845 // stream count limit.
846 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52847 4, true, 50 + 1,
David Schinazicc1bc592019-04-24 19:40:31848 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:33849 quic_data.AddRead(
Ryan Hamilton4aeec562019-05-17 21:22:52850 ASYNC, server_maker_.MakeMaxStreamsPacket(1, true, 50 + 2,
David Schinazicc1bc592019-04-24 19:40:31851 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47852 } else {
853 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33854 SYNCHRONOUS, client_maker_.MakeRstPacket(
855 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
856 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:48857 }
858 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
859 quic_data.AddRead(ASYNC, OK); // EOF
860 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:08861
862 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44863 CompleteCryptoHandshake();
Fan Yang32c5a112018-12-10 20:06:33864 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
[email protected]dd3fd0e2012-11-04 05:14:40865
rch12fef552016-01-15 16:26:31866 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:08867 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:57868 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50869 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
[email protected]dd3fd0e2012-11-04 05:14:40870 EXPECT_TRUE(stream);
[email protected]f702d572012-12-04 15:56:20871 streams.push_back(stream);
[email protected]dd3fd0e2012-11-04 05:14:40872 }
David Schinazicc1bc592019-04-24 19:40:31873 // This stream, the 51st dynamic stream, can not be opened.
Fan Yang5a3bddf2018-10-12 10:05:50874 EXPECT_FALSE(
875 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
[email protected]dd3fd0e2012-11-04 05:14:40876
jri7e636642016-01-14 06:57:08877 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
rtennetiac06c2f2015-11-05 18:12:35878
[email protected]dd3fd0e2012-11-04 05:14:40879 // Close a stream and ensure I can now open a new one.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52880 quic::QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:08881 session_->CloseStream(stream_id);
rtennetiac06c2f2015-11-05 18:12:35882
Frank Kastenholzc9b9bea2018-12-03 20:13:47883 // Pump data, bringing in the max-stream-id
884 base::RunLoop().RunUntilIdle();
885
Fan Yang5a3bddf2018-10-12 10:05:50886 EXPECT_FALSE(
887 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52888 quic::QuicRstStreamFrame rst1(quic::kInvalidControlFrameId, stream_id,
889 quic::QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:08890 session_->OnRstStream(rst1);
891 EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
Frank Kastenholz878763bf2018-11-28 19:14:48892 base::RunLoop().RunUntilIdle();
Fan Yang5a3bddf2018-10-12 10:05:50893 EXPECT_TRUE(
894 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
[email protected]dd3fd0e2012-11-04 05:14:40895}
896
zhongyie34c035662016-10-19 22:26:02897TEST_P(QuicChromiumClientSessionTest, PushStreamTimedOutNoResponse) {
898 base::HistogramTester histogram_tester;
899 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52900 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:02901 client_maker_.MakeInitialSettingsPacket(1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52902 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
Fan Yang32c5a112018-12-10 20:06:33903 client_maker_.MakeRstPacket(
904 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
905 quic::QUIC_PUSH_STREAM_TIMED_OUT));
zhongyie34c035662016-10-19 22:26:02906 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37907 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
908 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01909 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyie34c035662016-10-19 22:26:02910 Initialize();
911
912 ProofVerifyDetailsChromium details;
913 details.cert_verify_result.verified_cert =
914 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
915 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
916
917 CompleteCryptoHandshake();
918 session_->OnProofVerifyDetailsAvailable(details);
919
Ramin Halavatif7788ea2018-02-26 07:02:57920 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50921 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyie34c035662016-10-19 22:26:02922 EXPECT_TRUE(stream);
923
Ryan Hamilton0239aac2018-05-19 00:03:13924 spdy::SpdyHeaderBlock promise_headers;
zhongyie34c035662016-10-19 22:26:02925 promise_headers[":method"] = "GET";
926 promise_headers[":authority"] = "www.example.org";
927 promise_headers[":scheme"] = "https";
928 promise_headers[":path"] = "/pushed.jpg";
929
930 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36931 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:33932 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
933 promise_headers));
zhongyie34c035662016-10-19 22:26:02934
Ryan Hamilton8d9ee76e2018-05-29 23:52:52935 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:33936 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyie34c035662016-10-19 22:26:02937 EXPECT_TRUE(promised);
938 // Fire alarm to time out the push stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52939 alarm_factory_.FireAlarm(
940 quic::test::QuicClientPromisedInfoPeer::GetAlarm(promised));
zhongyie34c035662016-10-19 22:26:02941 EXPECT_FALSE(
942 session_->GetPromisedByUrl("https://www.example.org/pushed.jpg"));
943 EXPECT_EQ(0u,
944 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
945 EXPECT_EQ(0u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
946 session_.get()));
947}
948
949TEST_P(QuicChromiumClientSessionTest, PushStreamTimedOutWithResponse) {
950 base::HistogramTester histogram_tester;
951 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52952 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:02953 client_maker_.MakeInitialSettingsPacket(1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52954 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
Fan Yang32c5a112018-12-10 20:06:33955 client_maker_.MakeRstPacket(
956 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
957 quic::QUIC_PUSH_STREAM_TIMED_OUT));
zhongyie34c035662016-10-19 22:26:02958 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37959 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
960 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01961 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyie34c035662016-10-19 22:26:02962 Initialize();
963
964 ProofVerifyDetailsChromium details;
965 details.cert_verify_result.verified_cert =
966 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
967 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
968
969 CompleteCryptoHandshake();
970 session_->OnProofVerifyDetailsAvailable(details);
971
Ramin Halavatif7788ea2018-02-26 07:02:57972 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50973 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyie34c035662016-10-19 22:26:02974 EXPECT_TRUE(stream);
975
Ryan Hamilton0239aac2018-05-19 00:03:13976 spdy::SpdyHeaderBlock promise_headers;
zhongyie34c035662016-10-19 22:26:02977 promise_headers[":method"] = "GET";
978 promise_headers[":authority"] = "www.example.org";
979 promise_headers[":scheme"] = "https";
980 promise_headers[":path"] = "/pushed.jpg";
981
Fan Yang32c5a112018-12-10 20:06:33982 session_->GetOrCreateStream(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyie34c035662016-10-19 22:26:02983 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36984 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:33985 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
986 promise_headers));
987 session_->OnInitialHeadersComplete(
988 GetNthServerInitiatedUnidirectionalStreamId(0), spdy::SpdyHeaderBlock());
zhongyie34c035662016-10-19 22:26:02989 // Read data on the pushed stream.
Fan Yang32c5a112018-12-10 20:06:33990 quic::QuicStreamFrame data(GetNthServerInitiatedUnidirectionalStreamId(0),
991 false, 0, quic::QuicStringPiece("SP"));
zhongyie34c035662016-10-19 22:26:02992 session_->OnStreamFrame(data);
993
Ryan Hamilton8d9ee76e2018-05-29 23:52:52994 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:33995 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyie34c035662016-10-19 22:26:02996 EXPECT_TRUE(promised);
997 // Fire alarm to time out the push stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52998 alarm_factory_.FireAlarm(
999 quic::test::QuicClientPromisedInfoPeer::GetAlarm(promised));
zhongyie34c035662016-10-19 22:26:021000 EXPECT_EQ(2u,
1001 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
1002 EXPECT_EQ(2u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
1003 session_.get()));
1004}
1005
Renjie7f5894b2019-05-31 03:41:311006// Regression test for crbug.com/968621.
1007TEST_P(QuicChromiumClientSessionTest, PendingStreamOnRst) {
1008 if (!quic::VersionHasStreamType(version_.transport_version))
1009 return;
1010
1011 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
1012 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021013 client_maker_.MakeInitialSettingsPacket(1));
Renjie7f5894b2019-05-31 03:41:311014 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
1015 client_maker_.MakeRstPacket(
1016 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
1017 quic::QUIC_RST_ACKNOWLEDGEMENT));
1018
1019 MockWrite writes[] = {
1020 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
1021 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
1022 socket_data_.reset(new SequencedSocketData(reads, writes));
1023
1024 Initialize();
1025 CompleteCryptoHandshake();
1026
1027 quic::QuicStreamFrame data(GetNthServerInitiatedUnidirectionalStreamId(0),
1028 false, 1, quic::QuicStringPiece("SP"));
1029 session_->OnStreamFrame(data);
1030 EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
1031 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
1032 GetNthServerInitiatedUnidirectionalStreamId(0),
1033 quic::QUIC_STREAM_CANCELLED, 0);
1034 session_->OnRstStream(rst);
1035}
1036
Renjie82ddaf42019-06-07 23:40:311037// Regression test for crbug.com/971361.
1038TEST_P(QuicChromiumClientSessionTest, ClosePendingStream) {
1039 if (!quic::VersionHasStreamType(version_.transport_version))
1040 return;
1041
1042 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
1043 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
1044 client_maker_.MakeInitialSettingsPacket(1));
1045 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
1046 client_maker_.MakeRstPacket(
1047 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
1048 quic::QUIC_RST_ACKNOWLEDGEMENT));
1049
1050 MockWrite writes[] = {
1051 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
1052 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
1053 socket_data_.reset(new SequencedSocketData(reads, writes));
1054
1055 Initialize();
1056 CompleteCryptoHandshake();
1057
1058 quic::QuicStreamId id = GetNthServerInitiatedUnidirectionalStreamId(0);
1059 quic::QuicStreamFrame data(id, false, 1, quic::QuicStringPiece("SP"));
1060 session_->OnStreamFrame(data);
1061 EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
1062 session_->CloseStream(id);
1063}
1064
zhongyi7465c1b2016-11-11 01:38:051065TEST_P(QuicChromiumClientSessionTest, CancelPushWhenPendingValidation) {
1066 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521067 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021068 client_maker_.MakeInitialSettingsPacket(1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521069 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
Fan Yang32c5a112018-12-10 20:06:331070 client_maker_.MakeRstPacket(2, true,
1071 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:521072 quic::QUIC_RST_ACKNOWLEDGEMENT));
zhongyi7465c1b2016-11-11 01:38:051073
1074 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:371075 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
1076 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011077 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyi7465c1b2016-11-11 01:38:051078 Initialize();
1079
1080 ProofVerifyDetailsChromium details;
1081 details.cert_verify_result.verified_cert =
1082 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1083 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1084
1085 CompleteCryptoHandshake();
1086 session_->OnProofVerifyDetailsAvailable(details);
1087
Ramin Halavatif7788ea2018-02-26 07:02:571088 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501089 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyi7465c1b2016-11-11 01:38:051090 EXPECT_TRUE(stream);
1091
Ryan Hamilton0239aac2018-05-19 00:03:131092 spdy::SpdyHeaderBlock promise_headers;
zhongyi7465c1b2016-11-11 01:38:051093 promise_headers[":method"] = "GET";
1094 promise_headers[":authority"] = "www.example.org";
1095 promise_headers[":scheme"] = "https";
1096 promise_headers[":path"] = "/pushed.jpg";
1097
1098 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361099 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:331100 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
1101 promise_headers));
zhongyi7465c1b2016-11-11 01:38:051102
Ryan Hamilton8d9ee76e2018-05-29 23:52:521103 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:331104 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi7465c1b2016-11-11 01:38:051105 EXPECT_TRUE(promised);
1106
1107 // Initiate rendezvous.
Ryan Hamilton0239aac2018-05-19 00:03:131108 spdy::SpdyHeaderBlock client_request = promise_headers.Clone();
Ryan Hamilton8d9ee76e2018-05-29 23:52:521109 quic::test::TestPushPromiseDelegate delegate(/*match=*/true);
zhongyi7465c1b2016-11-11 01:38:051110 promised->HandleClientRequest(client_request, &delegate);
1111
1112 // Cancel the push before receiving the response to the pushed request.
1113 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:501114 test_push_delegate_.CancelPush(pushed_url);
zhongyi7465c1b2016-11-11 01:38:051115 EXPECT_TRUE(session_->GetPromisedByUrl(pushed_url.spec()));
1116
1117 // Reset the stream now before tear down.
Fan Yang32c5a112018-12-10 20:06:331118 session_->CloseStream(GetNthClientInitiatedBidirectionalStreamId(0));
zhongyi7465c1b2016-11-11 01:38:051119}
1120
zhongyi18bb2d92016-10-27 19:38:501121TEST_P(QuicChromiumClientSessionTest, CancelPushBeforeReceivingResponse) {
1122 base::HistogramTester histogram_tester;
1123 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521124 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021125 client_maker_.MakeInitialSettingsPacket(1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521126 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
Fan Yang32c5a112018-12-10 20:06:331127 client_maker_.MakeRstPacket(
1128 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
1129 quic::QUIC_STREAM_CANCELLED));
zhongyi18bb2d92016-10-27 19:38:501130 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:371131 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
1132 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011133 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyi18bb2d92016-10-27 19:38:501134 Initialize();
1135
1136 ProofVerifyDetailsChromium details;
1137 details.cert_verify_result.verified_cert =
1138 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1139 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1140
1141 CompleteCryptoHandshake();
1142 session_->OnProofVerifyDetailsAvailable(details);
1143
Ramin Halavatif7788ea2018-02-26 07:02:571144 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501145 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyi18bb2d92016-10-27 19:38:501146 EXPECT_TRUE(stream);
1147
Ryan Hamilton0239aac2018-05-19 00:03:131148 spdy::SpdyHeaderBlock promise_headers;
zhongyi18bb2d92016-10-27 19:38:501149 promise_headers[":method"] = "GET";
1150 promise_headers[":authority"] = "www.example.org";
1151 promise_headers[":scheme"] = "https";
1152 promise_headers[":path"] = "/pushed.jpg";
1153
1154 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361155 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:331156 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
1157 promise_headers));
zhongyi18bb2d92016-10-27 19:38:501158
Ryan Hamilton8d9ee76e2018-05-29 23:52:521159 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:331160 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501161 EXPECT_TRUE(promised);
1162 // Cancel the push before receiving the response to the pushed request.
1163 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:501164 test_push_delegate_.CancelPush(pushed_url);
zhongyi18bb2d92016-10-27 19:38:501165
1166 EXPECT_FALSE(session_->GetPromisedByUrl(pushed_url.spec()));
1167 EXPECT_EQ(0u,
1168 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
1169 EXPECT_EQ(0u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
1170 session_.get()));
1171}
1172
1173TEST_P(QuicChromiumClientSessionTest, CancelPushAfterReceivingResponse) {
1174 base::HistogramTester histogram_tester;
1175 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521176 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021177 client_maker_.MakeInitialSettingsPacket(1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521178 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
Fan Yang32c5a112018-12-10 20:06:331179 client_maker_.MakeRstPacket(
1180 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
1181 quic::QUIC_STREAM_CANCELLED));
zhongyi18bb2d92016-10-27 19:38:501182 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:371183 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
1184 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011185 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyi18bb2d92016-10-27 19:38:501186 Initialize();
1187
1188 ProofVerifyDetailsChromium details;
1189 details.cert_verify_result.verified_cert =
1190 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1191 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1192
1193 CompleteCryptoHandshake();
1194 session_->OnProofVerifyDetailsAvailable(details);
1195
Ramin Halavatif7788ea2018-02-26 07:02:571196 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501197 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyi18bb2d92016-10-27 19:38:501198 EXPECT_TRUE(stream);
1199
Ryan Hamilton0239aac2018-05-19 00:03:131200 spdy::SpdyHeaderBlock promise_headers;
zhongyi18bb2d92016-10-27 19:38:501201 promise_headers[":method"] = "GET";
1202 promise_headers[":authority"] = "www.example.org";
1203 promise_headers[":scheme"] = "https";
1204 promise_headers[":path"] = "/pushed.jpg";
1205
Fan Yang32c5a112018-12-10 20:06:331206 session_->GetOrCreateStream(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501207 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361208 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:331209 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
1210 promise_headers));
1211 session_->OnInitialHeadersComplete(
1212 GetNthServerInitiatedUnidirectionalStreamId(0), spdy::SpdyHeaderBlock());
zhongyi18bb2d92016-10-27 19:38:501213 // Read data on the pushed stream.
Fan Yang32c5a112018-12-10 20:06:331214 quic::QuicStreamFrame data(GetNthServerInitiatedUnidirectionalStreamId(0),
1215 false, 0, quic::QuicStringPiece("SP"));
zhongyi18bb2d92016-10-27 19:38:501216 session_->OnStreamFrame(data);
1217
Ryan Hamilton8d9ee76e2018-05-29 23:52:521218 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:331219 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501220 EXPECT_TRUE(promised);
1221 // Cancel the push after receiving data on the push stream.
1222 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:501223 test_push_delegate_.CancelPush(pushed_url);
zhongyi18bb2d92016-10-27 19:38:501224
1225 EXPECT_FALSE(session_->GetPromisedByUrl(pushed_url.spec()));
1226 EXPECT_EQ(2u,
1227 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
1228 EXPECT_EQ(2u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
1229 session_.get()));
1230}
1231
ckrasic4f9d88d2015-07-22 22:23:161232TEST_P(QuicChromiumClientSessionTest, MaxNumStreamsViaRequest) {
Ryan Hamiltonabad59e2019-06-06 04:02:591233 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021234 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Nick Harper23290b82019-05-02 00:02:561235 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:311236 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:521237 2, true, 51,
David Schinazicc1bc592019-04-24 19:40:311238 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:331239 quic_data.AddWrite(
1240 SYNCHRONOUS, client_maker_.MakeRstPacket(
1241 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
1242 quic::QUIC_RST_ACKNOWLEDGEMENT));
1243 quic_data.AddRead(
David Schinazicc1bc592019-04-24 19:40:311244 ASYNC, server_maker_.MakeMaxStreamsPacket(1, true, 53,
1245 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471246 } else {
1247 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331248 SYNCHRONOUS, client_maker_.MakeRstPacket(
1249 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
1250 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:481251 }
1252 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1253 quic_data.AddRead(ASYNC, OK); // EOF
1254 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:081255
1256 Initialize();
[email protected]0b2294d32013-08-02 00:46:361257 CompleteCryptoHandshake();
Fan Yang32c5a112018-12-10 20:06:331258 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch12fef552016-01-15 16:26:311259 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:081260 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:571261 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501262 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
[email protected]0b2294d32013-08-02 00:46:361263 EXPECT_TRUE(stream);
1264 streams.push_back(stream);
1265 }
1266
rchf0b18c8a2017-05-05 19:31:571267 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:281268 session_->CreateHandle(destination_);
[email protected]0b2294d32013-08-02 00:46:361269 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:391270 ASSERT_EQ(
1271 ERR_IO_PENDING,
1272 handle->RequestStream(/*requires_confirmation=*/false,
1273 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]0b2294d32013-08-02 00:46:361274
1275 // Close a stream and ensure I can now open a new one.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521276 quic::QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:081277 session_->CloseStream(stream_id);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521278 quic::QuicRstStreamFrame rst1(quic::kInvalidControlFrameId, stream_id,
1279 quic::QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:081280 session_->OnRstStream(rst1);
Frank Kastenholz878763bf2018-11-28 19:14:481281 // Pump data, bringing in the max-stream-id
1282 base::RunLoop().RunUntilIdle();
[email protected]0b2294d32013-08-02 00:46:361283 ASSERT_TRUE(callback.have_result());
robpercival214763f2016-07-01 23:27:011284 EXPECT_THAT(callback.WaitForResult(), IsOk());
rch1bcfddf22017-06-03 00:26:291285 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
[email protected]0b2294d32013-08-02 00:46:361286}
1287
ckrasic4f9d88d2015-07-22 22:23:161288TEST_P(QuicChromiumClientSessionTest, GoAwayReceived) {
fayang3bcb8b502016-12-07 21:44:371289 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521290 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021291 client_maker_.MakeInitialSettingsPacket(1));
fayang3bcb8b502016-12-07 21:44:371292 MockWrite writes[] = {
1293 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011294 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081295 Initialize();
[email protected]8ba81212013-05-03 13:11:481296 CompleteCryptoHandshake();
[email protected]9db443912013-02-25 05:27:031297
1298 // After receiving a GoAway, I should no longer be able to create outgoing
1299 // streams.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521300 session_->connection()->OnGoAwayFrame(
1301 quic::QuicGoAwayFrame(quic::kInvalidControlFrameId,
1302 quic::QUIC_PEER_GOING_AWAY, 1u, "Going away."));
Fan Yang5a3bddf2018-10-12 10:05:501303 EXPECT_EQ(nullptr, QuicChromiumClientSessionPeer::CreateOutgoingStream(
Ramin Halavatif7788ea2018-02-26 07:02:571304 session_.get()));
[email protected]9db443912013-02-25 05:27:031305}
1306
ckrasic4f9d88d2015-07-22 22:23:161307TEST_P(QuicChromiumClientSessionTest, CanPool) {
fayang3bcb8b502016-12-07 21:44:371308 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521309 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021310 client_maker_.MakeInitialSettingsPacket(1));
fayang3bcb8b502016-12-07 21:44:371311 MockWrite writes[] = {
1312 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011313 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081314 Initialize();
[email protected]f21ec372014-07-02 07:15:121315 // Load a cert that is valid for:
1316 // www.example.org
1317 // mail.example.org
1318 // www.example.com
[email protected]f21ec372014-07-02 07:15:121319
[email protected]f21ec372014-07-02 07:15:121320 ProofVerifyDetailsChromium details;
1321 details.cert_verify_result.verified_cert =
[email protected]5db452202014-08-19 05:22:151322 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
dcheng4227c6d2014-08-25 23:58:181323 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]f21ec372014-07-02 07:15:121324
[email protected]f21ec372014-07-02 07:15:121325 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081326 session_->OnProofVerifyDetailsAvailable(details);
[email protected]f21ec372014-07-02 07:15:121327
Matt Menke26e41542019-06-05 01:09:511328 EXPECT_TRUE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED,
1329 SocketTag(), NetworkIsolationKey()));
1330 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_ENABLED,
1331 SocketTag(), NetworkIsolationKey()));
Paul Jensen8e3c5d32018-02-19 17:06:331332#if defined(OS_ANDROID)
1333 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
1334 SocketTag tag2(getuid(), 0x87654321);
Matt Menke26e41542019-06-05 01:09:511335 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag1,
1336 NetworkIsolationKey()));
1337 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag2,
1338 NetworkIsolationKey()));
Paul Jensen8e3c5d32018-02-19 17:06:331339#endif
1340 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
Matt Menke26e41542019-06-05 01:09:511341 SocketTag(), NetworkIsolationKey()));
Paul Jensen8e3c5d32018-02-19 17:06:331342 EXPECT_TRUE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
Matt Menke26e41542019-06-05 01:09:511343 SocketTag(), NetworkIsolationKey()));
1344 EXPECT_FALSE(session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED,
1345 SocketTag(), NetworkIsolationKey()));
1346
1347 // Check that NetworkIsolationKey is respected when feature is enabled.
1348 {
1349 base::test::ScopedFeatureList feature_list;
1350 feature_list.InitAndDisableFeature(
1351 features::kPartitionConnectionsByNetworkIsolationKey);
1352 EXPECT_TRUE(session_->CanPool(
1353 "mail.example.com", PRIVACY_MODE_DISABLED, SocketTag(),
1354 NetworkIsolationKey(url::Origin::Create(GURL("http://foo.test/")))));
1355 }
1356 {
1357 base::test::ScopedFeatureList feature_list;
1358 feature_list.InitAndEnableFeature(
1359 features::kPartitionConnectionsByNetworkIsolationKey);
1360 EXPECT_FALSE(session_->CanPool(
1361 "mail.example.com", PRIVACY_MODE_DISABLED, SocketTag(),
1362 NetworkIsolationKey(url::Origin::Create(GURL("http://foo.test/")))));
1363 }
1364}
1365
1366// Much as above, but uses a non-empty NetworkIsolationKey.
1367TEST_P(QuicChromiumClientSessionTest, CanPoolWithNetworkIsolationKey) {
1368 base::test::ScopedFeatureList feature_list;
1369 feature_list.InitAndEnableFeature(
1370 features::kPartitionConnectionsByNetworkIsolationKey);
1371
1372 const NetworkIsolationKey kNetworkIsolationKey1(
1373 url::Origin::Create(GURL("http://foo.test/")));
1374 const NetworkIsolationKey kNetworkIsolationKey2(
1375 url::Origin::Create(GURL("http://bar.test/")));
1376
1377 session_key_ =
1378 QuicSessionKey(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED,
1379 SocketTag(), kNetworkIsolationKey1);
1380
1381 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
1382 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021383 client_maker_.MakeInitialSettingsPacket(1));
Matt Menke26e41542019-06-05 01:09:511384 MockWrite writes[] = {
1385 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
1386 socket_data_.reset(new SequencedSocketData(reads, writes));
1387 Initialize();
1388 // Load a cert that is valid for:
1389 // www.example.org
1390 // mail.example.org
1391 // www.example.com
1392
1393 ProofVerifyDetailsChromium details;
1394 details.cert_verify_result.verified_cert =
1395 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1396 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1397
1398 CompleteCryptoHandshake();
1399 session_->OnProofVerifyDetailsAvailable(details);
1400
1401 EXPECT_TRUE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED,
1402 SocketTag(), kNetworkIsolationKey1));
1403 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_ENABLED,
1404 SocketTag(), kNetworkIsolationKey1));
1405#if defined(OS_ANDROID)
1406 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
1407 SocketTag tag2(getuid(), 0x87654321);
1408 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag1,
1409 kNetworkIsolationKey1));
1410 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag2,
1411 kNetworkIsolationKey1));
1412#endif
1413 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1414 SocketTag(), kNetworkIsolationKey1));
1415 EXPECT_TRUE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1416 SocketTag(), kNetworkIsolationKey1));
1417 EXPECT_FALSE(session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED,
1418 SocketTag(), kNetworkIsolationKey1));
1419
1420 EXPECT_FALSE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1421 SocketTag(), kNetworkIsolationKey2));
1422 EXPECT_FALSE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1423 SocketTag(), NetworkIsolationKey()));
[email protected]f21ec372014-07-02 07:15:121424}
1425
ckrasic4f9d88d2015-07-22 22:23:161426TEST_P(QuicChromiumClientSessionTest, ConnectionNotPooledWithDifferentPin) {
Matt Mueller230996f12018-10-22 19:39:441427 // Configure the TransportSecurityStateSource so that kPreloadedPKPHost will
1428 // have static PKP pins set.
1429 ScopedTransportSecurityStateSource scoped_security_state_source;
1430
1431 // |net::test_default::kHSTSSource| defines pins for kPreloadedPKPHost.
1432 // (This hostname must be in the spdy_pooling.pem SAN.)
1433 const char kPreloadedPKPHost[] = "www.example.org";
1434 // A hostname without any static state. (This hostname isn't in
1435 // spdy_pooling.pem SAN, but that's okay because the
1436 // ProofVerifyDetailsChromium are faked.)
1437 const char kNoPinsHost[] = "no-pkp.example.org";
1438
fayang3bcb8b502016-12-07 21:44:371439 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521440 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021441 client_maker_.MakeInitialSettingsPacket(1));
fayang3bcb8b502016-12-07 21:44:371442 MockWrite writes[] = {
1443 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011444 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081445 Initialize();
1446
Matt Mueller230996f12018-10-22 19:39:441447 transport_security_state_.EnableStaticPinsForTesting();
[email protected]5db452202014-08-19 05:22:151448
1449 ProofVerifyDetailsChromium details;
1450 details.cert_verify_result.verified_cert =
1451 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1452 details.cert_verify_result.is_issued_by_known_root = true;
Matt Mueller230996f12018-10-22 19:39:441453 uint8_t bad_pin = 3;
[email protected]5db452202014-08-19 05:22:151454 details.cert_verify_result.public_key_hashes.push_back(
1455 GetTestHashValue(bad_pin));
1456
dcheng4227c6d2014-08-25 23:58:181457 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:151458
[email protected]5db452202014-08-19 05:22:151459 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081460 session_->OnProofVerifyDetailsAvailable(details);
Matt Mueller230996f12018-10-22 19:39:441461 QuicChromiumClientSessionPeer::SetHostname(session_.get(), kNoPinsHost);
[email protected]5db452202014-08-19 05:22:151462
Matt Menke26e41542019-06-05 01:09:511463 EXPECT_FALSE(session_->CanPool(kPreloadedPKPHost, PRIVACY_MODE_DISABLED,
1464 SocketTag(), NetworkIsolationKey()));
[email protected]5db452202014-08-19 05:22:151465}
1466
ckrasic4f9d88d2015-07-22 22:23:161467TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithMatchingPin) {
Matt Mueller230996f12018-10-22 19:39:441468 ScopedTransportSecurityStateSource scoped_security_state_source;
1469
fayang3bcb8b502016-12-07 21:44:371470 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521471 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021472 client_maker_.MakeInitialSettingsPacket(1));
fayang3bcb8b502016-12-07 21:44:371473 MockWrite writes[] = {
1474 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011475 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081476 Initialize();
1477
Matt Mueller230996f12018-10-22 19:39:441478 transport_security_state_.EnableStaticPinsForTesting();
[email protected]5db452202014-08-19 05:22:151479
1480 ProofVerifyDetailsChromium details;
1481 details.cert_verify_result.verified_cert =
1482 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1483 details.cert_verify_result.is_issued_by_known_root = true;
Matt Mueller230996f12018-10-22 19:39:441484 HashValue primary_pin(HASH_VALUE_SHA256);
1485 EXPECT_TRUE(primary_pin.FromString(
1486 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
1487 details.cert_verify_result.public_key_hashes.push_back(primary_pin);
[email protected]5db452202014-08-19 05:22:151488
dcheng4227c6d2014-08-25 23:58:181489 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:151490
[email protected]5db452202014-08-19 05:22:151491 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081492 session_->OnProofVerifyDetailsAvailable(details);
1493 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
[email protected]5db452202014-08-19 05:22:151494
Paul Jensen8e3c5d32018-02-19 17:06:331495 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
Matt Menke26e41542019-06-05 01:09:511496 SocketTag(), NetworkIsolationKey()));
jri7e636642016-01-14 06:57:081497}
1498
1499TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) {
fayang3bcb8b502016-12-07 21:44:371500 MockRead old_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521501 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021502 client_maker_.MakeInitialSettingsPacket(1));
fayang3bcb8b502016-12-07 21:44:371503 MockWrite old_writes[] = {
1504 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011505 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081506 Initialize();
1507 CompleteCryptoHandshake();
1508
1509 char data[] = "ABCD";
Ryan Hamilton8d9ee76e2018-05-29 23:52:521510 std::unique_ptr<quic::QuicEncryptedPacket> client_ping;
1511 std::unique_ptr<quic::QuicEncryptedPacket> ack_and_data_out;
1512 client_ping = client_maker_.MakeAckAndPingPacket(2, false, 1, 1, 1);
Fan Yang32c5a112018-12-10 20:06:331513 ack_and_data_out = client_maker_.MakeDataPacket(
Ryan Hamilton7505eb92019-06-08 00:22:171514 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Fan Yang32c5a112018-12-10 20:06:331515 quic::QuicStringPiece(data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521516 std::unique_ptr<quic::QuicEncryptedPacket> server_ping(
alyssar2adf3ac2016-05-03 17:12:581517 server_maker_.MakePingPacket(1, /*include_version=*/false));
alyssar2adf3ac2016-05-03 17:12:581518 MockRead reads[] = {
1519 MockRead(SYNCHRONOUS, server_ping->data(), server_ping->length(), 0),
1520 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
1521 MockWrite writes[] = {
1522 MockWrite(SYNCHRONOUS, client_ping->data(), client_ping->length(), 2),
1523 MockWrite(SYNCHRONOUS, ack_and_data_out->data(),
1524 ack_and_data_out->length(), 3)};
Ryan Sleevib8d7ea02018-05-07 20:01:011525 StaticSocketDataProvider socket_data(reads, writes);
jri7e636642016-01-14 06:57:081526 socket_factory_.AddSocketDataProvider(&socket_data);
jri7e636642016-01-14 06:57:081527 // Create connected socket.
danakjad1777e2016-04-16 00:56:421528 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081529 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191530 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011531 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081532
1533 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421534 std::unique_ptr<QuicChromiumPacketReader> new_reader(
1535 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1536 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521537 quic::QuicTime::Delta::FromMilliseconds(
danakjad1777e2016-04-16 00:56:421538 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201539 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221540 new_reader->StartReading();
jried79618b2016-07-02 03:18:521541 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1542 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081543
1544 // Migrate session.
jri9f303712016-09-13 01:10:221545 EXPECT_TRUE(session_->MigrateToSocket(
1546 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1547 // Spin message loop to complete migration.
1548 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081549
1550 // Write data to session.
Ramin Halavatif7788ea2018-02-26 07:02:571551 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501552 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
jri7e636642016-01-14 06:57:081553 struct iovec iov[1];
1554 iov[0].iov_base = data;
1555 iov[0].iov_len = 4;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521556 quic::test::QuicStreamPeer::SendBuffer(stream).SaveStreamData(iov, 1, 0, 4);
1557 quic::test::QuicStreamPeer::SetStreamBytesWritten(4, stream);
1558 session_->WritevData(stream, stream->id(), 4, 0, quic::NO_FIN);
jri7e636642016-01-14 06:57:081559
1560 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1561 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1562}
1563
1564TEST_P(QuicChromiumClientSessionTest, MigrateToSocketMaxReaders) {
fayang3bcb8b502016-12-07 21:44:371565 MockRead old_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521566 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021567 client_maker_.MakeInitialSettingsPacket(1));
fayang3bcb8b502016-12-07 21:44:371568 MockWrite old_writes[] = {
1569 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011570 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081571 Initialize();
1572 CompleteCryptoHandshake();
1573
1574 for (size_t i = 0; i < kMaxReadersPerQuicSession; ++i) {
1575 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521576 std::unique_ptr<quic::QuicEncryptedPacket> ping_out(
fayang3bcb8b502016-12-07 21:44:371577 client_maker_.MakePingPacket(i + 2, /*include_version=*/true));
jri7e636642016-01-14 06:57:081578 MockWrite writes[] = {
1579 MockWrite(SYNCHRONOUS, ping_out->data(), ping_out->length(), i + 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011580 StaticSocketDataProvider socket_data(reads, writes);
jri7e636642016-01-14 06:57:081581 socket_factory_.AddSocketDataProvider(&socket_data);
1582
1583 // Create connected socket.
danakjad1777e2016-04-16 00:56:421584 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081585 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191586 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011587 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081588
1589 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421590 std::unique_ptr<QuicChromiumPacketReader> new_reader(
rcha02807b42016-01-29 21:56:151591 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1592 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521593 quic::QuicTime::Delta::FromMilliseconds(
rcha02807b42016-01-29 21:56:151594 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201595 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221596 new_reader->StartReading();
jried79618b2016-07-02 03:18:521597 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1598 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081599
1600 // Migrate session.
1601 if (i < kMaxReadersPerQuicSession - 1) {
jri9f303712016-09-13 01:10:221602 EXPECT_TRUE(session_->MigrateToSocket(
1603 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1604 // Spin message loop to complete migration.
1605 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081606 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1607 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1608 } else {
1609 // Max readers exceeded.
jri9f303712016-09-13 01:10:221610 EXPECT_FALSE(session_->MigrateToSocket(
1611 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
Zhongyi Shid3d5f502018-08-10 00:22:221612 EXPECT_TRUE(socket_data.AllReadDataConsumed());
jri7e636642016-01-14 06:57:081613 EXPECT_FALSE(socket_data.AllWriteDataConsumed());
1614 }
1615 }
1616}
1617
1618TEST_P(QuicChromiumClientSessionTest, MigrateToSocketReadError) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521619 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021620 client_maker_.MakeInitialSettingsPacket(1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521621 std::unique_ptr<quic::QuicEncryptedPacket> client_ping;
1622 client_ping = client_maker_.MakeAckAndPingPacket(2, false, 1, 1, 1);
1623 std::unique_ptr<quic::QuicEncryptedPacket> server_ping(
alyssar2adf3ac2016-05-03 17:12:581624 server_maker_.MakePingPacket(1, /*include_version=*/false));
fayang3bcb8b502016-12-07 21:44:371625 MockWrite old_writes[] = {
1626 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 0)};
jri7e636642016-01-14 06:57:081627 MockRead old_reads[] = {
jri7e636642016-01-14 06:57:081628 MockRead(ASYNC, ERR_IO_PENDING, 1), // causes reading to pause.
1629 MockRead(ASYNC, ERR_NETWORK_CHANGED, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011630 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081631 Initialize();
1632 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081633 MockWrite writes[] = {
alyssar2adf3ac2016-05-03 17:12:581634 MockWrite(SYNCHRONOUS, client_ping->data(), client_ping->length(), 1)};
jri7e636642016-01-14 06:57:081635 MockRead new_reads[] = {
alyssar2adf3ac2016-05-03 17:12:581636 MockRead(SYNCHRONOUS, server_ping->data(), server_ping->length(), 0),
jri7e636642016-01-14 06:57:081637 MockRead(ASYNC, ERR_IO_PENDING, 2), // pause reading.
alyssar2adf3ac2016-05-03 17:12:581638 MockRead(ASYNC, server_ping->data(), server_ping->length(), 3),
jri7e636642016-01-14 06:57:081639 MockRead(ASYNC, ERR_IO_PENDING, 4), // pause reading
1640 MockRead(ASYNC, ERR_NETWORK_CHANGED, 5)};
Ryan Sleevib8d7ea02018-05-07 20:01:011641 SequencedSocketData new_socket_data(new_reads, writes);
jri7e636642016-01-14 06:57:081642 socket_factory_.AddSocketDataProvider(&new_socket_data);
1643
1644 // Create connected socket.
danakjad1777e2016-04-16 00:56:421645 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081646 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191647 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011648 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081649
1650 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421651 std::unique_ptr<QuicChromiumPacketReader> new_reader(
1652 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1653 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521654 quic::QuicTime::Delta::FromMilliseconds(
danakjad1777e2016-04-16 00:56:421655 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201656 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221657 new_reader->StartReading();
jried79618b2016-07-02 03:18:521658 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1659 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081660
1661 // Store old socket and migrate session.
jri9f303712016-09-13 01:10:221662 EXPECT_TRUE(session_->MigrateToSocket(
1663 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1664 // Spin message loop to complete migration.
1665 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081666
1667 // Read error on old socket does not impact session.
1668 EXPECT_TRUE(socket_data_->IsPaused());
1669 socket_data_->Resume();
1670 EXPECT_TRUE(session_->connection()->connected());
1671 EXPECT_TRUE(new_socket_data.IsPaused());
1672 new_socket_data.Resume();
1673
1674 // Read error on new socket causes session close.
1675 EXPECT_TRUE(new_socket_data.IsPaused());
1676 EXPECT_TRUE(session_->connection()->connected());
1677 new_socket_data.Resume();
1678 EXPECT_FALSE(session_->connection()->connected());
1679
1680 EXPECT_TRUE(socket_data_->AllReadDataConsumed());
1681 EXPECT_TRUE(socket_data_->AllWriteDataConsumed());
1682 EXPECT_TRUE(new_socket_data.AllReadDataConsumed());
1683 EXPECT_TRUE(new_socket_data.AllWriteDataConsumed());
1684}
1685
Zhongyi Shi5068bb02018-08-03 02:44:091686TEST_P(QuicChromiumClientSessionTest, DetectPathDegradingDuringHandshake) {
Ryan Hamilton8380c652019-06-04 02:25:061687 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
1688 // TODO(nharper, b/112643533): Figure out why this test fails when TLS is
1689 // enabled and fix it.
1690 return;
1691 }
Zhongyi Shi5068bb02018-08-03 02:44:091692 migrate_session_early_v2_ = true;
1693
Ryan Hamiltonabad59e2019-06-06 04:02:591694 MockQuicData quic_data(version_);
Zhongyi Shi5068bb02018-08-03 02:44:091695 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
1696 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
1697 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(2));
1698 quic_data.AddSocketDataToFactory(&socket_factory_);
1699
1700 // Set the crypto handshake mode to cold start and send CHLO packets.
1701 crypto_client_stream_factory_.set_handshake_mode(
1702 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
1703 Initialize();
1704
1705 session_->CryptoConnect(callback_.callback());
1706
1707 // Check retransmission alarm is set after sending the initial CHLO packet.
1708 quic::QuicAlarm* retransmission_alarm =
1709 quic::test::QuicConnectionPeer::GetRetransmissionAlarm(
1710 session_->connection());
1711 EXPECT_TRUE(retransmission_alarm->IsSet());
1712 quic::QuicTime retransmission_time = retransmission_alarm->deadline();
1713
1714 // Check path degrading alarm is set after sending the initial CHLO packet.
1715 quic::QuicAlarm* path_degrading_alarm =
1716 quic::test::QuicConnectionPeer::GetPathDegradingAlarm(
1717 session_->connection());
1718 EXPECT_TRUE(path_degrading_alarm->IsSet());
1719 quic::QuicTime path_degrading_time = path_degrading_alarm->deadline();
1720 EXPECT_LE(retransmission_time, path_degrading_time);
1721
1722 // Do not create outgoing stream since encryption is not established.
1723 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
1724 session_->CreateHandle(destination_);
1725 TestCompletionCallback callback;
1726 EXPECT_TRUE(handle->IsConnected());
1727 EXPECT_FALSE(handle->IsCryptoHandshakeConfirmed());
1728 EXPECT_EQ(
1729 ERR_IO_PENDING,
1730 handle->RequestStream(/*require_handshake_confirmation=*/true,
1731 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
1732
1733 // Fire the retransmission alarm to retransmit the crypto packet.
1734 quic::QuicTime::Delta delay = retransmission_time - clock_.ApproximateNow();
1735 clock_.AdvanceTime(delay);
1736 alarm_factory_.FireAlarm(retransmission_alarm);
1737
1738 // Fire the path degrading alarm to notify session that path is degrading
1739 // during crypto handshake.
1740 delay = path_degrading_time - clock_.ApproximateNow();
1741 clock_.AdvanceTime(delay);
1742 EXPECT_CALL(*session_.get(), OnPathDegrading());
1743 alarm_factory_.FireAlarm(path_degrading_alarm);
1744
1745 EXPECT_TRUE(session_->connection()->IsPathDegrading());
1746 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1747 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
1748}
1749
Yixin Wangf65c4b6d2018-03-08 22:37:401750TEST_P(QuicChromiumClientSessionTest, RetransmittableOnWireTimeout) {
1751 migrate_session_early_v2_ = true;
1752
Ryan Hamiltonabad59e2019-06-06 04:02:591753 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021754 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(1));
Zhongyi Shi32f2fd02018-04-16 18:23:431755 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
1756 quic_data.AddRead(ASYNC, server_maker_.MakeAckPacket(1, 2, 1, 1, false));
Yixin Wangf65c4b6d2018-03-08 22:37:401757
Zhongyi Shi32f2fd02018-04-16 18:23:431758 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(3, false));
Yixin Wangf65c4b6d2018-03-08 22:37:401759 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1760 quic_data.AddRead(ASYNC, OK); // EOF
1761 quic_data.AddSocketDataToFactory(&socket_factory_);
1762
1763 Initialize();
1764 CompleteCryptoHandshake();
1765
Ryan Hamilton8d9ee76e2018-05-29 23:52:521766 EXPECT_EQ(quic::QuicTime::Delta::FromMilliseconds(100),
Yixin Wangf65c4b6d2018-03-08 22:37:401767 session_->connection()->retransmittable_on_wire_timeout());
1768
1769 // Open a stream since the connection only sends PINGs to keep a
1770 // retransmittable packet on the wire if there's an open stream.
Fan Yang5a3bddf2018-10-12 10:05:501771 EXPECT_TRUE(
1772 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
Yixin Wangf65c4b6d2018-03-08 22:37:401773
Ryan Hamilton8d9ee76e2018-05-29 23:52:521774 quic::QuicAlarm* alarm =
Zhongyi Shi4bd7bf42018-11-06 21:05:101775 quic::test::QuicConnectionPeer::GetPingAlarm(session_->connection());
Yixin Wangf65c4b6d2018-03-08 22:37:401776 EXPECT_FALSE(alarm->IsSet());
1777
1778 // Send PING, which will be ACKed by the server. After the ACK, there will be
1779 // no retransmittable packets on the wire, so the alarm should be set.
1780 session_->SendPing();
1781 base::RunLoop().RunUntilIdle();
1782 EXPECT_TRUE(alarm->IsSet());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521783 EXPECT_EQ(
1784 clock_.ApproximateNow() + quic::QuicTime::Delta::FromMilliseconds(100),
1785 alarm->deadline());
Yixin Wangf65c4b6d2018-03-08 22:37:401786
1787 // Advance clock and simulate the alarm firing. This should cause a PING to be
1788 // sent.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521789 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(100));
Yixin Wangf65c4b6d2018-03-08 22:37:401790 alarm_factory_.FireAlarm(alarm);
1791 base::RunLoop().RunUntilIdle();
1792
1793 quic_data.Resume();
1794 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1795 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
1796}
1797
[email protected]dd3fd0e2012-11-04 05:14:401798} // namespace
1799} // namespace test
1800} // namespace net