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(&notifier_);
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