1 /** @file
2  *
3  *  A brief file description
4  *
5  *  @section license License
6  *
7  *  Licensed to the Apache Software Foundation (ASF) under one
8  *  or more contributor license agreements.  See the NOTICE file
9  *  distributed with this work for additional information
10  *  regarding copyright ownership.  The ASF licenses this file
11  *  to you under the Apache License, Version 2.0 (the
12  *  "License"); you may not use this file except in compliance
13  *  with the License.  You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  *  Unless required by applicable law or agreed to in writing, software
18  *  distributed under the License is distributed on an "AS IS" BASIS,
19  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  *  See the License for the specific language governing permissions and
21  *  limitations under the License.
22  */
23 
24 #include "catch.hpp"
25 
26 #include "quic/QUICFlowController.h"
27 #include "quic/Mock.h"
28 #include <memory>
29 
30 static constexpr int DEFAULT_RTT = 1 * HRTIME_SECOND;
31 
32 class MockRTTProvider : public QUICRTTProvider
33 {
34 public:
35   ink_hrtime
smoothed_rtt() const36   smoothed_rtt() const override
37   {
38     return this->_smoothed_rtt;
39   }
40 
MockRTTProvider(ink_hrtime rtt)41   MockRTTProvider(ink_hrtime rtt) : _smoothed_rtt(rtt) {}
42   void
set_smoothed_rtt(ink_hrtime rtt)43   set_smoothed_rtt(ink_hrtime rtt)
44   {
45     this->_smoothed_rtt = rtt;
46   }
47 
48   ink_hrtime
latest_rtt() const49   latest_rtt() const override
50   {
51     return HRTIME_MSECONDS(1);
52   }
53 
54   ink_hrtime
rttvar() const55   rttvar() const override
56   {
57     return HRTIME_MSECONDS(1);
58   }
59 
60   ink_hrtime
congestion_period(uint32_t period) const61   congestion_period(uint32_t period) const override
62   {
63     return HRTIME_MSECONDS(1);
64   }
65 
66 private:
67   ink_hrtime _smoothed_rtt = 0;
68 };
69 
70 TEST_CASE("QUICFlowController_Local_Connection", "[quic]")
71 {
72   int ret = 0;
73   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
74   MockRTTProvider rp(DEFAULT_RTT);
75   QUICLocalConnectionFlowController fc(&rp, 1024);
76 
77   // Check initial state
78   CHECK(fc.current_offset() == 0);
79   CHECK(fc.current_limit() == 1024);
80 
81   ret = fc.update(256);
82   CHECK(fc.current_offset() == 256);
83   CHECK(fc.current_limit() == 1024);
84   CHECK(ret == 0);
85 
86   ret = fc.update(512);
87   CHECK(fc.current_offset() == 512);
88   CHECK(fc.current_limit() == 1024);
89   CHECK(ret == 0);
90 
91   // Retransmit
92   ret = fc.update(512);
93   CHECK(fc.current_offset() == 512);
94   CHECK(fc.current_limit() == 1024);
95   CHECK(ret == 0);
96 
97   ret = fc.update(1024);
98   CHECK(fc.current_offset() == 1024);
99   CHECK(fc.current_limit() == 1024);
100   CHECK(ret == 0);
101 
102   // Delay
103   ret = fc.update(512);
104   CHECK(fc.current_offset() == 1024);
105   CHECK(fc.current_limit() == 1024);
106   CHECK(ret == 0);
107   Thread::get_hrtime_updated();
108 
109   // Exceed limit
110   ret = fc.update(1280);
111   CHECK(fc.current_offset() == 1024);
112   CHECK(fc.current_limit() == 1024);
113   CHECK(ret != 0);
114 
115   // MAX_STREAM_DATA
116   fc.forward_limit(2048);
117   CHECK(fc.current_offset() == 1024);
118   CHECK(fc.current_limit() == 2048);
119   QUICFrame *frame = fc.generate_frame(frame_buf, QUICEncryptionLevel::ONE_RTT, 0, 1024, 0, 0);
120   CHECK(frame);
121   CHECK(frame->type() == QUICFrameType::MAX_DATA);
122 
123   ret = fc.update(1280);
124   CHECK(fc.current_offset() == 1280);
125   CHECK(fc.current_limit() == 2048);
126   CHECK(ret == 0);
127 }
128 
129 TEST_CASE("QUICFlowController_Remote_Connection", "[quic]")
130 {
131   int ret = 0;
132   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
133   QUICRemoteConnectionFlowController fc(1024);
134 
135   // Check initial state
136   CHECK(fc.current_offset() == 0);
137   CHECK(fc.current_limit() == 1024);
138 
139   ret = fc.update(256);
140   CHECK(fc.current_offset() == 256);
141   CHECK(fc.current_limit() == 1024);
142   CHECK(ret == 0);
143 
144   ret = fc.update(512);
145   CHECK(fc.current_offset() == 512);
146   CHECK(fc.current_limit() == 1024);
147   CHECK(ret == 0);
148 
149   // Retransmit
150   ret = fc.update(512);
151   CHECK(fc.current_offset() == 512);
152   CHECK(fc.current_limit() == 1024);
153   CHECK(ret == 0);
154 
155   ret = fc.update(1000);
156   CHECK(fc.current_offset() == 1000);
157   CHECK(fc.current_limit() == 1024);
158   CHECK(ret == 0);
159 
160   // Delay
161   ret = fc.update(512);
162   CHECK(fc.current_offset() == 1000);
163   CHECK(fc.current_limit() == 1024);
164   CHECK(ret == 0);
165 
166   // Exceed limit
167   ret = fc.update(1280);
168   CHECK(fc.current_offset() == 1000);
169   CHECK(fc.current_limit() == 1024);
170   CHECK(ret != 0);
171   QUICFrame *frame = fc.generate_frame(frame_buf, QUICEncryptionLevel::ONE_RTT, 0, 1024, 0, 0);
172   CHECK(frame);
173   CHECK(frame->type() == QUICFrameType::DATA_BLOCKED);
174 
175   // MAX_STREAM_DATA
176   fc.forward_limit(2048);
177   CHECK(fc.current_offset() == 1000);
178   CHECK(fc.current_limit() == 2048);
179 
180   ret = fc.update(1280);
181   CHECK(fc.current_offset() == 1280);
182   CHECK(fc.current_limit() == 2048);
183   CHECK(ret == 0);
184 }
185 
186 TEST_CASE("QUICFlowController_Remote_Connection_ZERO_Credit", "[quic]")
187 {
188   int ret = 0;
189   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
190   QUICRemoteConnectionFlowController fc(1024);
191 
192   // Check initial state
193   CHECK(fc.current_offset() == 0);
194   CHECK(fc.current_limit() == 1024);
195 
196   // Zero credit
197   ret = fc.update(1024);
198   CHECK(fc.current_offset() == 1024);
199   CHECK(fc.current_limit() == 1024);
200   CHECK(ret == 0);
201 
202   CHECK(fc.will_generate_frame(QUICEncryptionLevel::ONE_RTT, 0, true, 0));
203   // if there're anything to send
204   QUICFrame *frame = fc.generate_frame(frame_buf, QUICEncryptionLevel::ONE_RTT, 0, 1024, 0, 0);
205   CHECK(frame);
206   CHECK(frame->type() == QUICFrameType::DATA_BLOCKED);
207 
208   // MAX_STREAM_DATA
209   fc.forward_limit(2048);
210   CHECK(fc.current_offset() == 1024);
211   CHECK(fc.current_limit() == 2048);
212 
213   ret = fc.update(1280);
214   CHECK(fc.current_offset() == 1280);
215   CHECK(fc.current_limit() == 2048);
216   CHECK(ret == 0);
217 }
218 
219 TEST_CASE("QUICFlowController_Local_Stream", "[quic]")
220 {
221   int ret = 0;
222   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
223   MockRTTProvider rp(DEFAULT_RTT);
224   QUICLocalStreamFlowController fc(&rp, 1024, 0);
225 
226   // Check initial state
227   CHECK(fc.current_offset() == 0);
228   CHECK(fc.current_limit() == 1024);
229 
230   ret = fc.update(256);
231   CHECK(fc.current_offset() == 256);
232   CHECK(fc.current_limit() == 1024);
233   CHECK(ret == 0);
234 
235   ret = fc.update(512);
236   CHECK(fc.current_offset() == 512);
237   CHECK(fc.current_limit() == 1024);
238   CHECK(ret == 0);
239 
240   // Retransmit
241   ret = fc.update(512);
242   CHECK(fc.current_offset() == 512);
243   CHECK(fc.current_limit() == 1024);
244   CHECK(ret == 0);
245 
246   ret = fc.update(1024);
247   CHECK(fc.current_offset() == 1024);
248   CHECK(fc.current_limit() == 1024);
249   CHECK(ret == 0);
250 
251   // Delay
252   ret = fc.update(512);
253   CHECK(fc.current_offset() == 1024);
254   CHECK(fc.current_limit() == 1024);
255   CHECK(ret == 0);
256   Thread::get_hrtime_updated();
257 
258   // Exceed limit
259   ret = fc.update(1280);
260   CHECK(fc.current_offset() == 1024);
261   CHECK(fc.current_limit() == 1024);
262   CHECK(ret != 0);
263 
264   // MAX_STREAM_DATA
265   fc.forward_limit(2048);
266   CHECK(fc.current_offset() == 1024);
267   CHECK(fc.current_limit() == 2048);
268   QUICFrame *frame = fc.generate_frame(frame_buf, QUICEncryptionLevel::ONE_RTT, 0, 1024, 0, 0);
269   CHECK(frame);
270   CHECK(frame->type() == QUICFrameType::MAX_STREAM_DATA);
271 
272   ret = fc.update(1280);
273   CHECK(fc.current_offset() == 1280);
274   CHECK(fc.current_limit() == 2048);
275   CHECK(ret == 0);
276 }
277 
278 TEST_CASE("QUICFlowController_Remote_Stream", "[quic]")
279 {
280   int ret = 0;
281   QUICRemoteStreamFlowController fc(1024, 0);
282 
283   // Check initial state
284   CHECK(fc.current_offset() == 0);
285   CHECK(fc.current_limit() == 1024);
286 
287   ret = fc.update(256);
288   CHECK(fc.current_offset() == 256);
289   CHECK(fc.current_limit() == 1024);
290   CHECK(ret == 0);
291 
292   ret = fc.update(512);
293   CHECK(fc.current_offset() == 512);
294   CHECK(fc.current_limit() == 1024);
295   CHECK(ret == 0);
296 
297   // Retransmit
298   ret = fc.update(512);
299   CHECK(fc.current_offset() == 512);
300   CHECK(fc.current_limit() == 1024);
301   CHECK(ret == 0);
302 
303   ret = fc.update(1024);
304   CHECK(fc.current_offset() == 1024);
305   CHECK(fc.current_limit() == 1024);
306   CHECK(ret == 0);
307 
308   CHECK(fc.credit() == 0);
309   CHECK(fc.will_generate_frame(QUICEncryptionLevel::ONE_RTT, 0, true, 0));
310 
311   // Delay
312   ret = fc.update(512);
313   CHECK(fc.current_offset() == 1024);
314   CHECK(fc.current_limit() == 1024);
315   CHECK(ret == 0);
316 
317   // Exceed limit
318   ret = fc.update(1280);
319   CHECK(fc.current_offset() == 1024);
320   CHECK(fc.current_limit() == 1024);
321   CHECK(ret != 0);
322 
323   // MAX_STREAM_DATA
324   fc.forward_limit(2048);
325   CHECK(fc.current_offset() == 1024);
326   CHECK(fc.current_limit() == 2048);
327 
328   ret = fc.update(1280);
329   CHECK(fc.current_offset() == 1280);
330   CHECK(fc.current_limit() == 2048);
331   CHECK(ret == 0);
332 }
333 
334 TEST_CASE("Frame retransmission", "[quic]")
335 {
336   QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
337 
338   SECTION("BLOCKED frame")
339   {
340     int ret = 0;
341     uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
342     QUICRemoteConnectionFlowController fc(1024);
343 
344     // Check initial state
345     auto frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
346     CHECK(!frame);
347 
348     ret = fc.update(1024);
349     CHECK(ret == 0);
350     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
351     REQUIRE(frame);
352     CHECK(static_cast<QUICDataBlockedFrame *>(frame)->offset() == 1024);
353     QUICFrameId id = frame->id();
354 
355     // Don't retransmit unless the frame is lost
356     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
357     REQUIRE(!frame);
358 
359     // Retransmit
360     fc.on_frame_lost(id);
361     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
362     REQUIRE(frame);
363     CHECK(static_cast<QUICDataBlockedFrame *>(frame)->offset() == 1024);
364 
365     // Don't send if it was not blocked
366     fc.on_frame_lost(frame->id());
367     fc.forward_limit(2048);
368     ret   = fc.update(1536);
369     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
370     CHECK(!frame);
371 
372     // This should not be retransmition
373     ret   = fc.update(2048);
374     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
375     REQUIRE(frame);
376     CHECK(static_cast<QUICDataBlockedFrame *>(frame)->offset() == 2048);
377   }
378 
379   SECTION("STREAM_DATA_BLOCKED frame")
380   {
381     int ret = 0;
382     uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
383     QUICRemoteStreamFlowController fc(1024, 0);
384 
385     // Check initial state
386     auto frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
387     CHECK(!frame);
388 
389     ret = fc.update(1024);
390     CHECK(ret == 0);
391     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
392     REQUIRE(frame);
393     CHECK(static_cast<QUICStreamDataBlockedFrame *>(frame)->offset() == 1024);
394     QUICFrameId id = frame->id();
395 
396     // Don't retransmit unless the frame is lost
397     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
398     REQUIRE(!frame);
399 
400     // Retransmit
401     fc.on_frame_lost(id);
402     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
403     REQUIRE(frame);
404     CHECK(static_cast<QUICStreamDataBlockedFrame *>(frame)->offset() == 1024);
405 
406     // Don't send if it was not blocked
407     fc.on_frame_lost(frame->id());
408     fc.forward_limit(2048);
409     ret   = fc.update(1536);
410     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
411     CHECK(!frame);
412 
413     // This should not be retransmition
414     ret   = fc.update(2048);
415     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
416     REQUIRE(frame);
417     CHECK(static_cast<QUICStreamDataBlockedFrame *>(frame)->offset() == 2048);
418   }
419 
420   SECTION("MAX_DATA frame")
421   {
422     uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
423     MockRTTProvider rp(DEFAULT_RTT);
424     QUICLocalConnectionFlowController fc(&rp, 1024);
425 
426     // Check initial state
427     auto frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
428     CHECK(!frame);
429 
430     fc.update(1024);
431     fc.forward_limit(1024);
432     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
433     REQUIRE(frame);
434     CHECK(static_cast<QUICMaxDataFrame *>(frame)->maximum_data() == 1024);
435     QUICFrameId id = frame->id();
436 
437     // Don't retransmit unless the frame is lost
438     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
439     REQUIRE(!frame);
440 
441     // Retransmit
442     fc.on_frame_lost(id);
443     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
444     REQUIRE(frame);
445     CHECK(static_cast<QUICMaxDataFrame *>(frame)->maximum_data() == 1024);
446 
447     // Send new one if it was updated
448     fc.on_frame_lost(id);
449     fc.forward_limit(2048);
450     fc.update(2048);
451     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
452     REQUIRE(frame);
453     CHECK(static_cast<QUICMaxDataFrame *>(frame)->maximum_data() == 2048);
454   }
455 
456   SECTION("MAX_STREAM_DATA frame")
457   {
458     uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
459     MockRTTProvider rp(DEFAULT_RTT);
460     QUICLocalStreamFlowController fc(&rp, 1024, 0);
461 
462     // Check initial state
463     auto frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
464     CHECK(!frame);
465 
466     fc.update(1024);
467     fc.forward_limit(1024);
468     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
469     REQUIRE(frame);
470     CHECK(static_cast<QUICMaxStreamDataFrame *>(frame)->maximum_stream_data() == 1024);
471     QUICFrameId id = frame->id();
472 
473     // Don't retransmit unless the frame is lost
474     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
475     REQUIRE(!frame);
476 
477     // Retransmit
478     fc.on_frame_lost(id);
479     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
480     REQUIRE(frame);
481     CHECK(static_cast<QUICMaxStreamDataFrame *>(frame)->maximum_stream_data() == 1024);
482 
483     // Send new one if it was updated
484     fc.on_frame_lost(id);
485     fc.forward_limit(2048);
486     fc.update(2048);
487     frame = fc.generate_frame(frame_buf, level, 1024, 1024, 0, 0);
488     REQUIRE(frame);
489     CHECK(static_cast<QUICMaxStreamDataFrame *>(frame)->maximum_stream_data() == 2048);
490   }
491 }
492