xref: /trafficserver/iocore/net/quic/QUICFrame.cc (revision 6239297f)
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 vaild
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);
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;
67 }
68 
69 const QUICPacket *
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::UNKNOWN)) {
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 QUICPacket * packet)150 QUICStreamFrame::QUICStreamFrame(const uint8_t *buf, size_t len, const QUICPacket *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 QUICPacket * packet)167 QUICStreamFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *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 QUICPacket * packet)395 QUICCryptoFrame::QUICCryptoFrame(const uint8_t *buf, size_t len, const QUICPacket *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 QUICPacket * packet)406 QUICCryptoFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *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 
QUICAckFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)544 QUICAckFrame::QUICAckFrame(const uint8_t *buf, size_t len, const QUICPacket *packet) : QUICFrame(0, nullptr, packet)
545 {
546   this->parse(buf, len, packet);
547 }
548 
549 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)550 QUICAckFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
551 {
552   ink_assert(len >= 1);
553   this->_reset();
554   this->_packet = packet;
555   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
556   bool has_ecn  = (buf[0] == static_cast<uint8_t>(QUICFrameType::ACK_WITH_ECN));
557 
558   size_t field_len = 0;
559   if (!read_varint(pos, LEFT_SPACE(pos), this->_largest_acknowledged, field_len)) {
560     return;
561   }
562 
563   if (!read_varint(pos, LEFT_SPACE(pos), this->_ack_delay, field_len)) {
564     return;
565   }
566 
567   uint64_t ack_block_count = 0;
568   if (!read_varint(pos, LEFT_SPACE(pos), ack_block_count, field_len)) {
569     return;
570   }
571 
572   uint64_t first_ack_block = 0;
573   if (!read_varint(pos, LEFT_SPACE(pos), first_ack_block, field_len)) {
574     return;
575   }
576 
577   this->_ack_block_section = new AckBlockSection(first_ack_block);
578   for (size_t i = 0; i < ack_block_count; i++) {
579     uint64_t gap           = 0;
580     uint64_t add_ack_block = 0;
581 
582     if (!read_varint(pos, LEFT_SPACE(pos), gap, field_len)) {
583       return;
584     }
585 
586     if (!read_varint(pos, LEFT_SPACE(pos), add_ack_block, field_len)) {
587       return;
588     }
589 
590     this->_ack_block_section->add_ack_block({gap, add_ack_block});
591   }
592 
593   if (has_ecn) {
594     this->_ecn_section = new EcnSection(pos, LEFT_SPACE(pos));
595     if (!this->_ecn_section->valid()) {
596       return;
597     }
598     pos += this->_ecn_section->size();
599   }
600 
601   this->_valid = true;
602   this->_size  = FRAME_SIZE(pos);
603 }
604 
QUICAckFrame(QUICPacketNumber largest_acknowledged,uint64_t ack_delay,uint64_t first_ack_block,QUICFrameId id,QUICFrameGenerator * owner)605 QUICAckFrame::QUICAckFrame(QUICPacketNumber largest_acknowledged, uint64_t ack_delay, uint64_t first_ack_block, QUICFrameId id,
606                            QUICFrameGenerator *owner)
607   : QUICFrame(id, owner)
608 {
609   this->_largest_acknowledged = largest_acknowledged;
610   this->_ack_delay            = ack_delay;
611   this->_ack_block_section    = new AckBlockSection(first_ack_block);
612 }
613 
614 void
_reset()615 QUICAckFrame::_reset()
616 {
617   if (this->_ack_block_section) {
618     delete this->_ack_block_section;
619     this->_ack_block_section = nullptr;
620   }
621   if (this->_ecn_section) {
622     delete this->_ecn_section;
623     this->_ecn_section = nullptr;
624   }
625 
626   this->_largest_acknowledged = 0;
627   this->_ack_delay            = 0;
628   this->_owner                = nullptr;
629   this->_id                   = 0;
630   this->_valid                = false;
631   this->_size                 = 0;
632 }
633 
~QUICAckFrame()634 QUICAckFrame::~QUICAckFrame()
635 {
636   if (this->_ack_block_section) {
637     delete this->_ack_block_section;
638     this->_ack_block_section = nullptr;
639   }
640   if (this->_ecn_section) {
641     delete this->_ecn_section;
642     this->_ecn_section = nullptr;
643   }
644 }
645 
646 QUICFrameType
type() const647 QUICAckFrame::type() const
648 {
649   // TODO ECN
650   return QUICFrameType::ACK;
651 }
652 
653 size_t
size() const654 QUICAckFrame::size() const
655 {
656   if (this->_size) {
657     return this->_size;
658   }
659 
660   size_t pre_len = 1 + QUICVariableInt::size(this->_largest_acknowledged) + QUICVariableInt::size(this->_ack_delay) +
661                    QUICVariableInt::size(this->_ack_block_section->count());
662   if (this->_ack_block_section) {
663     pre_len += this->_ack_block_section->size();
664   }
665 
666   if (this->_ecn_section) {
667     return pre_len + this->_ecn_section->size();
668   }
669 
670   return pre_len;
671 }
672 
673 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const674 QUICAckFrame::to_io_buffer_block(size_t limit) const
675 {
676   Ptr<IOBufferBlock> block;
677   size_t n = 0;
678 
679   if (limit < this->size()) {
680     return block;
681   }
682 
683   size_t written_len = 0;
684   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
685   block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
686   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
687 
688   // Type
689   block_start[0] = static_cast<uint8_t>(QUICFrameType::ACK);
690   n += 1;
691 
692   // Largest Acknowledged (i)
693   QUICIntUtil::write_QUICVariableInt(this->_largest_acknowledged, block_start + n, &written_len);
694   n += written_len;
695 
696   // Ack Delay (i)
697   QUICIntUtil::write_QUICVariableInt(this->_ack_delay, block_start + n, &written_len);
698   n += written_len;
699 
700   // Ack Range Count (i)
701   QUICIntUtil::write_QUICVariableInt(this->ack_block_count(), block_start + n, &written_len);
702   n += written_len;
703 
704   block->fill(n);
705 
706   // First Ack Range (i) + Ack Ranges (*)
707   block->next = this->_ack_block_section->to_io_buffer_block(limit - n);
708 
709   return block;
710 }
711 
712 int
debug_msg(char * msg,size_t msg_len) const713 QUICAckFrame::debug_msg(char *msg, size_t msg_len) const
714 {
715   int len = snprintf(msg, msg_len, "ACK size=%zu largest_acked=%" PRIu64 " delay=%" PRIu64 " block_count=%" PRIu64, this->size(),
716                      this->largest_acknowledged(), this->ack_delay(), this->ack_block_count());
717   msg_len -= len;
718 
719   if (this->ack_block_section()) {
720     len += snprintf(msg + len, msg_len, " first_ack_block=%" PRIu64, this->ack_block_section()->first_ack_block());
721   }
722 
723   return len;
724 }
725 
726 QUICPacketNumber
largest_acknowledged() const727 QUICAckFrame::largest_acknowledged() const
728 {
729   return this->_largest_acknowledged;
730 }
731 
732 uint64_t
ack_delay() const733 QUICAckFrame::ack_delay() const
734 {
735   return this->_ack_delay;
736 }
737 
738 uint64_t
ack_block_count() const739 QUICAckFrame::ack_block_count() const
740 {
741   return this->_ack_block_section->count();
742 }
743 
744 QUICAckFrame::AckBlockSection *
ack_block_section()745 QUICAckFrame::ack_block_section()
746 {
747   return this->_ack_block_section;
748 }
749 
750 const QUICAckFrame::AckBlockSection *
ack_block_section() const751 QUICAckFrame::ack_block_section() const
752 {
753   return this->_ack_block_section;
754 }
755 
756 QUICAckFrame::EcnSection *
ecn_section()757 QUICAckFrame::ecn_section()
758 {
759   return this->_ecn_section;
760 }
761 
762 const QUICAckFrame::EcnSection *
ecn_section() const763 QUICAckFrame::ecn_section() const
764 {
765   return this->_ecn_section;
766 }
767 
768 //
769 // QUICAckFrame::PacketNumberRange
770 //
PacketNumberRange(PacketNumberRange && a)771 QUICAckFrame::PacketNumberRange::PacketNumberRange(PacketNumberRange &&a) noexcept
772 {
773   this->_first = a._first;
774   this->_last  = a._last;
775 }
776 
777 uint64_t
first() const778 QUICAckFrame::PacketNumberRange::first() const
779 {
780   return this->_first;
781 }
782 
783 uint64_t
last() const784 QUICAckFrame::PacketNumberRange::last() const
785 {
786   return this->_last;
787 }
788 
789 uint64_t
size() const790 QUICAckFrame::PacketNumberRange::size() const
791 {
792   return this->_first - this->_last;
793 }
794 
795 bool
contains(QUICPacketNumber x) const796 QUICAckFrame::PacketNumberRange::contains(QUICPacketNumber x) const
797 {
798   return static_cast<uint64_t>(this->_last) <= static_cast<uint64_t>(x) &&
799          static_cast<uint64_t>(x) <= static_cast<uint64_t>(this->_first);
800 }
801 
802 //
803 // QUICAckFrame::AckBlock
804 //
805 uint64_t
gap() const806 QUICAckFrame::AckBlock::gap() const
807 {
808   return this->_gap;
809 }
810 
811 uint64_t
length() const812 QUICAckFrame::AckBlock::length() const
813 {
814   return this->_length;
815 }
816 
817 size_t
size() const818 QUICAckFrame::AckBlock::size() const
819 {
820   return QUICVariableInt::size(this->_gap) + QUICVariableInt::size(this->_length);
821 }
822 
823 //
824 // QUICAckFrame::AckBlockSection
825 //
826 uint8_t
count() const827 QUICAckFrame::AckBlockSection::count() const
828 {
829   return this->_ack_blocks.size();
830 }
831 
832 size_t
size() const833 QUICAckFrame::AckBlockSection::size() const
834 {
835   size_t n = 0;
836 
837   n += QUICVariableInt::size(this->_first_ack_block);
838 
839   for (auto &&block : *this) {
840     n += block.size();
841   }
842 
843   return n;
844 }
845 
846 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const847 QUICAckFrame::AckBlockSection::to_io_buffer_block(size_t limit) const
848 {
849   Ptr<IOBufferBlock> block;
850   size_t n = 0;
851 
852   if (limit < this->size()) {
853     return block;
854   }
855 
856   size_t written_len = 0;
857   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
858   block->alloc(iobuffer_size_to_index(limit, BUFFER_SIZE_INDEX_32K));
859   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
860 
861   QUICIntUtil::write_QUICVariableInt(this->_first_ack_block, block_start + n, &written_len);
862   n += written_len;
863 
864   for (auto &&block : *this) {
865     QUICIntUtil::write_QUICVariableInt(block.gap(), block_start + n, &written_len);
866     n += written_len;
867     QUICIntUtil::write_QUICVariableInt(block.length(), block_start + n, &written_len);
868     n += written_len;
869   }
870 
871   block->fill(n);
872   return block;
873 }
874 
875 uint64_t
first_ack_block() const876 QUICAckFrame::AckBlockSection::first_ack_block() const
877 {
878   return this->_first_ack_block;
879 }
880 
881 void
add_ack_block(AckBlock block)882 QUICAckFrame::AckBlockSection::add_ack_block(AckBlock block)
883 {
884   this->_ack_blocks.push_back(block);
885 }
886 
887 QUICAckFrame::AckBlockSection::const_iterator
begin() const888 QUICAckFrame::AckBlockSection::begin() const
889 {
890   return const_iterator(0, &this->_ack_blocks);
891 }
892 
893 QUICAckFrame::AckBlockSection::const_iterator
end() const894 QUICAckFrame::AckBlockSection::end() const
895 {
896   return const_iterator(this->_ack_blocks.size(), &this->_ack_blocks);
897 }
898 
const_iterator(uint8_t index,const std::vector<QUICAckFrame::AckBlock> * ack_blocks)899 QUICAckFrame::AckBlockSection::const_iterator::const_iterator(uint8_t index, const std::vector<QUICAckFrame::AckBlock> *ack_blocks)
900   : _index(index), _ack_blocks(ack_blocks)
901 {
902   if (this->_ack_blocks->size()) {
903     if (this->_ack_blocks->size() == this->_index) {
904       this->_current_block = {UINT64_C(0), UINT64_C(0)};
905     } else {
906       this->_current_block = this->_ack_blocks->at(this->_index);
907     }
908   }
909 }
910 
911 // FIXME: something wrong with clang-format?
912 const QUICAckFrame::AckBlock &
operator ++()913 QUICAckFrame::AckBlockSection::const_iterator::operator++()
914 {
915   ++(this->_index);
916 
917   if (this->_ack_blocks->size() == this->_index) {
918     this->_current_block = {UINT64_C(0), UINT64_C(0)};
919   } else {
920     this->_current_block = this->_ack_blocks->at(this->_index);
921   }
922 
923   return this->_current_block;
924 }
925 
926 const bool
operator !=(const const_iterator & ite) const927 QUICAckFrame::AckBlockSection::const_iterator::operator!=(const const_iterator &ite) const
928 {
929   return this->_index != ite._index;
930 }
931 
932 const bool
operator ==(const const_iterator & ite) const933 QUICAckFrame::AckBlockSection::const_iterator::operator==(const const_iterator &ite) const
934 {
935   return this->_index == ite._index;
936 }
937 
EcnSection(const uint8_t * buf,size_t len)938 QUICAckFrame::EcnSection::EcnSection(const uint8_t *buf, size_t len)
939 {
940   uint8_t *pos = const_cast<uint8_t *>(buf);
941 
942   size_t field_len = 0;
943   if (!read_varint(pos, LEFT_SPACE(pos), this->_ect0_count, field_len)) {
944     return;
945   }
946 
947   if (!read_varint(pos, LEFT_SPACE(pos), this->_ect1_count, field_len)) {
948     return;
949   }
950 
951   if (!read_varint(pos, LEFT_SPACE(pos), this->_ecn_ce_count, field_len)) {
952     return;
953   }
954 
955   this->_valid = true;
956   this->_size  = FRAME_SIZE(pos);
957 }
958 
959 bool
valid() const960 QUICAckFrame::EcnSection::valid() const
961 {
962   return this->_valid;
963 }
964 
965 size_t
size() const966 QUICAckFrame::EcnSection::size() const
967 {
968   return QUICVariableInt::size(this->_ect0_count) + QUICVariableInt::size(this->_ect1_count) +
969          QUICVariableInt::size(this->_ecn_ce_count);
970 }
971 
972 uint64_t
ect0_count() const973 QUICAckFrame::EcnSection::ect0_count() const
974 {
975   return this->_ect0_count;
976 }
977 
978 uint64_t
ect1_count() const979 QUICAckFrame::EcnSection::ect1_count() const
980 {
981   return this->_ect1_count;
982 }
983 
984 uint64_t
ecn_ce_count() const985 QUICAckFrame::EcnSection::ecn_ce_count() const
986 {
987   return this->_ecn_ce_count;
988 }
989 
990 //
991 // RESET_STREAM frame
992 //
993 
QUICRstStreamFrame(QUICStreamId stream_id,QUICAppErrorCode error_code,QUICOffset final_offset,QUICFrameId id,QUICFrameGenerator * owner)994 QUICRstStreamFrame::QUICRstStreamFrame(QUICStreamId stream_id, QUICAppErrorCode error_code, QUICOffset final_offset, QUICFrameId id,
995                                        QUICFrameGenerator *owner)
996   : QUICFrame(id, owner), _stream_id(stream_id), _error_code(error_code), _final_offset(final_offset)
997 {
998 }
999 
QUICRstStreamFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)1000 QUICRstStreamFrame::QUICRstStreamFrame(const uint8_t *buf, size_t len, const QUICPacket *packet) : QUICFrame(0, nullptr, packet)
1001 {
1002   this->parse(buf, len, packet);
1003 }
1004 
1005 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)1006 QUICRstStreamFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
1007 {
1008   ink_assert(len >= 1);
1009   this->_reset();
1010   this->_packet = packet;
1011   uint8_t *pos  = 1 + const_cast<uint8_t *>(buf);
1012 
1013   size_t field_len = 0;
1014 
1015   // Stream ID (i)
1016   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
1017     return;
1018   }
1019 
1020   // Error Code (i)
1021   if (LEFT_SPACE(pos) < 1) {
1022     return;
1023   }
1024   if (!read_varint(pos, LEFT_SPACE(pos), this->_error_code, field_len)) {
1025     return;
1026   }
1027 
1028   // Final Offset (i)
1029   if (!read_varint(pos, LEFT_SPACE(pos), this->_final_offset, field_len)) {
1030     return;
1031   }
1032 
1033   this->_valid = true;
1034   this->_size  = FRAME_SIZE(pos);
1035 }
1036 
1037 void
_reset()1038 QUICRstStreamFrame::_reset()
1039 {
1040   this->_stream_id    = 0;
1041   this->_error_code   = 0;
1042   this->_final_offset = 0;
1043 
1044   this->_owner = nullptr;
1045   this->_id    = 0;
1046   this->_valid = false;
1047   this->_size  = 0;
1048 }
1049 
1050 QUICFrameType
type() const1051 QUICRstStreamFrame::type() const
1052 {
1053   return QUICFrameType::RESET_STREAM;
1054 }
1055 
1056 size_t
size() const1057 QUICRstStreamFrame::size() const
1058 {
1059   if (this->_size) {
1060     return this->_size;
1061   }
1062 
1063   return 1 + QUICVariableInt::size(this->_stream_id) + QUICVariableInt::size(this->_error_code) +
1064          QUICVariableInt::size(this->_final_offset);
1065 }
1066 
1067 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1068 QUICRstStreamFrame::to_io_buffer_block(size_t limit) const
1069 {
1070   Ptr<IOBufferBlock> block;
1071   size_t n = 0;
1072 
1073   if (limit < this->size()) {
1074     return block;
1075   }
1076 
1077   size_t written_len = 0;
1078   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1079   block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
1080   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1081 
1082   // Type
1083   block_start[0] = static_cast<uint8_t>(QUICFrameType::RESET_STREAM);
1084   n += 1;
1085 
1086   // Stream ID (i)
1087   QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
1088   n += written_len;
1089 
1090   // Application Error Code (i)
1091   QUICTypeUtil::write_QUICAppErrorCode(this->_error_code, block_start + n, &written_len);
1092   n += written_len;
1093 
1094   // Final Size (i)
1095   QUICTypeUtil::write_QUICOffset(this->_final_offset, block_start + n, &written_len);
1096   n += written_len;
1097 
1098   block->fill(n);
1099   return block;
1100 }
1101 
1102 int
debug_msg(char * msg,size_t msg_len) const1103 QUICRstStreamFrame::debug_msg(char *msg, size_t msg_len) const
1104 {
1105   return snprintf(msg, msg_len, "RESET_STREAM size=%zu stream_id=%" PRIu64 " code=0x%" PRIx64, this->size(), this->stream_id(),
1106                   this->error_code());
1107 }
1108 
1109 QUICStreamId
stream_id() const1110 QUICRstStreamFrame::stream_id() const
1111 {
1112   return this->_stream_id;
1113 }
1114 
1115 QUICAppErrorCode
error_code() const1116 QUICRstStreamFrame::error_code() const
1117 {
1118   return this->_error_code;
1119 }
1120 
1121 QUICOffset
final_offset() const1122 QUICRstStreamFrame::final_offset() const
1123 {
1124   return this->_final_offset;
1125 }
1126 
1127 //
1128 // PING frame
1129 //
1130 
QUICPingFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)1131 QUICPingFrame::QUICPingFrame(const uint8_t *buf, size_t len, const QUICPacket *packet) : QUICFrame(0, nullptr, packet)
1132 {
1133   this->parse(buf, len, packet);
1134 }
1135 
1136 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)1137 QUICPingFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
1138 {
1139   this->_reset();
1140   this->_packet = packet;
1141   this->_valid  = true;
1142   this->_size   = 1;
1143 }
1144 
1145 QUICFrameType
type() const1146 QUICPingFrame::type() const
1147 {
1148   return QUICFrameType::PING;
1149 }
1150 
1151 size_t
size() const1152 QUICPingFrame::size() const
1153 {
1154   return 1;
1155 }
1156 
1157 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1158 QUICPingFrame::to_io_buffer_block(size_t limit) const
1159 {
1160   Ptr<IOBufferBlock> block;
1161   size_t n = 0;
1162 
1163   if (limit < this->size()) {
1164     return block;
1165   }
1166 
1167   block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1168   block->alloc(iobuffer_size_to_index(this->size(), BUFFER_SIZE_INDEX_32K));
1169   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1170 
1171   // Type
1172   block_start[0] = static_cast<uint8_t>(QUICFrameType::PING);
1173   n += 1;
1174 
1175   block->fill(n);
1176   return block;
1177 }
1178 
1179 //
1180 // PADDING frame
1181 //
QUICPaddingFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)1182 QUICPaddingFrame::QUICPaddingFrame(const uint8_t *buf, size_t len, const QUICPacket *packet) : QUICFrame(0, nullptr, packet)
1183 {
1184   this->parse(buf, len, packet);
1185 }
1186 
1187 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)1188 QUICPaddingFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
1189 {
1190   ink_assert(len >= 1);
1191   this->_reset();
1192   this->_packet = packet;
1193   this->_size   = 0;
1194   this->_valid  = true;
1195   // find out how many padding frames in this buf
1196   for (size_t i = 0; i < len; i++) {
1197     if (*(buf + i) == static_cast<uint8_t>(QUICFrameType::PADDING)) {
1198       ++this->_size;
1199     } else {
1200       break;
1201     }
1202   }
1203 }
1204 
1205 QUICFrameType
type() const1206 QUICPaddingFrame::type() const
1207 {
1208   return QUICFrameType::PADDING;
1209 }
1210 
1211 size_t
size() const1212 QUICPaddingFrame::size() const
1213 {
1214   return this->_size;
1215 }
1216 
1217 bool
is_probing_frame() const1218 QUICPaddingFrame::is_probing_frame() const
1219 {
1220   return true;
1221 }
1222 
1223 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1224 QUICPaddingFrame::to_io_buffer_block(size_t limit) const
1225 {
1226   Ptr<IOBufferBlock> block;
1227   size_t n = 0;
1228 
1229   if (limit < this->size()) {
1230     return block;
1231   }
1232 
1233   block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1234   block->alloc(iobuffer_size_to_index(this->_size, BUFFER_SIZE_INDEX_32K));
1235   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1236 
1237   memset(block_start, 0, this->_size);
1238   n = this->_size;
1239 
1240   block->fill(n);
1241   return block;
1242 }
1243 
1244 //
1245 // CONNECTION_CLOSE frame
1246 //
QUICConnectionCloseFrame(uint64_t error_code,QUICFrameType frame_type,uint64_t reason_phrase_length,const char * reason_phrase,QUICFrameId id,QUICFrameGenerator * owner)1247 QUICConnectionCloseFrame::QUICConnectionCloseFrame(uint64_t error_code, QUICFrameType frame_type, uint64_t reason_phrase_length,
1248                                                    const char *reason_phrase, QUICFrameId id, QUICFrameGenerator *owner)
1249   : QUICFrame(id, owner),
1250     _type(0x1c),
1251     _error_code(error_code),
1252     _frame_type(frame_type),
1253     _reason_phrase_length(reason_phrase_length),
1254     _reason_phrase(reason_phrase)
1255 {
1256 }
1257 
QUICConnectionCloseFrame(uint64_t error_code,uint64_t reason_phrase_length,const char * reason_phrase,QUICFrameId id,QUICFrameGenerator * owner)1258 QUICConnectionCloseFrame::QUICConnectionCloseFrame(uint64_t error_code, uint64_t reason_phrase_length, const char *reason_phrase,
1259                                                    QUICFrameId id, QUICFrameGenerator *owner)
1260   : QUICFrame(id, owner),
1261     _type(0x1d),
1262     _error_code(error_code),
1263     _reason_phrase_length(reason_phrase_length),
1264     _reason_phrase(reason_phrase)
1265 {
1266 }
1267 
QUICConnectionCloseFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)1268 QUICConnectionCloseFrame::QUICConnectionCloseFrame(const uint8_t *buf, size_t len, const QUICPacket *packet)
1269   : QUICFrame(0, nullptr, packet)
1270 {
1271   this->parse(buf, len, packet);
1272 }
1273 
1274 void
_reset()1275 QUICConnectionCloseFrame::_reset()
1276 {
1277   this->_error_code           = 0;
1278   this->_reason_phrase_length = 0;
1279   this->_reason_phrase        = nullptr;
1280   this->_frame_type           = QUICFrameType::UNKNOWN;
1281 
1282   this->_owner = nullptr;
1283   this->_id    = 0;
1284   this->_size  = 0;
1285   this->_valid = false;
1286 }
1287 
1288 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)1289 QUICConnectionCloseFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
1290 {
1291   ink_assert(len >= 1);
1292   this->_reset();
1293   this->_packet = packet;
1294   this->_type   = buf[0];
1295   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
1296 
1297   size_t field_len = 0;
1298   uint64_t field   = 0;
1299 
1300   // Error Code (i)
1301   if (LEFT_SPACE(pos) < 1) {
1302     return;
1303   }
1304   read_varint(pos, LEFT_SPACE(pos), field, field_len);
1305   this->_error_code = field;
1306 
1307   if (this->_type == 0x1c) {
1308     // Frame Type (i)
1309     if (!read_varint(pos, LEFT_SPACE(pos), field, field_len)) {
1310       return;
1311     }
1312     this->_frame_type = static_cast<QUICFrameType>(field);
1313 
1314     /**
1315        Frame Type Field Accessor
1316 
1317        PADDING frame in Frame Type field means frame type that triggered the error is unknown.
1318        Return QUICFrameType::UNKNOWN when Frame Type field is PADDING (0x0).
1319      */
1320     if (this->_frame_type == QUICFrameType::PADDING) {
1321       this->_frame_type = QUICFrameType::UNKNOWN;
1322     }
1323   }
1324 
1325   // Reason Phrase Length (i)
1326   if (LEFT_SPACE(pos) < 1) {
1327     return;
1328   }
1329   if (!read_varint(pos, LEFT_SPACE(pos), this->_reason_phrase_length, field_len)) {
1330     return;
1331   }
1332 
1333   // Reason Phrase
1334   if (LEFT_SPACE(pos) < this->_reason_phrase_length) {
1335     return;
1336   }
1337   this->_reason_phrase = reinterpret_cast<const char *>(pos);
1338 
1339   this->_valid = true;
1340   pos += this->_reason_phrase_length;
1341   this->_size = FRAME_SIZE(pos);
1342 }
1343 
1344 QUICFrameType
type() const1345 QUICConnectionCloseFrame::type() const
1346 {
1347   return QUICFrameType::CONNECTION_CLOSE;
1348 }
1349 
1350 size_t
size() const1351 QUICConnectionCloseFrame::size() const
1352 {
1353   if (this->_size) {
1354     return this->_size;
1355   }
1356 
1357   return 1 + QUICVariableInt::size(sizeof(QUICTransErrorCode)) + QUICVariableInt::size(sizeof(QUICFrameType)) +
1358          QUICVariableInt::size(this->_reason_phrase_length) + this->_reason_phrase_length;
1359 }
1360 
1361 /**
1362    Store CONNECTION_CLOSE frame in buffer.
1363 
1364    PADDING frame in Frame Type field means frame type that triggered the error is unknown.
1365    When `_frame_type` is QUICFrameType::UNKNOWN, it's converted to QUICFrameType::PADDING (0x0).
1366  */
1367 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1368 QUICConnectionCloseFrame::to_io_buffer_block(size_t limit) const
1369 {
1370   Ptr<IOBufferBlock> first_block;
1371   size_t n = 0;
1372 
1373   if (limit < this->size()) {
1374     return first_block;
1375   }
1376 
1377   // Create a block for Error Code(i) and Frame Type(i)
1378   size_t written_len = 0;
1379   first_block        = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1380   first_block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
1381   uint8_t *block_start = reinterpret_cast<uint8_t *>(first_block->start());
1382 
1383   // Type
1384   block_start[0] = this->_type;
1385   n += 1;
1386 
1387   // Error Code (i)
1388   QUICIntUtil::write_QUICVariableInt(this->_error_code, block_start + n, &written_len);
1389   n += written_len;
1390 
1391   // Frame Type (i)
1392   QUICFrameType frame_type = this->_frame_type;
1393   if (frame_type == QUICFrameType::UNKNOWN) {
1394     frame_type = QUICFrameType::PADDING;
1395   }
1396   QUICIntUtil::write_QUICVariableInt(static_cast<uint64_t>(frame_type), block_start + n, &written_len);
1397   n += written_len;
1398 
1399   // Reason Phrase Length (i)
1400   QUICIntUtil::write_QUICVariableInt(this->_reason_phrase_length, block_start + n, &written_len);
1401   n += written_len;
1402 
1403   first_block->fill(n);
1404 
1405   // Create a block for reason if necessary
1406   if (this->_reason_phrase_length != 0) {
1407     // Reason Phrase (*)
1408     Ptr<IOBufferBlock> reason_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1409     reason_block->alloc(iobuffer_size_to_index(this->_reason_phrase_length, BUFFER_SIZE_INDEX_32K));
1410     memcpy(reinterpret_cast<uint8_t *>(reason_block->start()), this->_reason_phrase, this->_reason_phrase_length);
1411     reason_block->fill(this->_reason_phrase_length);
1412 
1413     // Append reason block to the first block
1414     first_block->next = reason_block;
1415   }
1416 
1417   // Return the chain
1418   return first_block;
1419 }
1420 
1421 int
debug_msg(char * msg,size_t msg_len) const1422 QUICConnectionCloseFrame::debug_msg(char *msg, size_t msg_len) const
1423 {
1424   int len;
1425   if (this->_type == 0x1c) {
1426     len =
1427       snprintf(msg, msg_len, "CONNECTION_CLOSE size=%zu code=%s (0x%" PRIx16 ") frame=%s", this->size(),
1428                QUICDebugNames::error_code(this->error_code()), this->error_code(), QUICDebugNames::frame_type(this->frame_type()));
1429   } else {
1430     // Application-specific error. It doesn't have a frame type and we don't know string representations of error codes.
1431     len = snprintf(msg, msg_len, "CONNECTION_CLOSE size=%zu code=0x%" PRIx16 " ", this->size(), this->error_code());
1432   }
1433 
1434   if (this->reason_phrase_length() != 0 && this->reason_phrase() != nullptr) {
1435     memcpy(msg + len, " reason=", 8);
1436     len += 8;
1437 
1438     int phrase_len = std::min(msg_len - len, static_cast<size_t>(this->reason_phrase_length()));
1439     memcpy(msg + len, this->reason_phrase(), phrase_len);
1440     len += phrase_len;
1441     msg[len] = '\0';
1442     ++len;
1443   }
1444 
1445   return len;
1446 }
1447 
1448 uint16_t
error_code() const1449 QUICConnectionCloseFrame::error_code() const
1450 {
1451   return this->_error_code;
1452 }
1453 
1454 QUICFrameType
frame_type() const1455 QUICConnectionCloseFrame::frame_type() const
1456 {
1457   return this->_frame_type;
1458 }
1459 
1460 uint64_t
reason_phrase_length() const1461 QUICConnectionCloseFrame::reason_phrase_length() const
1462 {
1463   return this->_reason_phrase_length;
1464 }
1465 
1466 const char *
reason_phrase() const1467 QUICConnectionCloseFrame::reason_phrase() const
1468 {
1469   return this->_reason_phrase;
1470 }
1471 
1472 //
1473 // MAX_DATA frame
1474 //
QUICMaxDataFrame(uint64_t maximum_data,QUICFrameId id,QUICFrameGenerator * owner)1475 QUICMaxDataFrame::QUICMaxDataFrame(uint64_t maximum_data, QUICFrameId id, QUICFrameGenerator *owner) : QUICFrame(id, owner)
1476 {
1477   this->_maximum_data = maximum_data;
1478 }
1479 
1480 void
_reset()1481 QUICMaxDataFrame::_reset()
1482 {
1483   this->_maximum_data = 0;
1484 
1485   this->_owner = nullptr;
1486   this->_id    = 0;
1487   this->_valid = false;
1488   this->_size  = 0;
1489 }
1490 
QUICMaxDataFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)1491 QUICMaxDataFrame::QUICMaxDataFrame(const uint8_t *buf, size_t len, const QUICPacket *packet) : QUICFrame(0, nullptr, packet)
1492 {
1493   this->parse(buf, len, packet);
1494 }
1495 
1496 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)1497 QUICMaxDataFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
1498 {
1499   ink_assert(len >= 1);
1500   this->_reset();
1501   this->_packet = packet;
1502   uint8_t *pos  = 1 + const_cast<uint8_t *>(buf);
1503 
1504   size_t field_len = 0;
1505   if (!read_varint(pos, LEFT_SPACE(pos), this->_maximum_data, field_len)) {
1506     return;
1507   }
1508 
1509   this->_valid = true;
1510   this->_size  = FRAME_SIZE(pos);
1511 }
1512 
1513 QUICFrameType
type() const1514 QUICMaxDataFrame::type() const
1515 {
1516   return QUICFrameType::MAX_DATA;
1517 }
1518 
1519 size_t
size() const1520 QUICMaxDataFrame::size() const
1521 {
1522   if (this->_size) {
1523     return this->_size;
1524   }
1525 
1526   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_maximum_data);
1527 }
1528 
1529 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1530 QUICMaxDataFrame::to_io_buffer_block(size_t limit) const
1531 {
1532   Ptr<IOBufferBlock> block;
1533   size_t n = 0;
1534 
1535   if (limit < this->size()) {
1536     return block;
1537   }
1538 
1539   size_t written_len = 0;
1540   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1541   block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
1542   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1543 
1544   // Type
1545   block_start[0] = static_cast<uint8_t>(QUICFrameType::MAX_DATA);
1546   n += 1;
1547 
1548   // Maximum Data (i)
1549   QUICTypeUtil::write_QUICMaxData(this->_maximum_data, block_start + n, &written_len);
1550   n += written_len;
1551 
1552   block->fill(n);
1553   return block;
1554 }
1555 
1556 int
debug_msg(char * msg,size_t msg_len) const1557 QUICMaxDataFrame::debug_msg(char *msg, size_t msg_len) const
1558 {
1559   return snprintf(msg, msg_len, "MAX_DATA size=%zu maximum=%" PRIu64, this->size(), this->maximum_data());
1560 }
1561 
1562 uint64_t
maximum_data() const1563 QUICMaxDataFrame::maximum_data() const
1564 {
1565   return this->_maximum_data;
1566 }
1567 
1568 //
1569 // MAX_STREAM_DATA
1570 //
QUICMaxStreamDataFrame(QUICStreamId stream_id,uint64_t maximum_stream_data,QUICFrameId id,QUICFrameGenerator * owner)1571 QUICMaxStreamDataFrame::QUICMaxStreamDataFrame(QUICStreamId stream_id, uint64_t maximum_stream_data, QUICFrameId id,
1572                                                QUICFrameGenerator *owner)
1573   : QUICFrame(id, owner)
1574 {
1575   this->_stream_id           = stream_id;
1576   this->_maximum_stream_data = maximum_stream_data;
1577 }
1578 
1579 void
_reset()1580 QUICMaxStreamDataFrame::_reset()
1581 {
1582   this->_stream_id           = 0;
1583   this->_maximum_stream_data = 0;
1584 
1585   this->_owner = nullptr;
1586   this->_id    = 0;
1587   this->_valid = false;
1588   this->_size  = 0;
1589 }
1590 
QUICMaxStreamDataFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)1591 QUICMaxStreamDataFrame::QUICMaxStreamDataFrame(const uint8_t *buf, size_t len, const QUICPacket *packet)
1592   : QUICFrame(0, nullptr, packet)
1593 {
1594   this->parse(buf, len, packet);
1595 }
1596 
1597 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)1598 QUICMaxStreamDataFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
1599 {
1600   ink_assert(len >= 1);
1601   this->_reset();
1602   this->_packet = packet;
1603   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
1604 
1605   size_t field_len = 0;
1606   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
1607     return;
1608   }
1609 
1610   if (!read_varint(pos, LEFT_SPACE(pos), this->_maximum_stream_data, field_len)) {
1611     return;
1612   }
1613 
1614   this->_valid = true;
1615   this->_size  = FRAME_SIZE(pos);
1616 }
1617 
1618 QUICFrameType
type() const1619 QUICMaxStreamDataFrame::type() const
1620 {
1621   return QUICFrameType::MAX_STREAM_DATA;
1622 }
1623 
1624 size_t
size() const1625 QUICMaxStreamDataFrame::size() const
1626 {
1627   if (this->_size) {
1628     return this->_size;
1629   }
1630 
1631   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_maximum_stream_data) + QUICVariableInt::size(this->_stream_id);
1632 }
1633 
1634 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1635 QUICMaxStreamDataFrame::to_io_buffer_block(size_t limit) const
1636 {
1637   Ptr<IOBufferBlock> block;
1638   size_t n = 0;
1639 
1640   if (limit < this->size()) {
1641     return block;
1642   }
1643 
1644   size_t written_len = 0;
1645   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1646   block->alloc(iobuffer_size_to_index(1 + sizeof(uint64_t) + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
1647   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1648 
1649   // Type
1650   block_start[0] = static_cast<uint8_t>(QUICFrameType::MAX_STREAM_DATA);
1651   n += 1;
1652 
1653   // Stream ID (i)
1654   QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
1655   n += written_len;
1656 
1657   // Maximum Stream Data (i)
1658   QUICTypeUtil::write_QUICMaxData(this->_maximum_stream_data, block_start + n, &written_len);
1659   n += written_len;
1660 
1661   block->fill(n);
1662   return block;
1663 }
1664 
1665 int
debug_msg(char * msg,size_t msg_len) const1666 QUICMaxStreamDataFrame::debug_msg(char *msg, size_t msg_len) const
1667 {
1668   return snprintf(msg, msg_len, "MAX_STREAM_DATA size=%zu id=%" PRIu64 " maximum=%" PRIu64, this->size(), this->stream_id(),
1669                   this->maximum_stream_data());
1670 }
1671 
1672 QUICStreamId
stream_id() const1673 QUICMaxStreamDataFrame::stream_id() const
1674 {
1675   return this->_stream_id;
1676 }
1677 
1678 uint64_t
maximum_stream_data() const1679 QUICMaxStreamDataFrame::maximum_stream_data() const
1680 {
1681   return this->_maximum_stream_data;
1682 }
1683 
1684 //
1685 // MAX_STREAMS
1686 //
QUICMaxStreamsFrame(QUICStreamId maximum_streams,QUICFrameId id,QUICFrameGenerator * owner)1687 QUICMaxStreamsFrame::QUICMaxStreamsFrame(QUICStreamId maximum_streams, QUICFrameId id, QUICFrameGenerator *owner)
1688   : QUICFrame(id, owner)
1689 {
1690   this->_maximum_streams = maximum_streams;
1691 }
1692 
1693 void
_reset()1694 QUICMaxStreamsFrame::_reset()
1695 {
1696   this->_maximum_streams = 0;
1697 
1698   this->_owner = nullptr;
1699   this->_id    = 0;
1700   this->_valid = false;
1701   this->_size  = 0;
1702 }
1703 
QUICMaxStreamsFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)1704 QUICMaxStreamsFrame::QUICMaxStreamsFrame(const uint8_t *buf, size_t len, const QUICPacket *packet) : QUICFrame(0, nullptr, packet)
1705 {
1706   this->parse(buf, len, packet);
1707 }
1708 
1709 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)1710 QUICMaxStreamsFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
1711 {
1712   ink_assert(len >= 1);
1713   this->_reset();
1714   this->_packet = packet;
1715   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
1716 
1717   size_t field_len = 0;
1718   if (!read_varint(pos, LEFT_SPACE(pos), this->_maximum_streams, field_len)) {
1719     return;
1720   }
1721 
1722   this->_valid = true;
1723   this->_size  = FRAME_SIZE(pos);
1724 }
1725 
1726 QUICFrameType
type() const1727 QUICMaxStreamsFrame::type() const
1728 {
1729   return QUICFrameType::MAX_STREAMS;
1730 }
1731 
1732 size_t
size() const1733 QUICMaxStreamsFrame::size() const
1734 {
1735   if (this->_size) {
1736     return this->_size;
1737   }
1738 
1739   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_maximum_streams);
1740 }
1741 
1742 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1743 QUICMaxStreamsFrame::to_io_buffer_block(size_t limit) const
1744 {
1745   Ptr<IOBufferBlock> block;
1746   size_t n = 0;
1747 
1748   if (limit < this->size()) {
1749     return block;
1750   }
1751 
1752   size_t written_len = 0;
1753   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1754   block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
1755   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1756 
1757   // Type
1758   block_start[0] = static_cast<uint8_t>(QUICFrameType::MAX_STREAMS);
1759   n += 1;
1760 
1761   // Maximum Streams (i)
1762   QUICTypeUtil::write_QUICStreamId(this->_maximum_streams, block_start + n, &written_len);
1763   n += written_len;
1764 
1765   block->fill(n);
1766   return block;
1767 }
1768 
1769 uint64_t
maximum_streams() const1770 QUICMaxStreamsFrame::maximum_streams() const
1771 {
1772   return this->_maximum_streams;
1773 }
1774 
1775 //
1776 // DATA_BLOCKED frame
1777 //
QUICDataBlockedFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)1778 QUICDataBlockedFrame::QUICDataBlockedFrame(const uint8_t *buf, size_t len, const QUICPacket *packet) : QUICFrame(0, nullptr, packet)
1779 {
1780   this->parse(buf, len, packet);
1781 }
1782 
1783 void
_reset()1784 QUICDataBlockedFrame::_reset()
1785 {
1786   this->_offset = 0;
1787 
1788   this->_owner = nullptr;
1789   this->_id    = 0;
1790   this->_valid = false;
1791   this->_size  = 0;
1792 }
1793 
1794 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)1795 QUICDataBlockedFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
1796 {
1797   ink_assert(len >= 1);
1798   this->_reset();
1799   this->_packet = packet;
1800   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
1801 
1802   size_t field_len = 0;
1803   if (!read_varint(pos, LEFT_SPACE(pos), this->_offset, field_len)) {
1804     return;
1805   }
1806 
1807   this->_valid = true;
1808   this->_size  = FRAME_SIZE(pos);
1809 }
1810 
1811 int
debug_msg(char * msg,size_t msg_len) const1812 QUICDataBlockedFrame::debug_msg(char *msg, size_t msg_len) const
1813 {
1814   return snprintf(msg, msg_len, "DATA_BLOCKED size=%zu offset=%" PRIu64, this->size(), this->offset());
1815 }
1816 
1817 QUICFrameType
type() const1818 QUICDataBlockedFrame::type() const
1819 {
1820   return QUICFrameType::DATA_BLOCKED;
1821 }
1822 
1823 size_t
size() const1824 QUICDataBlockedFrame::size() const
1825 {
1826   if (this->_size) {
1827     return this->_size;
1828   }
1829 
1830   return sizeof(QUICFrameType) + QUICVariableInt::size(this->offset());
1831 }
1832 
1833 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1834 QUICDataBlockedFrame::to_io_buffer_block(size_t limit) const
1835 {
1836   Ptr<IOBufferBlock> block;
1837   size_t n = 0;
1838 
1839   if (limit < this->size()) {
1840     return block;
1841   }
1842 
1843   size_t written_len = 0;
1844   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1845   block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
1846   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1847 
1848   // Type
1849   block_start[0] = static_cast<uint8_t>(QUICFrameType::DATA_BLOCKED);
1850   n += 1;
1851 
1852   // Data Limit (i)
1853   QUICTypeUtil::write_QUICOffset(this->_offset, block_start + n, &written_len);
1854   n += written_len;
1855 
1856   block->fill(n);
1857   return block;
1858 }
1859 
1860 QUICOffset
offset() const1861 QUICDataBlockedFrame::offset() const
1862 {
1863   return this->_offset;
1864 }
1865 
1866 //
1867 // STREAM_DATA_BLOCKED frame
1868 //
QUICStreamDataBlockedFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)1869 QUICStreamDataBlockedFrame::QUICStreamDataBlockedFrame(const uint8_t *buf, size_t len, const QUICPacket *packet)
1870   : QUICFrame(0, nullptr, packet)
1871 {
1872   this->parse(buf, len, packet);
1873 }
1874 
1875 void
_reset()1876 QUICStreamDataBlockedFrame::_reset()
1877 {
1878   this->_stream_id = 0;
1879   this->_offset    = 0;
1880 
1881   this->_owner = nullptr;
1882   this->_id    = 0;
1883   this->_valid = false;
1884   this->_size  = 0;
1885 }
1886 
1887 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)1888 QUICStreamDataBlockedFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
1889 {
1890   ink_assert(len >= 1);
1891   this->_reset();
1892   this->_packet = packet;
1893   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
1894 
1895   size_t field_len = 0;
1896   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
1897     return;
1898   }
1899 
1900   if (!read_varint(pos, LEFT_SPACE(pos), this->_offset, field_len)) {
1901     return;
1902   }
1903 
1904   this->_valid = true;
1905   this->_size  = FRAME_SIZE(pos);
1906 }
1907 
1908 int
debug_msg(char * msg,size_t msg_len) const1909 QUICStreamDataBlockedFrame::debug_msg(char *msg, size_t msg_len) const
1910 {
1911   return snprintf(msg, msg_len, "STREAM_DATA_BLOCKED size=%zu id=%" PRIu64 " offset=%" PRIu64, this->size(), this->stream_id(),
1912                   this->offset());
1913 }
1914 
1915 QUICFrameType
type() const1916 QUICStreamDataBlockedFrame::type() const
1917 {
1918   return QUICFrameType::STREAM_DATA_BLOCKED;
1919 }
1920 
1921 size_t
size() const1922 QUICStreamDataBlockedFrame::size() const
1923 {
1924   if (this->_size) {
1925     return this->_size;
1926   }
1927 
1928   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_offset) + QUICVariableInt::size(this->_stream_id);
1929 }
1930 
1931 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const1932 QUICStreamDataBlockedFrame::to_io_buffer_block(size_t limit) const
1933 {
1934   Ptr<IOBufferBlock> block;
1935   size_t n = 0;
1936 
1937   if (limit < this->size()) {
1938     return block;
1939   }
1940 
1941   size_t written_len = 0;
1942   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1943   block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
1944   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
1945 
1946   // Type
1947   block_start[0] = static_cast<uint8_t>(QUICFrameType::STREAM_DATA_BLOCKED);
1948   n += 1;
1949 
1950   // Stream ID (i)
1951   QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
1952   n += written_len;
1953 
1954   // Data Limit (i)
1955   QUICTypeUtil::write_QUICOffset(this->_offset, block_start + n, &written_len);
1956   n += written_len;
1957 
1958   block->fill(n);
1959   return block;
1960 }
1961 
1962 QUICStreamId
stream_id() const1963 QUICStreamDataBlockedFrame::stream_id() const
1964 {
1965   return this->_stream_id;
1966 }
1967 
1968 QUICOffset
offset() const1969 QUICStreamDataBlockedFrame::offset() const
1970 {
1971   return this->_offset;
1972 }
1973 
1974 //
1975 // STREAMS_BLOCKED frame
1976 //
QUICStreamIdBlockedFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)1977 QUICStreamIdBlockedFrame::QUICStreamIdBlockedFrame(const uint8_t *buf, size_t len, const QUICPacket *packet)
1978   : QUICFrame(0, nullptr, packet)
1979 {
1980   this->parse(buf, len, packet);
1981 }
1982 
1983 void
_reset()1984 QUICStreamIdBlockedFrame::_reset()
1985 {
1986   this->_stream_id = 0;
1987 
1988   this->_owner = nullptr;
1989   this->_id    = 0;
1990   this->_size  = 0;
1991   this->_valid = false;
1992 }
1993 
1994 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)1995 QUICStreamIdBlockedFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
1996 {
1997   ink_assert(len >= 1);
1998   this->_reset();
1999   this->_packet = packet;
2000   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2001 
2002   size_t field_len = 0;
2003   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
2004     return;
2005   }
2006 
2007   this->_valid = true;
2008   this->_size  = FRAME_SIZE(pos);
2009 }
2010 
2011 QUICFrameType
type() const2012 QUICStreamIdBlockedFrame::type() const
2013 {
2014   return QUICFrameType::STREAMS_BLOCKED;
2015 }
2016 
2017 size_t
size() const2018 QUICStreamIdBlockedFrame::size() const
2019 {
2020   if (this->_size) {
2021     return this->_size;
2022   }
2023 
2024   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_stream_id);
2025 }
2026 
2027 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2028 QUICStreamIdBlockedFrame::to_io_buffer_block(size_t limit) const
2029 {
2030   Ptr<IOBufferBlock> block;
2031   size_t n = 0;
2032 
2033   if (limit < this->size()) {
2034     return block;
2035   }
2036 
2037   size_t written_len = 0;
2038   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2039   block->alloc(iobuffer_size_to_index(1 + sizeof(size_t), BUFFER_SIZE_INDEX_32K));
2040   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2041 
2042   // Type
2043   block_start[0] = static_cast<uint8_t>(QUICFrameType::STREAMS_BLOCKED);
2044   n += 1;
2045 
2046   // Stream Limit (i)
2047   QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
2048   n += written_len;
2049 
2050   block->fill(n);
2051   return block;
2052 }
2053 
2054 QUICStreamId
stream_id() const2055 QUICStreamIdBlockedFrame::stream_id() const
2056 {
2057   return this->_stream_id;
2058 }
2059 
2060 //
2061 // NEW_CONNECTION_ID frame
2062 //
QUICNewConnectionIdFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)2063 QUICNewConnectionIdFrame::QUICNewConnectionIdFrame(const uint8_t *buf, size_t len, const QUICPacket *packet)
2064   : QUICFrame(0, nullptr, packet)
2065 {
2066   this->parse(buf, len, packet);
2067 }
2068 
2069 void
_reset()2070 QUICNewConnectionIdFrame::_reset()
2071 {
2072   this->_sequence        = 0;
2073   this->_retire_prior_to = 0;
2074   this->_connection_id   = QUICConnectionId::ZERO();
2075 
2076   this->_owner = nullptr;
2077   this->_id    = 0;
2078   this->_valid = false;
2079   this->_size  = 0;
2080 }
2081 
2082 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2083 QUICNewConnectionIdFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2084 {
2085   ink_assert(len >= 1);
2086   this->_reset();
2087   this->_packet = packet;
2088   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2089 
2090   // Sequence Number (i)
2091   size_t field_len = 0;
2092   if (!read_varint(pos, LEFT_SPACE(pos), this->_sequence, field_len)) {
2093     return;
2094   }
2095 
2096   // Retire Prior To (i)
2097   if (LEFT_SPACE(pos) < 1) {
2098     return;
2099   }
2100   if (!read_varint(pos, LEFT_SPACE(pos), this->_retire_prior_to, field_len)) {
2101     return;
2102   }
2103 
2104   // Length (8)
2105   if (LEFT_SPACE(pos) < 1) {
2106     return;
2107   }
2108   size_t cid_len = *pos;
2109   pos += 1;
2110 
2111   // Connection ID (8..160)
2112   if (LEFT_SPACE(pos) < cid_len) {
2113     return;
2114   }
2115   this->_connection_id = QUICTypeUtil::read_QUICConnectionId(pos, cid_len);
2116   pos += cid_len;
2117 
2118   // Stateless Reset Token (128)
2119   if (LEFT_SPACE(pos) < QUICStatelessResetToken::LEN) {
2120     return;
2121   }
2122 
2123   this->_stateless_reset_token = QUICStatelessResetToken(pos);
2124   this->_valid                 = true;
2125   this->_size                  = FRAME_SIZE(pos) + QUICStatelessResetToken::LEN;
2126 }
2127 
2128 QUICFrameType
type() const2129 QUICNewConnectionIdFrame::type() const
2130 {
2131   return QUICFrameType::NEW_CONNECTION_ID;
2132 }
2133 
2134 size_t
size() const2135 QUICNewConnectionIdFrame::size() const
2136 {
2137   if (this->_size) {
2138     return this->_size;
2139   }
2140 
2141   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_sequence) + QUICVariableInt::size(this->_retire_prior_to) + 1 +
2142          this->_connection_id.length() + QUICStatelessResetToken::LEN;
2143 }
2144 
2145 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2146 QUICNewConnectionIdFrame::to_io_buffer_block(size_t limit) const
2147 {
2148   Ptr<IOBufferBlock> block;
2149   size_t n = 0;
2150 
2151   if (limit < this->size()) {
2152     return block;
2153   }
2154 
2155   size_t written_len = 0;
2156   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2157   block->alloc(iobuffer_size_to_index(1 + sizeof(uint64_t) + sizeof(uint64_t) + 1 + QUICConnectionId::MAX_LENGTH +
2158                                         QUICStatelessResetToken::LEN,
2159                                       BUFFER_SIZE_INDEX_32K));
2160   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2161 
2162   // Type
2163   block_start[0] = static_cast<uint8_t>(QUICFrameType::NEW_CONNECTION_ID);
2164   n += 1;
2165 
2166   // Sequence Number (i)
2167   QUICIntUtil::write_QUICVariableInt(this->_sequence, block_start + n, &written_len);
2168   n += written_len;
2169 
2170   // Retire Prior To (i)
2171   QUICIntUtil::write_QUICVariableInt(this->_retire_prior_to, block_start + n, &written_len);
2172   n += written_len;
2173 
2174   // Length (8)
2175   *(block_start + n) = this->_connection_id.length();
2176   n += 1;
2177 
2178   // Connection ID (8..160)
2179   QUICTypeUtil::write_QUICConnectionId(this->_connection_id, block_start + n, &written_len);
2180   n += written_len;
2181 
2182   // Stateless Reset Token (128)
2183   memcpy(block_start + n, this->_stateless_reset_token.buf(), QUICStatelessResetToken::LEN);
2184   n += QUICStatelessResetToken::LEN;
2185 
2186   block->fill(n);
2187   return block;
2188 }
2189 
2190 int
debug_msg(char * msg,size_t msg_len) const2191 QUICNewConnectionIdFrame::debug_msg(char *msg, size_t msg_len) const
2192 {
2193   char cid_str[QUICConnectionId::MAX_HEX_STR_LENGTH];
2194   this->connection_id().hex(cid_str, QUICConnectionId::MAX_HEX_STR_LENGTH);
2195 
2196   return snprintf(msg, msg_len, "NEW_CONNECTION_ID size=%zu seq=%" PRIu64 " rpt=%" PRIu64 " cid=0x%s", this->size(),
2197                   this->sequence(), this->retire_prior_to(), cid_str);
2198 }
2199 
2200 uint64_t
sequence() const2201 QUICNewConnectionIdFrame::sequence() const
2202 {
2203   return this->_sequence;
2204 }
2205 
2206 uint64_t
retire_prior_to() const2207 QUICNewConnectionIdFrame::retire_prior_to() const
2208 {
2209   return this->_retire_prior_to;
2210 }
2211 
2212 QUICConnectionId
connection_id() const2213 QUICNewConnectionIdFrame::connection_id() const
2214 {
2215   return this->_connection_id;
2216 }
2217 
2218 QUICStatelessResetToken
stateless_reset_token() const2219 QUICNewConnectionIdFrame::stateless_reset_token() const
2220 {
2221   return this->_stateless_reset_token;
2222 }
2223 
2224 //
2225 // STOP_SENDING frame
2226 //
2227 
QUICStopSendingFrame(QUICStreamId stream_id,QUICAppErrorCode error_code,QUICFrameId id,QUICFrameGenerator * owner)2228 QUICStopSendingFrame::QUICStopSendingFrame(QUICStreamId stream_id, QUICAppErrorCode error_code, QUICFrameId id,
2229                                            QUICFrameGenerator *owner)
2230   : QUICFrame(id, owner), _stream_id(stream_id), _error_code(error_code)
2231 {
2232 }
2233 
2234 void
_reset()2235 QUICStopSendingFrame::_reset()
2236 {
2237   this->_stream_id  = 0;
2238   this->_error_code = 0;
2239 
2240   this->_owner = nullptr;
2241   this->_id    = 0;
2242   this->_valid = false;
2243   this->_size  = 0;
2244 }
2245 
QUICStopSendingFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)2246 QUICStopSendingFrame::QUICStopSendingFrame(const uint8_t *buf, size_t len, const QUICPacket *packet) : QUICFrame(0, nullptr, packet)
2247 {
2248   this->parse(buf, len, packet);
2249 }
2250 
2251 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2252 QUICStopSendingFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2253 {
2254   ink_assert(len >= 1);
2255   this->_reset();
2256   this->_packet = packet;
2257   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2258 
2259   // Stream ID (i)
2260   size_t field_len = 0;
2261   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
2262     return;
2263   }
2264 
2265   // Error Code (i)
2266   if (LEFT_SPACE(pos) < 1) {
2267     return;
2268   }
2269   if (!read_varint(pos, LEFT_SPACE(pos), this->_error_code, field_len)) {
2270     return;
2271   }
2272 
2273   this->_valid = true;
2274   this->_size  = FRAME_SIZE(pos);
2275 }
2276 
2277 QUICFrameType
type() const2278 QUICStopSendingFrame::type() const
2279 {
2280   return QUICFrameType::STOP_SENDING;
2281 }
2282 
2283 size_t
size() const2284 QUICStopSendingFrame::size() const
2285 {
2286   if (this->_size) {
2287     return this->_size;
2288   }
2289 
2290   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_stream_id) + QUICVariableInt::size(sizeof(QUICAppErrorCode));
2291 }
2292 
2293 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2294 QUICStopSendingFrame::to_io_buffer_block(size_t limit) const
2295 {
2296   Ptr<IOBufferBlock> block;
2297   size_t n = 0;
2298 
2299   if (limit < this->size()) {
2300     return block;
2301   }
2302 
2303   size_t written_len = 0;
2304   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2305   block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
2306   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2307 
2308   // Type
2309   block_start[0] = static_cast<uint8_t>(QUICFrameType::STOP_SENDING);
2310   n += 1;
2311 
2312   // Stream ID (i)
2313   QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
2314   n += written_len;
2315 
2316   // Application Error Code (i)
2317   QUICTypeUtil::write_QUICAppErrorCode(this->_error_code, block_start + n, &written_len);
2318   n += written_len;
2319 
2320   block->fill(n);
2321   return block;
2322 }
2323 
2324 QUICAppErrorCode
error_code() const2325 QUICStopSendingFrame::error_code() const
2326 {
2327   return this->_error_code;
2328 }
2329 
2330 QUICStreamId
stream_id() const2331 QUICStopSendingFrame::stream_id() const
2332 {
2333   return this->_stream_id;
2334 }
2335 
2336 //
2337 // PATH_CHALLENGE frame
2338 //
QUICPathChallengeFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)2339 QUICPathChallengeFrame::QUICPathChallengeFrame(const uint8_t *buf, size_t len, const QUICPacket *packet)
2340   : QUICFrame(0, nullptr, packet)
2341 {
2342   this->parse(buf, len, packet);
2343 }
2344 
2345 void
_reset()2346 QUICPathChallengeFrame::_reset()
2347 {
2348   this->_data  = nullptr;
2349   this->_owner = nullptr;
2350   this->_id    = 0;
2351   this->_valid = false;
2352   this->_size  = 0;
2353 }
2354 
2355 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2356 QUICPathChallengeFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2357 {
2358   ink_assert(len >= 1);
2359   this->_reset();
2360   this->_packet = packet;
2361   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2362 
2363   if (LEFT_SPACE(pos) < QUICPathChallengeFrame::DATA_LEN) {
2364     return;
2365   }
2366 
2367   this->_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
2368   memcpy(this->_data.get(), pos, QUICPathChallengeFrame::DATA_LEN);
2369   this->_valid = true;
2370   this->_size  = FRAME_SIZE(pos) + QUICPathChallengeFrame::DATA_LEN;
2371 }
2372 
2373 QUICFrameType
type() const2374 QUICPathChallengeFrame::type() const
2375 {
2376   return QUICFrameType::PATH_CHALLENGE;
2377 }
2378 
2379 size_t
size() const2380 QUICPathChallengeFrame::size() const
2381 {
2382   if (this->_size) {
2383     return this->_size;
2384   }
2385 
2386   return 1 + QUICPathChallengeFrame::DATA_LEN;
2387 }
2388 
2389 bool
is_probing_frame() const2390 QUICPathChallengeFrame::is_probing_frame() const
2391 {
2392   return true;
2393 }
2394 
2395 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2396 QUICPathChallengeFrame::to_io_buffer_block(size_t limit) const
2397 {
2398   Ptr<IOBufferBlock> block;
2399   size_t n = 0;
2400 
2401   if (limit < this->size()) {
2402     return block;
2403   }
2404 
2405   block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2406   block->alloc(iobuffer_size_to_index(1 + QUICPathChallengeFrame::DATA_LEN, BUFFER_SIZE_INDEX_32K));
2407   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2408 
2409   // Type
2410   block_start[0] = static_cast<uint8_t>(QUICFrameType::PATH_CHALLENGE);
2411   n += 1;
2412 
2413   // Data (64)
2414   memcpy(block_start + n, this->data(), QUICPathChallengeFrame::DATA_LEN);
2415   n += QUICPathChallengeFrame::DATA_LEN;
2416 
2417   block->fill(n);
2418   return block;
2419 }
2420 
2421 int
debug_msg(char * msg,size_t msg_len) const2422 QUICPathChallengeFrame::debug_msg(char *msg, size_t msg_len) const
2423 {
2424   auto data = this->data();
2425   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],
2426                   data[2], data[3], data[4], data[5], data[6], data[7]);
2427 }
2428 
2429 const uint8_t *
data() const2430 QUICPathChallengeFrame::data() const
2431 {
2432   return this->_data.get();
2433 }
2434 
2435 //
2436 // PATH_RESPONSE frame
2437 //
QUICPathResponseFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)2438 QUICPathResponseFrame::QUICPathResponseFrame(const uint8_t *buf, size_t len, const QUICPacket *packet)
2439   : QUICFrame(0, nullptr, packet)
2440 {
2441   this->parse(buf, len, packet);
2442 }
2443 
2444 void
_reset()2445 QUICPathResponseFrame::_reset()
2446 {
2447   this->_data  = nullptr;
2448   this->_owner = nullptr;
2449   this->_id    = 0;
2450   this->_valid = false;
2451   this->_size  = 0;
2452 }
2453 
2454 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2455 QUICPathResponseFrame::to_io_buffer_block(size_t limit) const
2456 {
2457   Ptr<IOBufferBlock> block;
2458   size_t n = 0;
2459 
2460   if (limit < this->size()) {
2461     return block;
2462   }
2463 
2464   block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2465   block->alloc(iobuffer_size_to_index(1 + QUICPathResponseFrame::DATA_LEN, BUFFER_SIZE_INDEX_32K));
2466   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2467 
2468   // Type
2469   block_start[0] = static_cast<uint8_t>(QUICFrameType::PATH_RESPONSE);
2470   n += 1;
2471 
2472   // Data (64)
2473   memcpy(block_start + n, this->data(), QUICPathChallengeFrame::DATA_LEN);
2474   n += QUICPathChallengeFrame::DATA_LEN;
2475 
2476   block->fill(n);
2477   return block;
2478 }
2479 
2480 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2481 QUICPathResponseFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2482 {
2483   ink_assert(len >= 1);
2484   this->_reset();
2485   this->_packet = packet;
2486   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2487 
2488   if (LEFT_SPACE(pos) < QUICPathChallengeFrame::DATA_LEN) {
2489     return;
2490   }
2491 
2492   this->_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
2493   memcpy(this->_data.get(), pos, QUICPathChallengeFrame::DATA_LEN);
2494   this->_valid = true;
2495   this->_size  = FRAME_SIZE(pos) + QUICPathChallengeFrame::DATA_LEN;
2496 }
2497 
2498 QUICFrameType
type() const2499 QUICPathResponseFrame::type() const
2500 {
2501   return QUICFrameType::PATH_RESPONSE;
2502 }
2503 
2504 size_t
size() const2505 QUICPathResponseFrame::size() const
2506 {
2507   return 1 + 8;
2508 }
2509 
2510 bool
is_probing_frame() const2511 QUICPathResponseFrame::is_probing_frame() const
2512 {
2513   return true;
2514 }
2515 
2516 int
debug_msg(char * msg,size_t msg_len) const2517 QUICPathResponseFrame::debug_msg(char *msg, size_t msg_len) const
2518 {
2519   auto data = this->data();
2520   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],
2521                   data[2], data[3], data[4], data[5], data[6], data[7]);
2522 }
2523 
2524 const uint8_t *
data() const2525 QUICPathResponseFrame::data() const
2526 {
2527   return this->_data.get();
2528 }
2529 
2530 //
2531 // QUICNewTokenFrame
2532 //
QUICNewTokenFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)2533 QUICNewTokenFrame::QUICNewTokenFrame(const uint8_t *buf, size_t len, const QUICPacket *packet) : QUICFrame(0, nullptr, packet)
2534 {
2535   this->parse(buf, len, packet);
2536 }
2537 
2538 void
_reset()2539 QUICNewTokenFrame::_reset()
2540 {
2541   this->_token        = nullptr;
2542   this->_token_length = 0;
2543 
2544   this->_owner = nullptr;
2545   this->_id    = 0;
2546   this->_valid = false;
2547   this->_size  = 0;
2548 }
2549 
2550 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2551 QUICNewTokenFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2552 {
2553   ink_assert(len >= 1);
2554   this->_reset();
2555   this->_packet = packet;
2556   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2557 
2558   size_t field_len = 0;
2559   if (!read_varint(pos, LEFT_SPACE(pos), this->_token_length, field_len)) {
2560     return;
2561   }
2562 
2563   if (LEFT_SPACE(pos) < this->_token_length) {
2564     return;
2565   }
2566 
2567   this->_token = ats_unique_malloc(this->_token_length);
2568   memcpy(this->_token.get(), pos, this->_token_length);
2569   this->_valid = true;
2570   this->_size  = FRAME_SIZE(pos) + this->_token_length;
2571 }
2572 
2573 QUICFrameType
type() const2574 QUICNewTokenFrame::type() const
2575 {
2576   return QUICFrameType::NEW_TOKEN;
2577 }
2578 
2579 size_t
size() const2580 QUICNewTokenFrame::size() const
2581 {
2582   if (this->_size) {
2583     return this->_size;
2584   }
2585 
2586   return 1 + QUICVariableInt::size(this->_token_length) + this->token_length();
2587 }
2588 
2589 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2590 QUICNewTokenFrame::to_io_buffer_block(size_t limit) const
2591 {
2592   Ptr<IOBufferBlock> block;
2593   size_t n = 0;
2594 
2595   if (limit < this->size()) {
2596     return block;
2597   }
2598 
2599   size_t written_len = 0;
2600   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2601   block->alloc(iobuffer_size_to_index(1 + 24, BUFFER_SIZE_INDEX_32K));
2602   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2603 
2604   // Type
2605   block_start[0] = static_cast<uint8_t>(QUICFrameType::NEW_TOKEN);
2606   n += 1;
2607 
2608   // Token Length (i)
2609   QUICIntUtil::write_QUICVariableInt(this->_token_length, block_start + n, &written_len);
2610   n += written_len;
2611 
2612   // Token (*)
2613   memcpy(block_start + n, this->token(), this->token_length());
2614   n += this->token_length();
2615 
2616   block->fill(n);
2617   return block;
2618 }
2619 
2620 uint64_t
token_length() const2621 QUICNewTokenFrame::token_length() const
2622 {
2623   return this->_token_length;
2624 }
2625 
2626 const uint8_t *
token() const2627 QUICNewTokenFrame::token() const
2628 {
2629   return this->_token.get();
2630 }
2631 
2632 //
2633 // RETIRE_CONNECTION_ID frame
2634 //
QUICRetireConnectionIdFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)2635 QUICRetireConnectionIdFrame::QUICRetireConnectionIdFrame(const uint8_t *buf, size_t len, const QUICPacket *packet)
2636   : QUICFrame(0, nullptr, packet)
2637 {
2638   this->parse(buf, len, packet);
2639 }
2640 
2641 void
_reset()2642 QUICRetireConnectionIdFrame::_reset()
2643 {
2644   this->_seq_num = 0;
2645 
2646   this->_owner = nullptr;
2647   this->_id    = 0;
2648   this->_valid = false;
2649   this->_size  = 0;
2650   this->_size  = 0;
2651 }
2652 
2653 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2654 QUICRetireConnectionIdFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2655 {
2656   ink_assert(len >= 1);
2657   this->_reset();
2658   this->_packet = packet;
2659   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2660 
2661   size_t field_len = 0;
2662   if (!read_varint(pos, LEFT_SPACE(pos), this->_seq_num, field_len)) {
2663     return;
2664   }
2665 
2666   this->_valid = true;
2667   this->_size  = FRAME_SIZE(pos);
2668 }
2669 
2670 QUICFrameType
type() const2671 QUICRetireConnectionIdFrame::type() const
2672 {
2673   return QUICFrameType::RETIRE_CONNECTION_ID;
2674 }
2675 
2676 size_t
size() const2677 QUICRetireConnectionIdFrame::size() const
2678 {
2679   if (this->_size) {
2680     return this->_size;
2681   }
2682 
2683   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_seq_num);
2684 }
2685 
2686 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2687 QUICRetireConnectionIdFrame::to_io_buffer_block(size_t limit) const
2688 {
2689   Ptr<IOBufferBlock> block;
2690   size_t n = 0;
2691 
2692   if (limit < this->size()) {
2693     return block;
2694   }
2695 
2696   size_t written_len = 0;
2697   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2698   block->alloc(iobuffer_size_to_index(1 + sizeof(uint64_t), BUFFER_SIZE_INDEX_32K));
2699   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2700 
2701   // Type
2702   block_start[0] = static_cast<uint8_t>(QUICFrameType::RETIRE_CONNECTION_ID);
2703   n += 1;
2704 
2705   // Sequence Number (i)
2706   QUICIntUtil::write_QUICVariableInt(this->_seq_num, block_start + n, &written_len);
2707   n += written_len;
2708 
2709   block->fill(n);
2710   return block;
2711 }
2712 
2713 int
debug_msg(char * msg,size_t msg_len) const2714 QUICRetireConnectionIdFrame::debug_msg(char *msg, size_t msg_len) const
2715 {
2716   return snprintf(msg, msg_len, "RETIRE_CONNECTION_ID size=%zu seq_num=%" PRIu64, this->size(), this->seq_num());
2717 }
2718 
2719 uint64_t
seq_num() const2720 QUICRetireConnectionIdFrame::seq_num() const
2721 {
2722   return this->_seq_num;
2723 }
2724 
2725 //
2726 // UNKNOWN
2727 //
2728 QUICFrameType
type() const2729 QUICUnknownFrame::type() const
2730 {
2731   return QUICFrameType::UNKNOWN;
2732 }
2733 
2734 size_t
size() const2735 QUICUnknownFrame::size() const
2736 {
2737   // FIXME size should be readable
2738   return 0;
2739 }
2740 
2741 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2742 QUICUnknownFrame::to_io_buffer_block(size_t limit) const
2743 {
2744   Ptr<IOBufferBlock> block;
2745   return block;
2746 }
2747 
2748 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2749 QUICUnknownFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2750 {
2751   this->_packet = packet;
2752 }
2753 
2754 int
debug_msg(char * msg,size_t msg_len) const2755 QUICUnknownFrame::debug_msg(char *msg, size_t msg_len) const
2756 {
2757   return 0;
2758 }
2759 
2760 //
2761 // QUICFrameFactory
2762 //
2763 
2764 QUICFrame *
create(uint8_t * buf,const uint8_t * src,size_t len,const QUICPacket * packet)2765 QUICFrameFactory::create(uint8_t *buf, const uint8_t *src, size_t len, const QUICPacket *packet)
2766 {
2767   switch (QUICFrame::type(src)) {
2768   case QUICFrameType::STREAM:
2769     new (buf) QUICStreamFrame(src, len, packet);
2770     return reinterpret_cast<QUICFrame *>(buf);
2771   case QUICFrameType::CRYPTO:
2772     new (buf) QUICCryptoFrame(src, len, packet);
2773     return reinterpret_cast<QUICFrame *>(buf);
2774   case QUICFrameType::ACK:
2775     new (buf) QUICAckFrame(src, len, packet);
2776     return reinterpret_cast<QUICFrame *>(buf);
2777   case QUICFrameType::PADDING:
2778     new (buf) QUICPaddingFrame(src, len, packet);
2779     return reinterpret_cast<QUICFrame *>(buf);
2780   case QUICFrameType::RESET_STREAM:
2781     new (buf) QUICRstStreamFrame(src, len, packet);
2782     return reinterpret_cast<QUICFrame *>(buf);
2783   case QUICFrameType::CONNECTION_CLOSE:
2784     new (buf) QUICConnectionCloseFrame(src, len, packet);
2785     return reinterpret_cast<QUICFrame *>(buf);
2786   case QUICFrameType::MAX_DATA:
2787     new (buf) QUICMaxDataFrame(src, len, packet);
2788     return reinterpret_cast<QUICFrame *>(buf);
2789   case QUICFrameType::MAX_STREAM_DATA:
2790     new (buf) QUICMaxStreamDataFrame(src, len, packet);
2791     return reinterpret_cast<QUICFrame *>(buf);
2792   case QUICFrameType::MAX_STREAMS:
2793     new (buf) QUICMaxStreamsFrame(src, len, packet);
2794     return reinterpret_cast<QUICFrame *>(buf);
2795   case QUICFrameType::PING:
2796     new (buf) QUICPingFrame(src, len, packet);
2797     return reinterpret_cast<QUICFrame *>(buf);
2798   case QUICFrameType::DATA_BLOCKED:
2799     new (buf) QUICDataBlockedFrame(src, len, packet);
2800     return reinterpret_cast<QUICFrame *>(buf);
2801   case QUICFrameType::STREAM_DATA_BLOCKED:
2802     new (buf) QUICStreamDataBlockedFrame(src, len, packet);
2803     return reinterpret_cast<QUICFrame *>(buf);
2804   case QUICFrameType::STREAMS_BLOCKED:
2805     new (buf) QUICStreamIdBlockedFrame(src, len, packet);
2806     return reinterpret_cast<QUICFrame *>(buf);
2807   case QUICFrameType::NEW_CONNECTION_ID:
2808     new (buf) QUICNewConnectionIdFrame(src, len, packet);
2809     return reinterpret_cast<QUICFrame *>(buf);
2810   case QUICFrameType::STOP_SENDING:
2811     new (buf) QUICStopSendingFrame(src, len, packet);
2812     return reinterpret_cast<QUICFrame *>(buf);
2813   case QUICFrameType::PATH_CHALLENGE:
2814     new (buf) QUICPathChallengeFrame(src, len, packet);
2815     return reinterpret_cast<QUICFrame *>(buf);
2816   case QUICFrameType::PATH_RESPONSE:
2817     new (buf) QUICPathResponseFrame(src, len, packet);
2818     return reinterpret_cast<QUICFrame *>(buf);
2819   case QUICFrameType::NEW_TOKEN:
2820     new (buf) QUICNewTokenFrame(src, len, packet);
2821     return reinterpret_cast<QUICFrame *>(buf);
2822   case QUICFrameType::RETIRE_CONNECTION_ID:
2823     new (buf) QUICRetireConnectionIdFrame(src, len, packet);
2824     return reinterpret_cast<QUICFrame *>(buf);
2825   default:
2826     // Unknown frame
2827     Debug("quic_frame_factory", "Unknown frame type %x", src[0]);
2828     return nullptr;
2829   }
2830 }
2831 
2832 const QUICFrame &
fast_create(const uint8_t * buf,size_t len,const QUICPacket * packet)2833 QUICFrameFactory::fast_create(const uint8_t *buf, size_t len, const QUICPacket *packet)
2834 {
2835   if (QUICFrame::type(buf) == QUICFrameType::UNKNOWN) {
2836     return this->_unknown_frame;
2837   }
2838 
2839   ptrdiff_t type_index = static_cast<ptrdiff_t>(QUICFrame::type(buf));
2840   QUICFrame *frame     = this->_reusable_frames[type_index];
2841 
2842   if (frame == nullptr) {
2843     frame = QUICFrameFactory::create(this->_buf_for_fast_create + (type_index * QUICFrame::MAX_INSTANCE_SIZE), buf, len, packet);
2844     if (frame != nullptr) {
2845       this->_reusable_frames[static_cast<ptrdiff_t>(QUICFrame::type(buf))] = frame;
2846     }
2847   } else {
2848     frame->parse(buf, len, packet);
2849   }
2850 
2851   return *frame;
2852 }
2853 
2854 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)2855 QUICFrameFactory::create_stream_frame(uint8_t *buf, Ptr<IOBufferBlock> &block, QUICStreamId stream_id, QUICOffset offset, bool last,
2856                                       bool has_offset_field, bool has_length_field, QUICFrameId id, QUICFrameGenerator *owner)
2857 {
2858   Ptr<IOBufferBlock> new_block = make_ptr<IOBufferBlock>(block->clone());
2859   new (buf) QUICStreamFrame(new_block, stream_id, offset, last, has_offset_field, has_length_field, id, owner);
2860   return reinterpret_cast<QUICStreamFrame *>(buf);
2861 }
2862 
2863 QUICCryptoFrame *
create_crypto_frame(uint8_t * buf,Ptr<IOBufferBlock> & block,QUICOffset offset,QUICFrameId id,QUICFrameGenerator * owner)2864 QUICFrameFactory::create_crypto_frame(uint8_t *buf, Ptr<IOBufferBlock> &block, QUICOffset offset, QUICFrameId id,
2865                                       QUICFrameGenerator *owner)
2866 {
2867   Ptr<IOBufferBlock> new_block = make_ptr<IOBufferBlock>(block->clone());
2868   new (buf) QUICCryptoFrame(new_block, offset, id, owner);
2869   return reinterpret_cast<QUICCryptoFrame *>(buf);
2870 }
2871 
2872 QUICAckFrame *
create_ack_frame(uint8_t * buf,QUICPacketNumber largest_acknowledged,uint64_t ack_delay,uint64_t first_ack_block,QUICFrameId id,QUICFrameGenerator * owner)2873 QUICFrameFactory::create_ack_frame(uint8_t *buf, QUICPacketNumber largest_acknowledged, uint64_t ack_delay,
2874                                    uint64_t first_ack_block, QUICFrameId id, QUICFrameGenerator *owner)
2875 {
2876   new (buf) QUICAckFrame(largest_acknowledged, ack_delay, first_ack_block, id, owner);
2877   return reinterpret_cast<QUICAckFrame *>(buf);
2878 }
2879 
2880 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)2881 QUICFrameFactory::create_connection_close_frame(uint8_t *buf, uint16_t error_code, QUICFrameType frame_type,
2882                                                 uint16_t reason_phrase_length, const char *reason_phrase, QUICFrameId id,
2883                                                 QUICFrameGenerator *owner)
2884 {
2885   new (buf) QUICConnectionCloseFrame(error_code, frame_type, reason_phrase_length, reason_phrase, id, owner);
2886   return reinterpret_cast<QUICConnectionCloseFrame *>(buf);
2887 }
2888 
2889 QUICConnectionCloseFrame *
create_connection_close_frame(uint8_t * buf,QUICConnectionError & error,QUICFrameId id,QUICFrameGenerator * owner)2890 QUICFrameFactory::create_connection_close_frame(uint8_t *buf, QUICConnectionError &error, QUICFrameId id, QUICFrameGenerator *owner)
2891 {
2892   ink_assert(error.cls == QUICErrorClass::TRANSPORT);
2893   if (error.msg) {
2894     return QUICFrameFactory::create_connection_close_frame(buf, error.code, error.frame_type(), strlen(error.msg), error.msg, id,
2895                                                            owner);
2896   } else {
2897     return QUICFrameFactory::create_connection_close_frame(buf, error.code, error.frame_type(), 0, nullptr, id, owner);
2898   }
2899 }
2900 
2901 QUICMaxDataFrame *
create_max_data_frame(uint8_t * buf,uint64_t maximum_data,QUICFrameId id,QUICFrameGenerator * owner)2902 QUICFrameFactory::create_max_data_frame(uint8_t *buf, uint64_t maximum_data, QUICFrameId id, QUICFrameGenerator *owner)
2903 {
2904   new (buf) QUICMaxDataFrame(maximum_data, id, owner);
2905   return reinterpret_cast<QUICMaxDataFrame *>(buf);
2906 }
2907 QUICMaxStreamDataFrame *
create_max_stream_data_frame(uint8_t * buf,QUICStreamId stream_id,uint64_t maximum_data,QUICFrameId id,QUICFrameGenerator * owner)2908 QUICFrameFactory::create_max_stream_data_frame(uint8_t *buf, QUICStreamId stream_id, uint64_t maximum_data, QUICFrameId id,
2909                                                QUICFrameGenerator *owner)
2910 {
2911   new (buf) QUICMaxStreamDataFrame(stream_id, maximum_data, id, owner);
2912   return reinterpret_cast<QUICMaxStreamDataFrame *>(buf);
2913 }
2914 
2915 QUICMaxStreamsFrame *
create_max_streams_frame(uint8_t * buf,QUICStreamId maximum_streams,QUICFrameId id,QUICFrameGenerator * owner)2916 QUICFrameFactory::create_max_streams_frame(uint8_t *buf, QUICStreamId maximum_streams, QUICFrameId id, QUICFrameGenerator *owner)
2917 {
2918   new (buf) QUICMaxStreamsFrame(maximum_streams, id, owner);
2919   return reinterpret_cast<QUICMaxStreamsFrame *>(buf);
2920 }
2921 
2922 QUICPingFrame *
create_ping_frame(uint8_t * buf,QUICFrameId id,QUICFrameGenerator * owner)2923 QUICFrameFactory::create_ping_frame(uint8_t *buf, QUICFrameId id, QUICFrameGenerator *owner)
2924 {
2925   new (buf) QUICPingFrame(id, owner);
2926   return reinterpret_cast<QUICPingFrame *>(buf);
2927 }
2928 
2929 QUICPaddingFrame *
create_padding_frame(uint8_t * buf,size_t size,QUICFrameId id,QUICFrameGenerator * owner)2930 QUICFrameFactory::create_padding_frame(uint8_t *buf, size_t size, QUICFrameId id, QUICFrameGenerator *owner)
2931 {
2932   new (buf) QUICPaddingFrame(size);
2933   return reinterpret_cast<QUICPaddingFrame *>(buf);
2934 }
2935 
2936 QUICPathChallengeFrame *
create_path_challenge_frame(uint8_t * buf,const uint8_t * data,QUICFrameId id,QUICFrameGenerator * owner)2937 QUICFrameFactory::create_path_challenge_frame(uint8_t *buf, const uint8_t *data, QUICFrameId id, QUICFrameGenerator *owner)
2938 {
2939   ats_unique_buf challenge_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
2940   memcpy(challenge_data.get(), data, QUICPathChallengeFrame::DATA_LEN);
2941 
2942   new (buf) QUICPathChallengeFrame(std::move(challenge_data), id, owner);
2943   return reinterpret_cast<QUICPathChallengeFrame *>(buf);
2944 }
2945 
2946 QUICPathResponseFrame *
create_path_response_frame(uint8_t * buf,const uint8_t * data,QUICFrameId id,QUICFrameGenerator * owner)2947 QUICFrameFactory::create_path_response_frame(uint8_t *buf, const uint8_t *data, QUICFrameId id, QUICFrameGenerator *owner)
2948 {
2949   ats_unique_buf response_data = ats_unique_malloc(QUICPathResponseFrame::DATA_LEN);
2950   memcpy(response_data.get(), data, QUICPathResponseFrame::DATA_LEN);
2951 
2952   new (buf) QUICPathResponseFrame(std::move(response_data), id, owner);
2953   return reinterpret_cast<QUICPathResponseFrame *>(buf);
2954 }
2955 
2956 QUICDataBlockedFrame *
create_data_blocked_frame(uint8_t * buf,QUICOffset offset,QUICFrameId id,QUICFrameGenerator * owner)2957 QUICFrameFactory::create_data_blocked_frame(uint8_t *buf, QUICOffset offset, QUICFrameId id, QUICFrameGenerator *owner)
2958 {
2959   new (buf) QUICDataBlockedFrame(offset, id, owner);
2960   return reinterpret_cast<QUICDataBlockedFrame *>(buf);
2961 }
2962 
2963 QUICStreamDataBlockedFrame *
create_stream_data_blocked_frame(uint8_t * buf,QUICStreamId stream_id,QUICOffset offset,QUICFrameId id,QUICFrameGenerator * owner)2964 QUICFrameFactory::create_stream_data_blocked_frame(uint8_t *buf, QUICStreamId stream_id, QUICOffset offset, QUICFrameId id,
2965                                                    QUICFrameGenerator *owner)
2966 {
2967   new (buf) QUICStreamDataBlockedFrame(stream_id, offset, id, owner);
2968   return reinterpret_cast<QUICStreamDataBlockedFrame *>(buf);
2969 }
2970 
2971 QUICStreamIdBlockedFrame *
create_stream_id_blocked_frame(uint8_t * buf,QUICStreamId stream_id,QUICFrameId id,QUICFrameGenerator * owner)2972 QUICFrameFactory::create_stream_id_blocked_frame(uint8_t *buf, QUICStreamId stream_id, QUICFrameId id, QUICFrameGenerator *owner)
2973 {
2974   new (buf) QUICStreamIdBlockedFrame(stream_id, id, owner);
2975   return reinterpret_cast<QUICStreamIdBlockedFrame *>(buf);
2976 }
2977 
2978 QUICRstStreamFrame *
create_rst_stream_frame(uint8_t * buf,QUICStreamId stream_id,QUICAppErrorCode error_code,QUICOffset final_offset,QUICFrameId id,QUICFrameGenerator * owner)2979 QUICFrameFactory::create_rst_stream_frame(uint8_t *buf, QUICStreamId stream_id, QUICAppErrorCode error_code,
2980                                           QUICOffset final_offset, QUICFrameId id, QUICFrameGenerator *owner)
2981 {
2982   new (buf) QUICRstStreamFrame(stream_id, error_code, final_offset, id, owner);
2983   return reinterpret_cast<QUICRstStreamFrame *>(buf);
2984 }
2985 
2986 QUICRstStreamFrame *
create_rst_stream_frame(uint8_t * buf,QUICStreamError & error,QUICFrameId id,QUICFrameGenerator * owner)2987 QUICFrameFactory::create_rst_stream_frame(uint8_t *buf, QUICStreamError &error, QUICFrameId id, QUICFrameGenerator *owner)
2988 {
2989   return QUICFrameFactory::create_rst_stream_frame(buf, error.stream->id(), error.code, error.stream->final_offset(), id,