blob: f5933d2fd896dcb438fc09d84b88d781c860f6ac [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
6
7#include <cstdint>
8#include <memory>
vasilvv872e7a32019-03-12 16:42:44 -07009#include <string>
bnc463f2352019-10-10 04:49:34 -070010#include <utility>
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include <vector>
12
QUICHE teama6ef0a62019-03-07 20:34:33 -050013#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
14#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
15#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
16#include "net/third_party/quiche/src/quic/core/quic_utils.h"
17#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050018#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
19#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
20#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
21#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
22
23using testing::_;
24using testing::InSequence;
25using testing::Invoke;
26using testing::InvokeWithoutArgs;
fayangaee31ef2019-08-20 06:47:51 -070027using testing::Return;
QUICHE teama6ef0a62019-03-07 20:34:33 -050028
29namespace quic {
30namespace test {
31namespace {
32
33class MockQuicCryptoStream : public QuicCryptoStream,
34 public QuicCryptoHandshaker {
35 public:
36 explicit MockQuicCryptoStream(QuicSession* session)
37 : QuicCryptoStream(session),
38 QuicCryptoHandshaker(this, session),
39 params_(new QuicCryptoNegotiatedParameters) {}
40 MockQuicCryptoStream(const MockQuicCryptoStream&) = delete;
41 MockQuicCryptoStream& operator=(const MockQuicCryptoStream&) = delete;
42
43 void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
44 messages_.push_back(message);
45 }
46
47 std::vector<CryptoHandshakeMessage>* messages() { return &messages_; }
48
49 bool encryption_established() const override { return false; }
50 bool handshake_confirmed() const override { return false; }
51
52 const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
53 const override {
54 return *params_;
55 }
56 CryptoMessageParser* crypto_message_parser() override {
57 return QuicCryptoHandshaker::crypto_message_parser();
58 }
59
60 private:
61 QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
62 std::vector<CryptoHandshakeMessage> messages_;
63};
64
65class QuicCryptoStreamTest : public QuicTest {
66 public:
67 QuicCryptoStreamTest()
68 : connection_(new MockQuicConnection(&helper_,
69 &alarm_factory_,
70 Perspective::IS_CLIENT)),
71 session_(connection_, /*create_mock_crypto_stream=*/false) {
72 stream_ = new MockQuicCryptoStream(&session_);
73 session_.SetCryptoStream(stream_);
74 session_.Initialize();
75 message_.set_tag(kSHLO);
76 message_.SetStringPiece(1, "abc");
77 message_.SetStringPiece(2, "def");
78 ConstructHandshakeMessage();
79 }
80 QuicCryptoStreamTest(const QuicCryptoStreamTest&) = delete;
81 QuicCryptoStreamTest& operator=(const QuicCryptoStreamTest&) = delete;
82
83 void ConstructHandshakeMessage() {
84 CryptoFramer framer;
QUICHE team3fe6a8b2019-03-14 09:10:38 -070085 message_data_ = framer.ConstructHandshakeMessage(message_);
QUICHE teama6ef0a62019-03-07 20:34:33 -050086 }
87
88 protected:
89 MockQuicConnectionHelper helper_;
90 MockAlarmFactory alarm_factory_;
91 MockQuicConnection* connection_;
92 MockQuicSpdySession session_;
93 MockQuicCryptoStream* stream_;
94 CryptoHandshakeMessage message_;
95 std::unique_ptr<QuicData> message_data_;
96};
97
98TEST_F(QuicCryptoStreamTest, NotInitiallyConected) {
99 EXPECT_FALSE(stream_->encryption_established());
100 EXPECT_FALSE(stream_->handshake_confirmed());
101}
102
103TEST_F(QuicCryptoStreamTest, ProcessRawData) {
QUICHE teamea740082019-03-11 17:58:43 -0700104 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500105 stream_->OnStreamFrame(QuicStreamFrame(
106 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
107 /*fin=*/false,
108 /*offset=*/0, message_data_->AsStringPiece()));
109 } else {
QUICHE team6987b4a2019-03-15 16:23:04 -0700110 stream_->OnCryptoFrame(QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500111 message_data_->AsStringPiece()));
112 }
113 ASSERT_EQ(1u, stream_->messages()->size());
114 const CryptoHandshakeMessage& message = (*stream_->messages())[0];
115 EXPECT_EQ(kSHLO, message.tag());
116 EXPECT_EQ(2u, message.tag_value_map().size());
117 EXPECT_EQ("abc", crypto_test_utils::GetValueForTag(message, 1));
118 EXPECT_EQ("def", crypto_test_utils::GetValueForTag(message, 2));
119}
120
121TEST_F(QuicCryptoStreamTest, ProcessBadData) {
vasilvvc48c8712019-03-11 13:38:16 -0700122 std::string bad(message_data_->data(), message_data_->length());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500123 const int kFirstTagIndex = sizeof(uint32_t) + // message tag
124 sizeof(uint16_t) + // number of tag-value pairs
125 sizeof(uint16_t); // padding
126 EXPECT_EQ(1, bad[kFirstTagIndex]);
127 bad[kFirstTagIndex] = 0x7F; // out of order tag
128
129 EXPECT_CALL(*connection_, CloseConnection(QUIC_CRYPTO_TAGS_OUT_OF_ORDER,
130 testing::_, testing::_));
QUICHE teamea740082019-03-11 17:58:43 -0700131 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500132 stream_->OnStreamFrame(QuicStreamFrame(
133 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
134 /*fin=*/false, /*offset=*/0, bad));
135 } else {
QUICHE team6987b4a2019-03-15 16:23:04 -0700136 stream_->OnCryptoFrame(
137 QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0, bad));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500138 }
139}
140
141TEST_F(QuicCryptoStreamTest, NoConnectionLevelFlowControl) {
142 EXPECT_FALSE(
143 QuicStreamPeer::StreamContributesToConnectionFlowControl(stream_));
144}
145
146TEST_F(QuicCryptoStreamTest, RetransmitCryptoData) {
QUICHE teamea740082019-03-11 17:58:43 -0700147 if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500148 return;
149 }
150 InSequence s;
QUICHE team6987b4a2019-03-15 16:23:04 -0700151 // Send [0, 1350) in ENCRYPTION_INITIAL.
152 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700153 std::string data(1350, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500154 EXPECT_CALL(
155 session_,
156 WritevData(_,
157 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
158 1350, 0, _))
159 .WillOnce(Invoke(MockQuicSession::ConsumeData));
160 stream_->WriteOrBufferData(data, false, nullptr);
161 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
162 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
163 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
164 EXPECT_CALL(
165 session_,
166 WritevData(_,
167 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
168 1350, 1350, _))
169 .WillOnce(Invoke(MockQuicSession::ConsumeData));
170 stream_->WriteOrBufferData(data, false, nullptr);
171 connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
172 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
173
174 // Lost [0, 1000).
175 stream_->OnStreamFrameLost(0, 1000, false);
176 EXPECT_TRUE(stream_->HasPendingRetransmission());
177 // Lost [1200, 2000).
178 stream_->OnStreamFrameLost(1200, 800, false);
179 EXPECT_CALL(
180 session_,
181 WritevData(_,
182 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
183 1000, 0, _))
184 .WillOnce(Invoke(MockQuicSession::ConsumeData));
185 // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
186 // they are in different encryption levels.
187 EXPECT_CALL(
188 session_,
189 WritevData(_,
190 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
191 150, 1200, _))
192 .WillOnce(Invoke(MockQuicSession::ConsumeData));
193 EXPECT_CALL(
194 session_,
195 WritevData(_,
196 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
197 650, 1350, _))
198 .WillOnce(Invoke(MockQuicSession::ConsumeData));
199 stream_->OnCanWrite();
200 EXPECT_FALSE(stream_->HasPendingRetransmission());
201 // Verify connection's encryption level has restored.
202 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
203}
204
205TEST_F(QuicCryptoStreamTest, RetransmitCryptoDataInCryptoFrames) {
QUICHE teamea740082019-03-11 17:58:43 -0700206 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500207 return;
208 }
209 EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
210 InSequence s;
QUICHE team6987b4a2019-03-15 16:23:04 -0700211 // Send [0, 1350) in ENCRYPTION_INITIAL.
212 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700213 std::string data(1350, 'a');
QUICHE team6987b4a2019-03-15 16:23:04 -0700214 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500215 .WillOnce(Invoke(connection_,
216 &MockQuicConnection::QuicConnection_SendCryptoData));
QUICHE team6987b4a2019-03-15 16:23:04 -0700217 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500218 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
219 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
220 std::unique_ptr<NullEncrypter> encrypter =
vasilvv0fc587f2019-09-06 13:33:08 -0700221 std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500222 connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
223 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
224 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
225 .WillOnce(Invoke(connection_,
226 &MockQuicConnection::QuicConnection_SendCryptoData));
227 stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
228 connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
229 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
230
231 // Lost [0, 1000).
QUICHE team6987b4a2019-03-15 16:23:04 -0700232 QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500233 stream_->OnCryptoFrameLost(&lost_frame);
234 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
235 // Lost [1200, 2000).
QUICHE team6987b4a2019-03-15 16:23:04 -0700236 lost_frame = QuicCryptoFrame(ENCRYPTION_INITIAL, 1200, 150);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500237 stream_->OnCryptoFrameLost(&lost_frame);
238 lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
239 stream_->OnCryptoFrameLost(&lost_frame);
QUICHE team6987b4a2019-03-15 16:23:04 -0700240 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500241 .WillOnce(Invoke(connection_,
242 &MockQuicConnection::QuicConnection_SendCryptoData));
243 // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
244 // they are in different encryption levels.
QUICHE team6987b4a2019-03-15 16:23:04 -0700245 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 150, 1200))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500246 .WillOnce(Invoke(connection_,
247 &MockQuicConnection::QuicConnection_SendCryptoData));
248 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
249 .WillOnce(Invoke(connection_,
250 &MockQuicConnection::QuicConnection_SendCryptoData));
251 stream_->WritePendingCryptoRetransmission();
252 EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
253 // Verify connection's encryption level has restored.
254 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
255}
256
257TEST_F(QuicCryptoStreamTest, NeuterUnencryptedStreamData) {
QUICHE teamea740082019-03-11 17:58:43 -0700258 if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500259 return;
260 }
QUICHE team6987b4a2019-03-15 16:23:04 -0700261 // Send [0, 1350) in ENCRYPTION_INITIAL.
262 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700263 std::string data(1350, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500264 EXPECT_CALL(
265 session_,
266 WritevData(_,
267 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
268 1350, 0, _))
269 .WillOnce(Invoke(MockQuicSession::ConsumeData));
270 stream_->WriteOrBufferData(data, false, nullptr);
271 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
272 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
273 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
274 EXPECT_CALL(
275 session_,
276 WritevData(_,
277 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
278 1350, 1350, _))
279 .WillOnce(Invoke(MockQuicSession::ConsumeData));
280 stream_->WriteOrBufferData(data, false, nullptr);
281
282 // Lost [0, 1350).
283 stream_->OnStreamFrameLost(0, 1350, false);
284 EXPECT_TRUE(stream_->HasPendingRetransmission());
285 // Neuters [0, 1350).
286 stream_->NeuterUnencryptedStreamData();
287 EXPECT_FALSE(stream_->HasPendingRetransmission());
288 // Lost [0, 1350) again.
289 stream_->OnStreamFrameLost(0, 1350, false);
290 EXPECT_FALSE(stream_->HasPendingRetransmission());
291
292 // Lost [1350, 2000).
293 stream_->OnStreamFrameLost(1350, 650, false);
294 EXPECT_TRUE(stream_->HasPendingRetransmission());
295 stream_->NeuterUnencryptedStreamData();
296 EXPECT_TRUE(stream_->HasPendingRetransmission());
297}
298
299TEST_F(QuicCryptoStreamTest, NeuterUnencryptedCryptoData) {
QUICHE teamea740082019-03-11 17:58:43 -0700300 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500301 return;
302 }
QUICHE team6987b4a2019-03-15 16:23:04 -0700303 // Send [0, 1350) in ENCRYPTION_INITIAL.
304 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700305 std::string data(1350, 'a');
QUICHE team6987b4a2019-03-15 16:23:04 -0700306 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500307 .WillOnce(Invoke(connection_,
308 &MockQuicConnection::QuicConnection_SendCryptoData));
QUICHE team6987b4a2019-03-15 16:23:04 -0700309 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500310 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
311 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
312 std::unique_ptr<NullEncrypter> encrypter =
vasilvv0fc587f2019-09-06 13:33:08 -0700313 std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500314 connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
315 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
316 EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
317 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
318 .WillOnce(Invoke(connection_,
319 &MockQuicConnection::QuicConnection_SendCryptoData));
320 stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
321
322 // Lost [0, 1350).
QUICHE team6987b4a2019-03-15 16:23:04 -0700323 QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1350);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500324 stream_->OnCryptoFrameLost(&lost_frame);
325 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
326 // Neuters [0, 1350).
327 stream_->NeuterUnencryptedStreamData();
328 EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
329 // Lost [0, 1350) again.
330 stream_->OnCryptoFrameLost(&lost_frame);
331 EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
332
333 // Lost [1350, 2000), which starts at offset 0 at the ENCRYPTION_ZERO_RTT
334 // level.
335 lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
336 stream_->OnCryptoFrameLost(&lost_frame);
337 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
338 stream_->NeuterUnencryptedStreamData();
339 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
340}
341
342TEST_F(QuicCryptoStreamTest, RetransmitStreamData) {
QUICHE teamea740082019-03-11 17:58:43 -0700343 if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500344 return;
345 }
346 InSequence s;
QUICHE team6987b4a2019-03-15 16:23:04 -0700347 // Send [0, 1350) in ENCRYPTION_INITIAL.
348 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700349 std::string data(1350, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500350 EXPECT_CALL(
351 session_,
352 WritevData(_,
353 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
354 1350, 0, _))
355 .WillOnce(Invoke(MockQuicSession::ConsumeData));
356 stream_->WriteOrBufferData(data, false, nullptr);
357 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
358 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
359 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
360 EXPECT_CALL(
361 session_,
362 WritevData(_,
363 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
364 1350, 1350, _))
365 .WillOnce(Invoke(MockQuicSession::ConsumeData));
366 stream_->WriteOrBufferData(data, false, nullptr);
367 connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
368 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
369
370 // Ack [2000, 2500).
371 QuicByteCount newly_acked_length = 0;
372 stream_->OnStreamFrameAcked(2000, 500, false, QuicTime::Delta::Zero(),
373 &newly_acked_length);
374 EXPECT_EQ(500u, newly_acked_length);
375
376 // Force crypto stream to send [1350, 2700) and only [1350, 1500) is consumed.
377 EXPECT_CALL(
378 session_,
379 WritevData(_,
380 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
381 650, 1350, _))
382 .WillOnce(InvokeWithoutArgs([this]() {
383 return MockQuicSession::ConsumeData(
384 stream_,
385 QuicUtils::GetCryptoStreamId(connection_->transport_version()), 150,
386 1350, NO_FIN);
387 }));
388
389 EXPECT_FALSE(stream_->RetransmitStreamData(1350, 1350, false));
390 // Verify connection's encryption level has restored.
391 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
392
393 // Force session to send [1350, 1500) again and all data is consumed.
394 EXPECT_CALL(
395 session_,
396 WritevData(_,
397 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
398 650, 1350, _))
399 .WillOnce(Invoke(MockQuicSession::ConsumeData));
400 EXPECT_CALL(
401 session_,
402 WritevData(_,
403 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
404 200, 2500, _))
405 .WillOnce(Invoke(MockQuicSession::ConsumeData));
406 EXPECT_TRUE(stream_->RetransmitStreamData(1350, 1350, false));
407 // Verify connection's encryption level has restored.
408 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
409
410 EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(0);
411 // Force to send an empty frame.
412 EXPECT_TRUE(stream_->RetransmitStreamData(0, 0, false));
413}
414
415TEST_F(QuicCryptoStreamTest, RetransmitStreamDataWithCryptoFrames) {
QUICHE teamea740082019-03-11 17:58:43 -0700416 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500417 return;
418 }
419 InSequence s;
QUICHE team6987b4a2019-03-15 16:23:04 -0700420 // Send [0, 1350) in ENCRYPTION_INITIAL.
421 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700422 std::string data(1350, 'a');
QUICHE team6987b4a2019-03-15 16:23:04 -0700423 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500424 .WillOnce(Invoke(connection_,
425 &MockQuicConnection::QuicConnection_SendCryptoData));
QUICHE team6987b4a2019-03-15 16:23:04 -0700426 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500427 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
428 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
429 std::unique_ptr<NullEncrypter> encrypter =
vasilvv0fc587f2019-09-06 13:33:08 -0700430 std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500431 connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
432 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
433 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
434 .WillOnce(Invoke(connection_,
435 &MockQuicConnection::QuicConnection_SendCryptoData));
436 stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
437 connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
438 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
439
440 // Ack [2000, 2500).
441 QuicCryptoFrame acked_frame(ENCRYPTION_ZERO_RTT, 650, 500);
442 EXPECT_TRUE(
443 stream_->OnCryptoFrameAcked(acked_frame, QuicTime::Delta::Zero()));
444
445 // Retransmit only [1350, 1500).
446 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 150, 0))
447 .WillOnce(Invoke(connection_,
448 &MockQuicConnection::QuicConnection_SendCryptoData));
449 QuicCryptoFrame frame_to_retransmit(ENCRYPTION_ZERO_RTT, 0, 150);
450 stream_->RetransmitData(&frame_to_retransmit);
451
452 // Verify connection's encryption level has restored.
453 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
454
455 // Retransmit [1350, 2700) again and all data is sent.
456 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
457 .WillOnce(Invoke(connection_,
458 &MockQuicConnection::QuicConnection_SendCryptoData));
459 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 200, 1150))
460 .WillOnce(Invoke(connection_,
461 &MockQuicConnection::QuicConnection_SendCryptoData));
462 frame_to_retransmit = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 1350);
463 stream_->RetransmitData(&frame_to_retransmit);
464 // Verify connection's encryption level has restored.
465 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
466
467 EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
468 // Force to send an empty frame.
469 QuicCryptoFrame empty_frame(ENCRYPTION_FORWARD_SECURE, 0, 0);
470 stream_->RetransmitData(&empty_frame);
471}
472
473// Regression test for b/115926584.
474TEST_F(QuicCryptoStreamTest, HasUnackedCryptoData) {
QUICHE teamea740082019-03-11 17:58:43 -0700475 if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500476 return;
477 }
vasilvvc48c8712019-03-11 13:38:16 -0700478 std::string data(1350, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500479 EXPECT_CALL(
480 session_,
481 WritevData(_,
482 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
483 1350, 0, _))
484 .WillOnce(testing::Return(QuicConsumedData(0, false)));
485 stream_->WriteOrBufferData(data, false, nullptr);
486 EXPECT_FALSE(stream_->IsWaitingForAcks());
487 // Although there is no outstanding data, verify session has pending crypto
488 // data.
fayang44fa92f2019-07-01 07:32:14 -0700489 EXPECT_TRUE(session_.HasUnackedCryptoData());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500490
491 EXPECT_CALL(
492 session_,
493 WritevData(_,
494 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
495 1350, 0, _))
496 .WillOnce(Invoke(MockQuicSession::ConsumeData));
497 stream_->OnCanWrite();
498 EXPECT_TRUE(stream_->IsWaitingForAcks());
499 EXPECT_TRUE(session_.HasUnackedCryptoData());
500}
501
502TEST_F(QuicCryptoStreamTest, HasUnackedCryptoDataWithCryptoFrames) {
QUICHE teamea740082019-03-11 17:58:43 -0700503 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500504 return;
505 }
QUICHE team6987b4a2019-03-15 16:23:04 -0700506 // Send [0, 1350) in ENCRYPTION_INITIAL.
507 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700508 std::string data(1350, 'a');
QUICHE team6987b4a2019-03-15 16:23:04 -0700509 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500510 .WillOnce(Invoke(connection_,
511 &MockQuicConnection::QuicConnection_SendCryptoData));
QUICHE team6987b4a2019-03-15 16:23:04 -0700512 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500513 EXPECT_TRUE(stream_->IsWaitingForAcks());
514 EXPECT_TRUE(session_.HasUnackedCryptoData());
515}
516
nharperd43f1d62019-07-01 15:18:20 -0700517// Regression test for bugfix of GetPacketHeaderSize.
518TEST_F(QuicCryptoStreamTest, CryptoMessageFramingOverhead) {
nharperd43f1d62019-07-01 15:18:20 -0700519 for (auto version : AllSupportedTransportVersions()) {
520 SCOPED_TRACE(version);
521 QuicByteCount expected_overhead = 48;
522 if (VersionHasIetfInvariantHeader(version)) {
dschinazi48ac9192019-07-31 00:07:26 -0700523 expected_overhead += 4;
nharperd43f1d62019-07-01 15:18:20 -0700524 }
525 if (QuicVersionHasLongHeaderLengths(version)) {
dschinazi48ac9192019-07-31 00:07:26 -0700526 expected_overhead += 3;
527 }
528 if (VersionHasLengthPrefixedConnectionIds(version)) {
529 expected_overhead += 1;
nharperd43f1d62019-07-01 15:18:20 -0700530 }
531 EXPECT_EQ(expected_overhead, QuicCryptoStream::CryptoMessageFramingOverhead(
532 version, TestConnectionId()));
533 }
534}
535
fayangaee31ef2019-08-20 06:47:51 -0700536TEST_F(QuicCryptoStreamTest, WriteBufferedCryptoFrames) {
537 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
538 return;
539 }
540 EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
541 InSequence s;
542 // Send [0, 1350) in ENCRYPTION_INITIAL.
543 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
544 std::string data(1350, 'a');
545 // Only consumed 1000 bytes.
546 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
547 .WillOnce(Return(1000));
548 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
549 EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
550
551 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT and verify no write is attempted
552 // because there is buffered data.
553 EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
554 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
555 stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
556 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
557
558 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
559 .WillOnce(Return(350));
560 // Partial write of ENCRYPTION_ZERO_RTT data.
561 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
562 .WillOnce(Return(1000));
563 stream_->WriteBufferedCryptoFrames();
564 EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
565 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
566
567 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 350, 1000))
568 .WillOnce(Return(350));
569 stream_->WriteBufferedCryptoFrames();
570 EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
571}
572
nharper486a8a92019-08-28 16:25:10 -0700573TEST_F(QuicCryptoStreamTest, LimitBufferedCryptoData) {
574 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
575 return;
576 }
577
578 EXPECT_CALL(*connection_,
579 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
580 std::string large_frame(2 * GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes),
581 'a');
582
583 // Set offset to 1 so that we guarantee the data gets buffered instead of
584 // immediately processed.
585 QuicStreamOffset offset = 1;
586 stream_->OnCryptoFrame(
587 QuicCryptoFrame(ENCRYPTION_INITIAL, offset, large_frame));
588}
589
fayangd6db04a2019-10-02 14:21:42 -0700590TEST_F(QuicCryptoStreamTest, RetransmitCryptoFramesAndPartialWrite) {
591 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
592 return;
593 }
594
595 EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
596 InSequence s;
597 // Send [0, 1350) in ENCRYPTION_INITIAL.
598 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
599 std::string data(1350, 'a');
600 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
601 .WillOnce(Invoke(connection_,
602 &MockQuicConnection::QuicConnection_SendCryptoData));
603 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
604
605 // Lost [0, 1000).
606 QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
607 stream_->OnCryptoFrameLost(&lost_frame);
608 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
609 // Simulate connection is constrained by amplification restriction.
610 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
611 .WillOnce(Return(0));
612 stream_->WritePendingCryptoRetransmission();
613 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
614 // Connection gets unblocked.
615 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
616 .WillOnce(Invoke(connection_,
617 &MockQuicConnection::QuicConnection_SendCryptoData));
618 stream_->WritePendingCryptoRetransmission();
619 EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
620}
621
QUICHE teama6ef0a62019-03-07 20:34:33 -0500622} // namespace
623} // namespace test
624} // namespace quic