blob: 5cc15a2e3f03bdfc188ea04161672e03e2fe7442 [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"
gabf767595f2016-05-11 18:50:3514#include "base/threading/thread_task_runner_handle.h"
Zhongyi Shic16b4102019-02-12 00:37:4015#include "base/time/default_tick_clock.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0816#include "build/build_config.h"
[email protected]8ee611b2012-11-20 01:48:1217#include "net/base/test_completion_callback.h"
[email protected]f21ec372014-07-02 07:15:1218#include "net/cert/cert_verify_result.h"
[email protected]5db452202014-08-19 05:22:1519#include "net/http/transport_security_state.h"
Matt Mueller230996f12018-10-22 19:39:4420#include "net/http/transport_security_state_test_util.h"
mikecironef22f9812016-10-04 03:40:1921#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5122#include "net/log/test_net_log.h"
Victor Vasiliev4f6fb892019-05-31 16:58:3123#include "net/quic/address_utils.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0824#include "net/quic/crypto/proof_verifier_chromium.h"
25#include "net/quic/mock_crypto_client_stream_factory.h"
26#include "net/quic/mock_quic_data.h"
27#include "net/quic/quic_chromium_alarm_factory.h"
28#include "net/quic/quic_chromium_client_session_peer.h"
29#include "net/quic/quic_chromium_connection_helper.h"
30#include "net/quic/quic_chromium_packet_reader.h"
31#include "net/quic/quic_chromium_packet_writer.h"
32#include "net/quic/quic_crypto_client_stream_factory.h"
33#include "net/quic/quic_http_utils.h"
34#include "net/quic/quic_server_info.h"
35#include "net/quic/quic_test_packet_maker.h"
tfarina5dd13c22016-11-16 12:08:2636#include "net/socket/datagram_client_socket.h"
[email protected]4d283b32013-10-17 12:57:2737#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5838#include "net/spdy/spdy_test_util_common.h"
[email protected]f21ec372014-07-02 07:15:1239#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0140#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4341#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0142#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5143#include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h"
44#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
45#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
46#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
47#include "net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h"
48#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
49#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h"
50#include "net/third_party/quiche/src/quic/core/quic_utils.h"
51#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
52#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
53#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
54#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
55#include "net/third_party/quiche/src/quic/test_tools/quic_client_promised_info_peer.h"
56#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
57#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
58#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
59#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
60#include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h"
Victor Vasiliev27cc7712019-01-24 11:50:1461#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
Ramin Halavati683bcaa92018-02-14 08:42:3962#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0163#include "testing/gmock/include/gmock/gmock.h"
[email protected]dd3fd0e2012-11-04 05:14:4064
65using testing::_;
66
67namespace net {
68namespace test {
69namespace {
70
eroman36d84e54432016-03-17 03:23:0271const IPEndPoint kIpEndPoint = IPEndPoint(IPAddress::IPv4AllZeros(), 0);
rch1fe2eeb2015-10-26 14:45:5772const char kServerHostname[] = "test.example.com";
Avi Drissman13fc8932015-12-20 04:40:4673const uint16_t kServerPort = 443;
jri7e636642016-01-14 06:57:0874const size_t kMaxReadersPerQuicSession = 5;
75
David Benjamin3cc59772019-04-02 07:33:3176// A subclass of QuicChromiumClientSession that allows OnPathDegrading to be
77// mocked.
Nick Harpere45fe4fc2017-07-13 00:34:5878class TestingQuicChromiumClientSession : public QuicChromiumClientSession {
79 public:
80 using QuicChromiumClientSession::QuicChromiumClientSession;
81
Zhongyi Shi5068bb02018-08-03 02:44:0982 MOCK_METHOD0(OnPathDegrading, void());
Nick Harpere45fe4fc2017-07-13 00:34:5883};
84
ckrasic4f9d88d2015-07-22 22:23:1685class QuicChromiumClientSessionTest
Ryan Hamilton8d9ee76e2018-05-29 23:52:5286 : public ::testing::TestWithParam<
Nick Harper23290b82019-05-02 00:02:5687 std::tuple<quic::ParsedQuicVersion, bool>>,
Bence Béky98447b12018-05-08 03:14:0188 public WithScopedTaskEnvironment {
Ryan Hamilton9883ff62017-08-01 06:07:0589 public:
ckrasic4f9d88d2015-07-22 22:23:1690 QuicChromiumClientSessionTest()
Yixin Wang079ad542018-01-11 04:06:0591 : version_(std::get<0>(GetParam())),
92 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:5293 crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting(),
94 quic::TlsClientHandshaker::CreateSslCtx()),
jri7e636642016-01-14 06:57:0895 default_read_(new MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)),
96 socket_data_(
Ryan Sleevib8d7ea02018-05-07 20:01:0197 new SequencedSocketData(base::make_span(default_read_.get(), 1),
98 base::span<MockWrite>())),
jri7e636642016-01-14 06:57:0899 random_(0),
rch16c74d1d2016-04-22 06:14:07100 helper_(&clock_, &random_),
Paul Jensen8e3c5d32018-02-19 17:06:33101 session_key_(kServerHostname,
102 kServerPort,
103 PRIVACY_MODE_DISABLED,
104 SocketTag()),
Ryan Hamilton6c2a2a82017-12-15 02:06:28105 destination_(kServerHostname, kServerPort),
Yixin Wang079ad542018-01-11 04:06:05106 client_maker_(version_,
David Schinazic8281052019-01-24 06:14:17107 quic::QuicUtils::CreateRandomConnectionId(&random_),
alyssar2adf3ac2016-05-03 17:12:58108 &clock_,
109 kServerHostname,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52110 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05111 client_headers_include_h2_stream_dependency_),
112 server_maker_(version_,
David Schinazic8281052019-01-24 06:14:17113 quic::QuicUtils::CreateRandomConnectionId(&random_),
alyssar2adf3ac2016-05-03 17:12:58114 &clock_,
115 kServerHostname,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52116 quic::Perspective::IS_SERVER,
Yixin Wangf65c4b6d2018-03-08 22:37:40117 false),
118 migrate_session_early_v2_(false) {
xunjielic70cc862016-02-19 15:29:26119 // Advance the time, because timers do not like uninitialized times.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52120 clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
xunjielic70cc862016-02-19 15:29:26121 }
jri7e636642016-01-14 06:57:08122
Ryan Hamilton9883ff62017-08-01 06:07:05123 void ResetHandleOnError(
124 std::unique_ptr<QuicChromiumClientSession::Handle>* handle,
125 int net_error) {
126 EXPECT_NE(OK, net_error);
127 handle->reset();
128 }
129
130 protected:
jri7e636642016-01-14 06:57:08131 void Initialize() {
rch1baa7472017-04-26 05:43:58132 if (socket_data_)
133 socket_factory_.AddSocketDataProvider(socket_data_.get());
danakjad1777e2016-04-16 00:56:42134 std::unique_ptr<DatagramClientSocket> socket =
jri7e636642016-01-14 06:57:08135 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:19136 &net_log_, NetLogSource());
jri7e636642016-01-14 06:57:08137 socket->Connect(kIpEndPoint);
Ryan Hamilton9edcf1a2017-11-22 05:55:17138 QuicChromiumPacketWriter* writer = new net::QuicChromiumPacketWriter(
139 socket.get(), base::ThreadTaskRunnerHandle::Get().get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52140 quic::QuicConnection* connection = new quic::QuicConnection(
David Schinazic8281052019-01-24 06:14:17141 quic::QuicUtils::CreateRandomConnectionId(&random_),
Victor Vasiliev4f6fb892019-05-31 16:58:31142 ToQuicSocketAddress(kIpEndPoint), &helper_, &alarm_factory_, writer,
143 true, quic::Perspective::IS_CLIENT,
Nick Harper23290b82019-05-02 00:02:56144 quic::test::SupportedVersions(version_));
Nick Harpere45fe4fc2017-07-13 00:34:58145 session_.reset(new TestingQuicChromiumClientSession(
jri7e636642016-01-14 06:57:08146 connection, std::move(socket),
147 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57148 &transport_security_state_, /*ssl_config_service=*/nullptr,
Paul Jensen8e3c5d32018-02-19 17:06:33149 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)), session_key_,
Zhongyi Shi757fcce2018-06-27 05:41:27150 /*require_confirmation=*/false, migrate_session_early_v2_,
Yixin Wangf65c4b6d2018-03-08 22:37:40151 /*migrate_session_on_network_change_v2=*/false,
Zhongyi Shid672f7542018-06-08 01:03:26152 /*defaulet_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shie01f2db2019-02-22 19:53:23153 quic::QuicTime::Delta::FromMilliseconds(
154 kDefaultRetransmittableOnWireTimeoutMillisecs),
Zhongyi Shi32fe14d42019-02-28 00:25:36155 /*migrate_idle_session=*/false,
Zhongyi Shic16b4102019-02-12 00:37:40156 base::TimeDelta::FromSeconds(kDefaultIdleSessionMigrationPeriodSeconds),
Zhongyi Shi73f23ca872017-12-13 18:37:13157 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29158 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30159 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17160 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52161 quic::QuicTime::Delta::FromMilliseconds(
162 kQuicYieldAfterDurationMilliseconds),
Zhongyi Shidbce7f412019-02-01 23:16:29163 /*cert_verify_flags=*/0, /*go_away_on_path_degrading*/ false,
164 client_headers_include_h2_stream_dependency_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52165 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
Yixin Wang079ad542018-01-11 04:06:05166 base::TimeTicks::Now(), base::TimeTicks::Now(), &push_promise_index_,
Zhongyi Shic16b4102019-02-12 00:37:40167 &test_push_delegate_, base::DefaultTickClock::GetInstance(),
168 base::ThreadTaskRunnerHandle::Get().get(),
jri7e636642016-01-14 06:57:08169 /*socket_performance_watcher=*/nullptr, &net_log_));
170
171 scoped_refptr<X509Certificate> cert(
172 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
173 verify_details_.cert_verify_result.verified_cert = cert;
174 verify_details_.cert_verify_result.is_issued_by_known_root = true;
jri7e636642016-01-14 06:57:08175 session_->Initialize();
176 session_->StartReading();
jribce3eec2016-09-09 05:41:08177 writer->set_delegate(session_.get());
[email protected]dd3fd0e2012-11-04 05:14:40178 }
179
rtenneti85dcfac22015-03-27 20:22:19180 void TearDown() override {
rchf0b18c8a2017-05-05 19:31:57181 if (session_)
Renjieba55fae2018-09-20 03:05:16182 session_->CloseSessionOnError(
183 ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
184 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]4d283b32013-10-17 12:57:27185 }
186
[email protected]ed3fc15d2013-03-08 18:37:44187 void CompleteCryptoHandshake() {
rch433bf5f2017-02-14 04:10:47188 ASSERT_THAT(session_->CryptoConnect(callback_.callback()), IsOk());
[email protected]ed3fc15d2013-03-08 18:37:44189 }
190
jried79618b2016-07-02 03:18:52191 QuicChromiumPacketWriter* CreateQuicChromiumPacketWriter(
192 DatagramClientSocket* socket,
193 QuicChromiumClientSession* session) const {
danakjad1777e2016-04-16 00:56:42194 std::unique_ptr<QuicChromiumPacketWriter> writer(
Ryan Hamilton9edcf1a2017-11-22 05:55:17195 new QuicChromiumPacketWriter(
196 socket, base::ThreadTaskRunnerHandle::Get().get()));
jribce3eec2016-09-09 05:41:08197 writer->set_delegate(session);
jri7e636642016-01-14 06:57:08198 return writer.release();
199 }
200
Fan Yang32c5a112018-12-10 20:06:33201 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56202 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
203 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36204 }
205
Fan Yang32c5a112018-12-10 20:06:33206 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56207 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
208 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36209 }
210
Fan Yang32c5a112018-12-10 20:06:33211 size_t GetMaxAllowedOutgoingBidirectionalStreams() {
Frank Kastenholzc9b9bea2018-12-03 20:13:47212 quic::QuicSession* quic_session =
213 dynamic_cast<quic::QuicSession*>(&*session_);
Nick Harper23290b82019-05-02 00:02:56214 if (version_.transport_version != quic::QUIC_VERSION_99) {
Frank Kastenholzc9b9bea2018-12-03 20:13:47215 return quic::test::QuicSessionPeer::GetStreamIdManager(quic_session)
216 ->max_open_outgoing_streams();
217 }
David Schinazicc1bc592019-04-24 19:40:31218 // For version99, the count will include both static and dynamic streams.
219 // These tests are only concerned with dynamic streams (that is, the number
Ryan Hamilton4aeec562019-05-17 21:22:52220 // of streams that they can create), so back out the static header stream.
Frank Kastenholzc9b9bea2018-12-03 20:13:47221 return quic::test::QuicSessionPeer::v99_streamid_manager(quic_session)
David Schinazicc1bc592019-04-24 19:40:31222 ->max_allowed_outgoing_bidirectional_streams() -
Ryan Hamilton4aeec562019-05-17 21:22:52223 1;
Frank Kastenholzc9b9bea2018-12-03 20:13:47224 }
225
Nick Harper23290b82019-05-02 00:02:56226 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05227 const bool client_headers_include_h2_stream_dependency_;
Jana Iyengarf6b13d82017-09-04 02:09:10228 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52229 quic::QuicCryptoClientConfig crypto_config_;
vishal.b62985ca92015-04-17 08:45:51230 TestNetLog net_log_;
tfarina42834112016-09-22 13:38:20231 BoundTestNetLog bound_test_net_log_;
[email protected]4d283b32013-10-17 12:57:27232 MockClientSocketFactory socket_factory_;
danakjad1777e2016-04-16 00:56:42233 std::unique_ptr<MockRead> default_read_;
234 std::unique_ptr<SequencedSocketData> socket_data_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52235 quic::MockClock clock_;
236 quic::test::MockRandom random_;
rch12fef552016-01-15 16:26:31237 QuicChromiumConnectionHelper helper_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52238 quic::test::MockAlarmFactory alarm_factory_;
jri7e636642016-01-14 06:57:08239 TransportSecurityState transport_security_state_;
240 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52241 quic::QuicClientPushPromiseIndex push_promise_index_;
Paul Jensen8e3c5d32018-02-19 17:06:33242 QuicSessionKey session_key_;
Ryan Hamilton6c2a2a82017-12-15 02:06:28243 HostPortPair destination_;
Nick Harpere45fe4fc2017-07-13 00:34:58244 std::unique_ptr<TestingQuicChromiumClientSession> session_;
zhongyi0009f3e2016-11-11 19:47:50245 TestServerPushDelegate test_push_delegate_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52246 quic::QuicConnectionVisitorInterface* visitor_;
[email protected]8ee611b2012-11-20 01:48:12247 TestCompletionCallback callback_;
alyssar2adf3ac2016-05-03 17:12:58248 QuicTestPacketMaker client_maker_;
249 QuicTestPacketMaker server_maker_;
jri7e636642016-01-14 06:57:08250 ProofVerifyDetailsChromium verify_details_;
Yixin Wangf65c4b6d2018-03-08 22:37:40251 bool migrate_session_early_v2_;
[email protected]dd3fd0e2012-11-04 05:14:40252};
253
Victor Costane635086f2019-01-27 05:20:30254INSTANTIATE_TEST_SUITE_P(
Bence Békyce380cb2018-04-26 23:39:55255 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05256 QuicChromiumClientSessionTest,
Nick Harper23290b82019-05-02 00:02:56257 ::testing::Combine(::testing::ValuesIn(quic::AllSupportedVersions()),
258 ::testing::Bool()));
[email protected]4d640792013-12-18 22:21:08259
Carlos IL81133382017-12-06 17:18:45260TEST_P(QuicChromiumClientSessionTest, IsFatalErrorNotSetForNonFatalError) {
261 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52262 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Carlos IL81133382017-12-06 17:18:45263 client_maker_.MakeInitialSettingsPacket(1, nullptr));
264 MockWrite writes[] = {
265 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01266 socket_data_.reset(new SequencedSocketData(reads, writes));
Carlos IL81133382017-12-06 17:18:45267 Initialize();
268
269 SSLInfo ssl_info;
270 ProofVerifyDetailsChromium details;
271 details.cert_verify_result.verified_cert =
272 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
273 details.cert_verify_result.cert_status =
274 MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
275 details.is_fatal_cert_error = false;
276 CompleteCryptoHandshake();
277 session_->OnProofVerifyDetailsAvailable(details);
278
279 ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
280 EXPECT_FALSE(ssl_info.is_fatal_cert_error);
281}
282
283TEST_P(QuicChromiumClientSessionTest, IsFatalErrorSetForFatalError) {
284 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52285 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Carlos IL81133382017-12-06 17:18:45286 client_maker_.MakeInitialSettingsPacket(1, nullptr));
287 MockWrite writes[] = {
288 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01289 socket_data_.reset(new SequencedSocketData(reads, writes));
Carlos IL81133382017-12-06 17:18:45290 Initialize();
291
292 SSLInfo ssl_info;
293 ProofVerifyDetailsChromium details;
294 details.cert_verify_result.verified_cert =
295 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
296 details.cert_verify_result.cert_status =
297 MapNetErrorToCertStatus(ERR_CERT_DATE_INVALID);
298 details.is_fatal_cert_error = true;
299 CompleteCryptoHandshake();
300 session_->OnProofVerifyDetailsAvailable(details);
301 ASSERT_TRUE(session_->GetSSLInfo(&ssl_info));
302 EXPECT_TRUE(ssl_info.is_fatal_cert_error);
303}
304
ckrasic4f9d88d2015-07-22 22:23:16305TEST_P(QuicChromiumClientSessionTest, CryptoConnect) {
fayang3bcb8b502016-12-07 21:44:37306 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52307 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36308 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:37309 MockWrite writes[] = {
310 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01311 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:08312 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44313 CompleteCryptoHandshake();
[email protected]8ee611b2012-11-20 01:48:12314}
315
rchf0b18c8a2017-05-05 19:31:57316TEST_P(QuicChromiumClientSessionTest, Handle) {
317 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43318 quic_data.AddWrite(SYNCHRONOUS,
319 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rchf0b18c8a2017-05-05 19:31:57320 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
321 quic_data.AddRead(ASYNC, OK); // EOF
322 quic_data.AddSocketDataToFactory(&socket_factory_);
323
324 Initialize();
325
326 NetLogWithSource session_net_log = session_->net_log();
327 EXPECT_EQ(NetLogSourceType::QUIC_SESSION, session_net_log.source().type);
328 EXPECT_EQ(&net_log_, session_net_log.net_log());
329
330 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28331 session_->CreateHandle(destination_);
rchf0b18c8a2017-05-05 19:31:57332 EXPECT_TRUE(handle->IsConnected());
333 EXPECT_FALSE(handle->IsCryptoHandshakeConfirmed());
Nick Harper23290b82019-05-02 00:02:56334 EXPECT_EQ(version_.transport_version, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33335 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57336 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
337 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
338 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
339 IPEndPoint address;
340 EXPECT_EQ(OK, handle->GetPeerAddress(&address));
341 EXPECT_EQ(kIpEndPoint, address);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52342 EXPECT_TRUE(handle->CreatePacketBundler(quic::QuicConnection::NO_ACK).get() !=
rchf0b18c8a2017-05-05 19:31:57343 nullptr);
344
345 CompleteCryptoHandshake();
346
347 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
348
349 // Request a stream and verify that a stream was created.
350 TestCompletionCallback callback;
351 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39352 callback.callback(),
353 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29354 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchf0b18c8a2017-05-05 19:31:57355
356 quic_data.Resume();
357 EXPECT_TRUE(quic_data.AllReadDataConsumed());
358 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
359
360 // Veirfy that the handle works correctly after the session is closed.
361 EXPECT_FALSE(handle->IsConnected());
362 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
Nick Harper23290b82019-05-02 00:02:56363 EXPECT_EQ(version_.transport_version, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33364 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57365 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
366 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
367 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
368 EXPECT_EQ(ERR_CONNECTION_CLOSED, handle->GetPeerAddress(&address));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52369 EXPECT_TRUE(handle->CreatePacketBundler(quic::QuicConnection::NO_ACK).get() ==
rchf0b18c8a2017-05-05 19:31:57370 nullptr);
371 {
372 // Verify that CreateHandle() works even after the session is closed.
373 std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
Ryan Hamilton6c2a2a82017-12-15 02:06:28374 session_->CreateHandle(destination_);
rchf0b18c8a2017-05-05 19:31:57375 EXPECT_FALSE(handle2->IsConnected());
376 EXPECT_TRUE(handle2->IsCryptoHandshakeConfirmed());
377 ASSERT_EQ(ERR_CONNECTION_CLOSED,
378 handle2->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39379 callback.callback(),
380 TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57381 }
382
383 session_.reset();
384
385 // Veirfy that the handle works correctly after the session is deleted.
386 EXPECT_FALSE(handle->IsConnected());
387 EXPECT_TRUE(handle->IsCryptoHandshakeConfirmed());
Nick Harper23290b82019-05-02 00:02:56388 EXPECT_EQ(version_.transport_version, handle->GetQuicVersion());
Paul Jensen8e3c5d32018-02-19 17:06:33389 EXPECT_EQ(session_key_.server_id(), handle->server_id());
rchf0b18c8a2017-05-05 19:31:57390 EXPECT_EQ(session_net_log.source().type, handle->net_log().source().type);
391 EXPECT_EQ(session_net_log.source().id, handle->net_log().source().id);
392 EXPECT_EQ(session_net_log.net_log(), handle->net_log().net_log());
393 EXPECT_EQ(ERR_CONNECTION_CLOSED, handle->GetPeerAddress(&address));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52394 EXPECT_TRUE(handle->CreatePacketBundler(quic::QuicConnection::NO_ACK).get() ==
rchf0b18c8a2017-05-05 19:31:57395 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) {
403 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43404 quic_data.AddWrite(SYNCHRONOUS,
405 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rch1baa7472017-04-26 05:43:58406 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
407 quic_data.AddRead(ASYNC, OK); // EOF
408 quic_data.AddSocketDataToFactory(&socket_factory_);
409
410 Initialize();
411 CompleteCryptoHandshake();
412
413 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57414 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28415 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58416 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57417 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39418 callback.callback(),
419 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29420 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rch1baa7472017-04-26 05:43:58421
422 quic_data.Resume();
423 EXPECT_TRUE(quic_data.AllReadDataConsumed());
424 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
425}
426
rchd606b6c32017-05-02 17:32:57427TEST_P(QuicChromiumClientSessionTest, ConfirmationRequiredStreamRequest) {
428 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43429 quic_data.AddWrite(SYNCHRONOUS,
430 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rchd606b6c32017-05-02 17:32:57431 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
432 quic_data.AddRead(ASYNC, OK); // EOF
433 quic_data.AddSocketDataToFactory(&socket_factory_);
434
435 Initialize();
436 CompleteCryptoHandshake();
437
438 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57439 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28440 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57441 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57442 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/true,
Ramin Halavati683bcaa92018-02-14 08:42:39443 callback.callback(),
444 TRAFFIC_ANNOTATION_FOR_TESTS));
rch1bcfddf22017-06-03 00:26:29445 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchd606b6c32017-05-02 17:32:57446
447 quic_data.Resume();
448 EXPECT_TRUE(quic_data.AllReadDataConsumed());
449 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
450}
451
452TEST_P(QuicChromiumClientSessionTest, StreamRequestBeforeConfirmation) {
453 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43454 quic_data.AddWrite(SYNCHRONOUS,
455 client_maker_.MakeInitialSettingsPacket(1, nullptr));
rchd606b6c32017-05-02 17:32:57456 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
457 quic_data.AddRead(ASYNC, OK); // EOF
458 quic_data.AddSocketDataToFactory(&socket_factory_);
459
460 Initialize();
461
462 // Request a stream and verify that a stream was created.
rchf0b18c8a2017-05-05 19:31:57463 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28464 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57465 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39466 ASSERT_EQ(
467 ERR_IO_PENDING,
468 handle->RequestStream(/*requires_confirmation=*/true, callback.callback(),
469 TRAFFIC_ANNOTATION_FOR_TESTS));
rchd606b6c32017-05-02 17:32:57470
471 CompleteCryptoHandshake();
472
473 EXPECT_THAT(callback.WaitForResult(), IsOk());
474
rch1bcfddf22017-06-03 00:26:29475 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rchd606b6c32017-05-02 17:32:57476
477 quic_data.Resume();
478 EXPECT_TRUE(quic_data.AllReadDataConsumed());
479 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
480}
481
rch1baa7472017-04-26 05:43:58482TEST_P(QuicChromiumClientSessionTest, CancelStreamRequestBeforeRelease) {
483 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43484 quic_data.AddWrite(SYNCHRONOUS,
485 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Fan Yang32c5a112018-12-10 20:06:33486 quic_data.AddWrite(SYNCHRONOUS,
487 client_maker_.MakeRstPacket(
488 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
489 quic::QUIC_STREAM_CANCELLED));
rch1baa7472017-04-26 05:43:58490 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
491 quic_data.AddRead(ASYNC, OK); // EOF
492 quic_data.AddSocketDataToFactory(&socket_factory_);
493
494 Initialize();
495 CompleteCryptoHandshake();
496
497 // Request a stream and cancel it without releasing the stream.
rchf0b18c8a2017-05-05 19:31:57498 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28499 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58500 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57501 ASSERT_EQ(OK, handle->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39502 callback.callback(),
503 TRAFFIC_ANNOTATION_FOR_TESTS));
rchf0b18c8a2017-05-05 19:31:57504 handle.reset();
rch1baa7472017-04-26 05:43:58505
506 quic_data.Resume();
507 EXPECT_TRUE(quic_data.AllReadDataConsumed());
508 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
509}
510
511TEST_P(QuicChromiumClientSessionTest, AsyncStreamRequest) {
512 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43513 quic_data.AddWrite(SYNCHRONOUS,
514 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Nick Harper23290b82019-05-02 00:02:56515 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz878763bf2018-11-28 19:14:48516 // The open stream limit is set to 50 by
517 // MockCryptoClientStream::SetConfigNegotiated() so when the 51st stream is
David Schinazicc1bc592019-04-24 19:40:31518 // requested, a STREAMS_BLOCKED will be sent, indicating that it's blocked
Ryan Hamilton4aeec562019-05-17 21:22:52519 // at the limit of 50. The +1 accounts for the header stream.
David Schinazicc1bc592019-04-24 19:40:31520 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52521 2, true, 50 + 1,
David Schinazicc1bc592019-04-24 19:40:31522 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:33523 quic_data.AddWrite(
524 SYNCHRONOUS, client_maker_.MakeRstPacket(
525 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:18526 quic::QUIC_STREAM_CANCELLED, 0,
527 /*include_stop_sending_if_v99=*/false));
David Schinazicc1bc592019-04-24 19:40:31528 // After the STREAMS_BLOCKED is sent, receive a MAX_STREAMS to increase
529 // the limit to 53.
Fan Yang32c5a112018-12-10 20:06:33530 quic_data.AddRead(
David Schinazicc1bc592019-04-24 19:40:31531 ASYNC, server_maker_.MakeMaxStreamsPacket(1, true, 53,
532 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47533 } else {
534 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33535 SYNCHRONOUS, client_maker_.MakeRstPacket(
536 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
537 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:48538 }
rch1baa7472017-04-26 05:43:58539 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
540 quic_data.AddRead(ASYNC, OK); // EOF
541 quic_data.AddSocketDataToFactory(&socket_factory_);
rch1baa7472017-04-26 05:43:58542 Initialize();
543 CompleteCryptoHandshake();
544
545 // Open the maximum number of streams so that a subsequent request
546 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33547 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch1baa7472017-04-26 05:43:58548 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50549 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch1baa7472017-04-26 05:43:58550 }
551 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
552
553 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57554 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28555 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58556 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39557 ASSERT_EQ(
558 ERR_IO_PENDING,
559 handle->RequestStream(/*requires_confirmation=*/false,
560 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch1baa7472017-04-26 05:43:58561
562 // Close a stream and ensure the stream request completes.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52563 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
Fan Yang32c5a112018-12-10 20:06:33564 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52565 quic::QUIC_STREAM_CANCELLED, 0);
rch1baa7472017-04-26 05:43:58566 session_->OnRstStream(rst);
Nick Harper23290b82019-05-02 00:02:56567 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz684ea412019-02-13 18:48:18568 // For version99, to close the stream completely, we also must receive a
569 // STOP_SENDING frame:
570 quic::QuicStopSendingFrame stop_sending(
571 quic::kInvalidControlFrameId,
572 GetNthClientInitiatedBidirectionalStreamId(0),
573 quic::QUIC_STREAM_CANCELLED);
574 session_->OnStopSendingFrame(stop_sending);
575 }
Frank Kastenholz878763bf2018-11-28 19:14:48576 // Pump the message loop to read the max stream id packet.
577 base::RunLoop().RunUntilIdle();
578
rch1baa7472017-04-26 05:43:58579 ASSERT_TRUE(callback.have_result());
580 EXPECT_THAT(callback.WaitForResult(), IsOk());
rch1bcfddf22017-06-03 00:26:29581 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
rch1baa7472017-04-26 05:43:58582
583 quic_data.Resume();
584 EXPECT_TRUE(quic_data.AllReadDataConsumed());
585 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
586}
587
Ryan Hamilton9883ff62017-08-01 06:07:05588TEST_P(QuicChromiumClientSessionTest, ClosedWithAsyncStreamRequest) {
589 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43590 quic_data.AddWrite(SYNCHRONOUS,
591 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Nick Harper23290b82019-05-02 00:02:56592 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholzc9b9bea2018-12-03 20:13:47593 // The open stream limit is set to 50 by
594 // MockCryptoClientStream::SetConfigNegotiated() so when the 51st stream is
David Schinazicc1bc592019-04-24 19:40:31595 // requested, a STREAMS_BLOCKED will be sent, indicating that it's blocked
Ryan Hamilton4aeec562019-05-17 21:22:52596 // at the limit of 50. The +1 accounts for the header streams.
David Schinazicc1bc592019-04-24 19:40:31597 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52598 2, true, 50 + 1,
David Schinazicc1bc592019-04-24 19:40:31599 /*unidirectional=*/false));
600 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52601 3, true, 50 + 1,
David Schinazicc1bc592019-04-24 19:40:31602 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47603 }
Ryan Hamilton9883ff62017-08-01 06:07:05604 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
605 quic_data.AddRead(ASYNC, OK); // EOF
606 quic_data.AddSocketDataToFactory(&socket_factory_);
607
608 Initialize();
609 CompleteCryptoHandshake();
610
611 // Open the maximum number of streams so that a subsequent request
612 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33613 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
Ryan Hamilton9883ff62017-08-01 06:07:05614 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50615 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
Ryan Hamilton9883ff62017-08-01 06:07:05616 }
617 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
618
619 // Request two streams which will both be pending.
Frank Kastenholzc9b9bea2018-12-03 20:13:47620 // In V99 each will generate a max stream id for each attempt.
Ryan Hamilton9883ff62017-08-01 06:07:05621 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28622 session_->CreateHandle(destination_);
Ryan Hamilton9883ff62017-08-01 06:07:05623 std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
Ryan Hamilton6c2a2a82017-12-15 02:06:28624 session_->CreateHandle(destination_);
Ryan Hamilton9883ff62017-08-01 06:07:05625
626 ASSERT_EQ(ERR_IO_PENDING,
627 handle->RequestStream(
628 /*requires_confirmation=*/false,
629 base::Bind(&QuicChromiumClientSessionTest::ResetHandleOnError,
Ramin Halavati683bcaa92018-02-14 08:42:39630 base::Unretained(this), &handle2),
631 TRAFFIC_ANNOTATION_FOR_TESTS));
Ryan Hamilton9883ff62017-08-01 06:07:05632
633 TestCompletionCallback callback2;
634 ASSERT_EQ(ERR_IO_PENDING,
635 handle2->RequestStream(/*requires_confirmation=*/false,
Ramin Halavati683bcaa92018-02-14 08:42:39636 callback2.callback(),
637 TRAFFIC_ANNOTATION_FOR_TESTS));
Ryan Hamilton9883ff62017-08-01 06:07:05638
639 session_->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52640 quic::QUIC_NETWORK_IDLE_TIMEOUT, "Timed out",
641 quic::ConnectionCloseBehavior::SILENT_CLOSE);
Ryan Hamilton9883ff62017-08-01 06:07:05642
643 // Pump the message loop to read the connection close packet.
644 base::RunLoop().RunUntilIdle();
645 EXPECT_FALSE(handle2.get());
646 quic_data.Resume();
647 EXPECT_TRUE(quic_data.AllReadDataConsumed());
648 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
649}
650
rch1baa7472017-04-26 05:43:58651TEST_P(QuicChromiumClientSessionTest, CancelPendingStreamRequest) {
652 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43653 quic_data.AddWrite(SYNCHRONOUS,
654 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Nick Harper23290b82019-05-02 00:02:56655 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz878763bf2018-11-28 19:14:48656 // The open stream limit is set to 50 by
657 // MockCryptoClientStream::SetConfigNegotiated() so when the 51st stream is
David Schinazicc1bc592019-04-24 19:40:31658 // requested, a STREAMS_BLOCKED will be sent.
659 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52660 2, true, 51,
David Schinazicc1bc592019-04-24 19:40:31661 /*unidirectional=*/false));
Frank Kastenholz684ea412019-02-13 18:48:18662 // This node receives the RST_STREAM+STOP_SENDING, it responds
663 // with only a RST_STREAM.
Fan Yang32c5a112018-12-10 20:06:33664 quic_data.AddWrite(
665 SYNCHRONOUS, client_maker_.MakeRstPacket(
666 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:18667 quic::QUIC_STREAM_CANCELLED, 0,
668 /*include_stop_sending_if_v99=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47669 } else {
670 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33671 SYNCHRONOUS, client_maker_.MakeRstPacket(
672 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
673 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:48674 }
rch1baa7472017-04-26 05:43:58675 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
676 quic_data.AddRead(ASYNC, OK); // EOF
677 quic_data.AddSocketDataToFactory(&socket_factory_);
678
679 Initialize();
680 CompleteCryptoHandshake();
681
682 // Open the maximum number of streams so that a subsequent request
683 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33684 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch1baa7472017-04-26 05:43:58685 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50686 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch1baa7472017-04-26 05:43:58687 }
688 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
689
690 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57691 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28692 session_->CreateHandle(destination_);
rch1baa7472017-04-26 05:43:58693 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39694 ASSERT_EQ(
695 ERR_IO_PENDING,
696 handle->RequestStream(/*requires_confirmation=*/false,
697 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch1baa7472017-04-26 05:43:58698
699 // Cancel the pending stream request.
rchf0b18c8a2017-05-05 19:31:57700 handle.reset();
rch1baa7472017-04-26 05:43:58701
702 // Close a stream and ensure that no new stream is created.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52703 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
Fan Yang32c5a112018-12-10 20:06:33704 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52705 quic::QUIC_STREAM_CANCELLED, 0);
rch1baa7472017-04-26 05:43:58706 session_->OnRstStream(rst);
Nick Harper23290b82019-05-02 00:02:56707 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz684ea412019-02-13 18:48:18708 // For version99, we require a STOP_SENDING as well as a RESET_STREAM to
709 // fully close the stream.
710 quic::QuicStopSendingFrame stop_sending(
711 quic::kInvalidControlFrameId,
712 GetNthClientInitiatedBidirectionalStreamId(0),
713 quic::QUIC_STREAM_CANCELLED);
714 session_->OnStopSendingFrame(stop_sending);
715 }
rch1baa7472017-04-26 05:43:58716 EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
717
718 quic_data.Resume();
719 EXPECT_TRUE(quic_data.AllReadDataConsumed());
720 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
721}
722
rch94c26d682017-04-29 02:49:27723TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeStreamRequest) {
724 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43725 quic_data.AddWrite(SYNCHRONOUS,
726 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52727 quic_data.AddRead(
728 ASYNC,
729 server_maker_.MakeConnectionClosePacket(
730 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rch94c26d682017-04-29 02:49:27731 quic_data.AddSocketDataToFactory(&socket_factory_);
732
733 Initialize();
734 CompleteCryptoHandshake();
735
736 // Pump the message loop to read the connection close packet.
737 base::RunLoop().RunUntilIdle();
738
739 // Request a stream and verify that it failed.
rchf0b18c8a2017-05-05 19:31:57740 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28741 session_->CreateHandle(destination_);
rch94c26d682017-04-29 02:49:27742 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39743 ASSERT_EQ(
744 ERR_CONNECTION_CLOSED,
745 handle->RequestStream(/*requires_confirmation=*/false,
746 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch94c26d682017-04-29 02:49:27747
748 EXPECT_TRUE(quic_data.AllReadDataConsumed());
749 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
750}
751
rchd606b6c32017-05-02 17:32:57752TEST_P(QuicChromiumClientSessionTest, ConnectionCloseBeforeHandshakeConfirmed) {
David Schinazic8281052019-01-24 06:14:17753 // Force the connection close packet to use long headers with connection ID.
Ryan Hamilton840358c2019-03-19 19:00:35754 server_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
David Schinazic8281052019-01-24 06:14:17755
rchd606b6c32017-05-02 17:32:57756 MockQuicData quic_data;
757 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52758 quic_data.AddRead(
759 ASYNC,
760 server_maker_.MakeConnectionClosePacket(
761 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rchd606b6c32017-05-02 17:32:57762 quic_data.AddSocketDataToFactory(&socket_factory_);
763
764 Initialize();
765
766 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57767 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28768 session_->CreateHandle(destination_);
rchd606b6c32017-05-02 17:32:57769 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39770 ASSERT_EQ(
771 ERR_IO_PENDING,
772 handle->RequestStream(/*requires_confirmation=*/true, callback.callback(),
773 TRAFFIC_ANNOTATION_FOR_TESTS));
rchd606b6c32017-05-02 17:32:57774
775 // Close the connection and verify that the StreamRequest completes with
776 // an error.
777 quic_data.Resume();
778 base::RunLoop().RunUntilIdle();
779
780 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
781
782 EXPECT_TRUE(quic_data.AllReadDataConsumed());
783 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
784}
785
rch94c26d682017-04-29 02:49:27786TEST_P(QuicChromiumClientSessionTest, ConnectionCloseWithPendingStreamRequest) {
787 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:43788 quic_data.AddWrite(SYNCHRONOUS,
789 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Nick Harper23290b82019-05-02 00:02:56790 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:31791 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52792 2, true, 51,
David Schinazicc1bc592019-04-24 19:40:31793 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47794 }
rch94c26d682017-04-29 02:49:27795 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52796 quic_data.AddRead(
797 ASYNC,
798 server_maker_.MakeConnectionClosePacket(
799 1, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!"));
rch94c26d682017-04-29 02:49:27800 quic_data.AddSocketDataToFactory(&socket_factory_);
801
802 Initialize();
803 CompleteCryptoHandshake();
804
805 // Open the maximum number of streams so that a subsequent request
806 // can not proceed immediately.
Fan Yang32c5a112018-12-10 20:06:33807 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch94c26d682017-04-29 02:49:27808 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Fan Yang5a3bddf2018-10-12 10:05:50809 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
rch94c26d682017-04-29 02:49:27810 }
811 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
812
813 // Request a stream and verify that it's pending.
rchf0b18c8a2017-05-05 19:31:57814 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:28815 session_->CreateHandle(destination_);
rch94c26d682017-04-29 02:49:27816 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:39817 ASSERT_EQ(
818 ERR_IO_PENDING,
819 handle->RequestStream(/*requires_confirmation=*/false,
820 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
rch94c26d682017-04-29 02:49:27821
822 // Close the connection and verify that the StreamRequest completes with
823 // an error.
824 quic_data.Resume();
825 base::RunLoop().RunUntilIdle();
826
827 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
828
829 EXPECT_TRUE(quic_data.AllReadDataConsumed());
830 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
831}
832
ckrasic4f9d88d2015-07-22 22:23:16833TEST_P(QuicChromiumClientSessionTest, MaxNumStreams) {
Frank Kastenholz878763bf2018-11-28 19:14:48834 MockQuicData quic_data;
835 quic_data.AddWrite(SYNCHRONOUS,
836 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Nick Harper23290b82019-05-02 00:02:56837 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:31838 // Initial configuration is 50 dynamic streams. Taking into account
Ryan Hamilton4aeec562019-05-17 21:22:52839 // the static stream (headers), expect to block on when hitting the limit
840 // of 51 streams
David Schinazicc1bc592019-04-24 19:40:31841 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52842 2, true, 50 + 1,
David Schinazicc1bc592019-04-24 19:40:31843 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:33844 quic_data.AddWrite(
845 SYNCHRONOUS, client_maker_.MakeRstPacket(
846 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
847 quic::QUIC_RST_ACKNOWLEDGEMENT));
David Schinazicc1bc592019-04-24 19:40:31848 // For the second CreateOutgoingStream that fails because of hitting the
849 // stream count limit.
850 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:52851 4, true, 50 + 1,
David Schinazicc1bc592019-04-24 19:40:31852 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:33853 quic_data.AddRead(
Ryan Hamilton4aeec562019-05-17 21:22:52854 ASYNC, server_maker_.MakeMaxStreamsPacket(1, true, 50 + 2,
David Schinazicc1bc592019-04-24 19:40:31855 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:47856 } else {
857 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33858 SYNCHRONOUS, client_maker_.MakeRstPacket(
859 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
860 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:48861 }
862 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
863 quic_data.AddRead(ASYNC, OK); // EOF
864 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:08865
866 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44867 CompleteCryptoHandshake();
Fan Yang32c5a112018-12-10 20:06:33868 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
[email protected]dd3fd0e2012-11-04 05:14:40869
rch12fef552016-01-15 16:26:31870 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:08871 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:57872 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50873 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
[email protected]dd3fd0e2012-11-04 05:14:40874 EXPECT_TRUE(stream);
[email protected]f702d572012-12-04 15:56:20875 streams.push_back(stream);
[email protected]dd3fd0e2012-11-04 05:14:40876 }
David Schinazicc1bc592019-04-24 19:40:31877 // This stream, the 51st dynamic stream, can not be opened.
Fan Yang5a3bddf2018-10-12 10:05:50878 EXPECT_FALSE(
879 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
[email protected]dd3fd0e2012-11-04 05:14:40880
jri7e636642016-01-14 06:57:08881 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
rtennetiac06c2f2015-11-05 18:12:35882
[email protected]dd3fd0e2012-11-04 05:14:40883 // Close a stream and ensure I can now open a new one.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52884 quic::QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:08885 session_->CloseStream(stream_id);
rtennetiac06c2f2015-11-05 18:12:35886
Frank Kastenholzc9b9bea2018-12-03 20:13:47887 // Pump data, bringing in the max-stream-id
888 base::RunLoop().RunUntilIdle();
889
Fan Yang5a3bddf2018-10-12 10:05:50890 EXPECT_FALSE(
891 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52892 quic::QuicRstStreamFrame rst1(quic::kInvalidControlFrameId, stream_id,
893 quic::QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:08894 session_->OnRstStream(rst1);
895 EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
Frank Kastenholz878763bf2018-11-28 19:14:48896 base::RunLoop().RunUntilIdle();
Fan Yang5a3bddf2018-10-12 10:05:50897 EXPECT_TRUE(
898 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
[email protected]dd3fd0e2012-11-04 05:14:40899}
900
zhongyie34c035662016-10-19 22:26:02901TEST_P(QuicChromiumClientSessionTest, PushStreamTimedOutNoResponse) {
902 base::HistogramTester histogram_tester;
903 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52904 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36905 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52906 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
Fan Yang32c5a112018-12-10 20:06:33907 client_maker_.MakeRstPacket(
908 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
909 quic::QUIC_PUSH_STREAM_TIMED_OUT));
zhongyie34c035662016-10-19 22:26:02910 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37911 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
912 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01913 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyie34c035662016-10-19 22:26:02914 Initialize();
915
916 ProofVerifyDetailsChromium details;
917 details.cert_verify_result.verified_cert =
918 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
919 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
920
921 CompleteCryptoHandshake();
922 session_->OnProofVerifyDetailsAvailable(details);
923
Ramin Halavatif7788ea2018-02-26 07:02:57924 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50925 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyie34c035662016-10-19 22:26:02926 EXPECT_TRUE(stream);
927
Ryan Hamilton0239aac2018-05-19 00:03:13928 spdy::SpdyHeaderBlock promise_headers;
zhongyie34c035662016-10-19 22:26:02929 promise_headers[":method"] = "GET";
930 promise_headers[":authority"] = "www.example.org";
931 promise_headers[":scheme"] = "https";
932 promise_headers[":path"] = "/pushed.jpg";
933
934 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36935 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:33936 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
937 promise_headers));
zhongyie34c035662016-10-19 22:26:02938
Ryan Hamilton8d9ee76e2018-05-29 23:52:52939 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:33940 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyie34c035662016-10-19 22:26:02941 EXPECT_TRUE(promised);
942 // Fire alarm to time out the push stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52943 alarm_factory_.FireAlarm(
944 quic::test::QuicClientPromisedInfoPeer::GetAlarm(promised));
zhongyie34c035662016-10-19 22:26:02945 EXPECT_FALSE(
946 session_->GetPromisedByUrl("https://www.example.org/pushed.jpg"));
947 EXPECT_EQ(0u,
948 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
949 EXPECT_EQ(0u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
950 session_.get()));
951}
952
953TEST_P(QuicChromiumClientSessionTest, PushStreamTimedOutWithResponse) {
954 base::HistogramTester histogram_tester;
955 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:52956 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:36957 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52958 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
Fan Yang32c5a112018-12-10 20:06:33959 client_maker_.MakeRstPacket(
960 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
961 quic::QUIC_PUSH_STREAM_TIMED_OUT));
zhongyie34c035662016-10-19 22:26:02962 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:37963 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
964 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01965 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyie34c035662016-10-19 22:26:02966 Initialize();
967
968 ProofVerifyDetailsChromium details;
969 details.cert_verify_result.verified_cert =
970 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
971 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
972
973 CompleteCryptoHandshake();
974 session_->OnProofVerifyDetailsAvailable(details);
975
Ramin Halavatif7788ea2018-02-26 07:02:57976 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:50977 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyie34c035662016-10-19 22:26:02978 EXPECT_TRUE(stream);
979
Ryan Hamilton0239aac2018-05-19 00:03:13980 spdy::SpdyHeaderBlock promise_headers;
zhongyie34c035662016-10-19 22:26:02981 promise_headers[":method"] = "GET";
982 promise_headers[":authority"] = "www.example.org";
983 promise_headers[":scheme"] = "https";
984 promise_headers[":path"] = "/pushed.jpg";
985
Fan Yang32c5a112018-12-10 20:06:33986 session_->GetOrCreateStream(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyie34c035662016-10-19 22:26:02987 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:36988 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:33989 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
990 promise_headers));
991 session_->OnInitialHeadersComplete(
992 GetNthServerInitiatedUnidirectionalStreamId(0), spdy::SpdyHeaderBlock());
zhongyie34c035662016-10-19 22:26:02993 // Read data on the pushed stream.
Fan Yang32c5a112018-12-10 20:06:33994 quic::QuicStreamFrame data(GetNthServerInitiatedUnidirectionalStreamId(0),
995 false, 0, quic::QuicStringPiece("SP"));
zhongyie34c035662016-10-19 22:26:02996 session_->OnStreamFrame(data);
997
Ryan Hamilton8d9ee76e2018-05-29 23:52:52998 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:33999 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyie34c035662016-10-19 22:26:021000 EXPECT_TRUE(promised);
1001 // Fire alarm to time out the push stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521002 alarm_factory_.FireAlarm(
1003 quic::test::QuicClientPromisedInfoPeer::GetAlarm(promised));
zhongyie34c035662016-10-19 22:26:021004 EXPECT_EQ(2u,
1005 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
1006 EXPECT_EQ(2u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
1007 session_.get()));
1008}
1009
Renjie7f5894b2019-05-31 03:41:311010// Regression test for crbug.com/968621.
1011TEST_P(QuicChromiumClientSessionTest, PendingStreamOnRst) {
1012 if (!quic::VersionHasStreamType(version_.transport_version))
1013 return;
1014
1015 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
1016 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
1017 client_maker_.MakeInitialSettingsPacket(1, nullptr));
1018 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
1019 client_maker_.MakeRstPacket(
1020 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
1021 quic::QUIC_RST_ACKNOWLEDGEMENT));
1022
1023 MockWrite writes[] = {
1024 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
1025 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
1026 socket_data_.reset(new SequencedSocketData(reads, writes));
1027
1028 Initialize();
1029 CompleteCryptoHandshake();
1030
1031 quic::QuicStreamFrame data(GetNthServerInitiatedUnidirectionalStreamId(0),
1032 false, 1, quic::QuicStringPiece("SP"));
1033 session_->OnStreamFrame(data);
1034 EXPECT_EQ(0u, session_->GetNumOpenIncomingStreams());
1035 quic::QuicRstStreamFrame rst(quic::kInvalidControlFrameId,
1036 GetNthServerInitiatedUnidirectionalStreamId(0),
1037 quic::QUIC_STREAM_CANCELLED, 0);
1038 session_->OnRstStream(rst);
1039}
1040
zhongyi7465c1b2016-11-11 01:38:051041TEST_P(QuicChromiumClientSessionTest, CancelPushWhenPendingValidation) {
1042 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521043 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361044 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521045 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
Fan Yang32c5a112018-12-10 20:06:331046 client_maker_.MakeRstPacket(2, true,
1047 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:521048 quic::QUIC_RST_ACKNOWLEDGEMENT));
zhongyi7465c1b2016-11-11 01:38:051049
1050 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:371051 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
1052 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011053 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyi7465c1b2016-11-11 01:38:051054 Initialize();
1055
1056 ProofVerifyDetailsChromium details;
1057 details.cert_verify_result.verified_cert =
1058 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1059 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1060
1061 CompleteCryptoHandshake();
1062 session_->OnProofVerifyDetailsAvailable(details);
1063
Ramin Halavatif7788ea2018-02-26 07:02:571064 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501065 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyi7465c1b2016-11-11 01:38:051066 EXPECT_TRUE(stream);
1067
Ryan Hamilton0239aac2018-05-19 00:03:131068 spdy::SpdyHeaderBlock promise_headers;
zhongyi7465c1b2016-11-11 01:38:051069 promise_headers[":method"] = "GET";
1070 promise_headers[":authority"] = "www.example.org";
1071 promise_headers[":scheme"] = "https";
1072 promise_headers[":path"] = "/pushed.jpg";
1073
1074 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361075 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:331076 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
1077 promise_headers));
zhongyi7465c1b2016-11-11 01:38:051078
Ryan Hamilton8d9ee76e2018-05-29 23:52:521079 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:331080 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi7465c1b2016-11-11 01:38:051081 EXPECT_TRUE(promised);
1082
1083 // Initiate rendezvous.
Ryan Hamilton0239aac2018-05-19 00:03:131084 spdy::SpdyHeaderBlock client_request = promise_headers.Clone();
Ryan Hamilton8d9ee76e2018-05-29 23:52:521085 quic::test::TestPushPromiseDelegate delegate(/*match=*/true);
zhongyi7465c1b2016-11-11 01:38:051086 promised->HandleClientRequest(client_request, &delegate);
1087
1088 // Cancel the push before receiving the response to the pushed request.
1089 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:501090 test_push_delegate_.CancelPush(pushed_url);
zhongyi7465c1b2016-11-11 01:38:051091 EXPECT_TRUE(session_->GetPromisedByUrl(pushed_url.spec()));
1092
1093 // Reset the stream now before tear down.
Fan Yang32c5a112018-12-10 20:06:331094 session_->CloseStream(GetNthClientInitiatedBidirectionalStreamId(0));
zhongyi7465c1b2016-11-11 01:38:051095}
1096
zhongyi18bb2d92016-10-27 19:38:501097TEST_P(QuicChromiumClientSessionTest, CancelPushBeforeReceivingResponse) {
1098 base::HistogramTester histogram_tester;
1099 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521100 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361101 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521102 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
Fan Yang32c5a112018-12-10 20:06:331103 client_maker_.MakeRstPacket(
1104 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
1105 quic::QUIC_STREAM_CANCELLED));
zhongyi18bb2d92016-10-27 19:38:501106 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:371107 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
1108 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011109 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyi18bb2d92016-10-27 19:38:501110 Initialize();
1111
1112 ProofVerifyDetailsChromium details;
1113 details.cert_verify_result.verified_cert =
1114 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1115 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1116
1117 CompleteCryptoHandshake();
1118 session_->OnProofVerifyDetailsAvailable(details);
1119
Ramin Halavatif7788ea2018-02-26 07:02:571120 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501121 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyi18bb2d92016-10-27 19:38:501122 EXPECT_TRUE(stream);
1123
Ryan Hamilton0239aac2018-05-19 00:03:131124 spdy::SpdyHeaderBlock promise_headers;
zhongyi18bb2d92016-10-27 19:38:501125 promise_headers[":method"] = "GET";
1126 promise_headers[":authority"] = "www.example.org";
1127 promise_headers[":scheme"] = "https";
1128 promise_headers[":path"] = "/pushed.jpg";
1129
1130 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361131 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:331132 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
1133 promise_headers));
zhongyi18bb2d92016-10-27 19:38:501134
Ryan Hamilton8d9ee76e2018-05-29 23:52:521135 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:331136 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501137 EXPECT_TRUE(promised);
1138 // Cancel the push before receiving the response to the pushed request.
1139 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:501140 test_push_delegate_.CancelPush(pushed_url);
zhongyi18bb2d92016-10-27 19:38:501141
1142 EXPECT_FALSE(session_->GetPromisedByUrl(pushed_url.spec()));
1143 EXPECT_EQ(0u,
1144 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
1145 EXPECT_EQ(0u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
1146 session_.get()));
1147}
1148
1149TEST_P(QuicChromiumClientSessionTest, CancelPushAfterReceivingResponse) {
1150 base::HistogramTester histogram_tester;
1151 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521152 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361153 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521154 std::unique_ptr<quic::QuicEncryptedPacket> client_rst(
Fan Yang32c5a112018-12-10 20:06:331155 client_maker_.MakeRstPacket(
1156 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
1157 quic::QUIC_STREAM_CANCELLED));
zhongyi18bb2d92016-10-27 19:38:501158 MockWrite writes[] = {
fayang3bcb8b502016-12-07 21:44:371159 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1),
1160 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011161 socket_data_.reset(new SequencedSocketData(reads, writes));
zhongyi18bb2d92016-10-27 19:38:501162 Initialize();
1163
1164 ProofVerifyDetailsChromium details;
1165 details.cert_verify_result.verified_cert =
1166 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1167 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
1168
1169 CompleteCryptoHandshake();
1170 session_->OnProofVerifyDetailsAvailable(details);
1171
Ramin Halavatif7788ea2018-02-26 07:02:571172 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501173 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
zhongyi18bb2d92016-10-27 19:38:501174 EXPECT_TRUE(stream);
1175
Ryan Hamilton0239aac2018-05-19 00:03:131176 spdy::SpdyHeaderBlock promise_headers;
zhongyi18bb2d92016-10-27 19:38:501177 promise_headers[":method"] = "GET";
1178 promise_headers[":authority"] = "www.example.org";
1179 promise_headers[":scheme"] = "https";
1180 promise_headers[":path"] = "/pushed.jpg";
1181
Fan Yang32c5a112018-12-10 20:06:331182 session_->GetOrCreateStream(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501183 // Receive a PUSH PROMISE from the server.
ckrasicbf2f59c2017-05-04 23:54:361184 EXPECT_TRUE(session_->HandlePromised(
Fan Yang32c5a112018-12-10 20:06:331185 stream->id(), GetNthServerInitiatedUnidirectionalStreamId(0),
1186 promise_headers));
1187 session_->OnInitialHeadersComplete(
1188 GetNthServerInitiatedUnidirectionalStreamId(0), spdy::SpdyHeaderBlock());
zhongyi18bb2d92016-10-27 19:38:501189 // Read data on the pushed stream.
Fan Yang32c5a112018-12-10 20:06:331190 quic::QuicStreamFrame data(GetNthServerInitiatedUnidirectionalStreamId(0),
1191 false, 0, quic::QuicStringPiece("SP"));
zhongyi18bb2d92016-10-27 19:38:501192 session_->OnStreamFrame(data);
1193
Ryan Hamilton8d9ee76e2018-05-29 23:52:521194 quic::QuicClientPromisedInfo* promised =
Fan Yang32c5a112018-12-10 20:06:331195 session_->GetPromisedById(GetNthServerInitiatedUnidirectionalStreamId(0));
zhongyi18bb2d92016-10-27 19:38:501196 EXPECT_TRUE(promised);
1197 // Cancel the push after receiving data on the push stream.
1198 GURL pushed_url("https://www.example.org/pushed.jpg");
zhongyi0009f3e2016-11-11 19:47:501199 test_push_delegate_.CancelPush(pushed_url);
zhongyi18bb2d92016-10-27 19:38:501200
1201 EXPECT_FALSE(session_->GetPromisedByUrl(pushed_url.spec()));
1202 EXPECT_EQ(2u,
1203 QuicChromiumClientSessionPeer::GetPushedBytesCount(session_.get()));
1204 EXPECT_EQ(2u, QuicChromiumClientSessionPeer::GetPushedAndUnclaimedBytesCount(
1205 session_.get()));
1206}
1207
ckrasic4f9d88d2015-07-22 22:23:161208TEST_P(QuicChromiumClientSessionTest, MaxNumStreamsViaRequest) {
Frank Kastenholz878763bf2018-11-28 19:14:481209 MockQuicData quic_data;
1210 quic_data.AddWrite(SYNCHRONOUS,
1211 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Nick Harper23290b82019-05-02 00:02:561212 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:311213 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:521214 2, true, 51,
David Schinazicc1bc592019-04-24 19:40:311215 /*unidirectional=*/false));
Fan Yang32c5a112018-12-10 20:06:331216 quic_data.AddWrite(
1217 SYNCHRONOUS, client_maker_.MakeRstPacket(
1218 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
1219 quic::QUIC_RST_ACKNOWLEDGEMENT));
1220 quic_data.AddRead(
David Schinazicc1bc592019-04-24 19:40:311221 ASYNC, server_maker_.MakeMaxStreamsPacket(1, true, 53,
1222 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471223 } else {
1224 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331225 SYNCHRONOUS, client_maker_.MakeRstPacket(
1226 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
1227 quic::QUIC_RST_ACKNOWLEDGEMENT));
Frank Kastenholz878763bf2018-11-28 19:14:481228 }
1229 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1230 quic_data.AddRead(ASYNC, OK); // EOF
1231 quic_data.AddSocketDataToFactory(&socket_factory_);
jri7e636642016-01-14 06:57:081232
1233 Initialize();
[email protected]0b2294d32013-08-02 00:46:361234 CompleteCryptoHandshake();
Fan Yang32c5a112018-12-10 20:06:331235 const size_t kMaxOpenStreams = GetMaxAllowedOutgoingBidirectionalStreams();
rch12fef552016-01-15 16:26:311236 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:081237 for (size_t i = 0; i < kMaxOpenStreams; i++) {
Ramin Halavatif7788ea2018-02-26 07:02:571238 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501239 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
[email protected]0b2294d32013-08-02 00:46:361240 EXPECT_TRUE(stream);
1241 streams.push_back(stream);
1242 }
1243
rchf0b18c8a2017-05-05 19:31:571244 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
Ryan Hamilton6c2a2a82017-12-15 02:06:281245 session_->CreateHandle(destination_);
[email protected]0b2294d32013-08-02 00:46:361246 TestCompletionCallback callback;
Ramin Halavati683bcaa92018-02-14 08:42:391247 ASSERT_EQ(
1248 ERR_IO_PENDING,
1249 handle->RequestStream(/*requires_confirmation=*/false,
1250 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]0b2294d32013-08-02 00:46:361251
1252 // Close a stream and ensure I can now open a new one.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521253 quic::QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:081254 session_->CloseStream(stream_id);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521255 quic::QuicRstStreamFrame rst1(quic::kInvalidControlFrameId, stream_id,
1256 quic::QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:081257 session_->OnRstStream(rst1);
Frank Kastenholz878763bf2018-11-28 19:14:481258 // Pump data, bringing in the max-stream-id
1259 base::RunLoop().RunUntilIdle();
[email protected]0b2294d32013-08-02 00:46:361260 ASSERT_TRUE(callback.have_result());
robpercival214763f2016-07-01 23:27:011261 EXPECT_THAT(callback.WaitForResult(), IsOk());
rch1bcfddf22017-06-03 00:26:291262 EXPECT_TRUE(handle->ReleaseStream() != nullptr);
[email protected]0b2294d32013-08-02 00:46:361263}
1264
ckrasic4f9d88d2015-07-22 22:23:161265TEST_P(QuicChromiumClientSessionTest, GoAwayReceived) {
fayang3bcb8b502016-12-07 21:44:371266 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521267 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361268 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371269 MockWrite writes[] = {
1270 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011271 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081272 Initialize();
[email protected]8ba81212013-05-03 13:11:481273 CompleteCryptoHandshake();
[email protected]9db443912013-02-25 05:27:031274
1275 // After receiving a GoAway, I should no longer be able to create outgoing
1276 // streams.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521277 session_->connection()->OnGoAwayFrame(
1278 quic::QuicGoAwayFrame(quic::kInvalidControlFrameId,
1279 quic::QUIC_PEER_GOING_AWAY, 1u, "Going away."));
Fan Yang5a3bddf2018-10-12 10:05:501280 EXPECT_EQ(nullptr, QuicChromiumClientSessionPeer::CreateOutgoingStream(
Ramin Halavatif7788ea2018-02-26 07:02:571281 session_.get()));
[email protected]9db443912013-02-25 05:27:031282}
1283
ckrasic4f9d88d2015-07-22 22:23:161284TEST_P(QuicChromiumClientSessionTest, CanPool) {
fayang3bcb8b502016-12-07 21:44:371285 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521286 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361287 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371288 MockWrite writes[] = {
1289 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011290 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081291 Initialize();
[email protected]f21ec372014-07-02 07:15:121292 // Load a cert that is valid for:
1293 // www.example.org
1294 // mail.example.org
1295 // www.example.com
[email protected]f21ec372014-07-02 07:15:121296
[email protected]f21ec372014-07-02 07:15:121297 ProofVerifyDetailsChromium details;
1298 details.cert_verify_result.verified_cert =
[email protected]5db452202014-08-19 05:22:151299 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
dcheng4227c6d2014-08-25 23:58:181300 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]f21ec372014-07-02 07:15:121301
[email protected]f21ec372014-07-02 07:15:121302 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081303 session_->OnProofVerifyDetailsAvailable(details);
[email protected]f21ec372014-07-02 07:15:121304
Paul Jensen8e3c5d32018-02-19 17:06:331305 EXPECT_TRUE(
1306 session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, SocketTag()));
1307 EXPECT_FALSE(
1308 session_->CanPool("www.example.org", PRIVACY_MODE_ENABLED, SocketTag()));
1309#if defined(OS_ANDROID)
1310 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
1311 SocketTag tag2(getuid(), 0x87654321);
1312 EXPECT_FALSE(
1313 session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag1));
1314 EXPECT_FALSE(
1315 session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED, tag2));
1316#endif
1317 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1318 SocketTag()));
1319 EXPECT_TRUE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED,
1320 SocketTag()));
1321 EXPECT_FALSE(
1322 session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED, SocketTag()));
[email protected]f21ec372014-07-02 07:15:121323}
1324
ckrasic4f9d88d2015-07-22 22:23:161325TEST_P(QuicChromiumClientSessionTest, ConnectionNotPooledWithDifferentPin) {
Matt Mueller230996f12018-10-22 19:39:441326 // Configure the TransportSecurityStateSource so that kPreloadedPKPHost will
1327 // have static PKP pins set.
1328 ScopedTransportSecurityStateSource scoped_security_state_source;
1329
1330 // |net::test_default::kHSTSSource| defines pins for kPreloadedPKPHost.
1331 // (This hostname must be in the spdy_pooling.pem SAN.)
1332 const char kPreloadedPKPHost[] = "www.example.org";
1333 // A hostname without any static state. (This hostname isn't in
1334 // spdy_pooling.pem SAN, but that's okay because the
1335 // ProofVerifyDetailsChromium are faked.)
1336 const char kNoPinsHost[] = "no-pkp.example.org";
1337
fayang3bcb8b502016-12-07 21:44:371338 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521339 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361340 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371341 MockWrite writes[] = {
1342 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011343 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081344 Initialize();
1345
Matt Mueller230996f12018-10-22 19:39:441346 transport_security_state_.EnableStaticPinsForTesting();
[email protected]5db452202014-08-19 05:22:151347
1348 ProofVerifyDetailsChromium details;
1349 details.cert_verify_result.verified_cert =
1350 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1351 details.cert_verify_result.is_issued_by_known_root = true;
Matt Mueller230996f12018-10-22 19:39:441352 uint8_t bad_pin = 3;
[email protected]5db452202014-08-19 05:22:151353 details.cert_verify_result.public_key_hashes.push_back(
1354 GetTestHashValue(bad_pin));
1355
dcheng4227c6d2014-08-25 23:58:181356 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:151357
[email protected]5db452202014-08-19 05:22:151358 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081359 session_->OnProofVerifyDetailsAvailable(details);
Matt Mueller230996f12018-10-22 19:39:441360 QuicChromiumClientSessionPeer::SetHostname(session_.get(), kNoPinsHost);
[email protected]5db452202014-08-19 05:22:151361
Matt Mueller230996f12018-10-22 19:39:441362 EXPECT_FALSE(
1363 session_->CanPool(kPreloadedPKPHost, PRIVACY_MODE_DISABLED, SocketTag()));
[email protected]5db452202014-08-19 05:22:151364}
1365
ckrasic4f9d88d2015-07-22 22:23:161366TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithMatchingPin) {
Matt Mueller230996f12018-10-22 19:39:441367 ScopedTransportSecurityStateSource scoped_security_state_source;
1368
fayang3bcb8b502016-12-07 21:44:371369 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521370 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361371 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371372 MockWrite writes[] = {
1373 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011374 socket_data_.reset(new SequencedSocketData(reads, writes));
jri7e636642016-01-14 06:57:081375 Initialize();
1376
Matt Mueller230996f12018-10-22 19:39:441377 transport_security_state_.EnableStaticPinsForTesting();
[email protected]5db452202014-08-19 05:22:151378
1379 ProofVerifyDetailsChromium details;
1380 details.cert_verify_result.verified_cert =
1381 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
1382 details.cert_verify_result.is_issued_by_known_root = true;
Matt Mueller230996f12018-10-22 19:39:441383 HashValue primary_pin(HASH_VALUE_SHA256);
1384 EXPECT_TRUE(primary_pin.FromString(
1385 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
1386 details.cert_verify_result.public_key_hashes.push_back(primary_pin);
[email protected]5db452202014-08-19 05:22:151387
dcheng4227c6d2014-08-25 23:58:181388 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:151389
[email protected]5db452202014-08-19 05:22:151390 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081391 session_->OnProofVerifyDetailsAvailable(details);
1392 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
[email protected]5db452202014-08-19 05:22:151393
Paul Jensen8e3c5d32018-02-19 17:06:331394 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED,
1395 SocketTag()));
jri7e636642016-01-14 06:57:081396}
1397
1398TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) {
fayang3bcb8b502016-12-07 21:44:371399 MockRead old_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521400 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361401 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371402 MockWrite old_writes[] = {
1403 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011404 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081405 Initialize();
1406 CompleteCryptoHandshake();
1407
1408 char data[] = "ABCD";
Ryan Hamilton8d9ee76e2018-05-29 23:52:521409 std::unique_ptr<quic::QuicEncryptedPacket> client_ping;
1410 std::unique_ptr<quic::QuicEncryptedPacket> ack_and_data_out;
1411 client_ping = client_maker_.MakeAckAndPingPacket(2, false, 1, 1, 1);
Fan Yang32c5a112018-12-10 20:06:331412 ack_and_data_out = client_maker_.MakeDataPacket(
1413 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
1414 quic::QuicStringPiece(data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521415 std::unique_ptr<quic::QuicEncryptedPacket> server_ping(
alyssar2adf3ac2016-05-03 17:12:581416 server_maker_.MakePingPacket(1, /*include_version=*/false));
alyssar2adf3ac2016-05-03 17:12:581417 MockRead reads[] = {
1418 MockRead(SYNCHRONOUS, server_ping->data(), server_ping->length(), 0),
1419 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
1420 MockWrite writes[] = {
1421 MockWrite(SYNCHRONOUS, client_ping->data(), client_ping->length(), 2),
1422 MockWrite(SYNCHRONOUS, ack_and_data_out->data(),
1423 ack_and_data_out->length(), 3)};
Ryan Sleevib8d7ea02018-05-07 20:01:011424 StaticSocketDataProvider socket_data(reads, writes);
jri7e636642016-01-14 06:57:081425 socket_factory_.AddSocketDataProvider(&socket_data);
jri7e636642016-01-14 06:57:081426 // Create connected socket.
danakjad1777e2016-04-16 00:56:421427 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081428 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191429 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011430 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081431
1432 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421433 std::unique_ptr<QuicChromiumPacketReader> new_reader(
1434 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1435 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521436 quic::QuicTime::Delta::FromMilliseconds(
danakjad1777e2016-04-16 00:56:421437 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201438 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221439 new_reader->StartReading();
jried79618b2016-07-02 03:18:521440 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1441 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081442
1443 // Migrate session.
jri9f303712016-09-13 01:10:221444 EXPECT_TRUE(session_->MigrateToSocket(
1445 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1446 // Spin message loop to complete migration.
1447 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081448
1449 // Write data to session.
Ramin Halavatif7788ea2018-02-26 07:02:571450 QuicChromiumClientStream* stream =
Fan Yang5a3bddf2018-10-12 10:05:501451 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
jri7e636642016-01-14 06:57:081452 struct iovec iov[1];
1453 iov[0].iov_base = data;
1454 iov[0].iov_len = 4;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521455 quic::test::QuicStreamPeer::SendBuffer(stream).SaveStreamData(iov, 1, 0, 4);
1456 quic::test::QuicStreamPeer::SetStreamBytesWritten(4, stream);
1457 session_->WritevData(stream, stream->id(), 4, 0, quic::NO_FIN);
jri7e636642016-01-14 06:57:081458
1459 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1460 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1461}
1462
1463TEST_P(QuicChromiumClientSessionTest, MigrateToSocketMaxReaders) {
fayang3bcb8b502016-12-07 21:44:371464 MockRead old_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521465 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361466 client_maker_.MakeInitialSettingsPacket(1, nullptr));
fayang3bcb8b502016-12-07 21:44:371467 MockWrite old_writes[] = {
1468 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:011469 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081470 Initialize();
1471 CompleteCryptoHandshake();
1472
1473 for (size_t i = 0; i < kMaxReadersPerQuicSession; ++i) {
1474 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521475 std::unique_ptr<quic::QuicEncryptedPacket> ping_out(
fayang3bcb8b502016-12-07 21:44:371476 client_maker_.MakePingPacket(i + 2, /*include_version=*/true));
jri7e636642016-01-14 06:57:081477 MockWrite writes[] = {
1478 MockWrite(SYNCHRONOUS, ping_out->data(), ping_out->length(), i + 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011479 StaticSocketDataProvider socket_data(reads, writes);
jri7e636642016-01-14 06:57:081480 socket_factory_.AddSocketDataProvider(&socket_data);
1481
1482 // Create connected socket.
danakjad1777e2016-04-16 00:56:421483 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081484 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191485 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011486 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081487
1488 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421489 std::unique_ptr<QuicChromiumPacketReader> new_reader(
rcha02807b42016-01-29 21:56:151490 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1491 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521492 quic::QuicTime::Delta::FromMilliseconds(
rcha02807b42016-01-29 21:56:151493 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201494 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221495 new_reader->StartReading();
jried79618b2016-07-02 03:18:521496 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1497 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081498
1499 // Migrate session.
1500 if (i < kMaxReadersPerQuicSession - 1) {
jri9f303712016-09-13 01:10:221501 EXPECT_TRUE(session_->MigrateToSocket(
1502 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1503 // Spin message loop to complete migration.
1504 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081505 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1506 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1507 } else {
1508 // Max readers exceeded.
jri9f303712016-09-13 01:10:221509 EXPECT_FALSE(session_->MigrateToSocket(
1510 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
Zhongyi Shid3d5f502018-08-10 00:22:221511 EXPECT_TRUE(socket_data.AllReadDataConsumed());
jri7e636642016-01-14 06:57:081512 EXPECT_FALSE(socket_data.AllWriteDataConsumed());
1513 }
1514 }
1515}
1516
1517TEST_P(QuicChromiumClientSessionTest, MigrateToSocketReadError) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521518 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361519 client_maker_.MakeInitialSettingsPacket(1, nullptr));
Ryan Hamilton8d9ee76e2018-05-29 23:52:521520 std::unique_ptr<quic::QuicEncryptedPacket> client_ping;
1521 client_ping = client_maker_.MakeAckAndPingPacket(2, false, 1, 1, 1);
1522 std::unique_ptr<quic::QuicEncryptedPacket> server_ping(
alyssar2adf3ac2016-05-03 17:12:581523 server_maker_.MakePingPacket(1, /*include_version=*/false));
fayang3bcb8b502016-12-07 21:44:371524 MockWrite old_writes[] = {
1525 MockWrite(ASYNC, settings_packet->data(), settings_packet->length(), 0)};
jri7e636642016-01-14 06:57:081526 MockRead old_reads[] = {
jri7e636642016-01-14 06:57:081527 MockRead(ASYNC, ERR_IO_PENDING, 1), // causes reading to pause.
1528 MockRead(ASYNC, ERR_NETWORK_CHANGED, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:011529 socket_data_.reset(new SequencedSocketData(old_reads, old_writes));
jri7e636642016-01-14 06:57:081530 Initialize();
1531 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:081532 MockWrite writes[] = {
alyssar2adf3ac2016-05-03 17:12:581533 MockWrite(SYNCHRONOUS, client_ping->data(), client_ping->length(), 1)};
jri7e636642016-01-14 06:57:081534 MockRead new_reads[] = {
alyssar2adf3ac2016-05-03 17:12:581535 MockRead(SYNCHRONOUS, server_ping->data(), server_ping->length(), 0),
jri7e636642016-01-14 06:57:081536 MockRead(ASYNC, ERR_IO_PENDING, 2), // pause reading.
alyssar2adf3ac2016-05-03 17:12:581537 MockRead(ASYNC, server_ping->data(), server_ping->length(), 3),
jri7e636642016-01-14 06:57:081538 MockRead(ASYNC, ERR_IO_PENDING, 4), // pause reading
1539 MockRead(ASYNC, ERR_NETWORK_CHANGED, 5)};
Ryan Sleevib8d7ea02018-05-07 20:01:011540 SequencedSocketData new_socket_data(new_reads, writes);
jri7e636642016-01-14 06:57:081541 socket_factory_.AddSocketDataProvider(&new_socket_data);
1542
1543 // Create connected socket.
danakjad1777e2016-04-16 00:56:421544 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:081545 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
mikecironef22f9812016-10-04 03:40:191546 &net_log_, NetLogSource());
robpercival214763f2016-07-01 23:27:011547 EXPECT_THAT(new_socket->Connect(kIpEndPoint), IsOk());
jri7e636642016-01-14 06:57:081548
1549 // Create reader and writer.
danakjad1777e2016-04-16 00:56:421550 std::unique_ptr<QuicChromiumPacketReader> new_reader(
1551 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
1552 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521553 quic::QuicTime::Delta::FromMilliseconds(
danakjad1777e2016-04-16 00:56:421554 kQuicYieldAfterDurationMilliseconds),
tfarina42834112016-09-22 13:38:201555 bound_test_net_log_.bound()));
Zhongyi Shid3d5f502018-08-10 00:22:221556 new_reader->StartReading();
jried79618b2016-07-02 03:18:521557 std::unique_ptr<QuicChromiumPacketWriter> new_writer(
1558 CreateQuicChromiumPacketWriter(new_socket.get(), session_.get()));
jri7e636642016-01-14 06:57:081559
1560 // Store old socket and migrate session.
jri9f303712016-09-13 01:10:221561 EXPECT_TRUE(session_->MigrateToSocket(
1562 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
1563 // Spin message loop to complete migration.
1564 base::RunLoop().RunUntilIdle();
jri7e636642016-01-14 06:57:081565
1566 // Read error on old socket does not impact session.
1567 EXPECT_TRUE(socket_data_->IsPaused());
1568 socket_data_->Resume();
1569 EXPECT_TRUE(session_->connection()->connected());
1570 EXPECT_TRUE(new_socket_data.IsPaused());
1571 new_socket_data.Resume();
1572
1573 // Read error on new socket causes session close.
1574 EXPECT_TRUE(new_socket_data.IsPaused());
1575 EXPECT_TRUE(session_->connection()->connected());
1576 new_socket_data.Resume();
1577 EXPECT_FALSE(session_->connection()->connected());
1578
1579 EXPECT_TRUE(socket_data_->AllReadDataConsumed());
1580 EXPECT_TRUE(socket_data_->AllWriteDataConsumed());
1581 EXPECT_TRUE(new_socket_data.AllReadDataConsumed());
1582 EXPECT_TRUE(new_socket_data.AllWriteDataConsumed());
1583}
1584
Zhongyi Shi5068bb02018-08-03 02:44:091585TEST_P(QuicChromiumClientSessionTest, DetectPathDegradingDuringHandshake) {
1586 migrate_session_early_v2_ = true;
1587
1588 MockQuicData quic_data;
1589 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
1590 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
1591 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(2));
1592 quic_data.AddSocketDataToFactory(&socket_factory_);
1593
1594 // Set the crypto handshake mode to cold start and send CHLO packets.
1595 crypto_client_stream_factory_.set_handshake_mode(
1596 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
1597 Initialize();
1598
1599 session_->CryptoConnect(callback_.callback());
1600
1601 // Check retransmission alarm is set after sending the initial CHLO packet.
1602 quic::QuicAlarm* retransmission_alarm =
1603 quic::test::QuicConnectionPeer::GetRetransmissionAlarm(
1604 session_->connection());
1605 EXPECT_TRUE(retransmission_alarm->IsSet());
1606 quic::QuicTime retransmission_time = retransmission_alarm->deadline();
1607
1608 // Check path degrading alarm is set after sending the initial CHLO packet.
1609 quic::QuicAlarm* path_degrading_alarm =
1610 quic::test::QuicConnectionPeer::GetPathDegradingAlarm(
1611 session_->connection());
1612 EXPECT_TRUE(path_degrading_alarm->IsSet());
1613 quic::QuicTime path_degrading_time = path_degrading_alarm->deadline();
1614 EXPECT_LE(retransmission_time, path_degrading_time);
1615
1616 // Do not create outgoing stream since encryption is not established.
1617 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
1618 session_->CreateHandle(destination_);
1619 TestCompletionCallback callback;
1620 EXPECT_TRUE(handle->IsConnected());
1621 EXPECT_FALSE(handle->IsCryptoHandshakeConfirmed());
1622 EXPECT_EQ(
1623 ERR_IO_PENDING,
1624 handle->RequestStream(/*require_handshake_confirmation=*/true,
1625 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
1626
1627 // Fire the retransmission alarm to retransmit the crypto packet.
1628 quic::QuicTime::Delta delay = retransmission_time - clock_.ApproximateNow();
1629 clock_.AdvanceTime(delay);
1630 alarm_factory_.FireAlarm(retransmission_alarm);
1631
1632 // Fire the path degrading alarm to notify session that path is degrading
1633 // during crypto handshake.
1634 delay = path_degrading_time - clock_.ApproximateNow();
1635 clock_.AdvanceTime(delay);
1636 EXPECT_CALL(*session_.get(), OnPathDegrading());
1637 alarm_factory_.FireAlarm(path_degrading_alarm);
1638
1639 EXPECT_TRUE(session_->connection()->IsPathDegrading());
1640 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1641 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
1642}
1643
Yixin Wangf65c4b6d2018-03-08 22:37:401644TEST_P(QuicChromiumClientSessionTest, RetransmittableOnWireTimeout) {
1645 migrate_session_early_v2_ = true;
1646
1647 MockQuicData quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:431648 quic_data.AddWrite(SYNCHRONOUS,
1649 client_maker_.MakeInitialSettingsPacket(1, nullptr));
1650 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
1651 quic_data.AddRead(ASYNC, server_maker_.MakeAckPacket(1, 2, 1, 1, false));
Yixin Wangf65c4b6d2018-03-08 22:37:401652
Zhongyi Shi32f2fd02018-04-16 18:23:431653 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(3, false));
Yixin Wangf65c4b6d2018-03-08 22:37:401654 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1655 quic_data.AddRead(ASYNC, OK); // EOF
1656 quic_data.AddSocketDataToFactory(&socket_factory_);
1657
1658 Initialize();
1659 CompleteCryptoHandshake();
1660
Ryan Hamilton8d9ee76e2018-05-29 23:52:521661 EXPECT_EQ(quic::QuicTime::Delta::FromMilliseconds(100),
Yixin Wangf65c4b6d2018-03-08 22:37:401662 session_->connection()->retransmittable_on_wire_timeout());
1663
1664 // Open a stream since the connection only sends PINGs to keep a
1665 // retransmittable packet on the wire if there's an open stream.
Fan Yang5a3bddf2018-10-12 10:05:501666 EXPECT_TRUE(
1667 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get()));
Yixin Wangf65c4b6d2018-03-08 22:37:401668
Ryan Hamilton8d9ee76e2018-05-29 23:52:521669 quic::QuicAlarm* alarm =
Zhongyi Shi4bd7bf42018-11-06 21:05:101670 quic::test::QuicConnectionPeer::GetPingAlarm(session_->connection());
Yixin Wangf65c4b6d2018-03-08 22:37:401671 EXPECT_FALSE(alarm->IsSet());
1672
1673 // Send PING, which will be ACKed by the server. After the ACK, there will be
1674 // no retransmittable packets on the wire, so the alarm should be set.
1675 session_->SendPing();
1676 base::RunLoop().RunUntilIdle();
1677 EXPECT_TRUE(alarm->IsSet());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521678 EXPECT_EQ(
1679 clock_.ApproximateNow() + quic::QuicTime::Delta::FromMilliseconds(100),
1680 alarm->deadline());
Yixin Wangf65c4b6d2018-03-08 22:37:401681
1682 // Advance clock and simulate the alarm firing. This should cause a PING to be
1683 // sent.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521684 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(100));
Yixin Wangf65c4b6d2018-03-08 22:37:401685 alarm_factory_.FireAlarm(alarm);
1686 base::RunLoop().RunUntilIdle();
1687
1688 quic_data.Resume();
1689 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1690 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
1691}
1692
[email protected]dd3fd0e2012-11-04 05:14:401693} // namespace
1694} // namespace test
1695} // namespace net