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/QUICBidirectionalStream.h"
27 #include "quic/QUICUnidirectionalStream.h"
28 #include "quic/Mock.h"
29 
30 TEST_CASE("QUICBidiStream", "[quic]")
31 {
32   // Test Data
33   uint8_t payload[]        = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
34   uint32_t stream_id       = 0x03;
35   Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
36   block->alloc();
37   memcpy(block->start(), payload, sizeof(payload));
38   block->fill(sizeof(payload));
39 
40   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
41 
42   Ptr<IOBufferBlock> new_block = make_ptr<IOBufferBlock>(block->clone());
43   new_block->_end              = new_block->_start + 2;
44   QUICStreamFrame frame_1(new_block, stream_id, 0);
45   block->consume(2);
46 
47   new_block       = block->clone();
48   new_block->_end = new_block->_start + 2;
49   QUICStreamFrame frame_2(new_block, stream_id, 2);
50   block->consume(2);
51 
52   new_block       = block->clone();
53   new_block->_end = new_block->_start + 2;
54   QUICStreamFrame frame_3(new_block, stream_id, 4);
55   block->consume(2);
56 
57   new_block       = block->clone();
58   new_block->_end = new_block->_start + 2;
59   QUICStreamFrame frame_4(new_block, stream_id, 6);
60   block->consume(2);
61 
62   new_block       = block->clone();
63   new_block->_end = new_block->_start + 2;
64   QUICStreamFrame frame_5(new_block, stream_id, 8);
65   block->consume(2);
66 
67   new_block       = block->clone();
68   new_block->_end = new_block->_start + 2;
69   QUICStreamFrame frame_6(new_block, stream_id, 10);
70   block->consume(2);
71 
72   new_block       = block->clone();
73   new_block->_end = new_block->_start + 2;
74   QUICStreamFrame frame_7(new_block, stream_id, 12);
75   block->consume(2);
76 
77   new_block       = block->clone();
78   new_block->_end = new_block->_start + 2;
79   QUICStreamFrame frame_8(new_block, stream_id, 14);
80   block->consume(2);
81 
82   SECTION("QUICStream_assembling_byte_stream_1")
83   {
84     MIOBuffer *read_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
85     IOBufferReader *reader = read_buffer->alloc_reader();
86 
87     QUICRTTMeasure rtt_provider;
88     MockQUICConnectionInfoProvider cinfo_provider;
89     std::unique_ptr<QUICBidirectionalStream> stream(
90       new QUICBidirectionalStream(&rtt_provider, &cinfo_provider, stream_id, 1024, 1024));
91     stream->do_io_read(nullptr, INT64_MAX, read_buffer);
92 
93     stream->recv(frame_1);
94     stream->recv(frame_2);
95     stream->recv(frame_3);
96     stream->recv(frame_4);
97     stream->recv(frame_5);
98     stream->recv(frame_6);
99     stream->recv(frame_7);
100     stream->recv(frame_8);
101 
102     uint8_t buf[32];
103     int64_t len = reader->read_avail();
104     reader->read(buf, len);
105 
106     CHECK(len == 16);
107     CHECK(memcmp(buf, payload, len) == 0);
108   }
109 
110   SECTION("QUICStream_assembling_byte_stream_2")
111   {
112     MIOBuffer *read_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
113     IOBufferReader *reader = read_buffer->alloc_reader();
114 
115     QUICRTTMeasure rtt_provider;
116     MockQUICConnectionInfoProvider cinfo_provider;
117     std::unique_ptr<QUICBidirectionalStream> stream(
118       new QUICBidirectionalStream(&rtt_provider, &cinfo_provider, stream_id, UINT64_MAX, UINT64_MAX));
119     stream->do_io_read(nullptr, INT64_MAX, read_buffer);
120 
121     stream->recv(frame_8);
122     stream->recv(frame_7);
123     stream->recv(frame_6);
124     stream->recv(frame_5);
125     stream->recv(frame_4);
126     stream->recv(frame_3);
127     stream->recv(frame_2);
128     stream->recv(frame_1);
129 
130     uint8_t buf[32];
131     int64_t len = reader->read_avail();
132     reader->read(buf, len);
133 
134     CHECK(len == 16);
135     CHECK(memcmp(buf, payload, len) == 0);
136   }
137 
138   SECTION("QUICStream_assembling_byte_stream_3")
139   {
140     MIOBuffer *read_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
141     IOBufferReader *reader = read_buffer->alloc_reader();
142 
143     QUICRTTMeasure rtt_provider;
144     MockQUICConnectionInfoProvider cinfo_provider;
145     std::unique_ptr<QUICBidirectionalStream> stream(
146       new QUICBidirectionalStream(&rtt_provider, &cinfo_provider, stream_id, UINT64_MAX, UINT64_MAX));
147     stream->do_io_read(nullptr, INT64_MAX, read_buffer);
148 
149     stream->recv(frame_8);
150     stream->recv(frame_7);
151     stream->recv(frame_6);
152     stream->recv(frame_7); // duplicated frame
153     stream->recv(frame_5);
154     stream->recv(frame_3);
155     stream->recv(frame_1);
156     stream->recv(frame_2);
157     stream->recv(frame_4);
158     stream->recv(frame_5); // duplicated frame
159 
160     uint8_t buf[32];
161     int64_t len = reader->read_avail();
162     reader->read(buf, len);
163 
164     CHECK(len == 16);
165     CHECK(memcmp(buf, payload, len) == 0);
166   }
167 
168   SECTION("QUICStream_flow_control_local", "[quic]")
169   {
170     std::unique_ptr<QUICError> error = nullptr;
171 
172     MIOBuffer *read_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
173 
174     QUICRTTMeasure rtt_provider;
175     MockQUICConnectionInfoProvider cinfo_provider;
176     std::unique_ptr<QUICBidirectionalStream> stream(
177       new QUICBidirectionalStream(&rtt_provider, &cinfo_provider, stream_id, 4096, 4096));
178     stream->do_io_read(nullptr, INT64_MAX, read_buffer);
179 
180     Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
181     block->alloc();
182     block->fill(1024);
183 
184     // Start with 1024 but not 0 so received frames won't be processed
185     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 1024));
186     CHECK(error == nullptr);
187     // duplicate
188     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 1024));
189     CHECK(error == nullptr);
190     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 3072));
191     CHECK(error == nullptr);
192     // delay
193     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 2048));
194     CHECK(error == nullptr);
195     // all frames should be processed
196     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 0));
197     CHECK(error == nullptr);
198     // start again without the first block
199     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 5120));
200     CHECK(error == nullptr);
201     // this should exceed the limit
202     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 8192));
203     CHECK(error->cls == QUICErrorClass::TRANSPORT);
204     CHECK(error->code == static_cast<uint16_t>(QUICTransErrorCode::FLOW_CONTROL_ERROR));
205   }
206 
207   SECTION("QUICStream_flow_control_remote", "[quic]")
208   {
209     std::unique_ptr<QUICError> error = nullptr;
210 
211     MIOBuffer *read_buffer              = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
212     MIOBuffer *write_buffer             = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
213     IOBufferReader *write_buffer_reader = write_buffer->alloc_reader();
214 
215     QUICRTTMeasure rtt_provider;
216     MockQUICConnectionInfoProvider cinfo_provider;
217     std::unique_ptr<QUICBidirectionalStream> stream(
218       new QUICBidirectionalStream(&rtt_provider, &cinfo_provider, stream_id, 4096, 4096));
219     SCOPED_MUTEX_LOCK(lock, stream->mutex, this_ethread());
220 
221     MockContinuation mock_cont(stream->mutex);
222     stream->do_io_read(nullptr, INT64_MAX, read_buffer);
223     stream->do_io_write(&mock_cont, INT64_MAX, write_buffer_reader);
224 
225     QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
226 
227     const char data[1024] = {0};
228     QUICFrame *frame      = nullptr;
229 
230     write_buffer->write(data, 1024);
231     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
232     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
233     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
234     CHECK(frame->type() == QUICFrameType::STREAM);
235     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
236 
237     write_buffer->write(data, 1024);
238     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
239     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
240     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
241     CHECK(frame->type() == QUICFrameType::STREAM);
242     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
243 
244     write_buffer->write(data, 1024);
245     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
246     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
247     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
248     CHECK(frame->type() == QUICFrameType::STREAM);
249     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
250 
251     write_buffer->write(data, 1024);
252     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
253     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
254     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
255     CHECK(frame->type() == QUICFrameType::STREAM);
256     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
257 
258     // This should not send a frame because of flow control
259     write_buffer->write(data, 1024);
260     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
261     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
262     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
263     CHECK(frame);
264     CHECK(frame->type() == QUICFrameType::STREAM_DATA_BLOCKED);
265     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
266 
267     // Update window
268     stream->recv(*std::make_shared<QUICMaxStreamDataFrame>(stream_id, 5120));
269 
270     // This should send a frame
271     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
272     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
273     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
274     CHECK(frame->type() == QUICFrameType::STREAM);
275     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
276 
277     // Update window
278     stream->recv(*std::make_shared<QUICMaxStreamDataFrame>(stream_id, 5632));
279 
280     // This should send a frame
281     write_buffer->write(data, 1024);
282     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
283     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
284     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
285     CHECK(frame->type() == QUICFrameType::STREAM);
286     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
287 
288     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
289     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
290     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
291     CHECK(frame->type() == QUICFrameType::STREAM_DATA_BLOCKED);
292 
293     // Update window
294     stream->recv(*std::make_shared<QUICMaxStreamDataFrame>(stream_id, 6144));
295 
296     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
297     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
298     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
299     CHECK(frame->type() == QUICFrameType::STREAM);
300     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
301   }
302 
303   /*
304    * This test does not pass now
305    */
306   SECTION("Retransmit STREAM frame")
307   {
308     MIOBuffer *write_buffer             = new_MIOBuffer(BUFFER_SIZE_INDEX_8K);
309     IOBufferReader *write_buffer_reader = write_buffer->alloc_reader();
310 
311     QUICRTTMeasure rtt_provider;
312     MockQUICConnectionInfoProvider cinfo_provider;
313     std::unique_ptr<QUICBidirectionalStream> stream(
314       new QUICBidirectionalStream(&rtt_provider, &cinfo_provider, stream_id, UINT64_MAX, UINT64_MAX));
315     SCOPED_MUTEX_LOCK(lock, stream->mutex, this_ethread());
316 
317     MockContinuation mock_cont(stream->mutex);
318     stream->do_io_write(&mock_cont, INT64_MAX, write_buffer_reader);
319 
320     QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
321     const char data1[]        = "this is a test data";
322     const char data2[]        = "THIS IS ANOTHER TEST DATA";
323     QUICFrame *frame          = nullptr;
324     QUICStreamFrame *frame1   = nullptr;
325     QUICStreamFrame *frame2   = nullptr;
326     uint8_t frame_buf2[QUICFrame::MAX_INSTANCE_SIZE];
327 
328     // Write data1
329     write_buffer->write(data1, sizeof(data1));
330     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
331     // Generate STREAM frame
332     frame  = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
333     frame1 = static_cast<QUICStreamFrame *>(frame);
334     CHECK(frame->type() == QUICFrameType::STREAM);
335     CHECK(stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0) == nullptr);
336     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
337     stream->on_frame_lost(frame->id());
338     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
339 
340     // Write data2
341     write_buffer->write(data2, sizeof(data2));
342     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
343     // Lost the frame
344     stream->on_frame_lost(frame->id());
345     // Regenerate a frame
346     frame = stream->generate_frame(frame_buf2, level, 4096, 4096, 0, 0);
347     // Lost data should be resent first
348     frame2 = static_cast<QUICStreamFrame *>(frame);
349     CHECK(frame->type() == QUICFrameType::STREAM);
350     CHECK(frame1->offset() == frame2->offset());
351     CHECK(frame1->data_length() == frame2->data_length());
352     CHECK(memcmp(frame1->data()->buf(), frame2->data()->buf(), frame1->data_length()) == 0);
353   }
354 
355   SECTION("Retransmit RESET_STREAM frame")
356   {
357     MIOBuffer *write_buffer             = new_MIOBuffer(BUFFER_SIZE_INDEX_8K);
358     IOBufferReader *write_buffer_reader = write_buffer->alloc_reader();
359 
360     QUICRTTMeasure rtt_provider;
361     MockQUICConnectionInfoProvider cinfo_provider;
362     std::unique_ptr<QUICBidirectionalStream> stream(
363       new QUICBidirectionalStream(&rtt_provider, &cinfo_provider, stream_id, UINT64_MAX, UINT64_MAX));
364     SCOPED_MUTEX_LOCK(lock, stream->mutex, this_ethread());
365 
366     MockContinuation mock_cont(stream->mutex);
367     stream->do_io_write(&mock_cont, INT64_MAX, write_buffer_reader);
368 
369     QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
370     QUICFrame *frame          = nullptr;
371 
372     stream->reset(QUICStreamErrorUPtr(new QUICStreamError(stream.get(), QUIC_APP_ERROR_CODE_STOPPING)));
373     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
374     REQUIRE(frame);
375     CHECK(frame->type() == QUICFrameType::RESET_STREAM);
376     // Don't send it again untill it is considers as lost
377     CHECK(stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0) == nullptr);
378     // Loss the frame
379     stream->on_frame_lost(frame->id());
380     // After the loss the frame should be regenerated
381     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
382     REQUIRE(frame);
383     CHECK(frame->type() == QUICFrameType::RESET_STREAM);
384   }
385 
386   SECTION("Retransmit STOP_SENDING frame")
387   {
388     MIOBuffer *write_buffer             = new_MIOBuffer(BUFFER_SIZE_INDEX_8K);
389     IOBufferReader *write_buffer_reader = write_buffer->alloc_reader();
390 
391     QUICRTTMeasure rtt_provider;
392     MockQUICConnectionInfoProvider cinfo_provider;
393     std::unique_ptr<QUICBidirectionalStream> stream(
394       new QUICBidirectionalStream(&rtt_provider, &cinfo_provider, stream_id, UINT64_MAX, UINT64_MAX));
395     SCOPED_MUTEX_LOCK(lock, stream->mutex, this_ethread());
396 
397     MockContinuation mock_cont(stream->mutex);
398     stream->do_io_write(&mock_cont, INT64_MAX, write_buffer_reader);
399 
400     QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
401     QUICFrame *frame          = nullptr;
402 
403     stream->stop_sending(QUICStreamErrorUPtr(new QUICStreamError(stream.get(), QUIC_APP_ERROR_CODE_STOPPING)));
404     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
405     REQUIRE(frame);
406     CHECK(frame->type() == QUICFrameType::STOP_SENDING);
407     // Don't send it again untill it is considers as lost
408     CHECK(stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0) == nullptr);
409     // Loss the frame
410     stream->on_frame_lost(frame->id());
411     // After the loss the frame should be regenerated
412     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
413     REQUIRE(frame);
414     CHECK(frame->type() == QUICFrameType::STOP_SENDING);
415   }
416 }
417 
418 TEST_CASE("QUIC receive only stream", "[quic]")
419 {
420   // Test Data
421   uint8_t payload[]        = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
422   uint32_t stream_id       = 0x03;
423   Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
424   block->alloc();
425   memcpy(block->start(), payload, sizeof(payload));
426   block->fill(sizeof(payload));
427 
428   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
429 
430   Ptr<IOBufferBlock> new_block = make_ptr<IOBufferBlock>(block->clone());
431   new_block->_end              = new_block->_start + 2;
432   QUICStreamFrame frame_1(new_block, stream_id, 0);
433   block->consume(2);
434 
435   new_block       = block->clone();
436   new_block->_end = new_block->_start + 2;
437   QUICStreamFrame frame_2(new_block, stream_id, 2);
438   block->consume(2);
439 
440   new_block       = block->clone();
441   new_block->_end = new_block->_start + 2;
442   QUICStreamFrame frame_3(new_block, stream_id, 4);
443   block->consume(2);
444 
445   new_block       = block->clone();
446   new_block->_end = new_block->_start + 2;
447   QUICStreamFrame frame_4(new_block, stream_id, 6);
448   block->consume(2);
449 
450   new_block       = block->clone();
451   new_block->_end = new_block->_start + 2;
452   QUICStreamFrame frame_5(new_block, stream_id, 8);
453   block->consume(2);
454 
455   new_block       = block->clone();
456   new_block->_end = new_block->_start + 2;
457   QUICStreamFrame frame_6(new_block, stream_id, 10);
458   block->consume(2);
459 
460   new_block       = block->clone();
461   new_block->_end = new_block->_start + 2;
462   QUICStreamFrame frame_7(new_block, stream_id, 12);
463   block->consume(2);
464 
465   new_block       = block->clone();
466   new_block->_end = new_block->_start + 2;
467   QUICStreamFrame frame_8(new_block, stream_id, 14);
468   block->consume(2);
469 
470   SECTION("QUICStream_assembling_byte_stream_1")
471   {
472     MIOBuffer *read_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
473     IOBufferReader *reader = read_buffer->alloc_reader();
474 
475     QUICRTTMeasure rtt_provider;
476     MockQUICConnectionInfoProvider cinfo_provider;
477     std::unique_ptr<QUICReceiveStream> stream(new QUICReceiveStream(&rtt_provider, &cinfo_provider, stream_id, 1024));
478     stream->do_io_read(nullptr, INT64_MAX, read_buffer);
479 
480     stream->recv(frame_1);
481     stream->recv(frame_2);
482     stream->recv(frame_3);
483     stream->recv(frame_4);
484     stream->recv(frame_5);
485     stream->recv(frame_6);
486     stream->recv(frame_7);
487     stream->recv(frame_8);
488 
489     uint8_t buf[32];
490     int64_t len = reader->read_avail();
491     reader->read(buf, len);
492 
493     CHECK(len == 16);
494     CHECK(memcmp(buf, payload, len) == 0);
495   }
496 
497   SECTION("QUICStream_assembling_byte_stream_2")
498   {
499     MIOBuffer *read_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
500     IOBufferReader *reader = read_buffer->alloc_reader();
501 
502     QUICRTTMeasure rtt_provider;
503     MockQUICConnectionInfoProvider cinfo_provider;
504     std::unique_ptr<QUICReceiveStream> stream(new QUICReceiveStream(&rtt_provider, &cinfo_provider, stream_id, UINT64_MAX));
505     stream->do_io_read(nullptr, INT64_MAX, read_buffer);
506 
507     stream->recv(frame_8);
508     stream->recv(frame_7);
509     stream->recv(frame_6);
510     stream->recv(frame_5);
511     stream->recv(frame_4);
512     stream->recv(frame_3);
513     stream->recv(frame_2);
514     stream->recv(frame_1);
515 
516     uint8_t buf[32];
517     int64_t len = reader->read_avail();
518     reader->read(buf, len);
519 
520     CHECK(len == 16);
521     CHECK(memcmp(buf, payload, len) == 0);
522   }
523 
524   SECTION("QUICStream_assembling_byte_stream_3")
525   {
526     MIOBuffer *read_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
527     IOBufferReader *reader = read_buffer->alloc_reader();
528 
529     QUICRTTMeasure rtt_provider;
530     MockQUICConnectionInfoProvider cinfo_provider;
531     std::unique_ptr<QUICReceiveStream> stream(new QUICReceiveStream(&rtt_provider, &cinfo_provider, stream_id, UINT64_MAX));
532     stream->do_io_read(nullptr, INT64_MAX, read_buffer);
533 
534     stream->recv(frame_8);
535     stream->recv(frame_7);
536     stream->recv(frame_6);
537     stream->recv(frame_7); // duplicated frame
538     stream->recv(frame_5);
539     stream->recv(frame_3);
540     stream->recv(frame_1);
541     stream->recv(frame_2);
542     stream->recv(frame_4);
543     stream->recv(frame_5); // duplicated frame
544 
545     uint8_t buf[32];
546     int64_t len = reader->read_avail();
547     reader->read(buf, len);
548 
549     CHECK(len == 16);
550     CHECK(memcmp(buf, payload, len) == 0);
551   }
552 
553   SECTION("QUICStream_flow_control_local", "[quic]")
554   {
555     std::unique_ptr<QUICError> error = nullptr;
556 
557     MIOBuffer *read_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
558 
559     QUICRTTMeasure rtt_provider;
560     MockQUICConnectionInfoProvider cinfo_provider;
561     std::unique_ptr<QUICReceiveStream> stream(new QUICReceiveStream(&rtt_provider, &cinfo_provider, stream_id, 4096));
562     stream->do_io_read(nullptr, INT64_MAX, read_buffer);
563 
564     Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
565     block->alloc();
566     block->fill(1024);
567 
568     // Start with 1024 but not 0 so received frames won't be processed
569     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 1024));
570     CHECK(error == nullptr);
571     // duplicate
572     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 1024));
573     CHECK(error == nullptr);
574     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 3072));
575     CHECK(error == nullptr);
576     // delay
577     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 2048));
578     CHECK(error == nullptr);
579     // all frames should be processed
580     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 0));
581     CHECK(error == nullptr);
582     // start again without the first block
583     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 5120));
584     CHECK(error == nullptr);
585     // this should exceed the limit
586     error = stream->recv(*std::make_shared<QUICStreamFrame>(block, stream_id, 8192));
587     CHECK(error->cls == QUICErrorClass::TRANSPORT);
588     CHECK(error->code == static_cast<uint16_t>(QUICTransErrorCode::FLOW_CONTROL_ERROR));
589   }
590 
591   SECTION("Retransmit STOP_SENDING frame")
592   {
593     QUICRTTMeasure rtt_provider;
594     MockQUICConnectionInfoProvider cinfo_provider;
595     std::unique_ptr<QUICReceiveStream> stream(new QUICReceiveStream(&rtt_provider, &cinfo_provider, stream_id, UINT64_MAX));
596     SCOPED_MUTEX_LOCK(lock, stream->mutex, this_ethread());
597 
598     QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
599     QUICFrame *frame          = nullptr;
600 
601     stream->stop_sending(QUICStreamErrorUPtr(new QUICStreamError(stream.get(), QUIC_APP_ERROR_CODE_STOPPING)));
602     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
603     REQUIRE(frame);
604     CHECK(frame->type() == QUICFrameType::STOP_SENDING);
605     // Don't send it again untill it is considers as lost
606     CHECK(stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0) == nullptr);
607     // Loss the frame
608     stream->on_frame_lost(frame->id());
609     // After the loss the frame should be regenerated
610     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
611     REQUIRE(frame);
612     CHECK(frame->type() == QUICFrameType::STOP_SENDING);
613   }
614 }
615 
616 TEST_CASE("QUIC send only stream", "[quic]")
617 {
618   // Test Data
619   uint8_t payload[]        = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
620   uint32_t stream_id       = 0x03;
621   Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
622   block->alloc();
623   memcpy(block->start(), payload, sizeof(payload));
624   block->fill(sizeof(payload));
625 
626   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
627 
628   Ptr<IOBufferBlock> new_block = make_ptr<IOBufferBlock>(block->clone());
629   new_block->_end              = new_block->_start + 2;
630   QUICStreamFrame frame_1(new_block, stream_id, 0);
631   block->consume(2);
632 
633   new_block       = block->clone();
634   new_block->_end = new_block->_start + 2;
635   QUICStreamFrame frame_2(new_block, stream_id, 2);
636   block->consume(2);
637 
638   new_block       = block->clone();
639   new_block->_end = new_block->_start + 2;
640   QUICStreamFrame frame_3(new_block, stream_id, 4);
641   block->consume(2);
642 
643   new_block       = block->clone();
644   new_block->_end = new_block->_start + 2;
645   QUICStreamFrame frame_4(new_block, stream_id, 6);
646   block->consume(2);
647 
648   new_block       = block->clone();
649   new_block->_end = new_block->_start + 2;
650   QUICStreamFrame frame_5(new_block, stream_id, 8);
651   block->consume(2);
652 
653   new_block       = block->clone();
654   new_block->_end = new_block->_start + 2;
655   QUICStreamFrame frame_6(new_block, stream_id, 10);
656   block->consume(2);
657 
658   new_block       = block->clone();
659   new_block->_end = new_block->_start + 2;
660   QUICStreamFrame frame_7(new_block, stream_id, 12);
661   block->consume(2);
662 
663   new_block       = block->clone();
664   new_block->_end = new_block->_start + 2;
665   QUICStreamFrame frame_8(new_block, stream_id, 14);
666   block->consume(2);
667 
668   SECTION("QUICStream_flow_control_remote", "[quic]")
669   {
670     std::unique_ptr<QUICError> error = nullptr;
671 
672     MIOBuffer *write_buffer             = new_MIOBuffer(BUFFER_SIZE_INDEX_4K);
673     IOBufferReader *write_buffer_reader = write_buffer->alloc_reader();
674 
675     QUICRTTMeasure rtt_provider;
676     MockQUICConnectionInfoProvider cinfo_provider;
677     std::unique_ptr<QUICSendStream> stream(new QUICSendStream(&cinfo_provider, stream_id, 4096));
678     SCOPED_MUTEX_LOCK(lock, stream->mutex, this_ethread());
679 
680     MockContinuation mock_cont(stream->mutex);
681     stream->do_io_write(&mock_cont, INT64_MAX, write_buffer_reader);
682 
683     QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
684 
685     const char data[1024] = {0};
686     QUICFrame *frame      = nullptr;
687 
688     write_buffer->write(data, 1024);
689     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
690     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
691     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
692     CHECK(frame->type() == QUICFrameType::STREAM);
693     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
694 
695     write_buffer->write(data, 1024);
696     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
697     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
698     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
699     CHECK(frame->type() == QUICFrameType::STREAM);
700     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
701 
702     write_buffer->write(data, 1024);
703     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
704     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
705     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
706     CHECK(frame->type() == QUICFrameType::STREAM);
707     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
708 
709     write_buffer->write(data, 1024);
710     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
711     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
712     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
713     CHECK(frame->type() == QUICFrameType::STREAM);
714     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
715 
716     // This should not send a frame because of flow control
717     write_buffer->write(data, 1024);
718     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
719     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
720     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
721     CHECK(frame);
722     CHECK(frame->type() == QUICFrameType::STREAM_DATA_BLOCKED);
723     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
724 
725     // Update window
726     stream->recv(*std::make_shared<QUICMaxStreamDataFrame>(stream_id, 5120));
727 
728     // This should send a frame
729     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
730     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
731     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
732     CHECK(frame->type() == QUICFrameType::STREAM);
733     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
734 
735     // Update window
736     stream->recv(*std::make_shared<QUICMaxStreamDataFrame>(stream_id, 5632));
737 
738     // This should send a frame
739     write_buffer->write(data, 1024);
740     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
741     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
742     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
743     CHECK(frame->type() == QUICFrameType::STREAM);
744     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
745 
746     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
747     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
748     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
749     CHECK(frame->type() == QUICFrameType::STREAM_DATA_BLOCKED);
750 
751     // Update window
752     stream->recv(*std::make_shared<QUICMaxStreamDataFrame>(stream_id, 6144));
753 
754     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
755     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
756     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
757     CHECK(frame->type() == QUICFrameType::STREAM);
758     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
759   }
760 
761   /*
762    * This test does not pass now
763    */
764   SECTION("Retransmit STREAM frame")
765   {
766     MIOBuffer *write_buffer             = new_MIOBuffer(BUFFER_SIZE_INDEX_8K);
767     IOBufferReader *write_buffer_reader = write_buffer->alloc_reader();
768 
769     QUICRTTMeasure rtt_provider;
770     MockQUICConnectionInfoProvider cinfo_provider;
771     std::unique_ptr<QUICSendStream> stream(new QUICSendStream(&cinfo_provider, stream_id, UINT64_MAX));
772     SCOPED_MUTEX_LOCK(lock, stream->mutex, this_ethread());
773 
774     MockContinuation mock_cont(stream->mutex);
775     stream->do_io_write(&mock_cont, INT64_MAX, write_buffer_reader);
776 
777     QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
778     const char data1[]        = "this is a test data";
779     const char data2[]        = "THIS IS ANOTHER TEST DATA";
780     QUICFrame *frame          = nullptr;
781     QUICStreamFrame *frame1   = nullptr;
782     QUICStreamFrame *frame2   = nullptr;
783     uint8_t frame_buf2[QUICFrame::MAX_INSTANCE_SIZE];
784 
785     // Write data1
786     write_buffer->write(data1, sizeof(data1));
787     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
788     // Generate STREAM frame
789     frame  = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
790     frame1 = static_cast<QUICStreamFrame *>(frame);
791     CHECK(frame->type() == QUICFrameType::STREAM);
792     CHECK(stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0) == nullptr);
793     CHECK(stream->will_generate_frame(level, 0, false, 0) == false);
794     stream->on_frame_lost(frame->id());
795     CHECK(stream->will_generate_frame(level, 0, false, 0) == true);
796 
797     // Write data2
798     write_buffer->write(data2, sizeof(data2));
799     stream->handleEvent(VC_EVENT_WRITE_READY, nullptr);
800     // Lost the frame
801     stream->on_frame_lost(frame->id());
802     // Regenerate a frame
803     frame = stream->generate_frame(frame_buf2, level, 4096, 4096, 0, 0);
804     // Lost data should be resent first
805     frame2 = static_cast<QUICStreamFrame *>(frame);
806     CHECK(frame->type() == QUICFrameType::STREAM);
807     CHECK(frame1->offset() == frame2->offset());
808     CHECK(frame1->data_length() == frame2->data_length());
809     CHECK(memcmp(frame1->data()->buf(), frame2->data()->buf(), frame1->data_length()) == 0);
810   }
811 
812   SECTION("Retransmit RESET_STREAM frame")
813   {
814     MIOBuffer *write_buffer             = new_MIOBuffer(BUFFER_SIZE_INDEX_8K);
815     IOBufferReader *write_buffer_reader = write_buffer->alloc_reader();
816 
817     QUICRTTMeasure rtt_provider;
818     MockQUICConnectionInfoProvider cinfo_provider;
819     std::unique_ptr<QUICSendStream> stream(new QUICSendStream(&cinfo_provider, stream_id, UINT64_MAX));
820     SCOPED_MUTEX_LOCK(lock, stream->mutex, this_ethread());
821 
822     MockContinuation mock_cont(stream->mutex);
823     stream->do_io_write(&mock_cont, INT64_MAX, write_buffer_reader);
824 
825     QUICEncryptionLevel level = QUICEncryptionLevel::ONE_RTT;
826     QUICFrame *frame          = nullptr;
827 
828     stream->reset(QUICStreamErrorUPtr(new QUICStreamError(stream.get(), QUIC_APP_ERROR_CODE_STOPPING)));
829     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
830     REQUIRE(frame);
831     CHECK(frame->type() == QUICFrameType::RESET_STREAM);
832     // Don't send it again untill it is considers as lost
833     CHECK(stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0) == nullptr);
834     // Loss the frame
835     stream->on_frame_lost(frame->id());
836     // After the loss the frame should be regenerated
837     frame = stream->generate_frame(frame_buf, level, 4096, 4096, 0, 0);
838     REQUIRE(frame);
839     CHECK(frame->type() == QUICFrameType::RESET_STREAM);
840   }
841 }
842