1 // Copyright (c) 2018 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 "quiche/quic/test_tools/simple_session_notifier.h"
6
7 #include <utility>
8
9 #include "quiche/quic/core/crypto/null_encrypter.h"
10 #include "quiche/quic/core/quic_utils.h"
11 #include "quiche/quic/platform/api/quic_test.h"
12 #include "quiche/quic/test_tools/quic_connection_peer.h"
13 #include "quiche/quic/test_tools/quic_test_utils.h"
14 #include "quiche/quic/test_tools/simple_data_producer.h"
15
16 using testing::_;
17 using testing::InSequence;
18 using testing::Return;
19 using testing::StrictMock;
20
21 namespace quic {
22 namespace test {
23 namespace {
24
25 class MockQuicConnectionWithSendStreamData : public MockQuicConnection {
26 public:
MockQuicConnectionWithSendStreamData(MockQuicConnectionHelper * helper,MockAlarmFactory * alarm_factory,Perspective perspective)27 MockQuicConnectionWithSendStreamData(MockQuicConnectionHelper* helper,
28 MockAlarmFactory* alarm_factory,
29 Perspective perspective)
30 : MockQuicConnection(helper, alarm_factory, perspective) {}
31
32 MOCK_METHOD(QuicConsumedData, SendStreamData,
33 (QuicStreamId id, size_t write_length, QuicStreamOffset offset,
34 StreamSendingState state),
35 (override));
36 };
37
38 class SimpleSessionNotifierTest : public QuicTest {
39 public:
SimpleSessionNotifierTest()40 SimpleSessionNotifierTest()
41 : connection_(&helper_, &alarm_factory_, Perspective::IS_CLIENT),
42 notifier_(&connection_) {
43 connection_.set_visitor(&visitor_);
44 connection_.SetSessionNotifier(¬ifier_);
45 EXPECT_FALSE(notifier_.WillingToWrite());
46 EXPECT_EQ(0u, notifier_.StreamBytesSent());
47 EXPECT_FALSE(notifier_.HasBufferedStreamData());
48 }
49
ControlFrameConsumed(const QuicFrame & frame)50 bool ControlFrameConsumed(const QuicFrame& frame) {
51 DeleteFrame(&const_cast<QuicFrame&>(frame));
52 return true;
53 }
54
55 MockQuicConnectionHelper helper_;
56 MockAlarmFactory alarm_factory_;
57 MockQuicConnectionVisitor visitor_;
58 StrictMock<MockQuicConnectionWithSendStreamData> connection_;
59 SimpleSessionNotifier notifier_;
60 };
61
TEST_F(SimpleSessionNotifierTest,WriteOrBufferData)62 TEST_F(SimpleSessionNotifierTest, WriteOrBufferData) {
63 InSequence s;
64 EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, NO_FIN))
65 .WillOnce(Return(QuicConsumedData(1024, false)));
66 notifier_.WriteOrBufferData(3, 1024, NO_FIN);
67 EXPECT_EQ(0u, notifier_.StreamBytesToSend());
68 EXPECT_CALL(connection_, SendStreamData(5, 512, 0, NO_FIN))
69 .WillOnce(Return(QuicConsumedData(512, false)));
70 notifier_.WriteOrBufferData(5, 512, NO_FIN);
71 EXPECT_FALSE(notifier_.WillingToWrite());
72 // Connection is blocked.
73 EXPECT_CALL(connection_, SendStreamData(5, 512, 512, FIN))
74 .WillOnce(Return(QuicConsumedData(256, false)));
75 notifier_.WriteOrBufferData(5, 512, FIN);
76 EXPECT_TRUE(notifier_.WillingToWrite());
77 EXPECT_EQ(1792u, notifier_.StreamBytesSent());
78 EXPECT_EQ(256u, notifier_.StreamBytesToSend());
79 EXPECT_TRUE(notifier_.HasBufferedStreamData());
80
81 // New data cannot be sent as connection is blocked.
82 EXPECT_CALL(connection_, SendStreamData(7, 1024, 0, FIN)).Times(0);
83 notifier_.WriteOrBufferData(7, 1024, FIN);
84 EXPECT_EQ(1792u, notifier_.StreamBytesSent());
85 }
86
TEST_F(SimpleSessionNotifierTest,WriteOrBufferRstStream)87 TEST_F(SimpleSessionNotifierTest, WriteOrBufferRstStream) {
88 InSequence s;
89 EXPECT_CALL(connection_, SendStreamData(5, 1024, 0, FIN))
90 .WillOnce(Return(QuicConsumedData(1024, true)));
91 notifier_.WriteOrBufferData(5, 1024, FIN);
92 EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(5));
93 EXPECT_TRUE(notifier_.HasUnackedStreamData());
94
95 // Reset stream 5 with no error.
96 EXPECT_CALL(connection_, SendControlFrame(_))
97 .WillRepeatedly(
98 Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
99 notifier_.WriteOrBufferRstStream(5, QUIC_STREAM_NO_ERROR, 1024);
100 // Verify stream 5 is waiting for acks.
101 EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(5));
102 EXPECT_TRUE(notifier_.HasUnackedStreamData());
103
104 // Reset stream 5 with error.
105 notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
106 EXPECT_FALSE(notifier_.StreamIsWaitingForAcks(5));
107 EXPECT_FALSE(notifier_.HasUnackedStreamData());
108 }
109
TEST_F(SimpleSessionNotifierTest,WriteOrBufferPing)110 TEST_F(SimpleSessionNotifierTest, WriteOrBufferPing) {
111 InSequence s;
112 // Write ping when connection is not write blocked.
113 EXPECT_CALL(connection_, SendControlFrame(_))
114 .WillRepeatedly(
115 Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
116 notifier_.WriteOrBufferPing();
117 EXPECT_EQ(0u, notifier_.StreamBytesToSend());
118 EXPECT_FALSE(notifier_.WillingToWrite());
119
120 // Write stream data and cause the connection to be write blocked.
121 EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, NO_FIN))
122 .WillOnce(Return(QuicConsumedData(1024, false)));
123 notifier_.WriteOrBufferData(3, 1024, NO_FIN);
124 EXPECT_EQ(0u, notifier_.StreamBytesToSend());
125 EXPECT_CALL(connection_, SendStreamData(5, 512, 0, NO_FIN))
126 .WillOnce(Return(QuicConsumedData(256, false)));
127 notifier_.WriteOrBufferData(5, 512, NO_FIN);
128 EXPECT_TRUE(notifier_.WillingToWrite());
129
130 // Connection is blocked.
131 EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
132 notifier_.WriteOrBufferPing();
133 }
134
TEST_F(SimpleSessionNotifierTest,NeuterUnencryptedData)135 TEST_F(SimpleSessionNotifierTest, NeuterUnencryptedData) {
136 if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
137 // This test writes crypto data through crypto streams. It won't work when
138 // crypto frames are used instead.
139 return;
140 }
141 InSequence s;
142 // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
143 connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
144 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
145 connection_.transport_version()),
146 1024, 0, NO_FIN))
147 .WillOnce(Return(QuicConsumedData(1024, false)));
148 notifier_.WriteOrBufferData(
149 QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
150 NO_FIN);
151 // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
152 connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
153 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
154 connection_.transport_version()),
155 1024, 1024, NO_FIN))
156 .WillOnce(Return(QuicConsumedData(1024, false)));
157 notifier_.WriteOrBufferData(
158 QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
159 NO_FIN);
160 // Ack [1024, 2048).
161 QuicStreamFrame stream_frame(
162 QuicUtils::GetCryptoStreamId(connection_.transport_version()), false,
163 1024, 1024);
164 notifier_.OnFrameAcked(QuicFrame(stream_frame), QuicTime::Delta::Zero(),
165 QuicTime::Zero());
166 EXPECT_TRUE(notifier_.StreamIsWaitingForAcks(
167 QuicUtils::GetCryptoStreamId(connection_.transport_version())));
168 EXPECT_TRUE(notifier_.HasUnackedStreamData());
169
170 // Neuters unencrypted data.
171 notifier_.NeuterUnencryptedData();
172 EXPECT_FALSE(notifier_.StreamIsWaitingForAcks(
173 QuicUtils::GetCryptoStreamId(connection_.transport_version())));
174 EXPECT_FALSE(notifier_.HasUnackedStreamData());
175 }
176
TEST_F(SimpleSessionNotifierTest,OnCanWrite)177 TEST_F(SimpleSessionNotifierTest, OnCanWrite) {
178 if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
179 // This test writes crypto data through crypto streams. It won't work when
180 // crypto frames are used instead.
181 return;
182 }
183 InSequence s;
184 // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
185 connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
186 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
187 connection_.transport_version()),
188 1024, 0, NO_FIN))
189 .WillOnce(Return(QuicConsumedData(1024, false)));
190 notifier_.WriteOrBufferData(
191 QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
192 NO_FIN);
193
194 // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
195 connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
196 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
197 connection_.transport_version()),
198 1024, 1024, NO_FIN))
199 .WillOnce(Return(QuicConsumedData(1024, false)));
200 notifier_.WriteOrBufferData(
201 QuicUtils::GetCryptoStreamId(connection_.transport_version()), 1024,
202 NO_FIN);
203 // Send stream 3 [0, 1024) and connection is blocked.
204 EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
205 .WillOnce(Return(QuicConsumedData(512, false)));
206 notifier_.WriteOrBufferData(3, 1024, FIN);
207 // Send stream 5 [0, 1024).
208 EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
209 notifier_.WriteOrBufferData(5, 1024, NO_FIN);
210 // Reset stream 5 with error.
211 EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
212 notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
213
214 // Lost crypto data [500, 1500) and stream 3 [0, 512).
215 QuicStreamFrame frame1(
216 QuicUtils::GetCryptoStreamId(connection_.transport_version()), false, 500,
217 1000);
218 QuicStreamFrame frame2(3, false, 0, 512);
219 notifier_.OnFrameLost(QuicFrame(frame1));
220 notifier_.OnFrameLost(QuicFrame(frame2));
221
222 // Connection becomes writable.
223 // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
224 // they are in different encryption levels.
225 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
226 connection_.transport_version()),
227 524, 500, NO_FIN))
228 .WillOnce(Return(QuicConsumedData(524, false)));
229 EXPECT_CALL(connection_, SendStreamData(QuicUtils::GetCryptoStreamId(
230 connection_.transport_version()),
231 476, 1024, NO_FIN))
232 .WillOnce(Return(QuicConsumedData(476, false)));
233 // Lost stream 3 data gets retransmitted.
234 EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
235 .WillOnce(Return(QuicConsumedData(512, false)));
236 // Buffered control frames get sent.
237 EXPECT_CALL(connection_, SendControlFrame(_))
238 .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
239 // Buffered stream 3 data [512, 1024) gets sent.
240 EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
241 .WillOnce(Return(QuicConsumedData(512, true)));
242 notifier_.OnCanWrite();
243 EXPECT_FALSE(notifier_.WillingToWrite());
244 }
245
TEST_F(SimpleSessionNotifierTest,OnCanWriteCryptoFrames)246 TEST_F(SimpleSessionNotifierTest, OnCanWriteCryptoFrames) {
247 if (!QuicVersionUsesCryptoFrames(connection_.transport_version())) {
248 return;
249 }
250 SimpleDataProducer producer;
251 connection_.SetDataProducer(&producer);
252 InSequence s;
253 // Send crypto data [0, 1024) in ENCRYPTION_INITIAL.
254 connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
255 EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 1024, 0))
256 .WillOnce(Invoke(&connection_,
257 &MockQuicConnection::QuicConnection_SendCryptoData));
258 EXPECT_CALL(connection_, CloseConnection(QUIC_PACKET_WRITE_ERROR, _, _));
259 std::string crypto_data1(1024, 'a');
260 producer.SaveCryptoData(ENCRYPTION_INITIAL, 0, crypto_data1);
261 std::string crypto_data2(524, 'a');
262 producer.SaveCryptoData(ENCRYPTION_INITIAL, 500, crypto_data2);
263 notifier_.WriteCryptoData(ENCRYPTION_INITIAL, 1024, 0);
264 // Send crypto data [1024, 2048) in ENCRYPTION_ZERO_RTT.
265 connection_.SetEncrypter(ENCRYPTION_ZERO_RTT, std::make_unique<NullEncrypter>(
266 Perspective::IS_CLIENT));
267 connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
268 EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0))
269 .WillOnce(Invoke(&connection_,
270 &MockQuicConnection::QuicConnection_SendCryptoData));
271 std::string crypto_data3(1024, 'a');
272 producer.SaveCryptoData(ENCRYPTION_ZERO_RTT, 0, crypto_data3);
273 notifier_.WriteCryptoData(ENCRYPTION_ZERO_RTT, 1024, 0);
274 // Send stream 3 [0, 1024) and connection is blocked.
275 EXPECT_CALL(connection_, SendStreamData(3, 1024, 0, FIN))
276 .WillOnce(Return(QuicConsumedData(512, false)));
277 notifier_.WriteOrBufferData(3, 1024, FIN);
278 // Send stream 5 [0, 1024).
279 EXPECT_CALL(connection_, SendStreamData(5, _, _, _)).Times(0);
280 notifier_.WriteOrBufferData(5, 1024, NO_FIN);
281 // Reset stream 5 with error.
282 EXPECT_CALL(connection_, SendControlFrame(_)).Times(0);
283 notifier_.WriteOrBufferRstStream(5, QUIC_ERROR_PROCESSING_STREAM, 1024);
284
285 // Lost crypto data [500, 1500) and stream 3 [0, 512).
286 QuicCryptoFrame crypto_frame1(ENCRYPTION_INITIAL, 500, 524);
287 QuicCryptoFrame crypto_frame2(ENCRYPTION_ZERO_RTT, 0, 476);
288 QuicStreamFrame stream3_frame(3, false, 0, 512);
289 notifier_.OnFrameLost(QuicFrame(&crypto_frame1));
290 notifier_.OnFrameLost(QuicFrame(&crypto_frame2));
291 notifier_.OnFrameLost(QuicFrame(stream3_frame));
292
293 // Connection becomes writable.
294 // Lost crypto data gets retransmitted as [500, 1024) and [1024, 1500), as
295 // they are in different encryption levels.
296 EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_INITIAL, 524, 500))
297 .WillOnce(Invoke(&connection_,
298 &MockQuicConnection::QuicConnection_SendCryptoData));
299 EXPECT_CALL(connection_, SendCryptoData(ENCRYPTION_ZERO_RTT, 476, 0))
300 .WillOnce(Invoke(&connection_,
301 &MockQuicConnection::QuicConnection_SendCryptoData));
302 // Lost stream 3 data gets retransmitted.
303 EXPECT_CALL(connection_, SendStreamData(3, 512, 0, NO_FIN))
304 .WillOnce(Return(QuicConsumedData(512, false)));
305 // Buffered control frames get sent.
306 EXPECT_CALL(connection_, SendControlFrame(_))
307 .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
308 // Buffered stream 3 data [512, 1024) gets sent.
309 EXPECT_CALL(connection_, SendStreamData(3, 512, 512, FIN))
310 .WillOnce(Return(QuicConsumedData(512, true)));
311 notifier_.OnCanWrite();
312 EXPECT_FALSE(notifier_.WillingToWrite());
313 }
314
TEST_F(SimpleSessionNotifierTest,RetransmitFrames)315 TEST_F(SimpleSessionNotifierTest, RetransmitFrames) {
316 InSequence s;
317 connection_.SetEncrypter(
318 ENCRYPTION_FORWARD_SECURE,
319 std::make_unique<NullEncrypter>(Perspective::IS_CLIENT));
320 // Send stream 3 data [0, 10) and fin.
321 EXPECT_CALL(connection_, SendStreamData(3, 10, 0, FIN))
322 .WillOnce(Return(QuicConsumedData(10, true)));
323 notifier_.WriteOrBufferData(3, 10, FIN);
324 QuicStreamFrame frame1(3, true, 0, 10);
325 // Send stream 5 [0, 10) and fin.
326 EXPECT_CALL(connection_, SendStreamData(5, 10, 0, FIN))
327 .WillOnce(Return(QuicConsumedData(10, true)));
328 notifier_.WriteOrBufferData(5, 10, FIN);
329 QuicStreamFrame frame2(5, true, 0, 10);
330 // Reset stream 5 with no error.
331 EXPECT_CALL(connection_, SendControlFrame(_))
332 .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
333 notifier_.WriteOrBufferRstStream(5, QUIC_STREAM_NO_ERROR, 10);
334
335 // Ack stream 3 [3, 7), and stream 5 [8, 10).
336 QuicStreamFrame ack_frame1(3, false, 3, 4);
337 QuicStreamFrame ack_frame2(5, false, 8, 2);
338 notifier_.OnFrameAcked(QuicFrame(ack_frame1), QuicTime::Delta::Zero(),
339 QuicTime::Zero());
340 notifier_.OnFrameAcked(QuicFrame(ack_frame2), QuicTime::Delta::Zero(),
341 QuicTime::Zero());
342 EXPECT_FALSE(notifier_.WillingToWrite());
343
344 // Force to send.
345 QuicRstStreamFrame rst_stream(1, 5, QUIC_STREAM_NO_ERROR, 10);
346 QuicFrames frames;
347 frames.push_back(QuicFrame(frame2));
348 frames.push_back(QuicFrame(&rst_stream));
349 frames.push_back(QuicFrame(frame1));
350 // stream 5 data [0, 8), fin only are retransmitted.
351 EXPECT_CALL(connection_, SendStreamData(5, 8, 0, NO_FIN))
352 .WillOnce(Return(QuicConsumedData(8, false)));
353 EXPECT_CALL(connection_, SendStreamData(5, 0, 10, FIN))
354 .WillOnce(Return(QuicConsumedData(0, true)));
355 // rst_stream is retransmitted.
356 EXPECT_CALL(connection_, SendControlFrame(_))
357 .WillOnce(Invoke(this, &SimpleSessionNotifierTest::ControlFrameConsumed));
358 // stream 3 data [0, 3) is retransmitted and connection is blocked.
359 EXPECT_CALL(connection_, SendStreamData(3, 3, 0, NO_FIN))
360 .WillOnce(Return(QuicConsumedData(2, false)));
361 notifier_.RetransmitFrames(frames, PTO_RETRANSMISSION);
362 EXPECT_FALSE(notifier_.WillingToWrite());
363 }
364
365 } // namespace
366 } // namespace test
367 } // namespace quic
368