blob: f8e17f913d487a12dec6a5e10568629d950cfaf6 [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
ckrasic4f9d88d2015-07-22 22:23:165#include "net/quic/quic_chromium_client_session.h"
[email protected]dd3fd0e2012-11-04 05:14:406
7#include <vector>
8
[email protected]5db452202014-08-19 05:22:159#include "base/base64.h"
[email protected]f21ec372014-07-02 07:15:1210#include "base/files/file_path.h"
danakjad1777e2016-04-16 00:56:4211#include "base/memory/ptr_util.h"
[email protected]4d283b32013-10-17 12:57:2712#include "base/rand_util.h"
skyostil4891b25b2015-06-11 11:43:4513#include "base/thread_task_runner_handle.h"
tbansalfdf5665b2015-09-21 22:46:4014#include "net/base/socket_performance_watcher.h"
[email protected]8ee611b2012-11-20 01:48:1215#include "net/base/test_completion_callback.h"
[email protected]f21ec372014-07-02 07:15:1216#include "net/base/test_data_directory.h"
17#include "net/cert/cert_verify_result.h"
[email protected]5db452202014-08-19 05:22:1518#include "net/http/transport_security_state.h"
vishal.b62985ca92015-04-17 08:45:5119#include "net/log/test_net_log.h"
[email protected]0bbeb6972013-05-23 04:10:2120#include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
[email protected]dd3fd0e2012-11-04 05:14:4021#include "net/quic/crypto/crypto_protocol.h"
[email protected]f21ec372014-07-02 07:15:1222#include "net/quic/crypto/proof_verifier_chromium.h"
[email protected]4df69842013-02-27 06:32:1623#include "net/quic/crypto/quic_decrypter.h"
24#include "net/quic/crypto/quic_encrypter.h"
[email protected]17bf15c2014-03-14 10:08:0425#include "net/quic/crypto/quic_server_info.h"
rch16c74d1d2016-04-22 06:14:0726#include "net/quic/quic_chromium_alarm_factory.h"
rch12fef552016-01-15 16:26:3127#include "net/quic/quic_chromium_connection_helper.h"
rcha02807b42016-01-29 21:56:1528#include "net/quic/quic_chromium_packet_reader.h"
29#include "net/quic/quic_chromium_packet_writer.h"
rch1f83eaf32016-01-06 00:27:1130#include "net/quic/quic_crypto_client_stream_factory.h"
rtennetiac06c2f2015-11-05 18:12:3531#include "net/quic/quic_flags.h"
jri7e636642016-01-14 06:57:0832#include "net/quic/quic_http_utils.h"
jri7e636642016-01-14 06:57:0833#include "net/quic/quic_packet_writer.h"
rtennetiac06c2f2015-11-05 18:12:3534#include "net/quic/quic_protocol.h"
[email protected]ed3fc15d2013-03-08 18:37:4435#include "net/quic/test_tools/crypto_test_utils.h"
jri7e636642016-01-14 06:57:0836#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
ckrasic4f9d88d2015-07-22 22:23:1637#include "net/quic/test_tools/quic_chromium_client_session_peer.h"
rtennetib865eb82015-06-17 20:21:4638#include "net/quic/test_tools/quic_spdy_session_peer.h"
jri7e636642016-01-14 06:57:0839#include "net/quic/test_tools/quic_test_packet_maker.h"
[email protected]dd3fd0e2012-11-04 05:14:4040#include "net/quic/test_tools/quic_test_utils.h"
[email protected]c58a83ec2014-04-20 22:21:5041#include "net/quic/test_tools/simple_quic_framer.h"
[email protected]4d283b32013-10-17 12:57:2742#include "net/socket/socket_test_util.h"
[email protected]5db452202014-08-19 05:22:1543#include "net/spdy/spdy_test_utils.h"
[email protected]f21ec372014-07-02 07:15:1244#include "net/test/cert_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4445#include "net/udp/datagram_client_socket.h"
[email protected]dd3fd0e2012-11-04 05:14:4046
47using testing::_;
48
49namespace net {
50namespace test {
51namespace {
52
eroman36d84e54432016-03-17 03:23:0253const IPEndPoint kIpEndPoint = IPEndPoint(IPAddress::IPv4AllZeros(), 0);
rch1fe2eeb2015-10-26 14:45:5754const char kServerHostname[] = "test.example.com";
Avi Drissman13fc8932015-12-20 04:40:4655const uint16_t kServerPort = 443;
jri7e636642016-01-14 06:57:0856const size_t kMaxReadersPerQuicSession = 5;
57
ckrasic4f9d88d2015-07-22 22:23:1658class QuicChromiumClientSessionTest
59 : public ::testing::TestWithParam<QuicVersion> {
[email protected]dd3fd0e2012-11-04 05:14:4060 protected:
ckrasic4f9d88d2015-07-22 22:23:1661 QuicChromiumClientSessionTest()
rch1fe2eeb2015-10-26 14:45:5762 : crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
jri7e636642016-01-14 06:57:0863 default_read_(new MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)),
64 socket_data_(
65 new SequencedSocketData(default_read_.get(), 1, nullptr, 0)),
66 random_(0),
rch16c74d1d2016-04-22 06:14:0767 helper_(&clock_, &random_),
68 alarm_factory_(base::ThreadTaskRunnerHandle::Get().get(), &clock_),
xunjielic70cc862016-02-19 15:29:2669 maker_(GetParam(), 0, &clock_, kServerHostname) {
70 // Advance the time, because timers do not like uninitialized times.
71 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
72 }
jri7e636642016-01-14 06:57:0873
74 void Initialize() {
75 socket_factory_.AddSocketDataProvider(socket_data_.get());
danakjad1777e2016-04-16 00:56:4276 std::unique_ptr<DatagramClientSocket> socket =
jri7e636642016-01-14 06:57:0877 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
78 base::Bind(&base::RandInt),
79 &net_log_, NetLog::Source());
80 socket->Connect(kIpEndPoint);
rcha02807b42016-01-29 21:56:1581 QuicChromiumPacketWriter* writer =
82 new net::QuicChromiumPacketWriter(socket.get());
jri7e636642016-01-14 06:57:0883 QuicConnection* connection = new QuicConnection(
rch16c74d1d2016-04-22 06:14:0784 0, kIpEndPoint, &helper_, &alarm_factory_, writer, true,
85 Perspective::IS_CLIENT, SupportedVersions(GetParam()));
jdorfman90d185f32016-01-15 13:22:4786 writer->SetConnection(connection);
jri7e636642016-01-14 06:57:0887 session_.reset(new QuicChromiumClientSession(
88 connection, std::move(socket),
89 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
danakjad1777e2016-04-16 00:56:4290 &transport_security_state_, base::WrapUnique((QuicServerInfo*)nullptr),
jri7e636642016-01-14 06:57:0891 QuicServerId(kServerHostname, kServerPort, PRIVACY_MODE_DISABLED),
92 kQuicYieldAfterPacketsRead,
93 QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
94 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
ckrasic244375a32016-02-04 21:21:2295 "CONNECTION_UNKNOWN", base::TimeTicks::Now(), &push_promise_index_,
jri7e636642016-01-14 06:57:0896 base::ThreadTaskRunnerHandle::Get().get(),
97 /*socket_performance_watcher=*/nullptr, &net_log_));
98
99 scoped_refptr<X509Certificate> cert(
100 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
101 verify_details_.cert_verify_result.verified_cert = cert;
102 verify_details_.cert_verify_result.is_issued_by_known_root = true;
jri7e636642016-01-14 06:57:08103 session_->Initialize();
104 session_->StartReading();
[email protected]dd3fd0e2012-11-04 05:14:40105 }
106
rtenneti85dcfac22015-03-27 20:22:19107 void TearDown() override {
jri7e636642016-01-14 06:57:08108 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
[email protected]4d283b32013-10-17 12:57:27109 }
110
[email protected]ed3fc15d2013-03-08 18:37:44111 void CompleteCryptoHandshake() {
jri7e636642016-01-14 06:57:08112 ASSERT_EQ(OK, session_->CryptoConnect(false, callback_.callback()));
[email protected]ed3fc15d2013-03-08 18:37:44113 }
114
jri7e636642016-01-14 06:57:08115 QuicPacketWriter* CreateQuicPacketWriter(DatagramClientSocket* socket,
116 QuicConnection* connection) const {
danakjad1777e2016-04-16 00:56:42117 std::unique_ptr<QuicChromiumPacketWriter> writer(
rcha02807b42016-01-29 21:56:15118 new QuicChromiumPacketWriter(socket));
jri7e636642016-01-14 06:57:08119 writer->SetConnection(connection);
120 return writer.release();
121 }
122
rch1fe2eeb2015-10-26 14:45:57123 QuicCryptoClientConfig crypto_config_;
vishal.b62985ca92015-04-17 08:45:51124 TestNetLog net_log_;
jri7e636642016-01-14 06:57:08125 BoundTestNetLog bound_net_log_;
[email protected]4d283b32013-10-17 12:57:27126 MockClientSocketFactory socket_factory_;
danakjad1777e2016-04-16 00:56:42127 std::unique_ptr<MockRead> default_read_;
128 std::unique_ptr<SequencedSocketData> socket_data_;
[email protected]ed3fc15d2013-03-08 18:37:44129 MockClock clock_;
130 MockRandom random_;
rch12fef552016-01-15 16:26:31131 QuicChromiumConnectionHelper helper_;
rch16c74d1d2016-04-22 06:14:07132 QuicChromiumAlarmFactory alarm_factory_;
jri7e636642016-01-14 06:57:08133 TransportSecurityState transport_security_state_;
134 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42135 std::unique_ptr<QuicChromiumClientSession> session_;
[email protected]dd3fd0e2012-11-04 05:14:40136 QuicConnectionVisitorInterface* visitor_;
[email protected]8ee611b2012-11-20 01:48:12137 TestCompletionCallback callback_;
jri7e636642016-01-14 06:57:08138 QuicTestPacketMaker maker_;
139 ProofVerifyDetailsChromium verify_details_;
ckrasic244375a32016-02-04 21:21:22140 QuicClientPushPromiseIndex push_promise_index_;
[email protected]dd3fd0e2012-11-04 05:14:40141};
142
ckrasic4f9d88d2015-07-22 22:23:16143INSTANTIATE_TEST_CASE_P(Tests,
144 QuicChromiumClientSessionTest,
[email protected]4d640792013-12-18 22:21:08145 ::testing::ValuesIn(QuicSupportedVersions()));
146
ckrasic4f9d88d2015-07-22 22:23:16147TEST_P(QuicChromiumClientSessionTest, CryptoConnect) {
jri7e636642016-01-14 06:57:08148 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44149 CompleteCryptoHandshake();
[email protected]8ee611b2012-11-20 01:48:12150}
151
ckrasic4f9d88d2015-07-22 22:23:16152TEST_P(QuicChromiumClientSessionTest, MaxNumStreams) {
jri7e636642016-01-14 06:57:08153 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
danakjad1777e2016-04-16 00:56:42154 std::unique_ptr<QuicEncryptedPacket> client_rst(maker_.MakeRstPacket(
jri7e636642016-01-14 06:57:08155 1, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT));
156 MockWrite writes[] = {
157 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 1)};
158 socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes,
159 arraysize(writes)));
160
161 Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44162 CompleteCryptoHandshake();
rtenneti9f41c0a2016-02-02 23:59:30163 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
[email protected]dd3fd0e2012-11-04 05:14:40164
rch12fef552016-01-15 16:26:31165 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:08166 for (size_t i = 0; i < kMaxOpenStreams; i++) {
rch12fef552016-01-15 16:26:31167 QuicChromiumClientStream* stream =
jri7e636642016-01-14 06:57:08168 session_->CreateOutgoingDynamicStream(kDefaultPriority);
[email protected]dd3fd0e2012-11-04 05:14:40169 EXPECT_TRUE(stream);
[email protected]f702d572012-12-04 15:56:20170 streams.push_back(stream);
[email protected]dd3fd0e2012-11-04 05:14:40171 }
jri7e636642016-01-14 06:57:08172 EXPECT_FALSE(session_->CreateOutgoingDynamicStream(kDefaultPriority));
[email protected]dd3fd0e2012-11-04 05:14:40173
jri7e636642016-01-14 06:57:08174 EXPECT_EQ(kMaxOpenStreams, session_->GetNumOpenOutgoingStreams());
rtennetiac06c2f2015-11-05 18:12:35175
[email protected]dd3fd0e2012-11-04 05:14:40176 // Close a stream and ensure I can now open a new one.
rtennetiac06c2f2015-11-05 18:12:35177 QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:08178 session_->CloseStream(stream_id);
rtennetiac06c2f2015-11-05 18:12:35179
jri7e636642016-01-14 06:57:08180 EXPECT_FALSE(session_->CreateOutgoingDynamicStream(kDefaultPriority));
rtennetiac06c2f2015-11-05 18:12:35181 QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:08182 session_->OnRstStream(rst1);
183 EXPECT_EQ(kMaxOpenStreams - 1, session_->GetNumOpenOutgoingStreams());
184 EXPECT_TRUE(session_->CreateOutgoingDynamicStream(kDefaultPriority));
[email protected]dd3fd0e2012-11-04 05:14:40185}
186
ckrasic4f9d88d2015-07-22 22:23:16187TEST_P(QuicChromiumClientSessionTest, MaxNumStreamsViaRequest) {
jri7e636642016-01-14 06:57:08188 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
danakjad1777e2016-04-16 00:56:42189 std::unique_ptr<QuicEncryptedPacket> client_rst(maker_.MakeRstPacket(
jri7e636642016-01-14 06:57:08190 1, true, kClientDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT));
191 MockWrite writes[] = {
192 MockWrite(ASYNC, client_rst->data(), client_rst->length(), 1)};
193 socket_data_.reset(new SequencedSocketData(reads, arraysize(reads), writes,
194 arraysize(writes)));
195
196 Initialize();
[email protected]0b2294d32013-08-02 00:46:36197 CompleteCryptoHandshake();
rtenneti9f41c0a2016-02-02 23:59:30198 const size_t kMaxOpenStreams = session_->max_open_outgoing_streams();
[email protected]0b2294d32013-08-02 00:46:36199
rch12fef552016-01-15 16:26:31200 std::vector<QuicChromiumClientStream*> streams;
jri7e636642016-01-14 06:57:08201 for (size_t i = 0; i < kMaxOpenStreams; i++) {
rch12fef552016-01-15 16:26:31202 QuicChromiumClientStream* stream =
jri7e636642016-01-14 06:57:08203 session_->CreateOutgoingDynamicStream(kDefaultPriority);
[email protected]0b2294d32013-08-02 00:46:36204 EXPECT_TRUE(stream);
205 streams.push_back(stream);
206 }
207
rch12fef552016-01-15 16:26:31208 QuicChromiumClientStream* stream;
ckrasic4f9d88d2015-07-22 22:23:16209 QuicChromiumClientSession::StreamRequest stream_request;
[email protected]0b2294d32013-08-02 00:46:36210 TestCompletionCallback callback;
211 ASSERT_EQ(ERR_IO_PENDING,
jri7e636642016-01-14 06:57:08212 stream_request.StartRequest(session_->GetWeakPtr(), &stream,
[email protected]0b2294d32013-08-02 00:46:36213 callback.callback()));
214
215 // Close a stream and ensure I can now open a new one.
rtennetiac06c2f2015-11-05 18:12:35216 QuicStreamId stream_id = streams[0]->id();
jri7e636642016-01-14 06:57:08217 session_->CloseStream(stream_id);
rtennetiac06c2f2015-11-05 18:12:35218 QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0);
jri7e636642016-01-14 06:57:08219 session_->OnRstStream(rst1);
[email protected]0b2294d32013-08-02 00:46:36220 ASSERT_TRUE(callback.have_result());
221 EXPECT_EQ(OK, callback.WaitForResult());
rtennetibe635732014-10-02 22:51:42222 EXPECT_TRUE(stream != nullptr);
[email protected]0b2294d32013-08-02 00:46:36223}
224
ckrasic4f9d88d2015-07-22 22:23:16225TEST_P(QuicChromiumClientSessionTest, GoAwayReceived) {
jri7e636642016-01-14 06:57:08226 Initialize();
[email protected]8ba81212013-05-03 13:11:48227 CompleteCryptoHandshake();
[email protected]9db443912013-02-25 05:27:03228
229 // After receiving a GoAway, I should no longer be able to create outgoing
230 // streams.
jri7e636642016-01-14 06:57:08231 session_->connection()->OnGoAwayFrame(
rtenneti9bd5d4b2015-08-21 05:44:52232 QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away."));
jri7e636642016-01-14 06:57:08233 EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream(kDefaultPriority));
[email protected]9db443912013-02-25 05:27:03234}
235
ckrasic4f9d88d2015-07-22 22:23:16236TEST_P(QuicChromiumClientSessionTest, CanPool) {
jri7e636642016-01-14 06:57:08237 Initialize();
[email protected]f21ec372014-07-02 07:15:12238 // Load a cert that is valid for:
239 // www.example.org
240 // mail.example.org
241 // www.example.com
[email protected]f21ec372014-07-02 07:15:12242
[email protected]f21ec372014-07-02 07:15:12243 ProofVerifyDetailsChromium details;
244 details.cert_verify_result.verified_cert =
[email protected]5db452202014-08-19 05:22:15245 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
dcheng4227c6d2014-08-25 23:58:18246 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]f21ec372014-07-02 07:15:12247
[email protected]f21ec372014-07-02 07:15:12248 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:08249 session_->OnProofVerifyDetailsAvailable(details);
[email protected]f21ec372014-07-02 07:15:12250
jri7e636642016-01-14 06:57:08251 EXPECT_TRUE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED));
252 EXPECT_FALSE(session_->CanPool("www.example.org", PRIVACY_MODE_ENABLED));
253 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
254 EXPECT_TRUE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED));
255 EXPECT_FALSE(session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED));
[email protected]f21ec372014-07-02 07:15:12256}
257
ckrasic4f9d88d2015-07-22 22:23:16258TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithTlsChannelId) {
jri7e636642016-01-14 06:57:08259 Initialize();
[email protected]f21ec372014-07-02 07:15:12260 // Load a cert that is valid for:
261 // www.example.org
262 // mail.example.org
263 // www.example.com
[email protected]f21ec372014-07-02 07:15:12264
[email protected]f21ec372014-07-02 07:15:12265 ProofVerifyDetailsChromium details;
266 details.cert_verify_result.verified_cert =
[email protected]5db452202014-08-19 05:22:15267 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
dcheng4227c6d2014-08-25 23:58:18268 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]f21ec372014-07-02 07:15:12269
[email protected]f21ec372014-07-02 07:15:12270 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:08271 session_->OnProofVerifyDetailsAvailable(details);
272 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
273 QuicChromiumClientSessionPeer::SetChannelIDSent(session_.get(), true);
[email protected]f21ec372014-07-02 07:15:12274
jri7e636642016-01-14 06:57:08275 EXPECT_TRUE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED));
276 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
277 EXPECT_FALSE(session_->CanPool("mail.example.com", PRIVACY_MODE_DISABLED));
278 EXPECT_FALSE(session_->CanPool("mail.google.com", PRIVACY_MODE_DISABLED));
[email protected]f21ec372014-07-02 07:15:12279}
280
ckrasic4f9d88d2015-07-22 22:23:16281TEST_P(QuicChromiumClientSessionTest, ConnectionNotPooledWithDifferentPin) {
jri7e636642016-01-14 06:57:08282 Initialize();
283
Avi Drissman13fc8932015-12-20 04:40:46284 uint8_t primary_pin = 1;
285 uint8_t backup_pin = 2;
286 uint8_t bad_pin = 3;
[email protected]5db452202014-08-19 05:22:15287 AddPin(&transport_security_state_, "mail.example.org", primary_pin,
288 backup_pin);
289
290 ProofVerifyDetailsChromium details;
291 details.cert_verify_result.verified_cert =
292 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
293 details.cert_verify_result.is_issued_by_known_root = true;
294 details.cert_verify_result.public_key_hashes.push_back(
295 GetTestHashValue(bad_pin));
296
dcheng4227c6d2014-08-25 23:58:18297 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:15298
[email protected]5db452202014-08-19 05:22:15299 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:08300 session_->OnProofVerifyDetailsAvailable(details);
301 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
302 QuicChromiumClientSessionPeer::SetChannelIDSent(session_.get(), true);
[email protected]5db452202014-08-19 05:22:15303
jri7e636642016-01-14 06:57:08304 EXPECT_FALSE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
[email protected]5db452202014-08-19 05:22:15305}
306
ckrasic4f9d88d2015-07-22 22:23:16307TEST_P(QuicChromiumClientSessionTest, ConnectionPooledWithMatchingPin) {
jri7e636642016-01-14 06:57:08308 Initialize();
309
Avi Drissman13fc8932015-12-20 04:40:46310 uint8_t primary_pin = 1;
311 uint8_t backup_pin = 2;
[email protected]5db452202014-08-19 05:22:15312 AddPin(&transport_security_state_, "mail.example.org", primary_pin,
313 backup_pin);
314
315 ProofVerifyDetailsChromium details;
316 details.cert_verify_result.verified_cert =
317 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
318 details.cert_verify_result.is_issued_by_known_root = true;
319 details.cert_verify_result.public_key_hashes.push_back(
320 GetTestHashValue(primary_pin));
321
dcheng4227c6d2014-08-25 23:58:18322 ASSERT_TRUE(details.cert_verify_result.verified_cert.get());
[email protected]5db452202014-08-19 05:22:15323
[email protected]5db452202014-08-19 05:22:15324 CompleteCryptoHandshake();
jri7e636642016-01-14 06:57:08325 session_->OnProofVerifyDetailsAvailable(details);
326 QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
327 QuicChromiumClientSessionPeer::SetChannelIDSent(session_.get(), true);
[email protected]5db452202014-08-19 05:22:15328
jri7e636642016-01-14 06:57:08329 EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
330}
331
332TEST_P(QuicChromiumClientSessionTest, MigrateToSocket) {
333 Initialize();
334 CompleteCryptoHandshake();
335
336 char data[] = "ABCD";
danakjad1777e2016-04-16 00:56:42337 std::unique_ptr<QuicEncryptedPacket> ping(
jri7e636642016-01-14 06:57:08338 maker_.MakePingPacket(1, /*include_version=*/false));
danakjad1777e2016-04-16 00:56:42339 std::unique_ptr<QuicEncryptedPacket> ack_and_data_out(
340 maker_.MakeAckAndDataPacket(2, false, 5, 1, 1, false, 0,
341 StringPiece(data)));
jri7e636642016-01-14 06:57:08342 MockRead reads[] = {MockRead(SYNCHRONOUS, ping->data(), ping->length(), 0),
343 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
344 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ping->data(), ping->length(), 2),
345 MockWrite(SYNCHRONOUS, ack_and_data_out->data(),
346 ack_and_data_out->length(), 3)};
347 StaticSocketDataProvider socket_data(reads, arraysize(reads), writes,
348 arraysize(writes));
349 socket_factory_.AddSocketDataProvider(&socket_data);
350
351 // Create connected socket.
danakjad1777e2016-04-16 00:56:42352 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:08353 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
354 base::Bind(&base::RandInt),
355 &net_log_, NetLog::Source());
356 EXPECT_EQ(OK, new_socket->Connect(kIpEndPoint));
357
358 // Create reader and writer.
danakjad1777e2016-04-16 00:56:42359 std::unique_ptr<QuicChromiumPacketReader> new_reader(
360 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
361 kQuicYieldAfterPacketsRead,
362 QuicTime::Delta::FromMilliseconds(
363 kQuicYieldAfterDurationMilliseconds),
364 bound_net_log_.bound()));
365 std::unique_ptr<QuicPacketWriter> new_writer(
jri7e636642016-01-14 06:57:08366 CreateQuicPacketWriter(new_socket.get(), session_->connection()));
367
368 // Migrate session.
369 EXPECT_TRUE(session_->MigrateToSocket(
370 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
371
372 // Write data to session.
373 struct iovec iov[1];
374 iov[0].iov_base = data;
375 iov[0].iov_len = 4;
376 session_->WritevData(5, QuicIOVector(iov, arraysize(iov), 4), 0, false,
rjshaded069aaee2016-03-11 20:42:17377 nullptr);
jri7e636642016-01-14 06:57:08378
379 EXPECT_TRUE(socket_data.AllReadDataConsumed());
380 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
381}
382
383TEST_P(QuicChromiumClientSessionTest, MigrateToSocketMaxReaders) {
384 Initialize();
385 CompleteCryptoHandshake();
386
387 for (size_t i = 0; i < kMaxReadersPerQuicSession; ++i) {
388 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 1)};
danakjad1777e2016-04-16 00:56:42389 std::unique_ptr<QuicEncryptedPacket> ping_out(
jri7e636642016-01-14 06:57:08390 maker_.MakePingPacket(i + 1, /*include_version=*/true));
391 MockWrite writes[] = {
392 MockWrite(SYNCHRONOUS, ping_out->data(), ping_out->length(), i + 2)};
393 StaticSocketDataProvider socket_data(reads, arraysize(reads), writes,
394 arraysize(writes));
395 socket_factory_.AddSocketDataProvider(&socket_data);
396
397 // Create connected socket.
danakjad1777e2016-04-16 00:56:42398 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:08399 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
400 base::Bind(&base::RandInt),
401 &net_log_, NetLog::Source());
402 EXPECT_EQ(OK, new_socket->Connect(kIpEndPoint));
403
404 // Create reader and writer.
danakjad1777e2016-04-16 00:56:42405 std::unique_ptr<QuicChromiumPacketReader> new_reader(
rcha02807b42016-01-29 21:56:15406 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
407 kQuicYieldAfterPacketsRead,
408 QuicTime::Delta::FromMilliseconds(
409 kQuicYieldAfterDurationMilliseconds),
410 bound_net_log_.bound()));
danakjad1777e2016-04-16 00:56:42411 std::unique_ptr<QuicPacketWriter> new_writer(
jri7e636642016-01-14 06:57:08412 CreateQuicPacketWriter(new_socket.get(), session_->connection()));
413
414 // Migrate session.
415 if (i < kMaxReadersPerQuicSession - 1) {
416 EXPECT_TRUE(session_->MigrateToSocket(
417 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
418 EXPECT_TRUE(socket_data.AllReadDataConsumed());
419 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
420 } else {
421 // Max readers exceeded.
422 EXPECT_FALSE(session_->MigrateToSocket(
423 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
424
425 EXPECT_FALSE(socket_data.AllReadDataConsumed());
426 EXPECT_FALSE(socket_data.AllWriteDataConsumed());
427 }
428 }
429}
430
431TEST_P(QuicChromiumClientSessionTest, MigrateToSocketReadError) {
danakjad1777e2016-04-16 00:56:42432 std::unique_ptr<QuicEncryptedPacket> ping(
jri7e636642016-01-14 06:57:08433 maker_.MakePingPacket(1, /*include_version=*/true));
434 MockRead old_reads[] = {
435 MockRead(SYNCHRONOUS, ping->data(), ping->length(), 0),
436 MockRead(ASYNC, ERR_IO_PENDING, 1), // causes reading to pause.
437 MockRead(ASYNC, ERR_NETWORK_CHANGED, 2)};
438 socket_data_.reset(
439 new SequencedSocketData(old_reads, arraysize(old_reads), nullptr, 0));
440 Initialize();
441 CompleteCryptoHandshake();
442
443 MockWrite writes[] = {
444 MockWrite(SYNCHRONOUS, ping->data(), ping->length(), 1)};
445 MockRead new_reads[] = {
446 MockRead(SYNCHRONOUS, ping->data(), ping->length(), 0),
447 MockRead(ASYNC, ERR_IO_PENDING, 2), // pause reading.
448 MockRead(ASYNC, ping->data(), ping->length(), 3),
449 MockRead(ASYNC, ERR_IO_PENDING, 4), // pause reading
450 MockRead(ASYNC, ERR_NETWORK_CHANGED, 5)};
451 SequencedSocketData new_socket_data(new_reads, arraysize(new_reads), writes,
452 arraysize(writes));
453 socket_factory_.AddSocketDataProvider(&new_socket_data);
454
455 // Create connected socket.
danakjad1777e2016-04-16 00:56:42456 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:08457 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
458 base::Bind(&base::RandInt),
459 &net_log_, NetLog::Source());
460 EXPECT_EQ(OK, new_socket->Connect(kIpEndPoint));
461
462 // Create reader and writer.
danakjad1777e2016-04-16 00:56:42463 std::unique_ptr<QuicChromiumPacketReader> new_reader(
464 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
465 kQuicYieldAfterPacketsRead,
466 QuicTime::Delta::FromMilliseconds(
467 kQuicYieldAfterDurationMilliseconds),
468 bound_net_log_.bound()));
469 std::unique_ptr<QuicPacketWriter> new_writer(
jri7e636642016-01-14 06:57:08470 CreateQuicPacketWriter(new_socket.get(), session_->connection()));
471
472 // Store old socket and migrate session.
473 EXPECT_TRUE(session_->MigrateToSocket(
474 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
475
476 // Read error on old socket does not impact session.
477 EXPECT_TRUE(socket_data_->IsPaused());
478 socket_data_->Resume();
479 EXPECT_TRUE(session_->connection()->connected());
480 EXPECT_TRUE(new_socket_data.IsPaused());
481 new_socket_data.Resume();
482
483 // Read error on new socket causes session close.
484 EXPECT_TRUE(new_socket_data.IsPaused());
485 EXPECT_TRUE(session_->connection()->connected());
486 new_socket_data.Resume();
487 EXPECT_FALSE(session_->connection()->connected());
488
489 EXPECT_TRUE(socket_data_->AllReadDataConsumed());
490 EXPECT_TRUE(socket_data_->AllWriteDataConsumed());
491 EXPECT_TRUE(new_socket_data.AllReadDataConsumed());
492 EXPECT_TRUE(new_socket_data.AllWriteDataConsumed());
493}
494
495TEST_P(QuicChromiumClientSessionTest, MigrateToSocketWriteError) {
496 Initialize();
497 CompleteCryptoHandshake();
498
danakjad1777e2016-04-16 00:56:42499 std::unique_ptr<QuicEncryptedPacket> ping(
jri7e636642016-01-14 06:57:08500 maker_.MakePingPacket(1, /*include_version=*/true));
501 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
502 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ping->data(), ping->length(), 1),
503 MockWrite(SYNCHRONOUS, ERR_FAILED, 2)};
504 SequencedSocketData socket_data(reads, arraysize(reads), writes,
505 arraysize(writes));
506 socket_factory_.AddSocketDataProvider(&socket_data);
507
508 // Create connected socket.
danakjad1777e2016-04-16 00:56:42509 std::unique_ptr<DatagramClientSocket> new_socket =
jri7e636642016-01-14 06:57:08510 socket_factory_.CreateDatagramClientSocket(DatagramSocket::DEFAULT_BIND,
511 base::Bind(&base::RandInt),
512 &net_log_, NetLog::Source());
513 EXPECT_EQ(OK, new_socket->Connect(kIpEndPoint));
514
515 // Create reader and writer.
danakjad1777e2016-04-16 00:56:42516 std::unique_ptr<QuicChromiumPacketReader> new_reader(
517 new QuicChromiumPacketReader(new_socket.get(), &clock_, session_.get(),
518 kQuicYieldAfterPacketsRead,
519 QuicTime::Delta::FromMilliseconds(
520 kQuicYieldAfterDurationMilliseconds),
521 bound_net_log_.bound()));
522 std::unique_ptr<QuicPacketWriter> new_writer(
jri7e636642016-01-14 06:57:08523 CreateQuicPacketWriter(new_socket.get(), session_->connection()));
524
525 // Migrate session.
526 EXPECT_TRUE(session_->MigrateToSocket(
527 std::move(new_socket), std::move(new_reader), std::move(new_writer)));
528
529 // Write error on new socket causes session close.
530 EXPECT_TRUE(session_->connection()->connected());
531 session_->connection()->SendPing();
532 EXPECT_FALSE(session_->connection()->connected());
533
534 EXPECT_TRUE(socket_data.AllReadDataConsumed());
535 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:15536}
537
[email protected]dd3fd0e2012-11-04 05:14:40538} // namespace
539} // namespace test
540} // namespace net