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/Mock.h"
27 #include "quic/QUICFrame.h"
28 #include "quic/QUICStream.h"
29 
30 extern const ink_freelist_ops *freelist_global_ops;
31 extern const ink_freelist_ops *freelist_class_ops;
32 
33 TEST_CASE("QUICFrame Type", "[quic]")
34 {
35   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x00")) == QUICFrameType::PADDING);
36   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x01")) == QUICFrameType::PING);
37 
38   // Range of ACK
39   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x02")) == QUICFrameType::ACK);
40   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x03")) == QUICFrameType::ACK);
41 
42   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x04")) == QUICFrameType::RESET_STREAM);
43   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x05")) == QUICFrameType::STOP_SENDING);
44   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x06")) == QUICFrameType::CRYPTO);
45   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x07")) == QUICFrameType::NEW_TOKEN);
46 
47   // Range of STREAM
48   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x08")) == QUICFrameType::STREAM);
49   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x0f")) == QUICFrameType::STREAM);
50 
51   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x10")) == QUICFrameType::MAX_DATA);
52   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x11")) == QUICFrameType::MAX_STREAM_DATA);
53 
54   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x12")) == QUICFrameType::MAX_STREAMS);
55   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x13")) == QUICFrameType::MAX_STREAMS);
56 
57   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x14")) == QUICFrameType::DATA_BLOCKED);
58   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x15")) == QUICFrameType::STREAM_DATA_BLOCKED);
59 
60   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x16")) == QUICFrameType::STREAMS_BLOCKED);
61   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x17")) == QUICFrameType::STREAMS_BLOCKED);
62 
63   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x18")) == QUICFrameType::NEW_CONNECTION_ID);
64   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x19")) == QUICFrameType::RETIRE_CONNECTION_ID);
65   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x1a")) == QUICFrameType::PATH_CHALLENGE);
66   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x1b")) == QUICFrameType::PATH_RESPONSE);
67 
68   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x1c")) == QUICFrameType::CONNECTION_CLOSE);
69   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x1d")) == QUICFrameType::CONNECTION_CLOSE);
70 
71   // Undefined ragne
72   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x1e")) == QUICFrameType::UNKNOWN);
73   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\xff")) == QUICFrameType::UNKNOWN);
74 }
75 
76 TEST_CASE("Load STREAM Frame", "[quic]")
77 {
78   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
79 
80   SECTION("OLF=000")
81   {
82     uint8_t buf1[] = {
83       0x08,                   // 0b00001OLF (OLF=000)
84       0x01,                   // Stream ID
85       0x01, 0x02, 0x03, 0x04, // Stream Data
86     };
87     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
88     CHECK(frame1->type() == QUICFrameType::STREAM);
89     CHECK(frame1->size() == 6);
90     const QUICStreamFrame *stream_frame = static_cast<const QUICStreamFrame *>(frame1);
91     CHECK(stream_frame->stream_id() == 0x01);
92     CHECK(stream_frame->offset() == 0x00);
93     CHECK(stream_frame->data_length() == 4);
94     CHECK(memcmp(stream_frame->data()->start(), "\x01\x02\x03\x04", 4) == 0);
95     CHECK(stream_frame->has_fin_flag() == false);
96   }
97 
98   SECTION("OLF=010")
99   {
100     uint8_t buf1[] = {
101       0x0a,                         // 0b00001OLF (OLF=010)
102       0x01,                         // Stream ID
103       0x05,                         // Data Length
104       0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
105     };
106     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
107     CHECK(frame1->type() == QUICFrameType::STREAM);
108     CHECK(frame1->size() == 8);
109     const QUICStreamFrame *stream_frame = static_cast<const QUICStreamFrame *>(frame1);
110     CHECK(stream_frame->stream_id() == 0x01);
111     CHECK(stream_frame->offset() == 0x00);
112     CHECK(stream_frame->data_length() == 5);
113     CHECK(memcmp(stream_frame->data()->start(), "\x01\x02\x03\x04\x05", 5) == 0);
114     CHECK(stream_frame->has_fin_flag() == false);
115   }
116 
117   SECTION("OLF=110")
118   {
119     uint8_t buf1[] = {
120       0x0e,                         // 0b00001OLF (OLF=110)
121       0x01,                         // Stream ID
122       0x02,                         // Data Length
123       0x05,                         // Data Length
124       0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
125     };
126     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
127     CHECK(frame1->type() == QUICFrameType::STREAM);
128     CHECK(frame1->size() == 9);
129 
130     const QUICStreamFrame *stream_frame = static_cast<const QUICStreamFrame *>(frame1);
131     CHECK(stream_frame->stream_id() == 0x01);
132     CHECK(stream_frame->offset() == 0x02);
133     CHECK(stream_frame->data_length() == 5);
134     CHECK(memcmp(stream_frame->data()->start(), "\x01\x02\x03\x04\x05", 5) == 0);
135     CHECK(stream_frame->has_fin_flag() == false);
136   }
137 
138   SECTION("OLF=111")
139   {
140     uint8_t buf1[] = {
141       0x0f,                         // 0b00001OLF (OLF=111)
142       0x01,                         // Stream ID
143       0x02,                         // Data Length
144       0x05,                         // Data Length
145       0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
146     };
147     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
148     CHECK(frame1->type() == QUICFrameType::STREAM);
149     CHECK(frame1->size() == 9);
150 
151     const QUICStreamFrame *stream_frame = static_cast<const QUICStreamFrame *>(frame1);
152     CHECK(stream_frame->stream_id() == 0x01);
153     CHECK(stream_frame->offset() == 0x02);
154     CHECK(stream_frame->data_length() == 5);
155     CHECK(memcmp(stream_frame->data()->start(), "\x01\x02\x03\x04\x05", 5) == 0);
156     CHECK(stream_frame->has_fin_flag() == true);
157   }
158 
159   SECTION("BAD DATA")
160   {
161     uint8_t buf1[] = {
162       0x0e,                   // 0b00001OLF (OLF=110)
163       0x01,                   // Stream ID
164       0x02,                   // Data Length
165       0x05,                   // Data Length
166       0x01, 0x02, 0x03, 0x04, // BAD Stream Data
167     };
168     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
169     CHECK(frame1->type() == QUICFrameType::STREAM);
170     CHECK(frame1->valid() == false);
171   }
172 
173   SECTION("BAD DATA")
174   {
175     uint8_t buf1[] = {
176       0x0e, // 0b00001OLF (OLF=110)
177       0x01, // Stream ID
178     };
179     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
180     CHECK(frame1->type() == QUICFrameType::STREAM);
181     CHECK(frame1->valid() == false);
182   }
183 }
184 
185 TEST_CASE("Store STREAM Frame", "[quic]")
186 {
187   SECTION("8bit stream id, 0bit offset")
188   {
189     uint8_t buf[32]     = {0};
190     size_t len          = 0;
191     uint8_t expected1[] = {
192       0x0a,                         // 0b00001OLF (OLF=010)
193       0x01,                         // Stream ID
194       0x05,                         // Data Length
195       0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
196     };
197 
198     uint8_t raw1[]           = "\x01\x02\x03\x04\x05";
199     Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
200     block->alloc(BUFFER_SIZE_INDEX_32K);
201     memcpy(block->start(), raw1, 5);
202     block->fill(5);
203 
204     QUICStreamFrame stream_frame(block, 0x01, 0x00, false, false, true);
205     CHECK(stream_frame.size() == 8);
206 
207     Ptr<IOBufferBlock> ibb = stream_frame.to_io_buffer_block(sizeof(buf));
208     for (auto b = ibb; b; b = b->next) {
209       memcpy(buf + len, b->start(), b->size());
210       len += b->size();
211     }
212     CHECK(len == 8);
213     CHECK(memcmp(buf, expected1, len) == 0);
214   }
215 
216   SECTION("8bit stream id, 16bit offset")
217   {
218     uint8_t buf[32]     = {0};
219     size_t len          = 0;
220     uint8_t expected2[] = {
221       0x0e,                         // 0b00001OLF (OLF=110)
222       0x01,                         // Stream ID
223       0x01,                         // Offset
224       0x05,                         // Data Length
225       0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
226     };
227     uint8_t raw2[]           = "\x01\x02\x03\x04\x05";
228     Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
229     block->alloc(BUFFER_SIZE_INDEX_32K);
230     memcpy(block->start(), raw2, 5);
231     block->fill(5);
232 
233     QUICStreamFrame stream_frame(block, 0x01, 0x01);
234     CHECK(stream_frame.size() == 9);
235 
236     Ptr<IOBufferBlock> ibb = stream_frame.to_io_buffer_block(sizeof(buf));
237     for (auto b = ibb; b; b = b->next) {
238       memcpy(buf + len, b->start(), b->size());
239       len += b->size();
240     }
241     CHECK(len == 9);
242     CHECK(memcmp(buf, expected2, len) == 0);
243   }
244 
245   SECTION("8bit stream id, 32bit offset")
246   {
247     uint8_t buf[32]     = {0};
248     size_t len          = 0;
249     uint8_t expected3[] = {
250       0x0e,                         // 0b00001OLF (OLF=110)
251       0x01,                         // Stream ID
252       0x80, 0x01, 0x00, 0x00,       // Offset
253       0x05,                         // Data Length
254       0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
255     };
256     uint8_t raw3[]           = "\x01\x02\x03\x04\x05";
257     Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
258     block->alloc(BUFFER_SIZE_INDEX_32K);
259     memcpy(block->start(), raw3, 5);
260     block->fill(5);
261 
262     QUICStreamFrame stream_frame(block, 0x01, 0x010000);
263     CHECK(stream_frame.size() == 12);
264 
265     Ptr<IOBufferBlock> ibb = stream_frame.to_io_buffer_block(sizeof(buf));
266     for (auto b = ibb; b; b = b->next) {
267       memcpy(buf + len, b->start(), b->size());
268       len += b->size();
269     }
270     CHECK(len == 12);
271     CHECK(memcmp(buf, expected3, len) == 0);
272   }
273 
274   SECTION("8bit stream id, 64bit offset")
275   {
276     uint8_t buf[32]     = {0};
277     size_t len          = 0;
278     uint8_t expected4[] = {
279       0x0e,                                           // 0b00001OLF (OLF=110)
280       0x01,                                           // Stream ID
281       0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
282       0x05,                                           // Data Length
283       0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
284     };
285     uint8_t raw4[]           = "\x01\x02\x03\x04\x05";
286     Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
287     block->alloc(BUFFER_SIZE_INDEX_32K);
288     memcpy(block->start(), raw4, 5);
289     block->fill(5);
290 
291     QUICStreamFrame stream_frame(block, 0x01, 0x0100000000);
292     CHECK(stream_frame.size() == 16);
293 
294     Ptr<IOBufferBlock> ibb = stream_frame.to_io_buffer_block(sizeof(buf));
295     for (auto b = ibb; b; b = b->next) {
296       memcpy(buf + len, b->start(), b->size());
297       len += b->size();
298     }
299     CHECK(len == 16);
300     CHECK(memcmp(buf, expected4, len) == 0);
301   }
302 
303   SECTION("16bit stream id, 64bit offset")
304   {
305     uint8_t buf[32]     = {0};
306     size_t len          = 0;
307     uint8_t expected5[] = {
308       0x0e,                                           // 0b00001OLF (OLF=110)
309       0x41, 0x00,                                     // Stream ID
310       0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
311       0x05,                                           // Data Length
312       0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
313     };
314     uint8_t raw5[]           = "\x01\x02\x03\x04\x05";
315     Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
316     block->alloc(BUFFER_SIZE_INDEX_32K);
317     memcpy(block->start(), raw5, 5);
318     block->fill(5);
319 
320     QUICStreamFrame stream_frame(block, 0x0100, 0x0100000000);
321     CHECK(stream_frame.size() == 17);
322 
323     Ptr<IOBufferBlock> ibb = stream_frame.to_io_buffer_block(sizeof(buf));
324     for (auto b = ibb; b; b = b->next) {
325       memcpy(buf + len, b->start(), b->size());
326       len += b->size();
327     }
328     CHECK(len == 17);
329     CHECK(memcmp(buf, expected5, len) == 0);
330   }
331 
332   SECTION("24bit stream id, 64bit offset")
333   {
334     uint8_t buf[32]     = {0};
335     size_t len          = 0;
336     uint8_t expected6[] = {
337       0x0e,                                           // 0b00001OLF (OLF=110)
338       0x80, 0x01, 0x00, 0x00,                         // Stream ID
339       0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
340       0x05,                                           // Data Length
341       0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
342     };
343     uint8_t raw6[]           = "\x01\x02\x03\x04\x05";
344     Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
345     block->alloc(BUFFER_SIZE_INDEX_32K);
346     memcpy(block->start(), raw6, 5);
347     block->fill(5);
348 
349     QUICStreamFrame stream_frame(block, 0x010000, 0x0100000000);
350     CHECK(stream_frame.size() == 19);
351 
352     Ptr<IOBufferBlock> ibb = stream_frame.to_io_buffer_block(sizeof(buf));
353     for (auto b = ibb; b; b = b->next) {
354       memcpy(buf + len, b->start(), b->size());
355       len += b->size();
356     }
357     CHECK(len == 19);
358     CHECK(memcmp(buf, expected6, len) == 0);
359   }
360 
361   SECTION("32bit stream id, 64bit offset")
362   {
363     uint8_t buf[32]     = {0};
364     size_t len          = 0;
365     uint8_t expected7[] = {
366       0x0e,                                           // 0b00001OLF (OLF=110)
367       0x81, 0x00, 0x00, 0x00,                         // Stream ID
368       0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
369       0x05,                                           // Data Length
370       0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
371     };
372     uint8_t raw7[]           = "\x01\x02\x03\x04\x05";
373     Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
374     block->alloc(BUFFER_SIZE_INDEX_32K);
375     memcpy(block->start(), raw7, 5);
376     block->fill(5);
377 
378     QUICStreamFrame stream_frame(block, 0x01000000, 0x0100000000);
379     CHECK(stream_frame.size() == 19);
380 
381     Ptr<IOBufferBlock> ibb = stream_frame.to_io_buffer_block(sizeof(buf));
382     for (auto b = ibb; b; b = b->next) {
383       memcpy(buf + len, b->start(), b->size());
384       len += b->size();
385     }
386     CHECK(len == 19);
387     CHECK(memcmp(buf, expected7, len) == 0);
388   }
389 
390   SECTION("32bit stream id, 64bit offset, FIN bit")
391   {
392     uint8_t buf[32]    = {0};
393     size_t len         = 0;
394     uint8_t expected[] = {
395       0x0f,                                           // 0b00001OLF (OLF=111)
396       0x81, 0x00, 0x00, 0x00,                         // Stream ID
397       0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
398       0x05,                                           // Data Length
399       0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
400     };
401     uint8_t raw[]            = "\x01\x02\x03\x04\x05";
402     Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
403     block->alloc(BUFFER_SIZE_INDEX_32K);
404     memcpy(block->start(), raw, 5);
405     block->fill(5);
406 
407     QUICStreamFrame stream_frame(block, 0x01000000, 0x0100000000, true);
408     CHECK(stream_frame.size() == 19);
409 
410     Ptr<IOBufferBlock> ibb = stream_frame.to_io_buffer_block(sizeof(buf));
411     for (auto b = ibb; b; b = b->next) {
412       memcpy(buf + len, b->start(), b->size());
413       len += b->size();
414     }
415     CHECK(len == 19);
416     CHECK(memcmp(buf, expected, len) == 0);
417   }
418 }
419 
420 TEST_CASE("CRYPTO Frame", "[quic]")
421 {
422   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
423   SECTION("Loading")
424   {
425     uint8_t buf[] = {
426       0x06,                         // Type
427       0x80, 0x01, 0x00, 0x00,       // Offset
428       0x05,                         // Length
429       0x01, 0x02, 0x03, 0x04, 0x05, // Crypto Data
430     };
431     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
432     CHECK(frame->type() == QUICFrameType::CRYPTO);
433     CHECK(frame->size() == sizeof(buf));
434 
435     const QUICCryptoFrame *crypto_frame = static_cast<const QUICCryptoFrame *>(frame);
436     CHECK(crypto_frame->offset() == 0x010000);
437     CHECK(crypto_frame->data_length() == 5);
438     CHECK(memcmp(crypto_frame->data()->start(), "\x01\x02\x03\x04\x05", 5) == 0);
439   }
440 
441   SECTION("BAD Loading")
442   {
443     uint8_t buf[] = {
444       0x06,                   // Type
445       0x80, 0x01, 0x00, 0x00, // Offset
446     };
447     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
448     CHECK(frame->type() == QUICFrameType::CRYPTO);
449     CHECK(frame->valid() == false);
450   }
451 
452   SECTION("Storing")
453   {
454     uint8_t buf[32]    = {0};
455     size_t len         = 0;
456     uint8_t expected[] = {
457       0x06,                         // Typr
458       0x80, 0x01, 0x00, 0x00,       // Offset
459       0x05,                         // Length
460       0x01, 0x02, 0x03, 0x04, 0x05, // Crypto Data
461     };
462     uint8_t raw_data[]       = "\x01\x02\x03\x04\x05";
463     Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
464     block->alloc(BUFFER_SIZE_INDEX_32K);
465     memcpy(block->start(), raw_data, 5);
466     block->fill(5);
467 
468     QUICCryptoFrame crypto_frame(block, 0x010000);
469     CHECK(crypto_frame.size() == sizeof(expected));
470 
471     Ptr<IOBufferBlock> ibb = crypto_frame.to_io_buffer_block(sizeof(buf));
472     for (auto b = ibb; b; b = b->next) {
473       memcpy(buf + len, b->start(), b->size());
474       len += b->size();
475     }
476     CHECK(len == sizeof(expected));
477     CHECK(memcmp(buf, expected, sizeof(expected)) == 0);
478   }
479 }
480 
481 TEST_CASE("Load Ack Frame 1", "[quic]")
482 {
483   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
484   SECTION("0 Ack Block, 8 bit packet number length, 8 bit block length")
485   {
486     uint8_t buf1[] = {
487       0x02,       // Type
488       0x12,       // Largest Acknowledged
489       0x74, 0x56, // Ack Delay
490       0x00,       // Ack Block Count
491       0x00,       // Ack Block Section
492     };
493     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
494     CHECK(frame1->type() == QUICFrameType::ACK);
495     CHECK(frame1->size() == 6);
496     const QUICAckFrame *ack_frame1 = static_cast<const QUICAckFrame *>(frame1);
497     CHECK(ack_frame1 != nullptr);
498     CHECK(ack_frame1->ack_block_count() == 0);
499     CHECK(ack_frame1->largest_acknowledged() == 0x12);
500     CHECK(ack_frame1->ack_delay() == 0x3456);
501     frame1->~QUICFrame();
502   }
503 
504   SECTION("0 Ack Block, 8 bit packet number length, 8 bit block length")
505   {
506     uint8_t buf1[] = {
507       0x02,                   // Type
508       0x80, 0x00, 0x00, 0x01, // Largest Acknowledged
509       0x41, 0x71,             // Ack Delay
510       0x00,                   // Ack Block Count
511       0x80, 0x00, 0x00, 0x01, // Ack Block Section (First ACK Block Length)
512     };
513     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
514     CHECK(frame1->type() == QUICFrameType::ACK);
515     CHECK(frame1->size() == 12);
516 
517     const QUICAckFrame *ack_frame1 = static_cast<const QUICAckFrame *>(frame1);
518     CHECK(ack_frame1 != nullptr);
519     CHECK(ack_frame1->largest_acknowledged() == 0x01);
520     CHECK(ack_frame1->ack_delay() == 0x0171);
521     CHECK(ack_frame1->ack_block_count() == 0);
522     CHECK(ack_frame1->ecn_section() == nullptr);
523 
524     const QUICAckFrame::AckBlockSection *section = ack_frame1->ack_block_section();
525     CHECK(section->first_ack_block() == 0x01);
526     frame1->~QUICFrame();
527   }
528 
529   SECTION("2 Ack Block, 8 bit packet number length, 8 bit block length")
530   {
531     uint8_t buf1[] = {
532       0x02,                                           // Type
533       0x12,                                           // Largest Acknowledged
534       0x74, 0x56,                                     // Ack Delay
535       0x02,                                           // Ack Block Count
536       0x01,                                           // Ack Block Section (First ACK Block Length)
537       0x02,                                           // Ack Block Section (Gap 1)
538       0x43, 0x04,                                     // Ack Block Section (ACK Block 1 Length)
539       0x85, 0x06, 0x07, 0x08,                         // Ack Block Section (Gap 2)
540       0xc9, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, // Ack Block Section (ACK Block 2 Length)
541     };
542 
543     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
544     CHECK(frame1->type() == QUICFrameType::ACK);
545     CHECK(frame1->size() == 21);
546     const QUICAckFrame *ack_frame1 = static_cast<const QUICAckFrame *>(frame1);
547     CHECK(ack_frame1 != nullptr);
548     CHECK(ack_frame1->largest_acknowledged() == 0x12);
549     CHECK(ack_frame1->ack_delay() == 0x3456);
550     CHECK(ack_frame1->ack_block_count() == 2);
551     CHECK(ack_frame1->ecn_section() == nullptr);
552 
553     const QUICAckFrame::AckBlockSection *section = ack_frame1->ack_block_section();
554     CHECK(section->first_ack_block() == 0x01);
555     auto ite = section->begin();
556     CHECK(ite != section->end());
557     CHECK(ite->gap() == 0x02);
558     CHECK(ite->length() == 0x0304);
559     ++ite;
560     CHECK(ite != section->end());
561     CHECK(ite->gap() == 0x05060708);
562     CHECK(ite->length() == 0x090a0b0c0d0e0f10);
563     ++ite;
564     CHECK(ite == section->end());
565     frame1->~QUICFrame();
566   }
567 
568   SECTION("load bad frame")
569   {
570     uint8_t buf1[] = {
571       0x02, // Type
572       0x12, // Largest Acknowledged
573     };
574 
575     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
576     CHECK(frame1->type() == QUICFrameType::ACK);
577     CHECK(frame1->valid() == false);
578     frame1->~QUICFrame();
579   }
580 
581   SECTION("load bad block")
582   {
583     uint8_t buf1[] = {
584       0x02,                   // Type
585       0x12,                   // Largest Acknowledged
586       0x74, 0x56,             // Ack Delay
587       0x02,                   // Ack Block Count
588       0x01,                   // Ack Block Section (First ACK Block Length)
589       0x02,                   // Ack Block Section (Gap 1)
590       0x43, 0x04,             // Ack Block Section (ACK Block 1 Length)
591       0x85, 0x06, 0x07, 0x08, // Ack Block Section (Gap 2)
592     };
593 
594     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
595     CHECK(frame1->type() == QUICFrameType::ACK);
596     CHECK(frame1->valid() == false);
597     frame1->~QUICFrame();
598   }
599 
600   SECTION("0 Ack Block, 8 bit packet number length, 8 bit block length with ECN section")
601   {
602     uint8_t buf1[] = {
603       0x03,       // Type
604       0x12,       // Largest Acknowledged
605       0x74, 0x56, // Ack Delay
606       0x00,       // Ack Block Count
607       0x00,       // Ack Block Section
608       // ECN
609       0x01, // ECT0
610       0x02, // ECT1
611       0x03, // ECN-CE
612     };
613     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
614     CHECK(frame1->type() == QUICFrameType::ACK);
615     CHECK(frame1->size() == 9);
616     const QUICAckFrame *ack_frame1 = static_cast<const QUICAckFrame *>(frame1);
617     CHECK(ack_frame1 != nullptr);
618     CHECK(ack_frame1->ack_block_count() == 0);
619     CHECK(ack_frame1->largest_acknowledged() == 0x12);
620     CHECK(ack_frame1->ack_delay() == 0x3456);
621     CHECK(ack_frame1->ecn_section());
622     CHECK(ack_frame1->ecn_section()->ect0_count() == 1);
623     CHECK(ack_frame1->ecn_section()->ect1_count() == 2);
624     CHECK(ack_frame1->ecn_section()->ecn_ce_count() == 3);
625     frame1->~QUICFrame();
626   }
627 
628   SECTION("0 Ack Block, 8 bit packet number length, 8 bit block length with ECN section")
629   {
630     uint8_t buf1[] = {
631       0x03,       // Type
632       0x12,       // Largest Acknowledged
633       0x74, 0x56, // Ack Delay
634       0x00,       // Ack Block Count
635       0x00,       // Ack Block Section
636       // ECN
637       0x01, // ECT0
638       0x02, // ECT1
639     };
640     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
641     CHECK(frame1->type() == QUICFrameType::ACK);
642     CHECK(frame1->valid() == false);
643     frame1->~QUICFrame();
644   }
645 }
646 
647 TEST_CASE("Store Ack Frame", "[quic]")
648 {
649   SECTION("0 Ack Block, 8 bit packet number length, 8 bit block length")
650   {
651     uint8_t buf[32] = {0};
652     size_t len      = 0;
653 
654     uint8_t expected[] = {
655       0x02,       // Type
656       0x12,       // Largest Acknowledged
657       0x74, 0x56, // Ack Delay
658       0x00,       // Ack Block Count
659       0x00,       // Ack Block Section
660     };
661 
662     QUICAckFrame ack_frame(0x12, 0x3456, 0);
663     CHECK(ack_frame.size() == 6);
664 
665     Ptr<IOBufferBlock> ibb = ack_frame.to_io_buffer_block(sizeof(buf));
666     for (auto b = ibb; b; b = b->next) {
667       memcpy(buf + len, b->start(), b->size());
668       len += b->size();
669     }
670     CHECK(len == 6);
671     CHECK(memcmp(buf, expected, len) == 0);
672   }
673 
674   SECTION("2 Ack Block, 8 bit packet number length, 8 bit block length")
675   {
676     uint8_t buf[32] = {0};
677     size_t len      = 0;
678 
679     uint8_t expected[] = {
680       0x02,                                           // Type
681       0x12,                                           // Largest Acknowledged
682       0x74, 0x56,                                     // Ack Delay
683       0x02,                                           // Ack Block Count
684       0x01,                                           // Ack Block Section (First ACK Block Length)
685       0x02,                                           // Ack Block Section (Gap 1)
686       0x43, 0x04,                                     // Ack Block Section (ACK Block 1 Length)
687       0x85, 0x06, 0x07, 0x08,                         // Ack Block Section (Gap 2)
688       0xc9, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, // Ack Block Section (ACK Block 2 Length)
689     };
690     QUICAckFrame ack_frame(0x12, 0x3456, 0x01);
691     QUICAckFrame::AckBlockSection *section = ack_frame.ack_block_section();
692     section->add_ack_block({0x02, 0x0304});
693     section->add_ack_block({0x05060708, 0x090a0b0c0d0e0f10});
694     CHECK(ack_frame.size() == 21);
695 
696     Ptr<IOBufferBlock> ibb = ack_frame.to_io_buffer_block(sizeof(buf));
697     for (auto b = ibb; b; b = b->next) {
698       memcpy(buf + len, b->start(), b->size());
699       len += b->size();
700     }
701     CHECK(len == 21);
702     CHECK(memcmp(buf, expected, len) == 0);
703   }
704 }
705 
706 TEST_CASE("Load RESET_STREAM Frame", "[quic]")
707 {
708   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
709   SECTION("Load")
710   {
711     uint8_t buf1[] = {
712       0x04,                                          // Type
713       0x92, 0x34, 0x56, 0x78,                        // Stream ID
714       0x01,                                          // Error Code
715       0xd1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 // Final Offset
716     };
717     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
718     CHECK(frame1->type() == QUICFrameType::RESET_STREAM);
719     CHECK(frame1->size() == 14);
720     const QUICRstStreamFrame *rst_stream_frame1 = static_cast<const QUICRstStreamFrame *>(frame1);
721     CHECK(rst_stream_frame1 != nullptr);
722     CHECK(rst_stream_frame1->error_code() == 0x0001);
723     CHECK(rst_stream_frame1->stream_id() == 0x12345678);
724     CHECK(rst_stream_frame1->final_offset() == 0x1122334455667788);
725   }
726 
727   SECTION("BAD Load")
728   {
729     uint8_t buf1[] = {
730       0x04,                   // Type
731       0x92, 0x34, 0x56, 0x78, // Stream ID
732       0x01,                   // Error Code
733     };
734     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
735     CHECK(frame1->type() == QUICFrameType::RESET_STREAM);
736     CHECK(frame1->valid() == false);
737   }
738 }
739 
740 TEST_CASE("Store RESET_STREAM Frame", "[quic]")
741 {
742   uint8_t buf[65535];
743   size_t len = 0;
744 
745   uint8_t expected[] = {
746     0x04,                                          // Type
747     0x92, 0x34, 0x56, 0x78,                        // Stream ID
748     0x01,                                          // Error Code
749     0xd1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 // Final Offset
750   };
751   QUICRstStreamFrame rst_stream_frame(0x12345678, 0x0001, 0x1122334455667788);
752   CHECK(rst_stream_frame.size() == 14);
753 
754   Ptr<IOBufferBlock> ibb = rst_stream_frame.to_io_buffer_block(sizeof(buf));
755   for (auto b = ibb; b; b = b->next) {
756     memcpy(buf + len, b->start(), b->size());
757     len += b->size();
758   }
759   CHECK(len == 14);
760   CHECK(memcmp(buf, expected, len) == 0);
761 }
762 
763 TEST_CASE("Load Ping Frame", "[quic]")
764 {
765   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
766   uint8_t buf[] = {
767     0x01, // Type
768   };
769   const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
770   CHECK(frame->type() == QUICFrameType::PING);
771   CHECK(frame->size() == 1);
772 
773   const QUICPingFrame *ping_frame = static_cast<const QUICPingFrame *>(frame);
774   CHECK(ping_frame != nullptr);
775 }
776 
777 TEST_CASE("Store Ping Frame", "[quic]")
778 {
779   uint8_t buf[16];
780   size_t len = 0;
781 
782   uint8_t expected[] = {
783     0x01, // Type
784   };
785 
786   QUICPingFrame frame;
787   CHECK(frame.size() == 1);
788 
789   Ptr<IOBufferBlock> ibb = frame.to_io_buffer_block(sizeof(buf));
790   for (auto b = ibb; b; b = b->next) {
791     memcpy(buf + len, b->start(), b->size());
792     len += b->size();
793   }
794   CHECK(len == 1);
795   CHECK(memcmp(buf, expected, len) == 0);
796 }
797 
798 TEST_CASE("Load Padding Frame", "[quic]")
799 {
800   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
801   uint8_t buf1[] = {
802     0x00, 0x00, 0x00 // Type
803   };
804   const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
805   CHECK(frame1->type() == QUICFrameType::PADDING);
806   CHECK(frame1->size() == 3);
807   const QUICPaddingFrame *paddingFrame1 = static_cast<const QUICPaddingFrame *>(frame1);
808   CHECK(paddingFrame1 != nullptr);
809 }
810 
811 TEST_CASE("Store Padding Frame", "[quic]")
812 {
813   uint8_t buf[65535];
814   size_t len = 0;
815 
816   uint8_t expected[] = {
817     0x00, 0x00, 0x00, // Type
818   };
819   QUICPaddingFrame padding_frame(3);
820   Ptr<IOBufferBlock> ibb = padding_frame.to_io_buffer_block(sizeof(buf));
821   for (auto b = ibb; b; b = b->next) {
822     memcpy(buf + len, b->start(), b->size());
823     len += b->size();
824   }
825   CHECK(len == 3);
826   CHECK(memcmp(buf, expected, len) == 0);
827 }
828 
829 TEST_CASE("ConnectionClose Frame", "[quic]")
830 {
831   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
832   uint8_t reason_phrase[]  = {0x41, 0x42, 0x43, 0x44, 0x45};
833   size_t reason_phrase_len = sizeof(reason_phrase);
834 
835   SECTION("loading w/ reason phrase")
836   {
837     uint8_t buf[] = {
838       0x1c,                        // Type
839       0x0A,                        // Error Code
840       0x00,                        // Frame Type
841       0x05,                        // Reason Phrase Length
842       0x41, 0x42, 0x43, 0x44, 0x45 // Reason Phrase ("ABCDE");
843     };
844 
845     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
846     CHECK(frame->type() == QUICFrameType::CONNECTION_CLOSE);
847     CHECK(frame->size() == sizeof(buf));
848 
849     const QUICConnectionCloseFrame *conn_close_frame = static_cast<const QUICConnectionCloseFrame *>(frame);
850     CHECK(conn_close_frame != nullptr);
851     CHECK(conn_close_frame->error_code() == static_cast<uint16_t>(QUICTransErrorCode::PROTOCOL_VIOLATION));
852     CHECK(conn_close_frame->frame_type() == QUICFrameType::UNKNOWN);
853     CHECK(conn_close_frame->reason_phrase_length() == reason_phrase_len);
854     CHECK(memcmp(conn_close_frame->reason_phrase(), reason_phrase, reason_phrase_len) == 0);
855   }
856 
857   SECTION("Bad loading")
858   {
859     uint8_t buf[] = {
860       0x1c, // Type
861       0x0A, // Error Code
862       0x00, // Frame Type
863       0x05, // Reason Phrase Length
864     };
865 
866     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
867     CHECK(frame->type() == QUICFrameType::CONNECTION_CLOSE);
868     CHECK(frame->valid() == false);
869   }
870 
871   SECTION("loading w/o reason phrase")
872   {
873     uint8_t buf[] = {
874       0x1c, // Type
875       0x0A, // Error Code
876       0x04, // Frame Type
877       0x00, // Reason Phrase Length
878     };
879     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
880     CHECK(frame->type() == QUICFrameType::CONNECTION_CLOSE);
881     CHECK(frame->size() == sizeof(buf));
882 
883     const QUICConnectionCloseFrame *conn_close_frame = static_cast<const QUICConnectionCloseFrame *>(frame);
884     CHECK(conn_close_frame != nullptr);
885     CHECK(conn_close_frame->error_code() == static_cast<uint16_t>(QUICTransErrorCode::PROTOCOL_VIOLATION));
886     CHECK(conn_close_frame->frame_type() == QUICFrameType::RESET_STREAM);
887     CHECK(conn_close_frame->reason_phrase_length() == 0);
888   }
889 
890   SECTION("storing w/ reason phrase")
891   {
892     uint8_t buf[32];
893     size_t len = 0;
894 
895     uint8_t expected[] = {
896       0x1c,                        // Type
897       0x0A,                        // Error Code
898       0x08,                        // Frame Type
899       0x05,                        // Reason Phrase Length
900       0x41, 0x42, 0x43, 0x44, 0x45 // Reason Phrase ("ABCDE");
901     };
902     QUICConnectionCloseFrame connection_close_frame(static_cast<uint16_t>(QUICTransErrorCode::PROTOCOL_VIOLATION),
903                                                     QUICFrameType::STREAM, 5, "ABCDE");
904     CHECK(connection_close_frame.size() == sizeof(expected));
905 
906     Ptr<IOBufferBlock> ibb = connection_close_frame.to_io_buffer_block(sizeof(buf));
907     for (auto b = ibb; b; b = b->next) {
908       memcpy(buf + len, b->start(), b->size());
909       len += b->size();
910     }
911     CHECK(len == sizeof(expected));
912     CHECK(memcmp(buf, expected, len) == 0);
913   }
914 
915   SECTION("storing w/o reason phrase")
916   {
917     uint8_t buf[32];
918     size_t len = 0;
919 
920     uint8_t expected[] = {
921       0x1c, // Type
922       0x0A, // Error Code
923       0x00, // Frame Type
924       0x00, // Reason Phrase Length
925     };
926     QUICConnectionCloseFrame connection_close_frame(static_cast<uint16_t>(QUICTransErrorCode::PROTOCOL_VIOLATION),
927                                                     QUICFrameType::UNKNOWN, 0, nullptr);
928     Ptr<IOBufferBlock> ibb = connection_close_frame.to_io_buffer_block(sizeof(buf));
929     for (auto b = ibb; b; b = b->next) {
930       memcpy(buf + len, b->start(), b->size());
931       len += b->size();
932     }
933     CHECK(len == sizeof(expected));
934     CHECK(memcmp(buf, expected, len) == 0);
935   }
936 }
937 
938 TEST_CASE("Load MaxData Frame", "[quic]")
939 {
940   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
941   SECTION("Load")
942   {
943     uint8_t buf1[] = {
944       0x10,                                          // Type
945       0xd1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 // Maximum Data
946     };
947     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
948     CHECK(frame1->type() == QUICFrameType::MAX_DATA);
949     CHECK(frame1->size() == 9);
950     const QUICMaxDataFrame *max_data_frame = static_cast<const QUICMaxDataFrame *>(frame1);
951     CHECK(max_data_frame != nullptr);
952     CHECK(max_data_frame->maximum_data() == 0x1122334455667788ULL);
953   }
954 
955   SECTION("Bad Load")
956   {
957     uint8_t buf1[] = {
958       0x10, // Type
959     };
960     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
961     CHECK(frame1->type() == QUICFrameType::MAX_DATA);
962     CHECK(frame1->valid() == false);
963   }
964 }
965 
966 TEST_CASE("Store MaxData Frame", "[quic]")
967 {
968   uint8_t buf[65535];
969   size_t len = 0;
970 
971   uint8_t expected[] = {
972     0x10,                                          // Type
973     0xd1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 // Maximum Data
974   };
975   QUICMaxDataFrame max_data_frame(0x1122334455667788, 0, nullptr);
976   CHECK(max_data_frame.size() == 9);
977 
978   Ptr<IOBufferBlock> ibb = max_data_frame.to_io_buffer_block(sizeof(buf));
979   for (auto b = ibb; b; b = b->next) {
980     memcpy(buf + len, b->start(), b->size());
981     len += b->size();
982   }
983   CHECK(len == 9);
984   CHECK(memcmp(buf, expected, len) == 0);
985 }
986 
987 TEST_CASE("Load MaxStreamData Frame", "[quic]")
988 {
989   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
990   SECTION("Load")
991   {
992     uint8_t buf1[] = {
993       0x11,                                          // Type
994       0x81, 0x02, 0x03, 0x04,                        // Stream ID
995       0xd1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 // Maximum Stream Data
996     };
997     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
998     CHECK(frame1->type() == QUICFrameType::MAX_STREAM_DATA);
999     CHECK(frame1->size() == 13);
1000     const QUICMaxStreamDataFrame *maxStreamDataFrame1 = static_cast<const QUICMaxStreamDataFrame *>(frame1);
1001     CHECK(maxStreamDataFrame1 != nullptr);
1002     CHECK(maxStreamDataFrame1->stream_id() == 0x01020304);
1003     CHECK(maxStreamDataFrame1->maximum_stream_data() == 0x1122334455667788ULL);
1004   }
1005 
1006   SECTION("Load")
1007   {
1008     uint8_t buf1[] = {
1009       0x11,                   // Type
1010       0x81, 0x02, 0x03, 0x04, // Stream ID
1011     };
1012     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
1013     CHECK(frame1->type() == QUICFrameType::MAX_STREAM_DATA);
1014     CHECK(frame1->valid() == false);
1015   }
1016 }
1017 
1018 TEST_CASE("Store MaxStreamData Frame", "[quic]")
1019 {
1020   uint8_t buf[65535];
1021   size_t len = 0;
1022 
1023   uint8_t expected[] = {
1024     0x11,                                          // Type
1025     0x81, 0x02, 0x03, 0x04,                        // Stream ID
1026     0xd1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 // Maximum Stream Data
1027   };
1028   QUICMaxStreamDataFrame max_stream_data_frame(0x01020304, 0x1122334455667788ULL);
1029   CHECK(max_stream_data_frame.size() == 13);
1030 
1031   Ptr<IOBufferBlock> ibb = max_stream_data_frame.to_io_buffer_block(sizeof(buf));
1032   for (auto b = ibb; b; b = b->next) {
1033     memcpy(buf + len, b->start(), b->size());
1034     len += b->size();
1035   }
1036   CHECK(len == 13);
1037   CHECK(memcmp(buf, expected, len) == 0);
1038 }
1039 
1040 TEST_CASE("Load MaxStreams Frame", "[quic]")
1041 {
1042   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1043   SECTION("load")
1044   {
1045     uint8_t buf1[] = {
1046       0x12,                   // Type
1047       0x81, 0x02, 0x03, 0x04, // Stream ID
1048     };
1049     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
1050     CHECK(frame1->type() == QUICFrameType::MAX_STREAMS);
1051     CHECK(frame1->size() == 5);
1052     const QUICMaxStreamsFrame *max_streams_frame = static_cast<const QUICMaxStreamsFrame *>(frame1);
1053     CHECK(max_streams_frame != nullptr);
1054     CHECK(max_streams_frame->maximum_streams() == 0x01020304);
1055   }
1056   SECTION("bad load")
1057   {
1058     uint8_t buf1[] = {
1059       0x12, // Type
1060     };
1061     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
1062     CHECK(frame1->type() == QUICFrameType::MAX_STREAMS);
1063     CHECK(frame1->valid() == false);
1064   }
1065 }
1066 
1067 TEST_CASE("Store MaxStreams Frame", "[quic]")
1068 {
1069   uint8_t buf[65535];
1070   size_t len = 0;
1071 
1072   uint8_t expected[] = {
1073     0x12,                   // Type
1074     0x81, 0x02, 0x03, 0x04, // Stream ID
1075   };
1076   QUICMaxStreamsFrame max_streams_frame(0x01020304, 0, nullptr);
1077   CHECK(max_streams_frame.size() == 5);
1078 
1079   Ptr<IOBufferBlock> ibb = max_streams_frame.to_io_buffer_block(sizeof(buf));
1080   for (auto b = ibb; b; b = b->next) {
1081     memcpy(buf + len, b->start(), b->size());
1082     len += b->size();
1083   }
1084   CHECK(len == 5);
1085   CHECK(memcmp(buf, expected, len) == 0);
1086 }
1087 
1088 TEST_CASE("Load DataBlocked Frame", "[quic]")
1089 {
1090   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1091   SECTION("load")
1092   {
1093     uint8_t buf1[] = {
1094       0x14, // Type
1095       0x07, // Offset
1096     };
1097     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
1098     CHECK(frame1->type() == QUICFrameType::DATA_BLOCKED);
1099     CHECK(frame1->size() == 2);
1100     const QUICDataBlockedFrame *blocked_stream_frame = static_cast<const QUICDataBlockedFrame *>(frame1);
1101     CHECK(blocked_stream_frame != nullptr);
1102     CHECK(blocked_stream_frame->offset() == 0x07);
1103   }
1104 
1105   SECTION("bad load")
1106   {
1107     uint8_t buf1[] = {
1108       0x14, // Type
1109     };
1110     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
1111     CHECK(frame1->type() == QUICFrameType::DATA_BLOCKED);
1112     CHECK(frame1->valid() == false);
1113   }
1114 }
1115 
1116 TEST_CASE("Store DataBlocked Frame", "[quic]")
1117 {
1118   uint8_t buf[65535];
1119   size_t len = 0;
1120 
1121   uint8_t expected[] = {
1122     0x14, // Type
1123     0x07, // Offset
1124   };
1125   QUICDataBlockedFrame blocked_stream_frame(0x07, 0, nullptr);
1126   CHECK(blocked_stream_frame.size() == 2);
1127 
1128   Ptr<IOBufferBlock> ibb = blocked_stream_frame.to_io_buffer_block(sizeof(buf));
1129   for (auto b = ibb; b; b = b->next) {
1130     memcpy(buf + len, b->start(), b->size());
1131     len += b->size();
1132   }
1133   CHECK(len == 2);
1134   CHECK(memcmp(buf, expected, len) == 0);
1135 }
1136 
1137 TEST_CASE("Load StreamDataBlocked Frame", "[quic]")
1138 {
1139   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1140   SECTION("Load")
1141   {
1142     uint8_t buf1[] = {
1143       0x15,                   // Type
1144       0x81, 0x02, 0x03, 0x04, // Stream ID
1145       0x07,                   // Offset
1146     };
1147     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
1148     CHECK(frame1->type() == QUICFrameType::STREAM_DATA_BLOCKED);
1149     CHECK(frame1->size() == 6);
1150     const QUICStreamDataBlockedFrame *stream_blocked_frame = static_cast<const QUICStreamDataBlockedFrame *>(frame1);
1151     CHECK(stream_blocked_frame != nullptr);
1152     CHECK(stream_blocked_frame->stream_id() == 0x01020304);
1153     CHECK(stream_blocked_frame->offset() == 0x07);
1154   }
1155 
1156   SECTION("Load")
1157   {
1158     uint8_t buf1[] = {
1159       0x15,                   // Type
1160       0x81, 0x02, 0x03, 0x04, // Stream ID
1161     };
1162     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
1163     CHECK(frame1->type() == QUICFrameType::STREAM_DATA_BLOCKED);
1164     CHECK(frame1->valid() == false);
1165   }
1166 }
1167 
1168 TEST_CASE("Store StreamDataBlocked Frame", "[quic]")
1169 {
1170   uint8_t buf[65535];
1171   size_t len = 0;
1172 
1173   uint8_t expected[] = {
1174     0x15,                   // Type
1175     0x81, 0x02, 0x03, 0x04, // Stream ID
1176     0x07,                   // Offset
1177   };
1178   QUICStreamDataBlockedFrame stream_blocked_frame(0x01020304, 0x07);
1179   CHECK(stream_blocked_frame.size() == 6);
1180 
1181   Ptr<IOBufferBlock> ibb = stream_blocked_frame.to_io_buffer_block(sizeof(buf));
1182   for (auto b = ibb; b; b = b->next) {
1183     memcpy(buf + len, b->start(), b->size());
1184     len += b->size();
1185   }
1186   CHECK(len == 6);
1187   CHECK(memcmp(buf, expected, len) == 0);
1188 }
1189 
1190 TEST_CASE("Load StreamsBlocked Frame", "[quic]")
1191 {
1192   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1193   SECTION("Load")
1194   {
1195     uint8_t buf1[] = {
1196       0x16,       // Type
1197       0x41, 0x02, // Stream ID
1198     };
1199     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
1200     CHECK(frame1->type() == QUICFrameType::STREAMS_BLOCKED);
1201     CHECK(frame1->size() == 3);
1202     const QUICStreamIdBlockedFrame *stream_id_blocked_frame = static_cast<const QUICStreamIdBlockedFrame *>(frame1);
1203     CHECK(stream_id_blocked_frame != nullptr);
1204     CHECK(stream_id_blocked_frame->stream_id() == 0x0102);
1205   }
1206 
1207   SECTION("Load")
1208   {
1209     uint8_t buf1[] = {
1210       0x16, // Type
1211     };
1212     const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
1213     CHECK(frame1->type() == QUICFrameType::STREAMS_BLOCKED);
1214     CHECK(frame1->valid() == false);
1215   }
1216 }
1217 
1218 TEST_CASE("Store StreamsBlocked Frame", "[quic]")
1219 {
1220   uint8_t buf[65535];
1221   size_t len = 0;
1222 
1223   uint8_t expected[] = {
1224     0x16,       // Type
1225     0x41, 0x02, // Stream ID
1226   };
1227   QUICStreamIdBlockedFrame stream_id_blocked_frame(0x0102, 0, nullptr);
1228   CHECK(stream_id_blocked_frame.size() == 3);
1229 
1230   Ptr<IOBufferBlock> ibb = stream_id_blocked_frame.to_io_buffer_block(sizeof(buf));
1231   for (auto b = ibb; b; b = b->next) {
1232     memcpy(buf + len, b->start(), b->size());
1233     len += b->size();
1234   }
1235   CHECK(len == 3);
1236   CHECK(memcmp(buf, expected, len) == 0);
1237 }
1238 
1239 TEST_CASE("Load NewConnectionId Frame", "[quic]")
1240 {
1241   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1242 
1243   SECTION("load")
1244   {
1245     uint8_t buf[] = {
1246       0x18,                                           // Type
1247       0x41, 0x02,                                     // Sequence
1248       0x41, 0x00,                                     // Retire Prior To
1249       0x08,                                           // Length
1250       0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, // Connection ID
1251       0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, // Stateless Reset Token
1252       0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
1253     };
1254     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
1255     CHECK(frame->type() == QUICFrameType::NEW_CONNECTION_ID);
1256     CHECK(frame->size() == sizeof(buf));
1257     CHECK(frame->valid() == true);
1258 
1259     const QUICNewConnectionIdFrame *new_con_id_frame = static_cast<const QUICNewConnectionIdFrame *>(frame);
1260     CHECK(new_con_id_frame != nullptr);
1261     CHECK(new_con_id_frame->sequence() == 0x0102);
1262     CHECK(new_con_id_frame->retire_prior_to() == 0x0100);
1263     CHECK((new_con_id_frame->connection_id() ==
1264            QUICConnectionId(reinterpret_cast<const uint8_t *>("\x11\x22\x33\x44\x55\x66\x77\x88"), 8)));
1265     CHECK(memcmp(new_con_id_frame->stateless_reset_token().buf(), buf + sizeof(buf) - QUICStatelessResetToken::LEN,
1266                  QUICStatelessResetToken::LEN) == 0);
1267   }
1268 
1269   SECTION("Bad Load")
1270   {
1271     uint8_t buf[] = {
1272       0x18,                                           // Type
1273       0x41, 0x02,                                     // Sequence
1274       0x41, 0x00,                                     // Retire Prior To
1275       0x08,                                           // Length
1276       0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, // Connection ID
1277       0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, // Stateless Reset Token
1278     };
1279     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
1280     CHECK(frame->type() == QUICFrameType::NEW_CONNECTION_ID);
1281     CHECK(frame->valid() == false);
1282   }
1283 }
1284 
1285 TEST_CASE("Store NewConnectionId Frame", "[quic]")
1286 {
1287   uint8_t buf[32];
1288   size_t len = 0;
1289 
1290   uint8_t expected[] = {
1291     0x18,                                           // Type
1292     0x41, 0x02,                                     // Sequence Number
1293     0x41, 0x00,                                     // Retire Prior To
1294     0x08,                                           // Length
1295     0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, // Connection ID
1296     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // Stateless Reset Token
1297     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1298   };
1299   QUICNewConnectionIdFrame new_con_id_frame(0x0102, 0x0100,
1300                                             {reinterpret_cast<const uint8_t *>("\x11\x22\x33\x44\x55\x66\x77\x88"), 8},
1301                                             {expected + sizeof(expected) - QUICStatelessResetToken::LEN});
1302   CHECK(new_con_id_frame.size() == sizeof(expected));
1303 
1304   Ptr<IOBufferBlock> ibb = new_con_id_frame.to_io_buffer_block(sizeof(buf));
1305   for (auto b = ibb; b; b = b->next) {
1306     memcpy(buf + len, b->start(), b->size());
1307     len += b->size();
1308   }
1309   CHECK(len == sizeof(expected));
1310   CHECK(memcmp(buf, expected, len) == 0);
1311 }
1312 
1313 TEST_CASE("Load STOP_SENDING Frame", "[quic]")
1314 {
1315   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1316   SECTION("LOAD")
1317   {
1318     uint8_t buf[] = {
1319       0x05,                   // Type
1320       0x92, 0x34, 0x56, 0x78, // Stream ID
1321       0x01,                   // Error Code
1322     };
1323     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
1324     CHECK(frame->type() == QUICFrameType::STOP_SENDING);
1325     CHECK(frame->size() == 6);
1326 
1327     const QUICStopSendingFrame *stop_sending_frame = static_cast<const QUICStopSendingFrame *>(frame);
1328     CHECK(stop_sending_frame != nullptr);
1329     CHECK(stop_sending_frame->stream_id() == 0x12345678);
1330     CHECK(stop_sending_frame->error_code() == 0x01);
1331   }
1332 
1333   SECTION("Bad LOAD")
1334   {
1335     uint8_t buf[] = {
1336       0x05,                   // Type
1337       0x92, 0x34, 0x56, 0x78, // Stream ID
1338     };
1339     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
1340     CHECK(frame->type() == QUICFrameType::STOP_SENDING);
1341     CHECK(frame->valid() == false);
1342   }
1343 }
1344 
1345 TEST_CASE("Store STOP_SENDING Frame", "[quic]")
1346 {
1347   uint8_t buf[65535];
1348   size_t len = 0;
1349 
1350   uint8_t expected[] = {
1351     0x05,                   // Type
1352     0x92, 0x34, 0x56, 0x78, // Stream ID
1353     0x01,                   // Error Code
1354   };
1355   QUICStopSendingFrame stop_sending_frame(0x12345678, static_cast<QUICAppErrorCode>(0x01));
1356   CHECK(stop_sending_frame.size() == 6);
1357 
1358   Ptr<IOBufferBlock> ibb = stop_sending_frame.to_io_buffer_block(sizeof(buf));
1359   for (auto b = ibb; b; b = b->next) {
1360     memcpy(buf + len, b->start(), b->size());
1361     len += b->size();
1362   }
1363   CHECK(len == 6);
1364   CHECK(memcmp(buf, expected, len) == 0);
1365 }
1366 
1367 TEST_CASE("Load PATH_CHALLENGE Frame", "[quic]")
1368 {
1369   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1370   SECTION("Load")
1371   {
1372     uint8_t buf[] = {
1373       0x1a,                                           // Type
1374       0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // Data
1375     };
1376     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
1377     CHECK(frame->type() == QUICFrameType::PATH_CHALLENGE);
1378     CHECK(frame->size() == 9);
1379 
1380     const QUICPathChallengeFrame *path_challenge_frame = static_cast<const QUICPathChallengeFrame *>(frame);
1381     CHECK(path_challenge_frame != nullptr);
1382     CHECK(memcmp(path_challenge_frame->data(), "\x01\x23\x45\x67\x89\xab\xcd\xef", QUICPathChallengeFrame::DATA_LEN) == 0);
1383     frame->~QUICFrame();
1384   }
1385 
1386   SECTION("Load")
1387   {
1388     uint8_t buf[] = {
1389       0x1a,                                     // Type
1390       0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xef, // Data
1391     };
1392     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
1393     CHECK(frame->type() == QUICFrameType::PATH_CHALLENGE);
1394     CHECK(frame->valid() == false);
1395     frame->~QUICFrame();
1396   }
1397 }
1398 
1399 TEST_CASE("Store PATH_CHALLENGE Frame", "[quic]")
1400 {
1401   uint8_t buf[16];
1402   size_t len = 0;
1403 
1404   uint8_t expected[] = {
1405     0x1a,                                           // Type
1406     0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // Data
1407   };
1408 
1409   uint8_t raw[]       = "\x01\x23\x45\x67\x89\xab\xcd\xef";
1410   size_t raw_len      = sizeof(raw) - 1;
1411   ats_unique_buf data = ats_unique_malloc(raw_len);
1412   memcpy(data.get(), raw, raw_len);
1413 
1414   QUICPathChallengeFrame frame(std::move(data));
1415   CHECK(frame.size() == 9);
1416 
1417   Ptr<IOBufferBlock> ibb = frame.to_io_buffer_block(sizeof(buf));
1418   for (auto b = ibb; b; b = b->next) {
1419     memcpy(buf + len, b->start(), b->size());
1420     len += b->size();
1421   }
1422   CHECK(len == 9);
1423   CHECK(memcmp(buf, expected, len) == 0);
1424 }
1425 
1426 TEST_CASE("Load PATH_RESPONSE Frame", "[quic]")
1427 {
1428   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1429   SECTION("Load")
1430   {
1431     uint8_t buf[] = {
1432       0x1b,                                           // Type
1433       0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // Data
1434     };
1435     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
1436     CHECK(frame->type() == QUICFrameType::PATH_RESPONSE);
1437     CHECK(frame->size() == 9);
1438 
1439     const QUICPathResponseFrame *path_response_frame = static_cast<const QUICPathResponseFrame *>(frame);
1440     CHECK(path_response_frame != nullptr);
1441     CHECK(memcmp(path_response_frame->data(), "\x01\x23\x45\x67\x89\xab\xcd\xef", QUICPathResponseFrame::DATA_LEN) == 0);
1442     frame->~QUICFrame();
1443   }
1444 
1445   SECTION("Load")
1446   {
1447     uint8_t buf[] = {
1448       0x1b,                                     // Type
1449       0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // Data
1450     };
1451     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, buf, sizeof(buf), nullptr);
1452     CHECK(frame->type() == QUICFrameType::PATH_RESPONSE);
1453     CHECK(frame->valid() == false);
1454     frame->~QUICFrame();
1455   }
1456 }
1457 
1458 TEST_CASE("Store PATH_RESPONSE Frame", "[quic]")
1459 {
1460   uint8_t buf[16];
1461   size_t len = 0;
1462 
1463   uint8_t expected[] = {
1464     0x1b,                                           // Type
1465     0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // Data
1466   };
1467 
1468   uint8_t raw[]       = "\x01\x23\x45\x67\x89\xab\xcd\xef";
1469   size_t raw_len      = sizeof(raw) - 1;
1470   ats_unique_buf data = ats_unique_malloc(raw_len);
1471   memcpy(data.get(), raw, raw_len);
1472 
1473   QUICPathResponseFrame frame(std::move(data));
1474   CHECK(frame.size() == 9);
1475 
1476   Ptr<IOBufferBlock> ibb = frame.to_io_buffer_block(sizeof(buf));
1477   for (auto b = ibb; b; b = b->next) {
1478     memcpy(buf + len, b->start(), b->size());
1479     len += b->size();
1480   }
1481   CHECK(len == 9);
1482   CHECK(memcmp(buf, expected, len) == 0);
1483 }
1484 
1485 TEST_CASE("NEW_TOKEN Frame", "[quic]")
1486 {
1487   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1488   uint8_t raw_new_token_frame[] = {
1489     0x07,                                           // Type
1490     0x08,                                           // Token Length (i)
1491     0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, // Token (*)
1492   };
1493   size_t raw_new_token_frame_len = sizeof(raw_new_token_frame);
1494 
1495   uint8_t raw_token[]  = {0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef};
1496   size_t raw_token_len = sizeof(raw_token);
1497 
1498   SECTION("load")
1499   {
1500     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, raw_new_token_frame, raw_new_token_frame_len, nullptr);
1501     CHECK(frame->type() == QUICFrameType::NEW_TOKEN);
1502     CHECK(frame->size() == raw_new_token_frame_len);
1503 
1504     const QUICNewTokenFrame *new_token_frame = static_cast<const QUICNewTokenFrame *>(frame);
1505     CHECK(new_token_frame != nullptr);
1506     CHECK(new_token_frame->token_length() == raw_token_len);
1507     CHECK(memcmp(new_token_frame->token(), raw_token, raw_token_len) == 0);
1508     frame->~QUICFrame();
1509   }
1510 
1511   SECTION("bad load")
1512   {
1513     const QUICFrame *frame = QUICFrameFactory::create(frame_buf, raw_new_token_frame, raw_new_token_frame_len - 5, nullptr);
1514     CHECK(frame->type() == QUICFrameType::NEW_TOKEN);
1515     CHECK(frame->valid() == false);
1516     frame->~QUICFrame();
1517   }
1518 
1519   SECTION("store")
1520   {
1521     uint8_t buf[32];
1522     size_t len = 0;
1523 
1524     ats_unique_buf token = ats_unique_malloc(raw_token_len);
1525     memcpy(token.get(), raw_token, raw_token_len);
1526 
1527     QUICNewTokenFrame frame(std::move(token), raw_token_len);
1528     CHECK(frame.size() == raw_new_token_frame_len);
1529 
1530     Ptr<IOBufferBlock> ibb = frame.to_io_buffer_block(sizeof(buf));
1531     for (auto b = ibb; b; b = b->next) {
1532       memcpy(buf + len, b->start(), b->size());
1533       len += b->size();
1534     }
1535     CHECK(len == raw_new_token_frame_len);
1536     CHECK(memcmp(buf, raw_new_token_frame, len) == 0);
1537   }
1538 }
1539 
1540 TEST_CASE("RETIRE_CONNECTION_ID Frame", "[quic]")
1541 {
1542   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1543   uint8_t raw_retire_connection_id_frame[] = {
1544     0x19, // Type
1545     0x08, // Sequence Number (i)
1546   };
1547   size_t raw_retire_connection_id_frame_len = sizeof(raw_retire_connection_id_frame);
1548   uint64_t seq_num                          = 8;
1549 
1550   SECTION("load")
1551   {
1552     const QUICFrame *frame =
1553       QUICFrameFactory::create(frame_buf, raw_retire_connection_id_frame, raw_retire_connection_id_frame_len, nullptr);
1554     CHECK(frame->type() == QUICFrameType::RETIRE_CONNECTION_ID);
1555     CHECK(frame->size() == raw_retire_connection_id_frame_len);
1556 
1557     const QUICRetireConnectionIdFrame *retire_connection_id_frame = static_cast<const QUICRetireConnectionIdFrame *>(frame);
1558     CHECK(retire_connection_id_frame != nullptr);
1559     CHECK(retire_connection_id_frame->seq_num() == seq_num);
1560   }
1561 
1562   SECTION("bad load")
1563   {
1564     const QUICFrame *frame =
1565       QUICFrameFactory::create(frame_buf, raw_retire_connection_id_frame, raw_retire_connection_id_frame_len - 1, nullptr);
1566     CHECK(frame->type() == QUICFrameType::RETIRE_CONNECTION_ID);
1567     CHECK(frame->valid() == false);
1568   }
1569 
1570   SECTION("store")
1571   {
1572     uint8_t buf[32];
1573     size_t len = 0;
1574 
1575     QUICRetireConnectionIdFrame frame(seq_num, 0, nullptr);
1576     CHECK(frame.size() == raw_retire_connection_id_frame_len);
1577 
1578     Ptr<IOBufferBlock> ibb = frame.to_io_buffer_block(sizeof(buf));
1579     for (auto b = ibb; b; b = b->next) {
1580       memcpy(buf + len, b->start(), b->size());
1581       len += b->size();
1582     }
1583     CHECK(len == raw_retire_connection_id_frame_len);
1584     CHECK(memcmp(buf, raw_retire_connection_id_frame, len) == 0);
1585   }
1586 }
1587 
1588 TEST_CASE("QUICFrameFactory Create Unknown Frame", "[quic]")
1589 {
1590   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1591   uint8_t buf1[] = {
1592     0x20, // Type
1593   };
1594   const QUICFrame *frame1 = QUICFrameFactory::create(frame_buf, buf1, sizeof(buf1), nullptr);
1595   CHECK(frame1 == nullptr);
1596 }
1597 
1598 TEST_CASE("QUICFrameFactory Fast Create Frame", "[quic]")
1599 {
1600   QUICFrameFactory factory;
1601 
1602   uint8_t buf1[] = {
1603     0x12,                   // Type
1604     0x81, 0x02, 0x03, 0x04, // Stream Data
1605   };
1606   uint8_t buf2[] = {
1607     0x12,                   // Type
1608     0x85, 0x06, 0x07, 0x08, // Stream Data
1609   };
1610   const QUICFrame &frame1 = factory.fast_create(buf1, sizeof(buf1), nullptr);
1611   CHECK(frame1.type() == QUICFrameType::MAX_STREAMS);
1612 
1613   const QUICMaxStreamsFrame &max_streams_frame1 = static_cast<const QUICMaxStreamsFrame &>(frame1);
1614   CHECK(max_streams_frame1.maximum_streams() == 0x01020304);
1615 
1616   const QUICFrame &frame2 = factory.fast_create(buf2, sizeof(buf2), nullptr);
1617   CHECK(frame2.type() == QUICFrameType::MAX_STREAMS);
1618 
1619   const QUICMaxStreamsFrame &max_streams_frame2 = static_cast<const QUICMaxStreamsFrame &>(frame2);
1620   CHECK(max_streams_frame2.maximum_streams() == 0x05060708);
1621 
1622   CHECK(&frame1 == &frame2);
1623 }
1624 
1625 TEST_CASE("QUICFrameFactory Fast Create Unknown Frame", "[quic]")
1626 {
1627   QUICFrameFactory factory;
1628 
1629   uint8_t buf1[] = {
1630     0x20, // Type
1631   };
1632   const QUICFrame &frame1 = factory.fast_create(buf1, sizeof(buf1), nullptr);
1633   CHECK(frame1.type() == QUICFrameType::UNKNOWN);
1634 }
1635 
1636 TEST_CASE("QUICFrameFactory Create CONNECTION_CLOSE with a QUICConnectionError", "[quic]")
1637 {
1638   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1639 
1640   std::unique_ptr<QUICConnectionError> error =
1641     std::unique_ptr<QUICConnectionError>(new QUICConnectionError(QUICTransErrorCode::INTERNAL_ERROR));
1642   const QUICConnectionCloseFrame *connection_close_frame1 = QUICFrameFactory::create_connection_close_frame(frame_buf, *error);
1643   CHECK(connection_close_frame1->error_code() == static_cast<uint16_t>(QUICTransErrorCode::INTERNAL_ERROR));
1644   CHECK(connection_close_frame1->reason_phrase_length() == 0);
1645   CHECK(connection_close_frame1->reason_phrase() == nullptr);
1646 
1647   error = std::unique_ptr<QUICConnectionError>(new QUICConnectionError(QUICTransErrorCode::INTERNAL_ERROR, "test"));
1648   const QUICConnectionCloseFrame *connection_close_frame2 = QUICFrameFactory::create_connection_close_frame(frame_buf, *error);
1649   CHECK(connection_close_frame2->error_code() == static_cast<uint16_t>(QUICTransErrorCode::INTERNAL_ERROR));
1650   CHECK(connection_close_frame2->reason_phrase_length() == 4);
1651   CHECK(memcmp(connection_close_frame2->reason_phrase(), "test", 4) == 0);
1652 }
1653 
1654 TEST_CASE("QUICFrameFactory Create RESET_STREAM with a QUICStreamError", "[quic]")
1655 {
1656   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1657   QUICRTTMeasure mock_rtt;
1658   MockQUICConnection mock_connection;
1659   QUICBidirectionalStream stream(&mock_rtt, &mock_connection, 0x1234, 0, 0);
1660   std::unique_ptr<QUICStreamError> error =
1661     std::unique_ptr<QUICStreamError>(new QUICStreamError(&stream, static_cast<QUICAppErrorCode>(0x01)));
1662   const QUICRstStreamFrame *rst_stream_frame1 = QUICFrameFactory::create_rst_stream_frame(frame_buf, *error);
1663   CHECK(rst_stream_frame1->error_code() == 0x01);
1664   CHECK(rst_stream_frame1->stream_id() == 0x1234);
1665   CHECK(rst_stream_frame1->final_offset() == 0);
1666 }
1667