blob: 4b2e2f7679d1d0432b46ea70824a129a5b144f7c [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>
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include <vector>
11
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
13#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
14#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
15#include "net/third_party/quiche/src/quic/core/quic_utils.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050017#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
18#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
19#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
20#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
21
22using testing::_;
23using testing::InSequence;
24using testing::Invoke;
25using testing::InvokeWithoutArgs;
fayangaee31ef2019-08-20 06:47:51 -070026using testing::Return;
QUICHE teama6ef0a62019-03-07 20:34:33 -050027
28namespace quic {
29namespace test {
30namespace {
31
32class MockQuicCryptoStream : public QuicCryptoStream,
33 public QuicCryptoHandshaker {
34 public:
35 explicit MockQuicCryptoStream(QuicSession* session)
36 : QuicCryptoStream(session),
37 QuicCryptoHandshaker(this, session),
38 params_(new QuicCryptoNegotiatedParameters) {}
39 MockQuicCryptoStream(const MockQuicCryptoStream&) = delete;
40 MockQuicCryptoStream& operator=(const MockQuicCryptoStream&) = delete;
41
42 void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
43 messages_.push_back(message);
44 }
45
46 std::vector<CryptoHandshakeMessage>* messages() { return &messages_; }
47
48 bool encryption_established() const override { return false; }
49 bool handshake_confirmed() const override { return false; }
50
51 const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
52 const override {
53 return *params_;
54 }
55 CryptoMessageParser* crypto_message_parser() override {
56 return QuicCryptoHandshaker::crypto_message_parser();
57 }
58
59 private:
60 QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params_;
61 std::vector<CryptoHandshakeMessage> messages_;
62};
63
64class QuicCryptoStreamTest : public QuicTest {
65 public:
66 QuicCryptoStreamTest()
67 : connection_(new MockQuicConnection(&helper_,
68 &alarm_factory_,
69 Perspective::IS_CLIENT)),
70 session_(connection_, /*create_mock_crypto_stream=*/false) {
71 stream_ = new MockQuicCryptoStream(&session_);
72 session_.SetCryptoStream(stream_);
73 session_.Initialize();
74 message_.set_tag(kSHLO);
75 message_.SetStringPiece(1, "abc");
76 message_.SetStringPiece(2, "def");
77 ConstructHandshakeMessage();
78 }
79 QuicCryptoStreamTest(const QuicCryptoStreamTest&) = delete;
80 QuicCryptoStreamTest& operator=(const QuicCryptoStreamTest&) = delete;
81
82 void ConstructHandshakeMessage() {
83 CryptoFramer framer;
QUICHE team3fe6a8b2019-03-14 09:10:38 -070084 message_data_ = framer.ConstructHandshakeMessage(message_);
QUICHE teama6ef0a62019-03-07 20:34:33 -050085 }
86
87 protected:
88 MockQuicConnectionHelper helper_;
89 MockAlarmFactory alarm_factory_;
90 MockQuicConnection* connection_;
91 MockQuicSpdySession session_;
92 MockQuicCryptoStream* stream_;
93 CryptoHandshakeMessage message_;
94 std::unique_ptr<QuicData> message_data_;
95};
96
97TEST_F(QuicCryptoStreamTest, NotInitiallyConected) {
98 EXPECT_FALSE(stream_->encryption_established());
99 EXPECT_FALSE(stream_->handshake_confirmed());
100}
101
102TEST_F(QuicCryptoStreamTest, ProcessRawData) {
QUICHE teamea740082019-03-11 17:58:43 -0700103 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500104 stream_->OnStreamFrame(QuicStreamFrame(
105 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
106 /*fin=*/false,
107 /*offset=*/0, message_data_->AsStringPiece()));
108 } else {
QUICHE team6987b4a2019-03-15 16:23:04 -0700109 stream_->OnCryptoFrame(QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500110 message_data_->AsStringPiece()));
111 }
112 ASSERT_EQ(1u, stream_->messages()->size());
113 const CryptoHandshakeMessage& message = (*stream_->messages())[0];
114 EXPECT_EQ(kSHLO, message.tag());
115 EXPECT_EQ(2u, message.tag_value_map().size());
116 EXPECT_EQ("abc", crypto_test_utils::GetValueForTag(message, 1));
117 EXPECT_EQ("def", crypto_test_utils::GetValueForTag(message, 2));
118}
119
120TEST_F(QuicCryptoStreamTest, ProcessBadData) {
vasilvvc48c8712019-03-11 13:38:16 -0700121 std::string bad(message_data_->data(), message_data_->length());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500122 const int kFirstTagIndex = sizeof(uint32_t) + // message tag
123 sizeof(uint16_t) + // number of tag-value pairs
124 sizeof(uint16_t); // padding
125 EXPECT_EQ(1, bad[kFirstTagIndex]);
126 bad[kFirstTagIndex] = 0x7F; // out of order tag
127
128 EXPECT_CALL(*connection_, CloseConnection(QUIC_CRYPTO_TAGS_OUT_OF_ORDER,
129 testing::_, testing::_));
QUICHE teamea740082019-03-11 17:58:43 -0700130 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500131 stream_->OnStreamFrame(QuicStreamFrame(
132 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
133 /*fin=*/false, /*offset=*/0, bad));
134 } else {
QUICHE team6987b4a2019-03-15 16:23:04 -0700135 stream_->OnCryptoFrame(
136 QuicCryptoFrame(ENCRYPTION_INITIAL, /*offset*/ 0, bad));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500137 }
138}
139
140TEST_F(QuicCryptoStreamTest, NoConnectionLevelFlowControl) {
141 EXPECT_FALSE(
142 QuicStreamPeer::StreamContributesToConnectionFlowControl(stream_));
143}
144
145TEST_F(QuicCryptoStreamTest, RetransmitCryptoData) {
QUICHE teamea740082019-03-11 17:58:43 -0700146 if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500147 return;
148 }
149 InSequence s;
QUICHE team6987b4a2019-03-15 16:23:04 -0700150 // Send [0, 1350) in ENCRYPTION_INITIAL.
151 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700152 std::string data(1350, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500153 EXPECT_CALL(
154 session_,
155 WritevData(_,
156 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
157 1350, 0, _))
158 .WillOnce(Invoke(MockQuicSession::ConsumeData));
159 stream_->WriteOrBufferData(data, false, nullptr);
160 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
161 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
162 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
163 EXPECT_CALL(
164 session_,
165 WritevData(_,
166 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
167 1350, 1350, _))
168 .WillOnce(Invoke(MockQuicSession::ConsumeData));
169 stream_->WriteOrBufferData(data, false, nullptr);
170 connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
171 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
172
173 // Lost [0, 1000).
174 stream_->OnStreamFrameLost(0, 1000, false);
175 EXPECT_TRUE(stream_->HasPendingRetransmission());
176 // Lost [1200, 2000).
177 stream_->OnStreamFrameLost(1200, 800, false);
178 EXPECT_CALL(
179 session_,
180 WritevData(_,
181 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
182 1000, 0, _))
183 .WillOnce(Invoke(MockQuicSession::ConsumeData));
184 // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
185 // they are in different encryption levels.
186 EXPECT_CALL(
187 session_,
188 WritevData(_,
189 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
190 150, 1200, _))
191 .WillOnce(Invoke(MockQuicSession::ConsumeData));
192 EXPECT_CALL(
193 session_,
194 WritevData(_,
195 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
196 650, 1350, _))
197 .WillOnce(Invoke(MockQuicSession::ConsumeData));
198 stream_->OnCanWrite();
199 EXPECT_FALSE(stream_->HasPendingRetransmission());
200 // Verify connection's encryption level has restored.
201 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
202}
203
204TEST_F(QuicCryptoStreamTest, RetransmitCryptoDataInCryptoFrames) {
QUICHE teamea740082019-03-11 17:58:43 -0700205 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500206 return;
207 }
208 EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
209 InSequence s;
QUICHE team6987b4a2019-03-15 16:23:04 -0700210 // Send [0, 1350) in ENCRYPTION_INITIAL.
211 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700212 std::string data(1350, 'a');
QUICHE team6987b4a2019-03-15 16:23:04 -0700213 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500214 .WillOnce(Invoke(connection_,
215 &MockQuicConnection::QuicConnection_SendCryptoData));
QUICHE team6987b4a2019-03-15 16:23:04 -0700216 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500217 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
218 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
219 std::unique_ptr<NullEncrypter> encrypter =
vasilvv0fc587f2019-09-06 13:33:08 -0700220 std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500221 connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
222 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
223 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
224 .WillOnce(Invoke(connection_,
225 &MockQuicConnection::QuicConnection_SendCryptoData));
226 stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
227 connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
228 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
229
230 // Lost [0, 1000).
QUICHE team6987b4a2019-03-15 16:23:04 -0700231 QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500232 stream_->OnCryptoFrameLost(&lost_frame);
233 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
234 // Lost [1200, 2000).
QUICHE team6987b4a2019-03-15 16:23:04 -0700235 lost_frame = QuicCryptoFrame(ENCRYPTION_INITIAL, 1200, 150);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500236 stream_->OnCryptoFrameLost(&lost_frame);
237 lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
238 stream_->OnCryptoFrameLost(&lost_frame);
QUICHE team6987b4a2019-03-15 16:23:04 -0700239 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500240 .WillOnce(Invoke(connection_,
241 &MockQuicConnection::QuicConnection_SendCryptoData));
242 // Verify [1200, 2000) are sent in [1200, 1350) and [1350, 2000) because of
243 // they are in different encryption levels.
QUICHE team6987b4a2019-03-15 16:23:04 -0700244 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 150, 1200))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500245 .WillOnce(Invoke(connection_,
246 &MockQuicConnection::QuicConnection_SendCryptoData));
247 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
248 .WillOnce(Invoke(connection_,
249 &MockQuicConnection::QuicConnection_SendCryptoData));
250 stream_->WritePendingCryptoRetransmission();
251 EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
252 // Verify connection's encryption level has restored.
253 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
254}
255
256TEST_F(QuicCryptoStreamTest, NeuterUnencryptedStreamData) {
QUICHE teamea740082019-03-11 17:58:43 -0700257 if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500258 return;
259 }
QUICHE team6987b4a2019-03-15 16:23:04 -0700260 // Send [0, 1350) in ENCRYPTION_INITIAL.
261 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700262 std::string data(1350, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500263 EXPECT_CALL(
264 session_,
265 WritevData(_,
266 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
267 1350, 0, _))
268 .WillOnce(Invoke(MockQuicSession::ConsumeData));
269 stream_->WriteOrBufferData(data, false, nullptr);
270 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
271 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
272 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
273 EXPECT_CALL(
274 session_,
275 WritevData(_,
276 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
277 1350, 1350, _))
278 .WillOnce(Invoke(MockQuicSession::ConsumeData));
279 stream_->WriteOrBufferData(data, false, nullptr);
280
281 // Lost [0, 1350).
282 stream_->OnStreamFrameLost(0, 1350, false);
283 EXPECT_TRUE(stream_->HasPendingRetransmission());
284 // Neuters [0, 1350).
285 stream_->NeuterUnencryptedStreamData();
286 EXPECT_FALSE(stream_->HasPendingRetransmission());
287 // Lost [0, 1350) again.
288 stream_->OnStreamFrameLost(0, 1350, false);
289 EXPECT_FALSE(stream_->HasPendingRetransmission());
290
291 // Lost [1350, 2000).
292 stream_->OnStreamFrameLost(1350, 650, false);
293 EXPECT_TRUE(stream_->HasPendingRetransmission());
294 stream_->NeuterUnencryptedStreamData();
295 EXPECT_TRUE(stream_->HasPendingRetransmission());
296}
297
298TEST_F(QuicCryptoStreamTest, NeuterUnencryptedCryptoData) {
QUICHE teamea740082019-03-11 17:58:43 -0700299 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500300 return;
301 }
QUICHE team6987b4a2019-03-15 16:23:04 -0700302 // Send [0, 1350) in ENCRYPTION_INITIAL.
303 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700304 std::string data(1350, 'a');
QUICHE team6987b4a2019-03-15 16:23:04 -0700305 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500306 .WillOnce(Invoke(connection_,
307 &MockQuicConnection::QuicConnection_SendCryptoData));
QUICHE team6987b4a2019-03-15 16:23:04 -0700308 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500309 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
310 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
311 std::unique_ptr<NullEncrypter> encrypter =
vasilvv0fc587f2019-09-06 13:33:08 -0700312 std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500313 connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
314 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
315 EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
316 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
317 .WillOnce(Invoke(connection_,
318 &MockQuicConnection::QuicConnection_SendCryptoData));
319 stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
320
321 // Lost [0, 1350).
QUICHE team6987b4a2019-03-15 16:23:04 -0700322 QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1350);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500323 stream_->OnCryptoFrameLost(&lost_frame);
324 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
325 // Neuters [0, 1350).
326 stream_->NeuterUnencryptedStreamData();
327 EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
328 // Lost [0, 1350) again.
329 stream_->OnCryptoFrameLost(&lost_frame);
330 EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
331
332 // Lost [1350, 2000), which starts at offset 0 at the ENCRYPTION_ZERO_RTT
333 // level.
334 lost_frame = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 650);
335 stream_->OnCryptoFrameLost(&lost_frame);
336 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
337 stream_->NeuterUnencryptedStreamData();
338 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
339}
340
341TEST_F(QuicCryptoStreamTest, RetransmitStreamData) {
QUICHE teamea740082019-03-11 17:58:43 -0700342 if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500343 return;
344 }
345 InSequence s;
QUICHE team6987b4a2019-03-15 16:23:04 -0700346 // Send [0, 1350) in ENCRYPTION_INITIAL.
347 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700348 std::string data(1350, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500349 EXPECT_CALL(
350 session_,
351 WritevData(_,
352 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
353 1350, 0, _))
354 .WillOnce(Invoke(MockQuicSession::ConsumeData));
355 stream_->WriteOrBufferData(data, false, nullptr);
356 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
357 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
358 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
359 EXPECT_CALL(
360 session_,
361 WritevData(_,
362 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
363 1350, 1350, _))
364 .WillOnce(Invoke(MockQuicSession::ConsumeData));
365 stream_->WriteOrBufferData(data, false, nullptr);
366 connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
367 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
368
369 // Ack [2000, 2500).
370 QuicByteCount newly_acked_length = 0;
371 stream_->OnStreamFrameAcked(2000, 500, false, QuicTime::Delta::Zero(),
372 &newly_acked_length);
373 EXPECT_EQ(500u, newly_acked_length);
374
375 // Force crypto stream to send [1350, 2700) and only [1350, 1500) is consumed.
376 EXPECT_CALL(
377 session_,
378 WritevData(_,
379 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
380 650, 1350, _))
381 .WillOnce(InvokeWithoutArgs([this]() {
382 return MockQuicSession::ConsumeData(
383 stream_,
384 QuicUtils::GetCryptoStreamId(connection_->transport_version()), 150,
385 1350, NO_FIN);
386 }));
387
388 EXPECT_FALSE(stream_->RetransmitStreamData(1350, 1350, false));
389 // Verify connection's encryption level has restored.
390 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
391
392 // Force session to send [1350, 1500) again and all data is consumed.
393 EXPECT_CALL(
394 session_,
395 WritevData(_,
396 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
397 650, 1350, _))
398 .WillOnce(Invoke(MockQuicSession::ConsumeData));
399 EXPECT_CALL(
400 session_,
401 WritevData(_,
402 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
403 200, 2500, _))
404 .WillOnce(Invoke(MockQuicSession::ConsumeData));
405 EXPECT_TRUE(stream_->RetransmitStreamData(1350, 1350, false));
406 // Verify connection's encryption level has restored.
407 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
408
409 EXPECT_CALL(session_, WritevData(_, _, _, _, _)).Times(0);
410 // Force to send an empty frame.
411 EXPECT_TRUE(stream_->RetransmitStreamData(0, 0, false));
412}
413
414TEST_F(QuicCryptoStreamTest, RetransmitStreamDataWithCryptoFrames) {
QUICHE teamea740082019-03-11 17:58:43 -0700415 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500416 return;
417 }
418 InSequence s;
QUICHE team6987b4a2019-03-15 16:23:04 -0700419 // Send [0, 1350) in ENCRYPTION_INITIAL.
420 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700421 std::string data(1350, 'a');
QUICHE team6987b4a2019-03-15 16:23:04 -0700422 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500423 .WillOnce(Invoke(connection_,
424 &MockQuicConnection::QuicConnection_SendCryptoData));
QUICHE team6987b4a2019-03-15 16:23:04 -0700425 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500426 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT.
427 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
428 std::unique_ptr<NullEncrypter> encrypter =
vasilvv0fc587f2019-09-06 13:33:08 -0700429 std::make_unique<NullEncrypter>(Perspective::IS_CLIENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500430 connection_->SetEncrypter(ENCRYPTION_ZERO_RTT, std::move(encrypter));
431 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
432 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
433 .WillOnce(Invoke(connection_,
434 &MockQuicConnection::QuicConnection_SendCryptoData));
435 stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
436 connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
437 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
438
439 // Ack [2000, 2500).
440 QuicCryptoFrame acked_frame(ENCRYPTION_ZERO_RTT, 650, 500);
441 EXPECT_TRUE(
442 stream_->OnCryptoFrameAcked(acked_frame, QuicTime::Delta::Zero()));
443
444 // Retransmit only [1350, 1500).
445 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 150, 0))
446 .WillOnce(Invoke(connection_,
447 &MockQuicConnection::QuicConnection_SendCryptoData));
448 QuicCryptoFrame frame_to_retransmit(ENCRYPTION_ZERO_RTT, 0, 150);
449 stream_->RetransmitData(&frame_to_retransmit);
450
451 // Verify connection's encryption level has restored.
452 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
453
454 // Retransmit [1350, 2700) again and all data is sent.
455 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 650, 0))
456 .WillOnce(Invoke(connection_,
457 &MockQuicConnection::QuicConnection_SendCryptoData));
458 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 200, 1150))
459 .WillOnce(Invoke(connection_,
460 &MockQuicConnection::QuicConnection_SendCryptoData));
461 frame_to_retransmit = QuicCryptoFrame(ENCRYPTION_ZERO_RTT, 0, 1350);
462 stream_->RetransmitData(&frame_to_retransmit);
463 // Verify connection's encryption level has restored.
464 EXPECT_EQ(ENCRYPTION_FORWARD_SECURE, connection_->encryption_level());
465
466 EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
467 // Force to send an empty frame.
468 QuicCryptoFrame empty_frame(ENCRYPTION_FORWARD_SECURE, 0, 0);
469 stream_->RetransmitData(&empty_frame);
470}
471
472// Regression test for b/115926584.
473TEST_F(QuicCryptoStreamTest, HasUnackedCryptoData) {
QUICHE teamea740082019-03-11 17:58:43 -0700474 if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500475 return;
476 }
vasilvvc48c8712019-03-11 13:38:16 -0700477 std::string data(1350, 'a');
QUICHE teama6ef0a62019-03-07 20:34:33 -0500478 EXPECT_CALL(
479 session_,
480 WritevData(_,
481 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
482 1350, 0, _))
483 .WillOnce(testing::Return(QuicConsumedData(0, false)));
484 stream_->WriteOrBufferData(data, false, nullptr);
485 EXPECT_FALSE(stream_->IsWaitingForAcks());
486 // Although there is no outstanding data, verify session has pending crypto
487 // data.
fayang44fa92f2019-07-01 07:32:14 -0700488 EXPECT_TRUE(session_.HasUnackedCryptoData());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500489
490 EXPECT_CALL(
491 session_,
492 WritevData(_,
493 QuicUtils::GetCryptoStreamId(connection_->transport_version()),
494 1350, 0, _))
495 .WillOnce(Invoke(MockQuicSession::ConsumeData));
496 stream_->OnCanWrite();
497 EXPECT_TRUE(stream_->IsWaitingForAcks());
498 EXPECT_TRUE(session_.HasUnackedCryptoData());
499}
500
501TEST_F(QuicCryptoStreamTest, HasUnackedCryptoDataWithCryptoFrames) {
QUICHE teamea740082019-03-11 17:58:43 -0700502 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500503 return;
504 }
QUICHE team6987b4a2019-03-15 16:23:04 -0700505 // Send [0, 1350) in ENCRYPTION_INITIAL.
506 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
vasilvvc48c8712019-03-11 13:38:16 -0700507 std::string data(1350, 'a');
QUICHE team6987b4a2019-03-15 16:23:04 -0700508 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500509 .WillOnce(Invoke(connection_,
510 &MockQuicConnection::QuicConnection_SendCryptoData));
QUICHE team6987b4a2019-03-15 16:23:04 -0700511 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500512 EXPECT_TRUE(stream_->IsWaitingForAcks());
513 EXPECT_TRUE(session_.HasUnackedCryptoData());
514}
515
nharperd43f1d62019-07-01 15:18:20 -0700516// Regression test for bugfix of GetPacketHeaderSize.
517TEST_F(QuicCryptoStreamTest, CryptoMessageFramingOverhead) {
nharperd43f1d62019-07-01 15:18:20 -0700518 for (auto version : AllSupportedTransportVersions()) {
519 SCOPED_TRACE(version);
520 QuicByteCount expected_overhead = 48;
521 if (VersionHasIetfInvariantHeader(version)) {
dschinazi48ac9192019-07-31 00:07:26 -0700522 expected_overhead += 4;
nharperd43f1d62019-07-01 15:18:20 -0700523 }
524 if (QuicVersionHasLongHeaderLengths(version)) {
dschinazi48ac9192019-07-31 00:07:26 -0700525 expected_overhead += 3;
526 }
527 if (VersionHasLengthPrefixedConnectionIds(version)) {
528 expected_overhead += 1;
nharperd43f1d62019-07-01 15:18:20 -0700529 }
530 EXPECT_EQ(expected_overhead, QuicCryptoStream::CryptoMessageFramingOverhead(
531 version, TestConnectionId()));
532 }
533}
534
fayangaee31ef2019-08-20 06:47:51 -0700535TEST_F(QuicCryptoStreamTest, WriteBufferedCryptoFrames) {
536 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
537 return;
538 }
539 EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
540 InSequence s;
541 // Send [0, 1350) in ENCRYPTION_INITIAL.
542 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
543 std::string data(1350, 'a');
544 // Only consumed 1000 bytes.
545 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
546 .WillOnce(Return(1000));
547 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
548 EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
549
550 // Send [1350, 2700) in ENCRYPTION_ZERO_RTT and verify no write is attempted
551 // because there is buffered data.
552 EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
553 connection_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
554 stream_->WriteCryptoData(ENCRYPTION_ZERO_RTT, data);
555 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
556
557 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 350, 1000))
558 .WillOnce(Return(350));
559 // Partial write of ENCRYPTION_ZERO_RTT data.
560 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1350, 0))
561 .WillOnce(Return(1000));
562 stream_->WriteBufferedCryptoFrames();
563 EXPECT_TRUE(stream_->HasBufferedCryptoFrames());
564 EXPECT_EQ(ENCRYPTION_ZERO_RTT, connection_->encryption_level());
565
566 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 350, 1000))
567 .WillOnce(Return(350));
568 stream_->WriteBufferedCryptoFrames();
569 EXPECT_FALSE(stream_->HasBufferedCryptoFrames());
570}
571
nharper486a8a92019-08-28 16:25:10 -0700572TEST_F(QuicCryptoStreamTest, LimitBufferedCryptoData) {
573 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
574 return;
575 }
576
577 EXPECT_CALL(*connection_,
578 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _));
579 std::string large_frame(2 * GetQuicFlag(FLAGS_quic_max_buffered_crypto_bytes),
580 'a');
581
582 // Set offset to 1 so that we guarantee the data gets buffered instead of
583 // immediately processed.
584 QuicStreamOffset offset = 1;
585 stream_->OnCryptoFrame(
586 QuicCryptoFrame(ENCRYPTION_INITIAL, offset, large_frame));
587}
588
fayangd6db04a2019-10-02 14:21:42 -0700589TEST_F(QuicCryptoStreamTest, RetransmitCryptoFramesAndPartialWrite) {
590 if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
591 return;
592 }
593
594 EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
595 InSequence s;
596 // Send [0, 1350) in ENCRYPTION_INITIAL.
597 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
598 std::string data(1350, 'a');
599 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
600 .WillOnce(Invoke(connection_,
601 &MockQuicConnection::QuicConnection_SendCryptoData));
602 stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
603
604 // Lost [0, 1000).
605 QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
606 stream_->OnCryptoFrameLost(&lost_frame);
607 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
608 // Simulate connection is constrained by amplification restriction.
609 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
610 .WillOnce(Return(0));
611 stream_->WritePendingCryptoRetransmission();
612 EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
613 // Connection gets unblocked.
614 EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
615 .WillOnce(Invoke(connection_,
616 &MockQuicConnection::QuicConnection_SendCryptoData));
617 stream_->WritePendingCryptoRetransmission();
618 EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
619}
620
QUICHE teama6ef0a62019-03-07 20:34:33 -0500621} // namespace
622} // namespace test
623} // namespace quic