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 "QUICFrame.h"
25 
26 #include <algorithm>
27 
28 #include "QUICStream.h"
29 #include "QUICIntUtil.h"
30 #include "QUICDebugNames.h"
31 #include "QUICPacket.h"
32 
33 #define LEFT_SPACE(pos) ((size_t)(buf + len - pos))
34 #define FRAME_SIZE(pos) (pos - buf)
35 
36 // the pos will auto move forward . return true if the data valid
37 static bool
read_varint(uint8_t * & pos,size_t len,uint64_t & field,size_t & field_len)38 read_varint(uint8_t *&pos, size_t len, uint64_t &field, size_t &field_len)
39 {
40   if (len < 1) {
41     return false;
42   }
43 
44   field_len = QUICVariableInt::size(pos);
45   if (len < field_len) {
46     return false;
47   }
48 
49   field = QUICIntUtil::read_QUICVariableInt(pos, len);
50   pos += field_len;
51   return true;
52 }
53 
54 QUICFrameType
type() const55 QUICFrame::type() const
56 {
57   ink_assert("should not be called");
58   return QUICFrameType::UNKNOWN;
59 }
60 
61 bool
ack_eliciting() const62 QUICFrame::ack_eliciting() const
63 {
64   auto type = this->type();
65 
66   return type != QUICFrameType::PADDING && type != QUICFrameType::ACK && type != QUICFrameType::CONNECTION_CLOSE;
67 }
68 
69 const QUICPacketR *
packet() const70 QUICFrame::packet() const
71 {
72   return this->_packet;
73 }
74 
75 bool
is_probing_frame() const76 QUICFrame::is_probing_frame() const
77 {
78   return false;
79 }
80 
81 bool
is_flow_controlled() const82 QUICFrame::is_flow_controlled() const
83 {
84   return false;
85 }
86 
87 QUICFrameId
id() const88 QUICFrame::id() const
89 {
90   return this->_id;
91 }
92 
93 QUICFrameGenerator *
generated_by()94 QUICFrame::generated_by()
95 {
96   return this->_owner;
97 }
98 
99 QUICFrameType
type(const uint8_t * buf)100 QUICFrame::type(const uint8_t *buf)
101 {
102   if (buf[0] >= static_cast<uint8_t>(QUICFrameType::UNKNOWN)) {
103     return QUICFrameType::UNKNOWN;
104   } else if (static_cast<uint8_t>(QUICFrameType::ACK) <= buf[0] && buf[0] < static_cast<uint8_t>(QUICFrameType::RESET_STREAM)) {
105     return QUICFrameType::ACK;
106   } else if (static_cast<uint8_t>(QUICFrameType::STREAM) <= buf[0] && buf[0] < static_cast<uint8_t>(QUICFrameType::MAX_DATA)) {
107     return QUICFrameType::STREAM;
108   } else if (static_cast<uint8_t>(QUICFrameType::MAX_STREAMS) <= buf[0] &&
109              buf[0] < static_cast<uint8_t>(QUICFrameType::DATA_BLOCKED)) {
110     return QUICFrameType::MAX_STREAMS;
111   } else if (static_cast<uint8_t>(QUICFrameType::STREAMS_BLOCKED) <= buf[0] &&
112              buf[0] < static_cast<uint8_t>(QUICFrameType::NEW_CONNECTION_ID)) {
113     return QUICFrameType::STREAMS_BLOCKED;
114   } else if (static_cast<uint8_t>(QUICFrameType::CONNECTION_CLOSE) <= buf[0] &&
115              buf[0] < static_cast<uint8_t>(QUICFrameType::HANDSHAKE_DONE)) {
116     return QUICFrameType::CONNECTION_CLOSE;
117   } else {
118     return static_cast<QUICFrameType>(buf[0]);
119   }
120 }
121 
122 int
debug_msg(char * msg,size_t msg_len) const123 QUICFrame::debug_msg(char *msg, size_t msg_len) const
124 {
125   return snprintf(msg, msg_len, "%s size=%zu", QUICDebugNames::frame_type(this->type()), this->size());
126 }
127 
128 bool
valid() const129 QUICFrame::valid() const
130 {
131   return this->_valid;
132 }
133 
134 //
135 // STREAM Frame
136 //
137 
QUICStreamFrame(Ptr<IOBufferBlock> & block,QUICStreamId stream_id,QUICOffset offset,bool last,bool has_offset_field,bool has_length_field,QUICFrameId id,QUICFrameGenerator * owner)138 QUICStreamFrame::QUICStreamFrame(Ptr<IOBufferBlock> &block, QUICStreamId stream_id, QUICOffset offset, bool last,
139                                  bool has_offset_field, bool has_length_field, QUICFrameId id, QUICFrameGenerator *owner)
140   : QUICFrame(id, owner),
141     _block(block),
142     _stream_id(stream_id),
143     _offset(offset),
144     _fin(last),
145     _has_offset_field(has_offset_field),
146     _has_length_field(has_length_field)
147 {
148 }
149 
QUICStreamFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)150 QUICStreamFrame::QUICStreamFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
151 {
152   this->parse(buf, len, packet);
153 }
154 
QUICStreamFrame(const QUICStreamFrame & o)155 QUICStreamFrame::QUICStreamFrame(const QUICStreamFrame &o)
156   : QUICFrame(o),
157     _block(make_ptr<IOBufferBlock>(o._block->clone())),
158     _stream_id(o._stream_id),
159     _offset(o._offset),
160     _fin(o._fin),
161     _has_offset_field(o._has_offset_field),
162     _has_length_field(o._has_length_field)
163 {
164 }
165 
166 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)167 QUICStreamFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
168 {
169   ink_assert(len >= 1);
170   this->_reset();
171   this->_packet = packet;
172 
173   uint8_t *pos            = const_cast<uint8_t *>(buf);
174   this->_has_offset_field = (buf[0] & 0x04) != 0; // "O" of "0b00010OLF"
175   this->_has_length_field = (buf[0] & 0x02) != 0; // "L" of "0b00010OLF"
176   this->_fin              = (buf[0] & 0x01) != 0; // "F" of "0b00010OLF"
177   pos += 1;
178 
179   size_t field_len = 0;
180   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
181     return;
182   }
183 
184   if (this->_has_offset_field && !read_varint(pos, LEFT_SPACE(pos), this->_offset, field_len)) {
185     return;
186   }
187 
188   uint64_t data_len = 0;
189   if (this->_has_length_field && !read_varint(pos, LEFT_SPACE(pos), data_len, field_len)) {
190     return;
191   }
192 
193   if (!this->_has_length_field) {
194     data_len = LEFT_SPACE(pos);
195   }
196   if (LEFT_SPACE(pos) < data_len) {
197     return;
198   }
199 
200   this->_valid = true;
201   this->_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
202   this->_block->alloc(BUFFER_SIZE_INDEX_32K);
203   ink_assert(static_cast<uint64_t>(this->_block->write_avail()) > data_len);
204   memcpy(this->_block->start(), pos, data_len);
205   this->_block->fill(data_len);
206   pos += data_len;
207   this->_size = FRAME_SIZE(pos);
208 }
209 
210 void
_reset()211 QUICStreamFrame::_reset()
212 {
213   this->_block            = nullptr;
214   this->_fin              = false;
215   this->_has_length_field = true;
216   this->_has_offset_field = true;
217   this->_offset           = 0;
218   this->_stream_id        = 0;
219   this->_owner            = nullptr;
220   this->_id               = 0;
221   this->_valid            = false;
222   this->_size             = 0;
223 }
224 
225 QUICFrameType
type() const226 QUICStreamFrame::type() const
227 {
228   return QUICFrameType::STREAM;
229 }
230 
231 size_t
size() const232 QUICStreamFrame::size() const
233 {
234   if (this->_size) {
235     return this->_size;
236   }
237 
238   size_t size     = 1;
239   size_t data_len = 0;
240   if (this->_block.get() != nullptr) {
241     data_len = this->_block->read_avail();
242   }
243 
244   size += QUICVariableInt::size(this->_stream_id);
245   if (this->_has_offset_field) {
246     size += QUICVariableInt::size(this->_offset);
247   }
248 
249   if (this->_has_length_field) {
250     size += QUICVariableInt::size(data_len);
251     size += data_len;
252   }
253 
254   return size;
255 }
256 
257 bool
is_flow_controlled() const258 QUICStreamFrame::is_flow_controlled() const
259 {
260   return true;
261 }
262 
263 int
debug_msg(char * msg,size_t msg_len) const264 QUICStreamFrame::debug_msg(char *msg, size_t msg_len) const
265 {
266   return snprintf(msg, msg_len, "STREAM size=%zu id=%" PRIu64 " offset=%" PRIu64 " data_len=%" PRIu64 " fin=%d", this->size(),
267                   this->stream_id(), this->offset(), this->data_length(), this->has_fin_flag());
268 }
269 
270 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const271 QUICStreamFrame::to_io_buffer_block(size_t limit) const
272 {
273   Ptr<IOBufferBlock> header;
274 
275   if (limit < this->size()) {
276     return header;
277   }
278 
279   // Create header block
280   size_t written_len = 0;
281   header             = make_ptr<IOBufferBlock>(new_IOBufferBlock());
282   header->alloc(iobuffer_size_to_index(MAX_HEADER_SIZE, BUFFER_SIZE_INDEX_32K));
283   this->_store_header(reinterpret_cast<uint8_t *>(header->start()), &written_len, true);
284   header->fill(written_len);
285 
286   // Append payload block to a chain
287   ink_assert(written_len + this->data_length() <= limit);
288   header->next = this->data();
289 
290   // Return the chain
291   return header;
292 }
293 
294 size_t
_store_header(uint8_t * buf,size_t * len,bool include_length_field) const295 QUICStreamFrame::_store_header(uint8_t *buf, size_t *len, bool include_length_field) const
296 {
297   // Build Frame Type: "0b0010OLF"
298   buf[0] = static_cast<uint8_t>(QUICFrameType::STREAM);
299   *len   = 1;
300 
301   size_t n;
302 
303   // Stream ID (i)
304   QUICTypeUtil::write_QUICStreamId(this->stream_id(), buf + *len, &n);
305   *len += n;
306 
307   // [Offset (i)] "O" of "0b0010OLF"
308   if (this->has_offset_field()) {
309     QUICTypeUtil::write_QUICOffset(this->offset(), buf + *len, &n);
310     *len += n;
311     buf[0] += 0x04;
312   }
313 
314   // [Length (i)] "L of "0b0010OLF"
315   if (include_length_field) {
316     QUICIntUtil::write_QUICVariableInt(this->data_length(), buf + *len, &n);
317     *len += n;
318     buf[0] += 0x02;
319   }
320 
321   // "F" of "0b0010OLF"
322   if (this->has_fin_flag()) {
323     buf[0] += 0x01;
324   }
325 
326   return *len;
327 }
328 
329 QUICStreamId
stream_id() const330 QUICStreamFrame::stream_id() const
331 {
332   return this->_stream_id;
333 }
334 
335 QUICOffset
offset() const336 QUICStreamFrame::offset() const
337 {
338   if (this->has_offset_field()) {
339     return this->_offset;
340   }
341 
342   return 0;
343 }
344 
345 uint64_t
data_length() const346 QUICStreamFrame::data_length() const
347 {
348   return this->_block->read_avail();
349 }
350 
351 IOBufferBlock *
data() const352 QUICStreamFrame::data() const
353 {
354   return this->_block.get();
355 }
356 
357 /**
358  * "O" of "0b00010OLF"
359  */
360 bool
has_offset_field() const361 QUICStreamFrame::has_offset_field() const
362 {
363   return this->_has_offset_field;
364 }
365 
366 /**
367  * "L" of "0b00010OLF"
368  */
369 bool
has_length_field() const370 QUICStreamFrame::has_length_field() const
371 {
372   // This depends on `include_length_field` arg of QUICStreamFrame::store.
373   // Returning true for just in case.
374   return this->_has_length_field;
375 }
376 
377 /**
378  * "F" of "0b00010OLF"
379  */
380 bool
has_fin_flag() const381 QUICStreamFrame::has_fin_flag() const
382 {
383   return this->_fin;
384 }
385 
386 //
387 // CRYPTO frame
388 //
389 
QUICCryptoFrame(Ptr<IOBufferBlock> & block,QUICOffset offset,QUICFrameId id,QUICFrameGenerator * owner)390 QUICCryptoFrame::QUICCryptoFrame(Ptr<IOBufferBlock> &block, QUICOffset offset, QUICFrameId id, QUICFrameGenerator *owner)
391   : QUICFrame(id, owner), _offset(offset), _block(block)
392 {
393 }
394 
QUICCryptoFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)395 QUICCryptoFrame::QUICCryptoFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
396 {
397   this->parse(buf, len, packet);
398 }
399 
QUICCryptoFrame(const QUICCryptoFrame & o)400 QUICCryptoFrame::QUICCryptoFrame(const QUICCryptoFrame &o)
401   : QUICFrame(o), _offset(o._offset), _block(make_ptr<IOBufferBlock>(o._block->clone()))
402 {
403 }
404 
405 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)406 QUICCryptoFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
407 {
408   ink_assert(len >= 1);
409   this->_reset();
410   this->_packet = packet;
411   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
412 
413   size_t field_len = 0;
414   if (!read_varint(pos, LEFT_SPACE(pos), this->_offset, field_len)) {
415     return;
416   }
417 
418   uint64_t data_len = 0;
419   if (!read_varint(pos, LEFT_SPACE(pos), data_len, field_len)) {
420     return;
421   }
422 
423   if (LEFT_SPACE(pos) < data_len) {
424     return;
425   }
426 
427   this->_valid = true;
428   this->_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
429   this->_block->alloc(BUFFER_SIZE_INDEX_32K);
430   ink_assert(static_cast<uint64_t>(this->_block->write_avail()) > data_len);
431   memcpy(this->_block->start(), pos, data_len);
432   this->_block->fill(data_len);
433   pos += data_len;
434   this->_size = FRAME_SIZE(pos);
435 }
436 
437 void
_reset()438 QUICCryptoFrame::_reset()
439 {
440   this->_block  = nullptr;
441   this->_offset = 0;
442   this->_owner  = nullptr;
443   this->_id     = 0;
444   this->_valid  = false;
445   this->_size   = 0;
446 }
447 
448 // QUICFrame *
449 // QUICCryptoFrame::clone(uint8_t *buf) const
450 // {
451 //   Ptr<IOBufferBlock> block = make_ptr<IOBufferBlock>(this->_block->clone());
452 //   return QUICFrameFactory::create_crypto_frame(buf, block, this->offset(), this->_id, this->_owner);
453 // }
454 
455 QUICFrameType
type() const456 QUICCryptoFrame::type() const
457 {
458   return QUICFrameType::CRYPTO;
459 }
460 
461 size_t
size() const462 QUICCryptoFrame::size() const
463 {
464   if (this->_size) {
465     return this->_size;
466   }
467 
468   return 1 + this->_block->read_avail() + QUICVariableInt::size(this->_offset) + QUICVariableInt::size(this->_block->read_avail());
469 }
470 
471 int
debug_msg(char * msg,size_t msg_len) const472 QUICCryptoFrame::debug_msg(char *msg, size_t msg_len) const
473 {
474   return snprintf(msg, msg_len, "CRYPTO size=%zu offset=%" PRIu64 " data_len=%" PRIu64, this->size(), this->offset(),
475                   this->data_length());
476 }
477 
478 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const479 QUICCryptoFrame::to_io_buffer_block(size_t limit) const
480 {
481   Ptr<IOBufferBlock> header;
482 
483   if (limit < this->size()) {
484     return header;
485   }
486 
487   // Create header block
488   size_t written_len = 0;
489   header             = make_ptr<IOBufferBlock>(new_IOBufferBlock());
490   header->alloc(iobuffer_size_to_index(MAX_HEADER_SIZE, BUFFER_SIZE_INDEX_32K));
491   this->_store_header(reinterpret_cast<uint8_t *>(header->start()), &written_len);
492   header->fill(written_len);
493 
494   // Append payload block to a chain
495   ink_assert(written_len + this->data_length() <= limit);
496   header->next = this->data();
497 
498   // Return the chain
499   return header;
500 }
501 
502 size_t
_store_header(uint8_t * buf,size_t * len) const503 QUICCryptoFrame::_store_header(uint8_t *buf, size_t *len) const
504 {
505   // Type
506   buf[0] = static_cast<uint8_t>(QUICFrameType::CRYPTO);
507   *len   = 1;
508 
509   size_t n;
510 
511   // Offset (i)
512   QUICTypeUtil::write_QUICOffset(this->offset(), buf + *len, &n);
513   *len += n;
514 
515   // Length (i)
516   QUICIntUtil::write_QUICVariableInt(this->data_length(), buf + *len, &n);
517   *len += n;
518 
519   return *len;
520 }
521 
522 QUICOffset
offset() const523 QUICCryptoFrame::offset() const
524 {
525   return this->_offset;
526 }
527 
528 uint64_t
data_length() const529 QUICCryptoFrame::data_length() const
530 {
531   return this->_block->read_avail();
532 }
533 
534 IOBufferBlock *
data() const535 QUICCryptoFrame::data() const
536 {
537   return this->_block.get();
538 }
539 
540 //
541 // ACK frame
542 //
543 
544 std::set<QUICAckFrame::PacketNumberRange>
ranges() const545 QUICAckFrame::ranges() const
546 {
547   std::set<QUICAckFrame::PacketNumberRange> numbers;
548   QUICPacketNumber x = this->largest_acknowledged();
549   numbers.insert({x, static_cast<uint64_t>(x) - this->ack_block_section()->first_ack_block()});
550   x -= this->ack_block_section()->first_ack_block() + 1;
551   for (auto &&block : *(this->ack_block_section())) {
552     x -= block.gap() + 1;
553     numbers.insert({x, static_cast<uint64_t>(x) - block.length()});
554     x -= block.length() + 1;
555   }
556 
557   return numbers;
558 }
559 
QUICAckFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)560 QUICAckFrame::QUICAckFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
561 {
562   this->parse(buf, len, packet);
563 }
564 
565 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)566 QUICAckFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
567 {
568   ink_assert(len >= 1);
569   this->_reset();
570   this->_packet = packet;
571   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
572   bool has_ecn  = (buf[0] == static_cast<uint8_t>(QUICFrameType::ACK_WITH_ECN));
573 
574   size_t field_len = 0;
575   if (!read_varint(pos, LEFT_SPACE(pos), this->_largest_acknowledged, field_len)) {
576     return;
577   }
578 
579   if (!read_varint(pos, LEFT_SPACE(pos), this->_ack_delay, field_len)) {
580     return;
581   }
582 
583   uint64_t ack_block_count = 0;
584   if (!read_varint(pos, LEFT_SPACE(pos), ack_block_count, field_len)) {
585     return;
586   }
587 
588   uint64_t first_ack_block = 0;
589   if (!read_varint(pos, LEFT_SPACE(pos), first_ack_block, field_len)) {
590     return;
591   }
592 
593   this->_ack_block_section = new AckBlockSection(first_ack_block);
594   for (size_t i = 0; i < ack_block_count; i++) {
595     uint64_t gap           = 0;
596     uint64_t add_ack_block = 0;
597 
598     if (!read_varint(pos, LEFT_SPACE(pos), gap, field_len)) {
599       return;
600     }
601 
602     if (!read_varint(pos, LEFT_SPACE(pos), add_ack_block, field_len)) {
603       return;
604     }
605 
606     this->_ack_block_section->add_ack_block({gap, add_ack_block});
607   }
608 
609   if (has_ecn) {
610     this->_ecn_section = new EcnSection(pos, LEFT_SPACE(pos));
611     if (!this->_ecn_section->valid()) {
612       return;
613     }
614     pos += this->_ecn_section->size();
615   }
616 
617   this->_valid = true;
618   this->_size  = FRAME_SIZE(pos);
619 }
620 
QUICAckFrame(QUICPacketNumber largest_acknowledged,uint64_t ack_delay,uint64_t first_ack_block,QUICFrameId id,QUICFrameGenerator * owner)621 QUICAckFrame::QUICAckFrame(QUICPacketNumber largest_acknowledged, uint64_t ack_delay, uint64_t first_ack_block, QUICFrameId id,
622                            QUICFrameGenerator *owner)
623   : QUICFrame(id, owner)
624 {
625   this->_largest_acknowledged = largest_acknowledged;
626   this->_ack_delay            = ack_delay;
627   this->_ack_block_section    = new AckBlockSection(first_ack_block);
628 }
629 
630 void
_reset()631 QUICAckFrame::_reset()
632 {
633   if (this->_ack_block_section) {
634     delete this->_ack_block_section;
635     this->_ack_block_section = nullptr;
636   }
637   if (this->_ecn_section) {
638     delete this->_ecn_section;
639     this->_ecn_section = nullptr;
640   }
641 
642   this->_largest_acknowledged = 0;
643   this->_ack_delay            = 0;
644   this->_owner                = nullptr;
645   this->_id                   = 0;
646   this->_valid                = false;
647   this->_size                 = 0;
648 }
649 
~QUICAckFrame()650 QUICAckFrame::~QUICAckFrame()
651 {
652   if (this->_ack_block_section) {
653     delete this->_ack_block_section;
654     this->_ack_block_section = nullptr;
655   }
656   if (this->_ecn_section) {
657     delete this->_ecn_section;
658     this->_ecn_section = nullptr;
659   }
660 }
661 
662 QUICFrameType
type() const663 QUICAckFrame::type() const
664 {
665   // TODO ECN
666   return QUICFrameType::ACK;
667 }
668 
669 size_t
size() const670 QUICAckFrame::size() const
671 {
672   if (this->_size) {
673     return this->_size;
674   }
675 
676   size_t pre_len = 1 + QUICVariableInt::size(this->_largest_acknowledged) + QUICVariableInt::size(this->_ack_delay) +
677                    QUICVariableInt::size(this->_ack_block_section->count());
678   if (this->_ack_block_section) {
679     pre_len += this->_ack_block_section->size();
680   }
681 
682   if (this->_ecn_section) {
683     return pre_len + this->_ecn_section->size();
684   }
685 
686   return pre_len;
687 }
688 
689 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const690 QUICAckFrame::to_io_buffer_block(size_t limit) const
691 {
692   Ptr<IOBufferBlock> block;
693   size_t n = 0;
694 
695   if (limit < this->size()) {
696     return block;
697   }
698 
699   size_t written_len = 0;
700   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
701   block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
702   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
703 
704   // Type
705   block_start[0] = static_cast<uint8_t>(QUICFrameType::ACK);
706   n += 1;
707 
708   // Largest Acknowledged (i)
709   QUICIntUtil::write_QUICVariableInt(this->_largest_acknowledged, block_start + n, &written_len);
710   n += written_len;
711 
712   // Ack Delay (i)
713   QUICIntUtil::write_QUICVariableInt(this->_ack_delay, block_start + n, &written_len);
714   n += written_len;
715 
716   // Ack Range Count (i)
717   QUICIntUtil::write_QUICVariableInt(this->ack_block_count(), block_start + n, &written_len);
718   n += written_len;
719 
720   block->fill(n);
721 
722   // First Ack Range (i) + Ack Ranges (*)
723   block->next = this->_ack_block_section->to_io_buffer_block(limit - n);
724 
725   return block;
726 }
727 
728 int
debug_msg(char * msg,size_t msg_len) const729 QUICAckFrame::debug_msg(char *msg, size_t msg_len) const
730 {
731   int len = snprintf(msg, msg_len, "ACK size=%zu largest_acked=%" PRIu64 " delay=%" PRIu64 " block_count=%" PRIu64, this->size(),
732                      this->largest_acknowledged(), this->ack_delay(), this->ack_block_count());
733   msg_len -= len;
734 
735   if (this->ack_block_section()) {
736     len += snprintf(msg + len, msg_len, " first_ack_block=%" PRIu64, this->ack_block_section()->first_ack_block());
737   }
738 
739   return len;
740 }
741 
742 QUICPacketNumber
largest_acknowledged() const743 QUICAckFrame::largest_acknowledged() const
744 {
745   return this->_largest_acknowledged;
746 }
747 
748 uint64_t
ack_delay() const749 QUICAckFrame::ack_delay() const
750 {
751   return this->_ack_delay;
752 }
753 
754 uint64_t
ack_block_count() const755 QUICAckFrame::ack_block_count() const
756 {
757   return this->_ack_block_section->count();
758 }
759 
760 QUICAckFrame::AckBlockSection *
ack_block_section()761 QUICAckFrame::ack_block_section()
762 {
763   return this->_ack_block_section;
764 }
765 
766 const QUICAckFrame::AckBlockSection *
ack_block_section() const767 QUICAckFrame::ack_block_section() const
768 {
769   return this->_ack_block_section;
770 }
771 
772 QUICAckFrame::EcnSection *
ecn_section()773 QUICAckFrame::ecn_section()
774 {
775   return this->_ecn_section;
776 }
777 
778 const QUICAckFrame::EcnSection *
ecn_section() const779 QUICAckFrame::ecn_section() const
780 {
781   return this->_ecn_section;
782 }
783 
784 //
785 // QUICAckFrame::PacketNumberRange
786 //
PacketNumberRange(PacketNumberRange && a)787 QUICAckFrame::PacketNumberRange::PacketNumberRange(PacketNumberRange &&a) noexcept
788 {
789   this->_first = a._first;
790   this->_last  = a._last;
791 }
792 
793 uint64_t
first() const794 QUICAckFrame::PacketNumberRange::first() const
795 {
796   return this->_first;
797 }
798 
799 uint64_t
last() const800 QUICAckFrame::PacketNumberRange::last() const
801 {
802   return this->_last;
803 }
804 
805 uint64_t
size() const806 QUICAckFrame::PacketNumberRange::size() const
807 {
808   return this->_first - this->_last;
809 }
810 
811 bool
contains(QUICPacketNumber x) const812 QUICAckFrame::PacketNumberRange::contains(QUICPacketNumber x) const
813 {
814   return static_cast<uint64_t>(this->_last) <= static_cast<uint64_t>(x) &&
815          static_cast<uint64_t>(x) <= static_cast<uint64_t>(this->_first);
816 }
817 
818 //
819 // QUICAckFrame::AckBlock
820 //
821 uint64_t
gap() const822 QUICAckFrame::AckBlock::gap() const
823 {
824   return this->_gap;
825 }
826 
827 uint64_t
length() const828 QUICAckFrame::AckBlock::length() const
829 {
830   return this->_length;
831 }
832 
833 size_t
size() const834 QUICAckFrame::AckBlock::size() const
835 {
836   return QUICVariableInt::size(this->_gap) + QUICVariableInt::size(this->_length);
837 }
838 
839 //
840 // QUICAckFrame::AckBlockSection
841 //
842 uint8_t
count() const843 QUICAckFrame::AckBlockSection::count() const
844 {
845   return this->_ack_blocks.size();
846 }
847 
848 size_t
size() const849 QUICAckFrame::AckBlockSection::size() const
850 {
851   size_t n = 0;
852 
853   n += QUICVariableInt::size(this->_first_ack_block);
854 
855   for (auto &&block : *this) {
856     n += block.size();
857   }
858 
859   return n;
860 }
861 
862 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const863 QUICAckFrame::AckBlockSection::to_io_buffer_block(size_t limit) const
864 {
865   Ptr<IOBufferBlock> block;
866   size_t n = 0;
867 
868   if (limit < this->size()) {
869     return block;
870   }
871 
872   size_t written_len = 0;
873   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
874   block->alloc(iobuffer_size_to_index(limit, BUFFER_SIZE_INDEX_32K));
875   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
876 
877   QUICIntUtil::write_QUICVariableInt(this->_first_ack_block, block_start + n, &written_len);
878   n += written_len;
879 
880   for (auto &&block : *this) {
881     QUICIntUtil::write_QUICVariableInt(block.gap(), block_start + n, &written_len);
882     n += written_len;
883     QUICIntUtil::write_QUICVariableInt(block.length(), block_start + n, &written_len);
884     n += written_len;
885   }
886 
887   block->fill(n);
888   return block;
889 }
890 
891 uint64_t
first_ack_block() const892 QUICAckFrame::AckBlockSection::first_ack_block() const
893 {
894   return this->_first_ack_block;
895 }
896 
897 void
add_ack_block(const AckBlock & block)898 QUICAckFrame::AckBlockSection::add_ack_block(const AckBlock &block)
899 {
900   this->_ack_blocks.push_back(block);
901 }
902 
903 QUICAckFrame::AckBlockSection::const_iterator
begin() const904 QUICAckFrame::AckBlockSection::begin() const
905 {
906   return const_iterator(0, &this->_ack_blocks);
907 }
908 
909 QUICAckFrame::AckBlockSection::const_iterator
end() const910 QUICAckFrame::AckBlockSection::end() const
911 {
912   return const_iterator(this->_ack_blocks.size(), &this->_ack_blocks);
913 }
914 
const_iterator(uint8_t index,const std::vector<QUICAckFrame::AckBlock> * ack_blocks)915 QUICAckFrame::AckBlockSection::const_iterator::const_iterator(uint8_t index, const std::vector<QUICAckFrame::AckBlock> *ack_blocks)
916   : _index(index), _ack_blocks(ack_blocks)
917 {
918   if (this->_ack_blocks->size()) {
919     if (this->_ack_blocks->size() == this->_index) {
920       this->_current_block = {UINT64_C(0), UINT64_C(0)};
921     } else {
922       this->_current_block = this->_ack_blocks->at(this->_index);
923     }
924   }
925 }
926 
927 // FIXME: something wrong with clang-format?
928 const QUICAckFrame::AckBlock &
operator ++()929 QUICAckFrame::AckBlockSection::const_iterator::operator++()
930 {
931   ++(this->_index);
932 
933   if (this->_ack_blocks->size() == this->_index) {
934     this->_current_block = {UINT64_C(0), UINT64_C(0)};
935   } else {
936     this->_current_block = this->_ack_blocks->at(this->_index);
937   }
938 
939   return this->_current_block;
940 }
941 
942 const bool
operator !=(const const_iterator & ite) const943 QUICAckFrame::AckBlockSection::const_iterator::operator!=(const const_iterator &ite) const
944 {
945   return this->_index != ite._index;
946 }
947 
948 const bool
operator ==(const const_iterator & ite) const949 QUICAckFrame::AckBlockSection::const_iterator::operator==(const const_iterator &ite) const
950 {
951   return this->_index == ite._index;
952 }
953 
EcnSection(const uint8_t * buf,size_t len)954 QUICAckFrame::EcnSection::EcnSection(const uint8_t *buf, size_t len)
955 {
956   uint8_t *pos = const_cast<uint8_t *>(buf);
957 
958   size_t field_len = 0;
959   if (!read_varint(pos, LEFT_SPACE(pos), this->_ect0_count, field_len)) {
960     return;
961   }
962 
963   if (!read_varint(pos, LEFT_SPACE(pos), this->_ect1_count, field_len)) {
964     return;
965   }
966 
967   if (!read_varint(pos, LEFT_SPACE(pos), this->_ecn_ce_count, field_len)) {
968     return;
969   }
970 
971   this->_valid = true;
972   this->_size  = FRAME_SIZE(pos);
973 }
974 
975 bool
valid() const976 QUICAckFrame::EcnSection::valid() const
977 {
978   return this->_valid;
979 }
980 
981 size_t
size() const982 QUICAckFrame::EcnSection::size() const
983 {
984   return QUICVariableInt::size(this->_ect0_count) + QUICVariableInt::size(this->_ect1_count) +
985          QUICVariableInt::size(this->_ecn_ce_count);
986 }
987 
988 uint64_t
ect0_count() const989 QUICAckFrame::EcnSection::ect0_count() const
990 {
991   return this->_ect0_count;
992 }
993 
994 uint64_t
ect1_count() const995 QUICAckFrame::EcnSection::ect1_count() const
996 {
997   return this->_ect1_count;
998 }
999 
1000 uint64_t
ecn_ce_count() const1001 QUICAckFrame::EcnSection::ecn_ce_count() const
1002 {
1003   return this->_ecn_ce_count;
1004 }
1005 
1006 //
1007 // RESET_STREAM frame
1008 //
1009 
QUICRstStreamFrame(QUICStreamId stream_id,QUICAppErrorCode error_code,QUICOffset final_offset,QUICFrameId id,QUICFrameGenerator * owner)1010 QUICRstStreamFrame::QUICRstStreamFrame(QUICStreamId stream_id, QUICAppErrorCode error_code, QUICOffset final_offset, QUICFrameId id,
1011                                        QUICFrameGenerator *owner)
1012   : QUICFrame(id, owner), _stream_id(stream_id), _error_code(error_code), _final_offset(final_offset)
1013 {
1014 }
1015 
QUICRstStreamFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)1016 QUICRstStreamFrame::QUICRstStreamFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
1017 {
1018   this->parse(buf, len, packet);
1019 }
1020 
1021 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)1022 QUICRstStreamFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1023 {
1024   ink_assert(len >= 1);
1025   this->_reset();
1026   this->_packet = packet;
1027   uint8_t *pos  = 1 + const_cast<uint8_t *>(buf);
1028 
1029   size_t field_len = 0;
1030 
1031   // Stream ID (i)
1032   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
1033     return;
1034   }
1035 
1036   // Error Code (i)
1037   if (LEFT_SPACE(pos) < 1) {
1038     return;
1039   }
1040   if (!read_varint(pos, LEFT_SPACE(pos), this->_error_code, field_len)) {
1041     return;
1042   }
1043 
1044   // Final Offset (i)
1045   if (!read_varint(pos, LEFT_SPACE(pos), this->_final_offset, field_len)) {
1046     return;
1047   }
1048 
1049   this->_valid = true;
1050   this->_size  = FRAME_SIZE(pos);
1051 }
1052 
1053 void
_reset()1054 QUICRstStreamFrame::_reset()
1055 {
1056   this->_stream_id    = 0;
1057   this->_error_code   = 0;
1058   this->_final_offset = 0;
1059 
1060   this->_owner = nullptr;
1061   this->_id    = 0;
1062   this->_valid = false;
1063   this->_size  = 0;
1064 }
1065 
1066 QUICFrameType
type() const1067 QUICRstStreamFrame::type() const
1068 {
1069   return QUICFrameType::RESET_STREAM;
1070 }
1071 
1072 size_t
size() const1073 QUICRstStreamFrame::size() const
1074 {
1075   if (this->_size) {
1076     return this->_size;
1077   }
1078 
1079   return 1 + QUICVariableInt::size(this->_stream_id) + QUICVariableInt::size(this->_error_code) +
1080          QUICVariableInt::size(this->_final_offset);
1081 }
1082 
1083 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1084 QUICRstStreamFrame::to_io_buffer_block(size_t limit) const
1085 {
1086   Ptr<IOBufferBlock> block;
1087   size_t n = 0;
1088 
1089   if (limit < this->size()) {
1090     return block;
1091   }
1092 
1093   size_t written_len = 0;
1094   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1095   block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
1096   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1097 
1098   // Type
1099   block_start[0] = static_cast<uint8_t>(QUICFrameType::RESET_STREAM);
1100   n += 1;
1101 
1102   // Stream ID (i)
1103   QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
1104   n += written_len;
1105 
1106   // Application Error Code (i)
1107   QUICTypeUtil::write_QUICAppErrorCode(this->_error_code, block_start + n, &written_len);
1108   n += written_len;
1109 
1110   // Final Size (i)
1111   QUICTypeUtil::write_QUICOffset(this->_final_offset, block_start + n, &written_len);
1112   n += written_len;
1113 
1114   block->fill(n);
1115   return block;
1116 }
1117 
1118 int
debug_msg(char * msg,size_t msg_len) const1119 QUICRstStreamFrame::debug_msg(char *msg, size_t msg_len) const
1120 {
1121   return snprintf(msg, msg_len, "RESET_STREAM size=%zu stream_id=%" PRIu64 " code=0x%" PRIx64, this->size(), this->stream_id(),
1122                   this->error_code());
1123 }
1124 
1125 QUICStreamId
stream_id() const1126 QUICRstStreamFrame::stream_id() const
1127 {
1128   return this->_stream_id;
1129 }
1130 
1131 QUICAppErrorCode
error_code() const1132 QUICRstStreamFrame::error_code() const
1133 {
1134   return this->_error_code;
1135 }
1136 
1137 QUICOffset
final_offset() const1138 QUICRstStreamFrame::final_offset() const
1139 {
1140   return this->_final_offset;
1141 }
1142 
1143 //
1144 // PING frame
1145 //
1146 
QUICPingFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)1147 QUICPingFrame::QUICPingFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
1148 {
1149   this->parse(buf, len, packet);
1150 }
1151 
1152 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)1153 QUICPingFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1154 {
1155   this->_reset();
1156   this->_packet = packet;
1157   this->_valid  = true;
1158   this->_size   = 1;
1159 }
1160 
1161 QUICFrameType
type() const1162 QUICPingFrame::type() const
1163 {
1164   return QUICFrameType::PING;
1165 }
1166 
1167 size_t
size() const1168 QUICPingFrame::size() const
1169 {
1170   return 1;
1171 }
1172 
1173 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1174 QUICPingFrame::to_io_buffer_block(size_t limit) const
1175 {
1176   Ptr<IOBufferBlock> block;
1177   size_t n = 0;
1178 
1179   if (limit < this->size()) {
1180     return block;
1181   }
1182 
1183   block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1184   block->alloc(iobuffer_size_to_index(this->size(), BUFFER_SIZE_INDEX_32K));
1185   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1186 
1187   // Type
1188   block_start[0] = static_cast<uint8_t>(QUICFrameType::PING);
1189   n += 1;
1190 
1191   block->fill(n);
1192   return block;
1193 }
1194 
1195 //
1196 // PADDING frame
1197 //
QUICPaddingFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)1198 QUICPaddingFrame::QUICPaddingFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
1199 {
1200   this->parse(buf, len, packet);
1201 }
1202 
1203 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)1204 QUICPaddingFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1205 {
1206   ink_assert(len >= 1);
1207   this->_reset();
1208   this->_packet = packet;
1209   this->_size   = 0;
1210   this->_valid  = true;
1211   // find out how many padding frames in this buf
1212   for (size_t i = 0; i < len; i++) {
1213     if (*(buf + i) == static_cast<uint8_t>(QUICFrameType::PADDING)) {
1214       ++this->_size;
1215     } else {
1216       break;
1217     }
1218   }
1219 }
1220 
1221 QUICFrameType
type() const1222 QUICPaddingFrame::type() const
1223 {
1224   return QUICFrameType::PADDING;
1225 }
1226 
1227 size_t
size() const1228 QUICPaddingFrame::size() const
1229 {
1230   return this->_size;
1231 }
1232 
1233 bool
is_probing_frame() const1234 QUICPaddingFrame::is_probing_frame() const
1235 {
1236   return true;
1237 }
1238 
1239 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1240 QUICPaddingFrame::to_io_buffer_block(size_t limit) const
1241 {
1242   Ptr<IOBufferBlock> block;
1243   size_t n = 0;
1244 
1245   if (limit < this->size()) {
1246     return block;
1247   }
1248 
1249   block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1250   block->alloc(iobuffer_size_to_index(this->_size, BUFFER_SIZE_INDEX_32K));
1251   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1252 
1253   memset(block_start, 0, this->_size);
1254   n = this->_size;
1255 
1256   block->fill(n);
1257   return block;
1258 }
1259 
1260 //
1261 // CONNECTION_CLOSE frame
1262 //
QUICConnectionCloseFrame(uint64_t error_code,QUICFrameType frame_type,uint64_t reason_phrase_length,const char * reason_phrase,QUICFrameId id,QUICFrameGenerator * owner)1263 QUICConnectionCloseFrame::QUICConnectionCloseFrame(uint64_t error_code, QUICFrameType frame_type, uint64_t reason_phrase_length,
1264                                                    const char *reason_phrase, QUICFrameId id, QUICFrameGenerator *owner)
1265   : QUICFrame(id, owner),
1266     _type(0x1c),
1267     _error_code(error_code),
1268     _frame_type(frame_type),
1269     _reason_phrase_length(reason_phrase_length),
1270     _reason_phrase(reason_phrase)
1271 {
1272 }
1273 
QUICConnectionCloseFrame(uint64_t error_code,uint64_t reason_phrase_length,const char * reason_phrase,QUICFrameId id,QUICFrameGenerator * owner)1274 QUICConnectionCloseFrame::QUICConnectionCloseFrame(uint64_t error_code, uint64_t reason_phrase_length, const char *reason_phrase,
1275                                                    QUICFrameId id, QUICFrameGenerator *owner)
1276   : QUICFrame(id, owner),
1277     _type(0x1d),
1278     _error_code(error_code),
1279     _reason_phrase_length(reason_phrase_length),
1280     _reason_phrase(reason_phrase)
1281 {
1282 }
1283 
QUICConnectionCloseFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)1284 QUICConnectionCloseFrame::QUICConnectionCloseFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1285   : QUICFrame(0, nullptr, packet)
1286 {
1287   this->parse(buf, len, packet);
1288 }
1289 
1290 void
_reset()1291 QUICConnectionCloseFrame::_reset()
1292 {
1293   this->_error_code           = 0;
1294   this->_reason_phrase_length = 0;
1295   this->_reason_phrase        = nullptr;
1296   this->_frame_type           = QUICFrameType::UNKNOWN;
1297 
1298   this->_owner = nullptr;
1299   this->_id    = 0;
1300   this->_size  = 0;
1301   this->_valid = false;
1302 }
1303 
1304 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)1305 QUICConnectionCloseFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1306 {
1307   ink_assert(len >= 1);
1308   this->_reset();
1309   this->_packet = packet;
1310   this->_type   = buf[0];
1311   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
1312 
1313   size_t field_len = 0;
1314   uint64_t field   = 0;
1315 
1316   // Error Code (i)
1317   if (LEFT_SPACE(pos) < 1) {
1318     return;
1319   }
1320   read_varint(pos, LEFT_SPACE(pos), field, field_len);
1321   this->_error_code = field;
1322 
1323   if (this->_type == 0x1c) {
1324     // Frame Type (i)
1325     if (!read_varint(pos, LEFT_SPACE(pos), field, field_len)) {
1326       return;
1327     }
1328     this->_frame_type = static_cast<QUICFrameType>(field);
1329 
1330     /**
1331        Frame Type Field Accessor
1332 
1333        PADDING frame in Frame Type field means frame type that triggered the error is unknown.
1334        Return QUICFrameType::UNKNOWN when Frame Type field is PADDING (0x0).
1335      */
1336     if (this->_frame_type == QUICFrameType::PADDING) {
1337       this->_frame_type = QUICFrameType::UNKNOWN;
1338     }
1339   }
1340 
1341   // Reason Phrase Length (i)
1342   if (LEFT_SPACE(pos) < 1) {
1343     return;
1344   }
1345   if (!read_varint(pos, LEFT_SPACE(pos), this->_reason_phrase_length, field_len)) {
1346     return;
1347   }
1348 
1349   // Reason Phrase
1350   if (LEFT_SPACE(pos) < this->_reason_phrase_length) {
1351     return;
1352   }
1353   this->_reason_phrase = reinterpret_cast<const char *>(pos);
1354 
1355   this->_valid = true;
1356   pos += this->_reason_phrase_length;
1357   this->_size = FRAME_SIZE(pos);
1358 }
1359 
1360 QUICFrameType
type() const1361 QUICConnectionCloseFrame::type() const
1362 {
1363   return QUICFrameType::CONNECTION_CLOSE;
1364 }
1365 
1366 size_t
size() const1367 QUICConnectionCloseFrame::size() const
1368 {
1369   if (this->_size) {
1370     return this->_size;
1371   }
1372 
1373   return 1 + QUICVariableInt::size(sizeof(QUICTransErrorCode)) + QUICVariableInt::size(sizeof(QUICFrameType)) +
1374          QUICVariableInt::size(this->_reason_phrase_length) + this->_reason_phrase_length;
1375 }
1376 
1377 /**
1378    Store CONNECTION_CLOSE frame in buffer.
1379 
1380    PADDING frame in Frame Type field means frame type that triggered the error is unknown.
1381    When `_frame_type` is QUICFrameType::UNKNOWN, it's converted to QUICFrameType::PADDING (0x0).
1382  */
1383 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1384 QUICConnectionCloseFrame::to_io_buffer_block(size_t limit) const
1385 {
1386   Ptr<IOBufferBlock> first_block;
1387   size_t n = 0;
1388 
1389   if (limit < this->size()) {
1390     return first_block;
1391   }
1392 
1393   // Create a block for Error Code(i) and Frame Type(i)
1394   size_t written_len = 0;
1395   first_block        = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1396   first_block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
1397   uint8_t *block_start = reinterpret_cast<uint8_t *>(first_block->start());
1398 
1399   // Type
1400   block_start[0] = this->_type;
1401   n += 1;
1402 
1403   // Error Code (i)
1404   QUICIntUtil::write_QUICVariableInt(this->_error_code, block_start + n, &written_len);
1405   n += written_len;
1406 
1407   // Frame Type (i)
1408   QUICFrameType frame_type = this->_frame_type;
1409   if (frame_type == QUICFrameType::UNKNOWN) {
1410     frame_type = QUICFrameType::PADDING;
1411   }
1412   QUICIntUtil::write_QUICVariableInt(static_cast<uint64_t>(frame_type), block_start + n, &written_len);
1413   n += written_len;
1414 
1415   // Reason Phrase Length (i)
1416   QUICIntUtil::write_QUICVariableInt(this->_reason_phrase_length, block_start + n, &written_len);
1417   n += written_len;
1418 
1419   first_block->fill(n);
1420 
1421   // Create a block for reason if necessary
1422   if (this->_reason_phrase_length != 0) {
1423     // Reason Phrase (*)
1424     Ptr<IOBufferBlock> reason_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1425     reason_block->alloc(iobuffer_size_to_index(this->_reason_phrase_length, BUFFER_SIZE_INDEX_32K));
1426     memcpy(reinterpret_cast<uint8_t *>(reason_block->start()), this->_reason_phrase, this->_reason_phrase_length);
1427     reason_block->fill(this->_reason_phrase_length);
1428 
1429     // Append reason block to the first block
1430     first_block->next = reason_block;
1431   }
1432 
1433   // Return the chain
1434   return first_block;
1435 }
1436 
1437 int
debug_msg(char * msg,size_t msg_len) const1438 QUICConnectionCloseFrame::debug_msg(char *msg, size_t msg_len) const
1439 {
1440   int len;
1441   if (this->_type == 0x1c) {
1442     len =
1443       snprintf(msg, msg_len, "CONNECTION_CLOSE size=%zu code=%s (0x%" PRIx16 ") frame=%s", this->size(),
1444                QUICDebugNames::error_code(this->error_code()), this->error_code(), QUICDebugNames::frame_type(this->frame_type()));
1445   } else {
1446     // Application-specific error. It doesn't have a frame type and we don't know string representations of error codes.
1447     len = snprintf(msg, msg_len, "CONNECTION_CLOSE size=%zu code=0x%" PRIx16 " ", this->size(), this->error_code());
1448   }
1449 
1450   if (this->reason_phrase_length() != 0 && this->reason_phrase() != nullptr) {
1451     memcpy(msg + len, " reason=", 8);
1452     len += 8;
1453 
1454     int phrase_len = std::min(msg_len - len, static_cast<size_t>(this->reason_phrase_length()));
1455     memcpy(msg + len, this->reason_phrase(), phrase_len);
1456     len += phrase_len;
1457     msg[len] = '\0';
1458     ++len;
1459   }
1460 
1461   return len;
1462 }
1463 
1464 uint16_t
error_code() const1465 QUICConnectionCloseFrame::error_code() const
1466 {
1467   return this->_error_code;
1468 }
1469 
1470 QUICFrameType
frame_type() const1471 QUICConnectionCloseFrame::frame_type() const
1472 {
1473   return this->_frame_type;
1474 }
1475 
1476 uint64_t
reason_phrase_length() const1477 QUICConnectionCloseFrame::reason_phrase_length() const
1478 {
1479   return this->_reason_phrase_length;
1480 }
1481 
1482 const char *
reason_phrase() const1483 QUICConnectionCloseFrame::reason_phrase() const
1484 {
1485   return this->_reason_phrase;
1486 }
1487 
1488 //
1489 // MAX_DATA frame
1490 //
QUICMaxDataFrame(uint64_t maximum_data,QUICFrameId id,QUICFrameGenerator * owner)1491 QUICMaxDataFrame::QUICMaxDataFrame(uint64_t maximum_data, QUICFrameId id, QUICFrameGenerator *owner) : QUICFrame(id, owner)
1492 {
1493   this->_maximum_data = maximum_data;
1494 }
1495 
1496 void
_reset()1497 QUICMaxDataFrame::_reset()
1498 {
1499   this->_maximum_data = 0;
1500 
1501   this->_owner = nullptr;
1502   this->_id    = 0;
1503   this->_valid = false;
1504   this->_size  = 0;
1505 }
1506 
QUICMaxDataFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)1507 QUICMaxDataFrame::QUICMaxDataFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
1508 {
1509   this->parse(buf, len, packet);
1510 }
1511 
1512 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)1513 QUICMaxDataFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1514 {
1515   ink_assert(len >= 1);
1516   this->_reset();
1517   this->_packet = packet;
1518   uint8_t *pos  = 1 + const_cast<uint8_t *>(buf);
1519 
1520   size_t field_len = 0;
1521   if (!read_varint(pos, LEFT_SPACE(pos), this->_maximum_data, field_len)) {
1522     return;
1523   }
1524 
1525   this->_valid = true;
1526   this->_size  = FRAME_SIZE(pos);
1527 }
1528 
1529 QUICFrameType
type() const1530 QUICMaxDataFrame::type() const
1531 {
1532   return QUICFrameType::MAX_DATA;
1533 }
1534 
1535 size_t
size() const1536 QUICMaxDataFrame::size() const
1537 {
1538   if (this->_size) {
1539     return this->_size;
1540   }
1541 
1542   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_maximum_data);
1543 }
1544 
1545 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1546 QUICMaxDataFrame::to_io_buffer_block(size_t limit) const
1547 {
1548   Ptr<IOBufferBlock> block;
1549   size_t n = 0;
1550 
1551   if (limit < this->size()) {
1552     return block;
1553   }
1554 
1555   size_t written_len = 0;
1556   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1557   block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
1558   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1559 
1560   // Type
1561   block_start[0] = static_cast<uint8_t>(QUICFrameType::MAX_DATA);
1562   n += 1;
1563 
1564   // Maximum Data (i)
1565   QUICTypeUtil::write_QUICMaxData(this->_maximum_data, block_start + n, &written_len);
1566   n += written_len;
1567 
1568   block->fill(n);
1569   return block;
1570 }
1571 
1572 int
debug_msg(char * msg,size_t msg_len) const1573 QUICMaxDataFrame::debug_msg(char *msg, size_t msg_len) const
1574 {
1575   return snprintf(msg, msg_len, "MAX_DATA size=%zu maximum=%" PRIu64, this->size(), this->maximum_data());
1576 }
1577 
1578 uint64_t
maximum_data() const1579 QUICMaxDataFrame::maximum_data() const
1580 {
1581   return this->_maximum_data;
1582 }
1583 
1584 //
1585 // MAX_STREAM_DATA
1586 //
QUICMaxStreamDataFrame(QUICStreamId stream_id,uint64_t maximum_stream_data,QUICFrameId id,QUICFrameGenerator * owner)1587 QUICMaxStreamDataFrame::QUICMaxStreamDataFrame(QUICStreamId stream_id, uint64_t maximum_stream_data, QUICFrameId id,
1588                                                QUICFrameGenerator *owner)
1589   : QUICFrame(id, owner)
1590 {
1591   this->_stream_id           = stream_id;
1592   this->_maximum_stream_data = maximum_stream_data;
1593 }
1594 
1595 void
_reset()1596 QUICMaxStreamDataFrame::_reset()
1597 {
1598   this->_stream_id           = 0;
1599   this->_maximum_stream_data = 0;
1600 
1601   this->_owner = nullptr;
1602   this->_id    = 0;
1603   this->_valid = false;
1604   this->_size  = 0;
1605 }
1606 
QUICMaxStreamDataFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)1607 QUICMaxStreamDataFrame::QUICMaxStreamDataFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1608   : QUICFrame(0, nullptr, packet)
1609 {
1610   this->parse(buf, len, packet);
1611 }
1612 
1613 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)1614 QUICMaxStreamDataFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1615 {
1616   ink_assert(len >= 1);
1617   this->_reset();
1618   this->_packet = packet;
1619   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
1620 
1621   size_t field_len = 0;
1622   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
1623     return;
1624   }
1625 
1626   if (!read_varint(pos, LEFT_SPACE(pos), this->_maximum_stream_data, field_len)) {
1627     return;
1628   }
1629 
1630   this->_valid = true;
1631   this->_size  = FRAME_SIZE(pos);
1632 }
1633 
1634 QUICFrameType
type() const1635 QUICMaxStreamDataFrame::type() const
1636 {
1637   return QUICFrameType::MAX_STREAM_DATA;
1638 }
1639 
1640 size_t
size() const1641 QUICMaxStreamDataFrame::size() const
1642 {
1643   if (this->_size) {
1644     return this->_size;
1645   }
1646 
1647   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_maximum_stream_data) + QUICVariableInt::size(this->_stream_id);
1648 }
1649 
1650 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1651 QUICMaxStreamDataFrame::to_io_buffer_block(size_t limit) const
1652 {
1653   Ptr<IOBufferBlock> block;
1654   size_t n = 0;
1655 
1656   if (limit < this->size()) {
1657     return block;
1658   }
1659 
1660   size_t written_len = 0;
1661   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1662   block->alloc(iobuffer_size_to_index(1 + sizeof(uint64_t) + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
1663   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1664 
1665   // Type
1666   block_start[0] = static_cast<uint8_t>(QUICFrameType::MAX_STREAM_DATA);
1667   n += 1;
1668 
1669   // Stream ID (i)
1670   QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
1671   n += written_len;
1672 
1673   // Maximum Stream Data (i)
1674   QUICTypeUtil::write_QUICMaxData(this->_maximum_stream_data, block_start + n, &written_len);
1675   n += written_len;
1676 
1677   block->fill(n);
1678   return block;
1679 }
1680 
1681 int
debug_msg(char * msg,size_t msg_len) const1682 QUICMaxStreamDataFrame::debug_msg(char *msg, size_t msg_len) const
1683 {
1684   return snprintf(msg, msg_len, "MAX_STREAM_DATA size=%zu id=%" PRIu64 " maximum=%" PRIu64, this->size(), this->stream_id(),
1685                   this->maximum_stream_data());
1686 }
1687 
1688 QUICStreamId
stream_id() const1689 QUICMaxStreamDataFrame::stream_id() const
1690 {
1691   return this->_stream_id;
1692 }
1693 
1694 uint64_t
maximum_stream_data() const1695 QUICMaxStreamDataFrame::maximum_stream_data() const
1696 {
1697   return this->_maximum_stream_data;
1698 }
1699 
1700 //
1701 // MAX_STREAMS
1702 //
QUICMaxStreamsFrame(QUICStreamId maximum_streams,QUICFrameId id,QUICFrameGenerator * owner)1703 QUICMaxStreamsFrame::QUICMaxStreamsFrame(QUICStreamId maximum_streams, QUICFrameId id, QUICFrameGenerator *owner)
1704   : QUICFrame(id, owner)
1705 {
1706   this->_maximum_streams = maximum_streams;
1707 }
1708 
1709 void
_reset()1710 QUICMaxStreamsFrame::_reset()
1711 {
1712   this->_maximum_streams = 0;
1713 
1714   this->_owner = nullptr;
1715   this->_id    = 0;
1716   this->_valid = false;
1717   this->_size  = 0;
1718 }
1719 
QUICMaxStreamsFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)1720 QUICMaxStreamsFrame::QUICMaxStreamsFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
1721 {
1722   this->parse(buf, len, packet);
1723 }
1724 
1725 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)1726 QUICMaxStreamsFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1727 {
1728   ink_assert(len >= 1);
1729   this->_reset();
1730   this->_packet = packet;
1731   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
1732 
1733   size_t field_len = 0;
1734   if (!read_varint(pos, LEFT_SPACE(pos), this->_maximum_streams, field_len)) {
1735     return;
1736   }
1737 
1738   this->_valid = true;
1739   this->_size  = FRAME_SIZE(pos);
1740 }
1741 
1742 QUICFrameType
type() const1743 QUICMaxStreamsFrame::type() const
1744 {
1745   return QUICFrameType::MAX_STREAMS;
1746 }
1747 
1748 size_t
size() const1749 QUICMaxStreamsFrame::size() const
1750 {
1751   if (this->_size) {
1752     return this->_size;
1753   }
1754 
1755   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_maximum_streams);
1756 }
1757 
1758 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1759 QUICMaxStreamsFrame::to_io_buffer_block(size_t limit) const
1760 {
1761   Ptr<IOBufferBlock> block;
1762   size_t n = 0;
1763 
1764   if (limit < this->size()) {
1765     return block;
1766   }
1767 
1768   size_t written_len = 0;
1769   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1770   block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
1771   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1772 
1773   // Type
1774   block_start[0] = static_cast<uint8_t>(QUICFrameType::MAX_STREAMS);
1775   n += 1;
1776 
1777   // Maximum Streams (i)
1778   QUICTypeUtil::write_QUICStreamId(this->_maximum_streams, block_start + n, &written_len);
1779   n += written_len;
1780 
1781   block->fill(n);
1782   return block;
1783 }
1784 
1785 uint64_t
maximum_streams() const1786 QUICMaxStreamsFrame::maximum_streams() const
1787 {
1788   return this->_maximum_streams;
1789 }
1790 
1791 //
1792 // DATA_BLOCKED frame
1793 //
QUICDataBlockedFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)1794 QUICDataBlockedFrame::QUICDataBlockedFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1795   : QUICFrame(0, nullptr, packet)
1796 {
1797   this->parse(buf, len, packet);
1798 }
1799 
1800 void
_reset()1801 QUICDataBlockedFrame::_reset()
1802 {
1803   this->_offset = 0;
1804 
1805   this->_owner = nullptr;
1806   this->_id    = 0;
1807   this->_valid = false;
1808   this->_size  = 0;
1809 }
1810 
1811 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)1812 QUICDataBlockedFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1813 {
1814   ink_assert(len >= 1);
1815   this->_reset();
1816   this->_packet = packet;
1817   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
1818 
1819   size_t field_len = 0;
1820   if (!read_varint(pos, LEFT_SPACE(pos), this->_offset, field_len)) {
1821     return;
1822   }
1823 
1824   this->_valid = true;
1825   this->_size  = FRAME_SIZE(pos);
1826 }
1827 
1828 int
debug_msg(char * msg,size_t msg_len) const1829 QUICDataBlockedFrame::debug_msg(char *msg, size_t msg_len) const
1830 {
1831   return snprintf(msg, msg_len, "DATA_BLOCKED size=%zu offset=%" PRIu64, this->size(), this->offset());
1832 }
1833 
1834 QUICFrameType
type() const1835 QUICDataBlockedFrame::type() const
1836 {
1837   return QUICFrameType::DATA_BLOCKED;
1838 }
1839 
1840 size_t
size() const1841 QUICDataBlockedFrame::size() const
1842 {
1843   if (this->_size) {
1844     return this->_size;
1845   }
1846 
1847   return sizeof(QUICFrameType) + QUICVariableInt::size(this->offset());
1848 }
1849 
1850 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1851 QUICDataBlockedFrame::to_io_buffer_block(size_t limit) const
1852 {
1853   Ptr<IOBufferBlock> block;
1854   size_t n = 0;
1855 
1856   if (limit < this->size()) {
1857     return block;
1858   }
1859 
1860   size_t written_len = 0;
1861   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1862   block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
1863   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1864 
1865   // Type
1866   block_start[0] = static_cast<uint8_t>(QUICFrameType::DATA_BLOCKED);
1867   n += 1;
1868 
1869   // Data Limit (i)
1870   QUICTypeUtil::write_QUICOffset(this->_offset, block_start + n, &written_len);
1871   n += written_len;
1872 
1873   block->fill(n);
1874   return block;
1875 }
1876 
1877 QUICOffset
offset() const1878 QUICDataBlockedFrame::offset() const
1879 {
1880   return this->_offset;
1881 }
1882 
1883 //
1884 // STREAM_DATA_BLOCKED frame
1885 //
QUICStreamDataBlockedFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)1886 QUICStreamDataBlockedFrame::QUICStreamDataBlockedFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1887   : QUICFrame(0, nullptr, packet)
1888 {
1889   this->parse(buf, len, packet);
1890 }
1891 
1892 void
_reset()1893 QUICStreamDataBlockedFrame::_reset()
1894 {
1895   this->_stream_id = 0;
1896   this->_offset    = 0;
1897 
1898   this->_owner = nullptr;
1899   this->_id    = 0;
1900   this->_valid = false;
1901   this->_size  = 0;
1902 }
1903 
1904 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)1905 QUICStreamDataBlockedFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1906 {
1907   ink_assert(len >= 1);
1908   this->_reset();
1909   this->_packet = packet;
1910   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
1911 
1912   size_t field_len = 0;
1913   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
1914     return;
1915   }
1916 
1917   if (!read_varint(pos, LEFT_SPACE(pos), this->_offset, field_len)) {
1918     return;
1919   }
1920 
1921   this->_valid = true;
1922   this->_size  = FRAME_SIZE(pos);
1923 }
1924 
1925 int
debug_msg(char * msg,size_t msg_len) const1926 QUICStreamDataBlockedFrame::debug_msg(char *msg, size_t msg_len) const
1927 {
1928   return snprintf(msg, msg_len, "STREAM_DATA_BLOCKED size=%zu id=%" PRIu64 " offset=%" PRIu64, this->size(), this->stream_id(),
1929                   this->offset());
1930 }
1931 
1932 QUICFrameType
type() const1933 QUICStreamDataBlockedFrame::type() const
1934 {
1935   return QUICFrameType::STREAM_DATA_BLOCKED;
1936 }
1937 
1938 size_t
size() const1939 QUICStreamDataBlockedFrame::size() const
1940 {
1941   if (this->_size) {
1942     return this->_size;
1943   }
1944 
1945   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_offset) + QUICVariableInt::size(this->_stream_id);
1946 }
1947 
1948 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1949 QUICStreamDataBlockedFrame::to_io_buffer_block(size_t limit) const
1950 {
1951   Ptr<IOBufferBlock> block;
1952   size_t n = 0;
1953 
1954   if (limit < this->size()) {
1955     return block;
1956   }
1957 
1958   size_t written_len = 0;
1959   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1960   block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
1961   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1962 
1963   // Type
1964   block_start[0] = static_cast<uint8_t>(QUICFrameType::STREAM_DATA_BLOCKED);
1965   n += 1;
1966 
1967   // Stream ID (i)
1968   QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
1969   n += written_len;
1970 
1971   // Data Limit (i)
1972   QUICTypeUtil::write_QUICOffset(this->_offset, block_start + n, &written_len);
1973   n += written_len;
1974 
1975   block->fill(n);
1976   return block;
1977 }
1978 
1979 QUICStreamId
stream_id() const1980 QUICStreamDataBlockedFrame::stream_id() const
1981 {
1982   return this->_stream_id;
1983 }
1984 
1985 QUICOffset
offset() const1986 QUICStreamDataBlockedFrame::offset() const
1987 {
1988   return this->_offset;
1989 }
1990 
1991 //
1992 // STREAMS_BLOCKED frame
1993 //
QUICStreamIdBlockedFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)1994 QUICStreamIdBlockedFrame::QUICStreamIdBlockedFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
1995   : QUICFrame(0, nullptr, packet)
1996 {
1997   this->parse(buf, len, packet);
1998 }
1999 
2000 void
_reset()2001 QUICStreamIdBlockedFrame::_reset()
2002 {
2003   this->_stream_id = 0;
2004 
2005   this->_owner = nullptr;
2006   this->_id    = 0;
2007   this->_size  = 0;
2008   this->_valid = false;
2009 }
2010 
2011 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)2012 QUICStreamIdBlockedFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2013 {
2014   ink_assert(len >= 1);
2015   this->_reset();
2016   this->_packet = packet;
2017   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2018 
2019   size_t field_len = 0;
2020   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
2021     return;
2022   }
2023 
2024   this->_valid = true;
2025   this->_size  = FRAME_SIZE(pos);
2026 }
2027 
2028 QUICFrameType
type() const2029 QUICStreamIdBlockedFrame::type() const
2030 {
2031   return QUICFrameType::STREAMS_BLOCKED;
2032 }
2033 
2034 size_t
size() const2035 QUICStreamIdBlockedFrame::size() const
2036 {
2037   if (this->_size) {
2038     return this->_size;
2039   }
2040 
2041   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_stream_id);
2042 }
2043 
2044 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2045 QUICStreamIdBlockedFrame::to_io_buffer_block(size_t limit) const
2046 {
2047   Ptr<IOBufferBlock> block;
2048   size_t n = 0;
2049 
2050   if (limit < this->size()) {
2051     return block;
2052   }
2053 
2054   size_t written_len = 0;
2055   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2056   block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
2057   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2058 
2059   // Type
2060   block_start[0] = static_cast<uint8_t>(QUICFrameType::STREAMS_BLOCKED);
2061   n += 1;
2062 
2063   // Stream Limit (i)
2064   QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
2065   n += written_len;
2066 
2067   block->fill(n);
2068   return block;
2069 }
2070 
2071 QUICStreamId
stream_id() const2072 QUICStreamIdBlockedFrame::stream_id() const
2073 {
2074   return this->_stream_id;
2075 }
2076 
2077 //
2078 // NEW_CONNECTION_ID frame
2079 //
QUICNewConnectionIdFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)2080 QUICNewConnectionIdFrame::QUICNewConnectionIdFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2081   : QUICFrame(0, nullptr, packet)
2082 {
2083   this->parse(buf, len, packet);
2084 }
2085 
2086 void
_reset()2087 QUICNewConnectionIdFrame::_reset()
2088 {
2089   this->_sequence        = 0;
2090   this->_retire_prior_to = 0;
2091   this->_connection_id   = QUICConnectionId::ZERO();
2092 
2093   this->_owner = nullptr;
2094   this->_id    = 0;
2095   this->_valid = false;
2096   this->_size  = 0;
2097 }
2098 
2099 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)2100 QUICNewConnectionIdFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2101 {
2102   ink_assert(len >= 1);
2103   this->_reset();
2104   this->_packet = packet;
2105   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2106 
2107   // Sequence Number (i)
2108   size_t field_len = 0;
2109   if (!read_varint(pos, LEFT_SPACE(pos), this->_sequence, field_len)) {
2110     return;
2111   }
2112 
2113   // Retire Prior To (i)
2114   if (LEFT_SPACE(pos) < 1) {
2115     return;
2116   }
2117   if (!read_varint(pos, LEFT_SPACE(pos), this->_retire_prior_to, field_len)) {
2118     return;
2119   }
2120 
2121   // Length (8)
2122   if (LEFT_SPACE(pos) < 1) {
2123     return;
2124   }
2125   size_t cid_len = *pos;
2126   pos += 1;
2127 
2128   // Connection ID (8..160)
2129   if (LEFT_SPACE(pos) < cid_len) {
2130     return;
2131   }
2132   this->_connection_id = QUICTypeUtil::read_QUICConnectionId(pos, cid_len);
2133   pos += cid_len;
2134 
2135   // Stateless Reset Token (128)
2136   if (LEFT_SPACE(pos) < QUICStatelessResetToken::LEN) {
2137     return;
2138   }
2139 
2140   this->_stateless_reset_token = QUICStatelessResetToken(pos);
2141   this->_valid                 = true;
2142   this->_size                  = FRAME_SIZE(pos) + QUICStatelessResetToken::LEN;
2143 }
2144 
2145 QUICFrameType
type() const2146 QUICNewConnectionIdFrame::type() const
2147 {
2148   return QUICFrameType::NEW_CONNECTION_ID;
2149 }
2150 
2151 size_t
size() const2152 QUICNewConnectionIdFrame::size() const
2153 {
2154   if (this->_size) {
2155     return this->_size;
2156   }
2157 
2158   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_sequence) + QUICVariableInt::size(this->_retire_prior_to) + 1 +
2159          this->_connection_id.length() + QUICStatelessResetToken::LEN;
2160 }
2161 
2162 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2163 QUICNewConnectionIdFrame::to_io_buffer_block(size_t limit) const
2164 {
2165   Ptr<IOBufferBlock> block;
2166   size_t n = 0;
2167 
2168   if (limit < this->size()) {
2169     return block;
2170   }
2171 
2172   size_t written_len = 0;
2173   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2174   block->alloc(iobuffer_size_to_index(1 + sizeof(uint64_t) + sizeof(uint64_t) + 1 + QUICConnectionId::MAX_LENGTH +
2175                                         QUICStatelessResetToken::LEN,
2176                                       BUFFER_SIZE_INDEX_32K));
2177   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2178 
2179   // Type
2180   block_start[0] = static_cast<uint8_t>(QUICFrameType::NEW_CONNECTION_ID);
2181   n += 1;
2182 
2183   // Sequence Number (i)
2184   QUICIntUtil::write_QUICVariableInt(this->_sequence, block_start + n, &written_len);
2185   n += written_len;
2186 
2187   // Retire Prior To (i)
2188   QUICIntUtil::write_QUICVariableInt(this->_retire_prior_to, block_start + n, &written_len);
2189   n += written_len;
2190 
2191   // Length (8)
2192   *(block_start + n) = this->_connection_id.length();
2193   n += 1;
2194 
2195   // Connection ID (8..160)
2196   QUICTypeUtil::write_QUICConnectionId(this->_connection_id, block_start + n, &written_len);
2197   n += written_len;
2198 
2199   // Stateless Reset Token (128)
2200   memcpy(block_start + n, this->_stateless_reset_token.buf(), QUICStatelessResetToken::LEN);
2201   n += QUICStatelessResetToken::LEN;
2202 
2203   block->fill(n);
2204   return block;
2205 }
2206 
2207 int
debug_msg(char * msg,size_t msg_len) const2208 QUICNewConnectionIdFrame::debug_msg(char *msg, size_t msg_len) const
2209 {
2210   return snprintf(msg, msg_len, "NEW_CONNECTION_ID size=%zu seq=%" PRIu64 " rpt=%" PRIu64 " cid=0x%s srt=%02x%02x%02x%02x",
2211                   this->size(), this->sequence(), this->retire_prior_to(), this->connection_id().hex().c_str(),
2212                   this->stateless_reset_token().buf()[0], this->stateless_reset_token().buf()[1],
2213                   this->stateless_reset_token().buf()[2], this->stateless_reset_token().buf()[3]);
2214 }
2215 
2216 uint64_t
sequence() const2217 QUICNewConnectionIdFrame::sequence() const
2218 {
2219   return this->_sequence;
2220 }
2221 
2222 uint64_t
retire_prior_to() const2223 QUICNewConnectionIdFrame::retire_prior_to() const
2224 {
2225   return this->_retire_prior_to;
2226 }
2227 
2228 QUICConnectionId
connection_id() const2229 QUICNewConnectionIdFrame::connection_id() const
2230 {
2231   return this->_connection_id;
2232 }
2233 
2234 QUICStatelessResetToken
stateless_reset_token() const2235 QUICNewConnectionIdFrame::stateless_reset_token() const
2236 {
2237   return this->_stateless_reset_token;
2238 }
2239 
2240 //
2241 // STOP_SENDING frame
2242 //
2243 
QUICStopSendingFrame(QUICStreamId stream_id,QUICAppErrorCode error_code,QUICFrameId id,QUICFrameGenerator * owner)2244 QUICStopSendingFrame::QUICStopSendingFrame(QUICStreamId stream_id, QUICAppErrorCode error_code, QUICFrameId id,
2245                                            QUICFrameGenerator *owner)
2246   : QUICFrame(id, owner), _stream_id(stream_id), _error_code(error_code)
2247 {
2248 }
2249 
2250 void
_reset()2251 QUICStopSendingFrame::_reset()
2252 {
2253   this->_stream_id  = 0;
2254   this->_error_code = 0;
2255 
2256   this->_owner = nullptr;
2257   this->_id    = 0;
2258   this->_valid = false;
2259   this->_size  = 0;
2260 }
2261 
QUICStopSendingFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)2262 QUICStopSendingFrame::QUICStopSendingFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2263   : QUICFrame(0, nullptr, packet)
2264 {
2265   this->parse(buf, len, packet);
2266 }
2267 
2268 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)2269 QUICStopSendingFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2270 {
2271   ink_assert(len >= 1);
2272   this->_reset();
2273   this->_packet = packet;
2274   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2275 
2276   // Stream ID (i)
2277   size_t field_len = 0;
2278   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
2279     return;
2280   }
2281 
2282   // Error Code (i)
2283   if (LEFT_SPACE(pos) < 1) {
2284     return;
2285   }
2286   if (!read_varint(pos, LEFT_SPACE(pos), this->_error_code, field_len)) {
2287     return;
2288   }
2289 
2290   this->_valid = true;
2291   this->_size  = FRAME_SIZE(pos);
2292 }
2293 
2294 QUICFrameType
type() const2295 QUICStopSendingFrame::type() const
2296 {
2297   return QUICFrameType::STOP_SENDING;
2298 }
2299 
2300 size_t
size() const2301 QUICStopSendingFrame::size() const
2302 {
2303   if (this->_size) {
2304     return this->_size;
2305   }
2306 
2307   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_stream_id) + QUICVariableInt::size(sizeof(QUICAppErrorCode));
2308 }
2309 
2310 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2311 QUICStopSendingFrame::to_io_buffer_block(size_t limit) const
2312 {
2313   Ptr<IOBufferBlock> block;
2314   size_t n = 0;
2315 
2316   if (limit < this->size()) {
2317     return block;
2318   }
2319 
2320   size_t written_len = 0;
2321   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2322   block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
2323   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2324 
2325   // Type
2326   block_start[0] = static_cast<uint8_t>(QUICFrameType::STOP_SENDING);
2327   n += 1;
2328 
2329   // Stream ID (i)
2330   QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
2331   n += written_len;
2332 
2333   // Application Error Code (i)
2334   QUICTypeUtil::write_QUICAppErrorCode(this->_error_code, block_start + n, &written_len);
2335   n += written_len;
2336 
2337   block->fill(n);
2338   return block;
2339 }
2340 
2341 QUICAppErrorCode
error_code() const2342 QUICStopSendingFrame::error_code() const
2343 {
2344   return this->_error_code;
2345 }
2346 
2347 QUICStreamId
stream_id() const2348 QUICStopSendingFrame::stream_id() const
2349 {
2350   return this->_stream_id;
2351 }
2352 
2353 //
2354 // PATH_CHALLENGE frame
2355 //
QUICPathChallengeFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)2356 QUICPathChallengeFrame::QUICPathChallengeFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2357   : QUICFrame(0, nullptr, packet)
2358 {
2359   this->parse(buf, len, packet);
2360 }
2361 
2362 void
_reset()2363 QUICPathChallengeFrame::_reset()
2364 {
2365   this->_data  = nullptr;
2366   this->_owner = nullptr;
2367   this->_id    = 0;
2368   this->_valid = false;
2369   this->_size  = 0;
2370 }
2371 
2372 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)2373 QUICPathChallengeFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2374 {
2375   ink_assert(len >= 1);
2376   this->_reset();
2377   this->_packet = packet;
2378   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2379 
2380   if (LEFT_SPACE(pos) < QUICPathChallengeFrame::DATA_LEN) {
2381     return;
2382   }
2383 
2384   this->_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
2385   memcpy(this->_data.get(), pos, QUICPathChallengeFrame::DATA_LEN);
2386   this->_valid = true;
2387   this->_size  = FRAME_SIZE(pos) + QUICPathChallengeFrame::DATA_LEN;
2388 }
2389 
2390 QUICFrameType
type() const2391 QUICPathChallengeFrame::type() const
2392 {
2393   return QUICFrameType::PATH_CHALLENGE;
2394 }
2395 
2396 size_t
size() const2397 QUICPathChallengeFrame::size() const
2398 {
2399   if (this->_size) {
2400     return this->_size;
2401   }
2402 
2403   return 1 + QUICPathChallengeFrame::DATA_LEN;
2404 }
2405 
2406 bool
is_probing_frame() const2407 QUICPathChallengeFrame::is_probing_frame() const
2408 {
2409   return true;
2410 }
2411 
2412 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2413 QUICPathChallengeFrame::to_io_buffer_block(size_t limit) const
2414 {
2415   Ptr<IOBufferBlock> block;
2416   size_t n = 0;
2417 
2418   if (limit < this->size()) {
2419     return block;
2420   }
2421 
2422   block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2423   block->alloc(iobuffer_size_to_index(1 + QUICPathChallengeFrame::DATA_LEN, BUFFER_SIZE_INDEX_32K));
2424   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2425 
2426   // Type
2427   block_start[0] = static_cast<uint8_t>(QUICFrameType::PATH_CHALLENGE);
2428   n += 1;
2429 
2430   // Data (64)
2431   memcpy(block_start + n, this->data(), QUICPathChallengeFrame::DATA_LEN);
2432   n += QUICPathChallengeFrame::DATA_LEN;
2433 
2434   block->fill(n);
2435   return block;
2436 }
2437 
2438 int
debug_msg(char * msg,size_t msg_len) const2439 QUICPathChallengeFrame::debug_msg(char *msg, size_t msg_len) const
2440 {
2441   auto data = this->data();
2442   return snprintf(msg, msg_len, "PATH_CHALLENGE size=%zu data=0x%02x%02x%02x%02x%02x%02x%02x%02x", this->size(), data[0], data[1],
2443                   data[2], data[3], data[4], data[5], data[6], data[7]);
2444 }
2445 
2446 const uint8_t *
data() const2447 QUICPathChallengeFrame::data() const
2448 {
2449   return this->_data.get();
2450 }
2451 
2452 //
2453 // PATH_RESPONSE frame
2454 //
QUICPathResponseFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)2455 QUICPathResponseFrame::QUICPathResponseFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2456   : QUICFrame(0, nullptr, packet)
2457 {
2458   this->parse(buf, len, packet);
2459 }
2460 
2461 void
_reset()2462 QUICPathResponseFrame::_reset()
2463 {
2464   this->_data  = nullptr;
2465   this->_owner = nullptr;
2466   this->_id    = 0;
2467   this->_valid = false;
2468   this->_size  = 0;
2469 }
2470 
2471 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2472 QUICPathResponseFrame::to_io_buffer_block(size_t limit) const
2473 {
2474   Ptr<IOBufferBlock> block;
2475   size_t n = 0;
2476 
2477   if (limit < this->size()) {
2478     return block;
2479   }
2480 
2481   block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2482   block->alloc(iobuffer_size_to_index(1 + QUICPathResponseFrame::DATA_LEN, BUFFER_SIZE_INDEX_32K));
2483   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2484 
2485   // Type
2486   block_start[0] = static_cast<uint8_t>(QUICFrameType::PATH_RESPONSE);
2487   n += 1;
2488 
2489   // Data (64)
2490   memcpy(block_start + n, this->data(), QUICPathChallengeFrame::DATA_LEN);
2491   n += QUICPathChallengeFrame::DATA_LEN;
2492 
2493   block->fill(n);
2494   return block;
2495 }
2496 
2497 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)2498 QUICPathResponseFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2499 {
2500   ink_assert(len >= 1);
2501   this->_reset();
2502   this->_packet = packet;
2503   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2504 
2505   if (LEFT_SPACE(pos) < QUICPathChallengeFrame::DATA_LEN) {
2506     return;
2507   }
2508 
2509   this->_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
2510   memcpy(this->_data.get(), pos, QUICPathChallengeFrame::DATA_LEN);
2511   this->_valid = true;
2512   this->_size  = FRAME_SIZE(pos) + QUICPathChallengeFrame::DATA_LEN;
2513 }
2514 
2515 QUICFrameType
type() const2516 QUICPathResponseFrame::type() const
2517 {
2518   return QUICFrameType::PATH_RESPONSE;
2519 }
2520 
2521 size_t
size() const2522 QUICPathResponseFrame::size() const
2523 {
2524   return 1 + 8;
2525 }
2526 
2527 bool
is_probing_frame() const2528 QUICPathResponseFrame::is_probing_frame() const
2529 {
2530   return true;
2531 }
2532 
2533 int
debug_msg(char * msg,size_t msg_len) const2534 QUICPathResponseFrame::debug_msg(char *msg, size_t msg_len) const
2535 {
2536   auto data = this->data();
2537   return snprintf(msg, msg_len, "PATH_RESPONSE size=%zu data=0x%02x%02x%02x%02x%02x%02x%02x%02x", this->size(), data[0], data[1],
2538                   data[2], data[3], data[4], data[5], data[6], data[7]);
2539 }
2540 
2541 const uint8_t *
data() const2542 QUICPathResponseFrame::data() const
2543 {
2544   return this->_data.get();
2545 }
2546 
2547 //
2548 // QUICNewTokenFrame
2549 //
QUICNewTokenFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)2550 QUICNewTokenFrame::QUICNewTokenFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet) : QUICFrame(0, nullptr, packet)
2551 {
2552   this->parse(buf, len, packet);
2553 }
2554 
2555 void
_reset()2556 QUICNewTokenFrame::_reset()
2557 {
2558   this->_token        = nullptr;
2559   this->_token_length = 0;
2560 
2561   this->_owner = nullptr;
2562   this->_id    = 0;
2563   this->_valid = false;
2564   this->_size  = 0;
2565 }
2566 
2567 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)2568 QUICNewTokenFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2569 {
2570   ink_assert(len >= 1);
2571   this->_reset();
2572   this->_packet = packet;
2573   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2574 
2575   size_t field_len = 0;
2576   if (!read_varint(pos, LEFT_SPACE(pos), this->_token_length, field_len)) {
2577     return;
2578   }
2579 
2580   if (LEFT_SPACE(pos) < this->_token_length) {
2581     return;
2582   }
2583 
2584   this->_token = ats_unique_malloc(this->_token_length);
2585   memcpy(this->_token.get(), pos, this->_token_length);
2586   this->_valid = true;
2587   this->_size  = FRAME_SIZE(pos) + this->_token_length;
2588 }
2589 
2590 QUICFrameType
type() const2591 QUICNewTokenFrame::type() const
2592 {
2593   return QUICFrameType::NEW_TOKEN;
2594 }
2595 
2596 size_t
size() const2597 QUICNewTokenFrame::size() const
2598 {
2599   if (this->_size) {
2600     return this->_size;
2601   }
2602 
2603   return 1 + QUICVariableInt::size(this->_token_length) + this->token_length();
2604 }
2605 
2606 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2607 QUICNewTokenFrame::to_io_buffer_block(size_t limit) const
2608 {
2609   Ptr<IOBufferBlock> block;
2610   size_t n = 0;
2611 
2612   if (limit < this->size()) {
2613     return block;
2614   }
2615 
2616   size_t written_len = 0;
2617   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2618   block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
2619   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2620 
2621   // Type
2622   block_start[0] = static_cast<uint8_t>(QUICFrameType::NEW_TOKEN);
2623   n += 1;
2624 
2625   // Token Length (i)
2626   QUICIntUtil::write_QUICVariableInt(this->_token_length, block_start + n, &written_len);
2627   n += written_len;
2628 
2629   // Token (*)
2630   memcpy(block_start + n, this->token(), this->token_length());
2631   n += this->token_length();
2632 
2633   block->fill(n);
2634   return block;
2635 }
2636 
2637 uint64_t
token_length() const2638 QUICNewTokenFrame::token_length() const
2639 {
2640   return this->_token_length;
2641 }
2642 
2643 const uint8_t *
token() const2644 QUICNewTokenFrame::token() const
2645 {
2646   return this->_token.get();
2647 }
2648 
2649 //
2650 // RETIRE_CONNECTION_ID frame
2651 //
QUICRetireConnectionIdFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)2652 QUICRetireConnectionIdFrame::QUICRetireConnectionIdFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2653   : QUICFrame(0, nullptr, packet)
2654 {
2655   this->parse(buf, len, packet);
2656 }
2657 
2658 void
_reset()2659 QUICRetireConnectionIdFrame::_reset()
2660 {
2661   this->_seq_num = 0;
2662 
2663   this->_owner = nullptr;
2664   this->_id    = 0;
2665   this->_valid = false;
2666   this->_size  = 0;
2667   this->_size  = 0;
2668 }
2669 
2670 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)2671 QUICRetireConnectionIdFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2672 {
2673   ink_assert(len >= 1);
2674   this->_reset();
2675   this->_packet = packet;
2676   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2677 
2678   size_t field_len = 0;
2679   if (!read_varint(pos, LEFT_SPACE(pos), this->_seq_num, field_len)) {
2680     return;
2681   }
2682 
2683   this->_valid = true;
2684   this->_size  = FRAME_SIZE(pos);
2685 }
2686 
2687 QUICFrameType
type() const2688 QUICRetireConnectionIdFrame::type() const
2689 {
2690   return QUICFrameType::RETIRE_CONNECTION_ID;
2691 }
2692 
2693 size_t
size() const2694 QUICRetireConnectionIdFrame::size() const
2695 {
2696   if (this->_size) {
2697     return this->_size;
2698   }
2699 
2700   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_seq_num);
2701 }
2702 
2703 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2704 QUICRetireConnectionIdFrame::to_io_buffer_block(size_t limit) const
2705 {
2706   Ptr<IOBufferBlock> block;
2707   size_t n = 0;
2708 
2709   if (limit < this->size()) {
2710     return block;
2711   }
2712 
2713   size_t written_len = 0;
2714   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2715   block->alloc(iobuffer_size_to_index(1 + sizeof(uint64_t), BUFFER_SIZE_INDEX_32K));
2716   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2717 
2718   // Type
2719   block_start[0] = static_cast<uint8_t>(QUICFrameType::RETIRE_CONNECTION_ID);
2720   n += 1;
2721 
2722   // Sequence Number (i)
2723   QUICIntUtil::write_QUICVariableInt(this->_seq_num, block_start + n, &written_len);
2724   n += written_len;
2725 
2726   block->fill(n);
2727   return block;
2728 }
2729 
2730 int
debug_msg(char * msg,size_t msg_len) const2731 QUICRetireConnectionIdFrame::debug_msg(char *msg, size_t msg_len) const
2732 {
2733   return snprintf(msg, msg_len, "RETIRE_CONNECTION_ID size=%zu seq_num=%" PRIu64, this->size(), this->seq_num());
2734 }
2735 
2736 uint64_t
seq_num() const2737 QUICRetireConnectionIdFrame::seq_num() const
2738 {
2739   return this->_seq_num;
2740 }
2741 
2742 //
2743 // HANDSHAKE_DONE frame
2744 //
2745 
QUICHandshakeDoneFrame(const uint8_t * buf,size_t len,const QUICPacketR * packet)2746 QUICHandshakeDoneFrame::QUICHandshakeDoneFrame(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2747   : QUICFrame(0, nullptr, packet)
2748 {
2749   this->parse(buf, len, packet);
2750 }
2751 
2752 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)2753 QUICHandshakeDoneFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2754 {
2755   this->_reset();
2756   this->_packet = packet;
2757   this->_valid  = true;
2758   this->_size   = 1;
2759 }
2760 
2761 QUICFrameType
type() const2762 QUICHandshakeDoneFrame::type() const
2763 {
2764   return QUICFrameType::HANDSHAKE_DONE;
2765 }
2766 
2767 size_t
size() const2768 QUICHandshakeDoneFrame::size() const
2769 {
2770   return 1;
2771 }
2772 
2773 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2774 QUICHandshakeDoneFrame::to_io_buffer_block(size_t limit) const
2775 {
2776   Ptr<IOBufferBlock> block;
2777   size_t n = 0;
2778 
2779   if (limit < this->size()) {
2780     return block;
2781   }
2782 
2783   block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2784   block->alloc(iobuffer_size_to_index(this->size(), BUFFER_SIZE_INDEX_32K));
2785   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2786 
2787   // Type
2788   block_start[0] = static_cast<uint8_t>(QUICFrameType::HANDSHAKE_DONE);
2789   n += 1;
2790 
2791   block->fill(n);
2792   return block;
2793 }
2794 
2795 //
2796 // UNKNOWN
2797 //
2798 QUICFrameType
type() const2799 QUICUnknownFrame::type() const
2800 {
2801   return QUICFrameType::UNKNOWN;
2802 }
2803 
2804 size_t
size() const2805 QUICUnknownFrame::size() const
2806 {
2807   // FIXME size should be readable
2808   return 0;
2809 }
2810 
2811 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2812 QUICUnknownFrame::to_io_buffer_block(size_t limit) const
2813 {
2814   Ptr<IOBufferBlock> block;
2815   return block;
2816 }
2817 
2818 void
parse(const uint8_t * buf,size_t len,const QUICPacketR * packet)2819 QUICUnknownFrame::parse(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2820 {
2821   this->_packet = packet;
2822 }
2823 
2824 int
debug_msg(char * msg,size_t msg_len) const2825 QUICUnknownFrame::debug_msg(char *msg, size_t msg_len) const
2826 {
2827   return 0;
2828 }
2829 
2830 //
2831 // QUICFrameFactory
2832 //
2833 
2834 QUICFrame *
create(uint8_t * buf,const uint8_t * src,size_t len,const QUICPacketR * packet)2835 QUICFrameFactory::create(uint8_t *buf, const uint8_t *src, size_t len, const QUICPacketR *packet)
2836 {
2837   switch (QUICFrame::type(src)) {
2838   case QUICFrameType::STREAM:
2839     new (buf) QUICStreamFrame(src, len, packet);
2840     return reinterpret_cast<QUICFrame *>(buf);
2841   case QUICFrameType::CRYPTO:
2842     new (buf) QUICCryptoFrame(src, len, packet);
2843     return reinterpret_cast<QUICFrame *>(buf);
2844   case QUICFrameType::ACK:
2845     new (buf) QUICAckFrame(src, len, packet);
2846     return reinterpret_cast<QUICFrame *>(buf);
2847   case QUICFrameType::PADDING:
2848     new (buf) QUICPaddingFrame(src, len, packet);
2849     return reinterpret_cast<QUICFrame *>(buf);
2850   case QUICFrameType::RESET_STREAM:
2851     new (buf) QUICRstStreamFrame(src, len, packet);
2852     return reinterpret_cast<QUICFrame *>(buf);
2853   case QUICFrameType::CONNECTION_CLOSE:
2854     new (buf) QUICConnectionCloseFrame(src, len, packet);
2855     return reinterpret_cast<QUICFrame *>(buf);
2856   case QUICFrameType::MAX_DATA:
2857     new (buf) QUICMaxDataFrame(src, len, packet);
2858     return reinterpret_cast<QUICFrame *>(buf);
2859   case QUICFrameType::MAX_STREAM_DATA:
2860     new (buf) QUICMaxStreamDataFrame(src, len, packet);
2861     return reinterpret_cast<QUICFrame *>(buf);
2862   case QUICFrameType::MAX_STREAMS:
2863     new (buf) QUICMaxStreamsFrame(src, len, packet);
2864     return reinterpret_cast<QUICFrame *>(buf);
2865   case QUICFrameType::PING:
2866     new (buf) QUICPingFrame(src, len, packet);
2867     return reinterpret_cast<QUICFrame *>(buf);
2868   case QUICFrameType::DATA_BLOCKED:
2869     new (buf) QUICDataBlockedFrame(src, len, packet);
2870     return reinterpret_cast<QUICFrame *>(buf);
2871   case QUICFrameType::STREAM_DATA_BLOCKED:
2872     new (buf) QUICStreamDataBlockedFrame(src, len, packet);
2873     return reinterpret_cast<QUICFrame *>(buf);
2874   case QUICFrameType::STREAMS_BLOCKED:
2875     new (buf) QUICStreamIdBlockedFrame(src, len, packet);
2876     return reinterpret_cast<QUICFrame *>(buf);
2877   case QUICFrameType::NEW_CONNECTION_ID:
2878     new (buf) QUICNewConnectionIdFrame(src, len, packet);
2879     return reinterpret_cast<QUICFrame *>(buf);
2880   case QUICFrameType::STOP_SENDING:
2881     new (buf) QUICStopSendingFrame(src, len, packet);
2882     return reinterpret_cast<QUICFrame *>(buf);
2883   case QUICFrameType::PATH_CHALLENGE:
2884     new (buf) QUICPathChallengeFrame(src, len, packet);
2885     return reinterpret_cast<QUICFrame *>(buf);
2886   case QUICFrameType::PATH_RESPONSE:
2887     new (buf) QUICPathResponseFrame(src, len, packet);
2888     return reinterpret_cast<QUICFrame *>(buf);
2889   case QUICFrameType::NEW_TOKEN:
2890     new (buf) QUICNewTokenFrame(src, len, packet);
2891     return reinterpret_cast<QUICFrame *>(buf);
2892   case QUICFrameType::RETIRE_CONNECTION_ID:
2893     new (buf) QUICRetireConnectionIdFrame(src, len, packet);
2894     return reinterpret_cast<QUICFrame *>(buf);
2895   case QUICFrameType::HANDSHAKE_DONE:
2896     new (buf) QUICHandshakeDoneFrame(src, len, packet);
2897     return reinterpret_cast<QUICFrame *>(buf);
2898   default:
2899     // Unknown frame
2900     Debug("quic_frame_factory", "Unknown frame type %x", src[0]);
2901     return nullptr;
2902   }
2903 }
2904 
2905 const QUICFrame &
fast_create(const uint8_t * buf,size_t len,const QUICPacketR * packet)2906 QUICFrameFactory::fast_create(const uint8_t *buf, size_t len, const QUICPacketR *packet)
2907 {
2908   if (QUICFrame::type(buf) == QUICFrameType::UNKNOWN) {
2909     return this->_unknown_frame;
2910   }
2911 
2912   ptrdiff_t type_index = static_cast<ptrdiff_t>(QUICFrame::type(buf));
2913   QUICFrame *frame     = this->_reusable_frames[type_index];
2914 
2915   if (frame == nullptr) {
2916     frame = QUICFrameFactory::create(this->_buf_for_fast_create + (type_index * QUICFrame::MAX_INSTANCE_SIZE), buf, len, packet);
2917     if (frame != nullptr) {
2918       this->_reusable_frames[static_cast<ptrdiff_t>(QUICFrame::type(buf))] = frame;
2919     }
2920   } else {
2921     frame->parse(buf, len, packet);
2922   }
2923 
2924   return *frame;
2925 }
2926 
2927 QUICStreamFrame *
create_stream_frame(uint8_t * buf,Ptr<IOBufferBlock> & block,QUICStreamId stream_id,QUICOffset offset,bool last,bool has_offset_field,bool has_length_field,QUICFrameId id,QUICFrameGenerator * owner)2928 QUICFrameFactory::create_stream_frame(uint8_t *buf, Ptr<IOBufferBlock> &block, QUICStreamId stream_id, QUICOffset offset, bool last,
2929                                       bool has_offset_field, bool has_length_field, QUICFrameId id, QUICFrameGenerator *owner)
2930 {
2931   Ptr<IOBufferBlock> new_block = make_ptr<IOBufferBlock>(block->clone());
2932   new (buf) QUICStreamFrame(new_block, stream_id, offset, last, has_offset_field, has_length_field, id, owner);
2933   return reinterpret_cast<QUICStreamFrame *>(buf);
2934 }
2935 
2936 QUICCryptoFrame *
create_crypto_frame(uint8_t * buf,Ptr<IOBufferBlock> & block,QUICOffset offset,QUICFrameId id,QUICFrameGenerator * owner)2937 QUICFrameFactory::create_crypto_frame(uint8_t *buf, Ptr<IOBufferBlock> &block, QUICOffset offset, QUICFrameId id,
2938                                       QUICFrameGenerator *owner)
2939 {
2940   Ptr<IOBufferBlock> new_block = make_ptr<IOBufferBlock>(block->clone());
2941   new (buf) QUICCryptoFrame(new_block, offset, id, owner);
2942   return reinterpret_cast<QUICCryptoFrame *>(buf);
2943 }
2944 
2945 QUICAckFrame *
create_ack_frame(uint8_t * buf,QUICPacketNumber largest_acknowledged,uint64_t ack_delay,uint64_t first_ack_block,QUICFrameId id,QUICFrameGenerator * owner)2946 QUICFrameFactory::create_ack_frame(uint8_t *buf, QUICPacketNumber largest_acknowledged, uint64_t ack_delay,
2947                                    uint64_t first_ack_block, QUICFrameId id, QUICFrameGenerator *owner)
2948 {
2949   new (buf) QUICAckFrame(largest_acknowledged, ack_delay, first_ack_block, id, owner);
2950   return reinterpret_cast<QUICAckFrame *>(buf);
2951 }
2952 
2953 QUICConnectionCloseFrame *
create_connection_close_frame(uint8_t * buf,uint16_t error_code,QUICFrameType frame_type,uint16_t reason_phrase_length,const char * reason_phrase,QUICFrameId id,QUICFrameGenerator * owner)2954 QUICFrameFactory::create_connection_close_frame(uint8_t *buf, uint16_t error_code, QUICFrameType frame_type,
2955                                                 uint16_t reason_phrase_length, const char *reason_phrase, QUICFrameId id,
2956                                                 QUICFrameGenerator *owner)
2957 {
2958   new (buf) QUICConnectionCloseFrame(error_code, frame_type, reason_phrase_length, reason_phrase, id, owner);
2959   return reinterpret_cast<QUICConnectionCloseFrame *>(buf);
2960 }
2961 
2962 QUICConnectionCloseFrame *
create_connection_close_frame(uint8_t * buf,const QUICConnectionError & error,QUICFrameId id,QUICFrameGenerator * owner)2963 QUICFrameFactory::create_connection_close_frame(uint8_t *buf, const QUICConnectionError &error, QUICFrameId id,
2964                                                 QUICFrameGenerator *owner)
2965 {
2966   ink_assert(error.cls == QUICErrorClass::TRANSPORT);
2967   if (error.msg) {
2968     return QUICFrameFactory::create_connection_close_frame(buf, error.code, error.frame_type(), strlen(error.msg), error.msg, id,
2969                                                            owner);
2970   } else {
2971     return QUICFrameFactory::create_connection_close_frame(buf, error.code, error.frame_type(), 0, nullptr, id, owner);
2972   }
2973 }
2974 
2975 QUICMaxDataFrame *
create_max_data_frame(uint8_t * buf,uint64_t maximum_data,QUICFrameId id,QUICFrameGenerator * owner)2976 QUICFrameFactory::create_max_data_frame(uint8_t *buf, uint64_t maximum_data, QUICFrameId id, QUICFrameGenerator *owner)
2977 {
2978   new (buf) QUICMaxDataFrame(maximum_data, id, owner);
2979   return reinterpret_cast<QUICMaxDataFrame *>(buf);
2980 }
2981 QUICMaxStreamDataFrame *
create_max_stream_data_frame(uint8_t * buf,QUICStreamId stream_id,uint64_t maximum_data,QUICFrameId id,QUICFrameGenerator * owner)2982 QUICFrameFactory::create_max_stream_data_frame(uint8_t *buf, QUICStreamId stream_id, uint64_t maximum_data, QUICFrameId id,
2983                                                QUICFrameGenerator *owner)
2984 {
2985   new (buf) QUICMaxStreamDataFrame(stream_id, maximum_data, id, owner);
2986   return reinterpret_cast<QUICMaxStreamDataFrame *>(buf);
2987 }
2988 
2989 QUICMaxStreamsFrame *
create_max_streams_frame(uint8_t * buf,QUICStreamId maximum_streams,QUICFrameId id,QUICFrameGenerator * owner)2990 QUICFrameFactory::create_max_streams_frame(uint8_t *buf, QUICStreamId maximum_streams, QUICFrameId id, QUICFrameGenerator *owner)
2991 {
2992   new (buf) QUICMaxStreamsFrame(maximum_streams, id, owner);
2993   return reinterpret_cast<QUICMaxStreamsFrame *>(buf);
2994 }
2995 
2996 QUICPingFrame *
create_ping_frame(uint8_t * buf,QUICFrameId id,QUICFrameGenerator * owner)2997 QUICFrameFactory::create_ping_frame(uint8_t *buf, QUICFrameId id, QUICFrameGenerator *owner)
2998 {
2999   new (buf) QUICPingFrame(id, owner);
3000   return reinterpret_cast<QUICPingFrame *>(buf);
3001 }
3002 
3003 QUICPaddingFrame *
create_padding_frame(uint8_t * buf,size_t size,QUICFrameId id,QUICFrameGenerator * owner)3004 QUICFrameFactory::create_padding_frame(uint8_t *buf, size_t size, QUICFrameId id, QUICFrameGenerator *owner)
3005 {
3006   new (buf) QUICPaddingFrame(size);
3007   return reinterpret_cast<QUICPaddingFrame *>(buf);
3008 }
3009 
3010 QUICPathChallengeFrame *
create_path_challenge_frame(uint8_t * buf,const uint8_t * data,QUICFrameId id,QUICFrameGenerator * owner)3011 QUICFrameFactory::create_path_challenge_frame(uint8_t *buf, const uint8_t *data, QUICFrameId id, QUICFrameGenerator *owner)
3012 {
3013   ats_unique_buf challenge_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
3014   memcpy(challenge_data.get(), data, QUICPathChallengeFrame::DATA_LEN);
3015 
3016   new (buf) QUICPathChallengeFrame(std::move(challenge_data), id, owner);
3017   return reinterpret_cast<QUICPathChallengeFrame *>(buf);
3018 }
3019 
3020 QUICPathResponseFrame *
create_path_response_frame(uint8_t * buf,const uint8_t * data,QUICFrameId id,QUICFrameGenerator * owner)3021 QUICFrameFactory::create_path_response_frame(uint8_t *buf, const uint8_t *data, QUICFrameId id, QUICFrameGenerator *owner)
3022 {
3023   ats_unique_buf response_data = ats_unique_malloc(QUICPathResponseFrame::DATA_LEN);
3024   memcpy(response_data.get(), data, QUICPathResponseFrame::DATA_LEN);
3025 
3026   new (buf) QUICPathResponseFrame(std::move(response_data), id, owner);
3027   return reinterpret_cast<QUICPathResponseFrame *>(buf);
3028 }
3029 
3030 QUICDataBlockedFrame *
create_data_blocked_frame(uint8_t * buf,QUICOffset offset,QUICFrameId id,QUICFrameGenerator * owner)3031 QUICFrameFactory::create_data_blocked_frame(uint8_t *buf, QUICOffset offset, QUICFrameId id, QUICFrameGenerator *owner)
3032 {
3033   new (buf) QUICDataBlockedFrame(offset, id, owner);
3034   return reinterpret_cast<QUICDataBlockedFrame *>(buf);
3035 }
3036 
3037 QUICStreamDataBlockedFrame *
create_stream_data_blocked_frame(uint8_t * buf,QUICStreamId stream_id,QUICOffset offset,QUICFrameId id,QUICFrameGenerator * owner)3038 QUICFrameFactory::create_stream_data_blocked_frame(uint8_t *buf, QUICStreamId stream_id, QUICOffset offset, QUICFrameId id,
3039                                                    QUICFrameGenerator *owner)
3040 {
3041   new (buf) QUICStreamDataBlockedFrame(stream_id, offset, id, owner);
3042   return reinterpret_cast<QUICStreamDataBlockedFrame *>(buf);
3043 }
3044 
3045 QUICStreamIdBlockedFrame *
create_stream_id_blocked_frame(uint8_t * buf,QUICStreamId stream_id,QUICFrameId id,QUICFrameGenerator * owner)3046 QUICFrameFactory::create_stream_id_blocked_frame(uint8_t *buf, QUICStreamId stream_id, QUICFrameId id, QUICFrameGenerator *owner)
3047 {
3048   new (buf) QUICStreamIdBlockedFrame(stream_id, id, owner);
3049   return reinterpret_cast<QUICStreamIdBlockedFrame *>(buf);
3050 }
3051 
3052 QUICRstStreamFrame *
create_rst_stream_frame(uint8_t * buf,QUICStreamId stream_id,QUICAppErrorCode error_code,QUICOffset final_offset,QUICFrameId id,QUICFrameGenerator * owner)3053 QUICFrameFactory::create_rst_stream_frame(uint8_t *buf, QUICStreamId stream_id, QUICAppErrorCode error_code,
3054                                           QUICOffset final_offset, QUICFrameId id, QUICFrameGenerator *owner)
3055 {
3056   new (buf) QUICRstStreamFrame(stream_id, error_code, final_offset, id, owner);
3057   return reinterpret_cast<QUICRstStreamFrame *>(buf);
3058 }
3059 
3060 QUICRstStreamFrame *
create_rst_stream_frame(uint8_t * buf,QUICStreamError & error,QUICFrameId id,QUICFrameGenerator * owner)3061 QUICFrameFactory::create_rst_stream_frame(uint8_t *buf, QUICStreamError &error, QUICFrameId id, QUICFrameGenerator *owner)
3062 {
3063   return QUICFrameFactory::create_rst_stream_frame(buf, error.stream->id(), error.code, error.stream->final_offset(), id, owner);
3064 }
3065 
3066 QUICStopSendingFrame *
create_stop_sending_frame(uint8_t * buf,QUICStreamId stream_id,QUICAppErrorCode error_code,QUICFrameId id,QUICFrameGenerator * owner)3067 QUICFrameFactory::create_stop_sending_frame(uint8_t *buf, QUICStreamId stream_id, QUICAppErrorCode error_code, QUICFrameId id,
3068                                             QUICFrameGenerator *owner)
3069 {
3070   new (buf) QUICStopSendingFrame(stream_id, error_code, id, owner);
3071   return reinterpret_cast<QUICStopSendingFrame *>(buf);
3072 }
3073 
3074 QUICNewConnectionIdFrame *
create_new_connection_id_frame(uint8_t * buf,uint64_t sequence,uint64_t retire_prior_to,QUICConnectionId connection_id,QUICStatelessResetToken stateless_reset_token,QUICFrameId id,QUICFrameGenerator * owner)3075 QUICFrameFactory::create_new_connection_id_frame(uint8_t *buf, uint64_t sequence, uint64_t retire_prior_to,
3076                                                  QUICConnectionId connection_id, QUICStatelessResetToken stateless_reset_token,
3077                                                  QUICFrameId id, QUICFrameGenerator *owner)
3078 {
3079   new (buf) QUICNewConnectionIdFrame(sequence, retire_prior_to, connection_id, stateless_reset_token, id, owner);
3080   return reinterpret_cast<QUICNewConnectionIdFrame *>(buf);
3081 }
3082 
3083 QUICNewTokenFrame *
create_new_token_frame(uint8_t * buf,const QUICResumptionToken & token,QUICFrameId id,QUICFrameGenerator * owner)3084 QUICFrameFactory::create_new_token_frame(uint8_t *buf, const QUICResumptionToken &token, QUICFrameId id, QUICFrameGenerator *owner)
3085 {
3086   uint64_t token_len       = token.length();
3087   ats_unique_buf token_buf = ats_unique_malloc(token_len);
3088   memcpy(token_buf.get(), token.buf(), token_len);
3089 
3090   new (buf) QUICNewTokenFrame(std::move(token_buf), token_len, id, owner);
3091   return reinterpret_cast<QUICNewTokenFrame *>(buf);
3092 }
3093 
3094 QUICRetireConnectionIdFrame *
create_retire_connection_id_frame(uint8_t * buf,uint64_t seq_num,QUICFrameId id,QUICFrameGenerator * owner)3095 QUICFrameFactory::create_retire_connection_id_frame(uint8_t *buf, uint64_t seq_num, QUICFrameId id, QUICFrameGenerator *owner)
3096 {
3097   new (buf) QUICRetireConnectionIdFrame(seq_num, id, owner);
3098   return reinterpret_cast<QUICRetireConnectionIdFrame *>(buf);
3099 }
3100 
3101 QUICHandshakeDoneFrame *
create_handshake_done_frame(uint8_t * buf,QUICFrameId id,QUICFrameGenerator * owner)3102 QUICFrameFactory::create_handshake_done_frame(uint8_t *buf, QUICFrameId id, QUICFrameGenerator *owner)
3103 {
3104   new (buf) QUICHandshakeDoneFrame(id, owner);
3105   return reinterpret_cast<QUICHandshakeDoneFrame *>(buf);
3106 }
3107