xref: /trafficserver/iocore/net/quic/QUICFrame.cc (revision a80d7794)
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();
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));
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();
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));
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));
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));
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));
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()));
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));
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));
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));
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)));
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)));
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)));
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)));
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)));
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)));
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   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2160 
2161   // Type
2162   block_start[0] = static_cast<uint8_t>(QUICFrameType::NEW_CONNECTION_ID);
2163   n += 1;
2164 
2165   // Sequence Number (i)
2166   QUICIntUtil::write_QUICVariableInt(this->_sequence, block_start + n, &written_len);
2167   n += written_len;
2168 
2169   // Retire Prior To (i)
2170   QUICIntUtil::write_QUICVariableInt(this->_retire_prior_to, block_start + n, &written_len);
2171   n += written_len;
2172 
2173   // Length (8)
2174   *(block_start + n) = this->_connection_id.length();
2175   n += 1;
2176 
2177   // Connection ID (8..160)
2178   QUICTypeUtil::write_QUICConnectionId(this->_connection_id, block_start + n, &written_len);
2179   n += written_len;
2180 
2181   // Stateless Reset Token (128)
2182   memcpy(block_start + n, this->_stateless_reset_token.buf(), QUICStatelessResetToken::LEN);
2183   n += QUICStatelessResetToken::LEN;
2184 
2185   block->fill(n);
2186   return block;
2187 }
2188 
2189 int
debug_msg(char * msg,size_t msg_len) const2190 QUICNewConnectionIdFrame::debug_msg(char *msg, size_t msg_len) const
2191 {
2192   char cid_str[QUICConnectionId::MAX_HEX_STR_LENGTH];
2193   this->connection_id().hex(cid_str, QUICConnectionId::MAX_HEX_STR_LENGTH);
2194 
2195   return snprintf(msg, msg_len, "NEW_CONNECTION_ID size=%zu seq=%" PRIu64 " rpt=%" PRIu64 " cid=0x%s", this->size(),
2196                   this->sequence(), this->retire_prior_to(), cid_str);
2197 }
2198 
2199 uint64_t
sequence() const2200 QUICNewConnectionIdFrame::sequence() const
2201 {
2202   return this->_sequence;
2203 }
2204 
2205 uint64_t
retire_prior_to() const2206 QUICNewConnectionIdFrame::retire_prior_to() const
2207 {
2208   return this->_retire_prior_to;
2209 }
2210 
2211 QUICConnectionId
connection_id() const2212 QUICNewConnectionIdFrame::connection_id() const
2213 {
2214   return this->_connection_id;
2215 }
2216 
2217 QUICStatelessResetToken
stateless_reset_token() const2218 QUICNewConnectionIdFrame::stateless_reset_token() const
2219 {
2220   return this->_stateless_reset_token;
2221 }
2222 
2223 //
2224 // STOP_SENDING frame
2225 //
2226 
QUICStopSendingFrame(QUICStreamId stream_id,QUICAppErrorCode error_code,QUICFrameId id,QUICFrameGenerator * owner)2227 QUICStopSendingFrame::QUICStopSendingFrame(QUICStreamId stream_id, QUICAppErrorCode error_code, QUICFrameId id,
2228                                            QUICFrameGenerator *owner)
2229   : QUICFrame(id, owner), _stream_id(stream_id), _error_code(error_code)
2230 {
2231 }
2232 
2233 void
_reset()2234 QUICStopSendingFrame::_reset()
2235 {
2236   this->_stream_id  = 0;
2237   this->_error_code = 0;
2238 
2239   this->_owner = nullptr;
2240   this->_id    = 0;
2241   this->_valid = false;
2242   this->_size  = 0;
2243 }
2244 
QUICStopSendingFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)2245 QUICStopSendingFrame::QUICStopSendingFrame(const uint8_t *buf, size_t len, const QUICPacket *packet) : QUICFrame(0, nullptr, packet)
2246 {
2247   this->parse(buf, len, packet);
2248 }
2249 
2250 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2251 QUICStopSendingFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2252 {
2253   ink_assert(len >= 1);
2254   this->_reset();
2255   this->_packet = packet;
2256   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2257 
2258   // Stream ID (i)
2259   size_t field_len = 0;
2260   if (!read_varint(pos, LEFT_SPACE(pos), this->_stream_id, field_len)) {
2261     return;
2262   }
2263 
2264   // Error Code (i)
2265   if (LEFT_SPACE(pos) < 1) {
2266     return;
2267   }
2268   if (!read_varint(pos, LEFT_SPACE(pos), this->_error_code, field_len)) {
2269     return;
2270   }
2271 
2272   this->_valid = true;
2273   this->_size  = FRAME_SIZE(pos);
2274 }
2275 
2276 QUICFrameType
type() const2277 QUICStopSendingFrame::type() const
2278 {
2279   return QUICFrameType::STOP_SENDING;
2280 }
2281 
2282 size_t
size() const2283 QUICStopSendingFrame::size() const
2284 {
2285   if (this->_size) {
2286     return this->_size;
2287   }
2288 
2289   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_stream_id) + QUICVariableInt::size(sizeof(QUICAppErrorCode));
2290 }
2291 
2292 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2293 QUICStopSendingFrame::to_io_buffer_block(size_t limit) const
2294 {
2295   Ptr<IOBufferBlock> block;
2296   size_t n = 0;
2297 
2298   if (limit < this->size()) {
2299     return block;
2300   }
2301 
2302   size_t written_len = 0;
2303   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2304   block->alloc(iobuffer_size_to_index(1 + 24));
2305   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2306 
2307   // Type
2308   block_start[0] = static_cast<uint8_t>(QUICFrameType::STOP_SENDING);
2309   n += 1;
2310 
2311   // Stream ID (i)
2312   QUICTypeUtil::write_QUICStreamId(this->_stream_id, block_start + n, &written_len);
2313   n += written_len;
2314 
2315   // Application Error Code (i)
2316   QUICTypeUtil::write_QUICAppErrorCode(this->_error_code, block_start + n, &written_len);
2317   n += written_len;
2318 
2319   block->fill(n);
2320   return block;
2321 }
2322 
2323 QUICAppErrorCode
error_code() const2324 QUICStopSendingFrame::error_code() const
2325 {
2326   return this->_error_code;
2327 }
2328 
2329 QUICStreamId
stream_id() const2330 QUICStopSendingFrame::stream_id() const
2331 {
2332   return this->_stream_id;
2333 }
2334 
2335 //
2336 // PATH_CHALLENGE frame
2337 //
QUICPathChallengeFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)2338 QUICPathChallengeFrame::QUICPathChallengeFrame(const uint8_t *buf, size_t len, const QUICPacket *packet)
2339   : QUICFrame(0, nullptr, packet)
2340 {
2341   this->parse(buf, len, packet);
2342 }
2343 
2344 void
_reset()2345 QUICPathChallengeFrame::_reset()
2346 {
2347   this->_data  = nullptr;
2348   this->_owner = nullptr;
2349   this->_id    = 0;
2350   this->_valid = false;
2351   this->_size  = 0;
2352 }
2353 
2354 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2355 QUICPathChallengeFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2356 {
2357   ink_assert(len >= 1);
2358   this->_reset();
2359   this->_packet = packet;
2360   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2361 
2362   if (LEFT_SPACE(pos) < QUICPathChallengeFrame::DATA_LEN) {
2363     return;
2364   }
2365 
2366   this->_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
2367   memcpy(this->_data.get(), pos, QUICPathChallengeFrame::DATA_LEN);
2368   this->_valid = true;
2369   this->_size  = FRAME_SIZE(pos) + QUICPathChallengeFrame::DATA_LEN;
2370 }
2371 
2372 QUICFrameType
type() const2373 QUICPathChallengeFrame::type() const
2374 {
2375   return QUICFrameType::PATH_CHALLENGE;
2376 }
2377 
2378 size_t
size() const2379 QUICPathChallengeFrame::size() const
2380 {
2381   if (this->_size) {
2382     return this->_size;
2383   }
2384 
2385   return 1 + QUICPathChallengeFrame::DATA_LEN;
2386 }
2387 
2388 bool
is_probing_frame() const2389 QUICPathChallengeFrame::is_probing_frame() const
2390 {
2391   return true;
2392 }
2393 
2394 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2395 QUICPathChallengeFrame::to_io_buffer_block(size_t limit) const
2396 {
2397   Ptr<IOBufferBlock> block;
2398   size_t n = 0;
2399 
2400   if (limit < this->size()) {
2401     return block;
2402   }
2403 
2404   block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2405   block->alloc(iobuffer_size_to_index(1 + QUICPathChallengeFrame::DATA_LEN));
2406   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2407 
2408   // Type
2409   block_start[0] = static_cast<uint8_t>(QUICFrameType::PATH_CHALLENGE);
2410   n += 1;
2411 
2412   // Data (64)
2413   memcpy(block_start + n, this->data(), QUICPathChallengeFrame::DATA_LEN);
2414   n += QUICPathChallengeFrame::DATA_LEN;
2415 
2416   block->fill(n);
2417   return block;
2418 }
2419 
2420 int
debug_msg(char * msg,size_t msg_len) const2421 QUICPathChallengeFrame::debug_msg(char *msg, size_t msg_len) const
2422 {
2423   auto data = this->data();
2424   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],
2425                   data[2], data[3], data[4], data[5], data[6], data[7]);
2426 }
2427 
2428 const uint8_t *
data() const2429 QUICPathChallengeFrame::data() const
2430 {
2431   return this->_data.get();
2432 }
2433 
2434 //
2435 // PATH_RESPONSE frame
2436 //
QUICPathResponseFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)2437 QUICPathResponseFrame::QUICPathResponseFrame(const uint8_t *buf, size_t len, const QUICPacket *packet)
2438   : QUICFrame(0, nullptr, packet)
2439 {
2440   this->parse(buf, len, packet);
2441 }
2442 
2443 void
_reset()2444 QUICPathResponseFrame::_reset()
2445 {
2446   this->_data  = nullptr;
2447   this->_owner = nullptr;
2448   this->_id    = 0;
2449   this->_valid = false;
2450   this->_size  = 0;
2451 }
2452 
2453 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2454 QUICPathResponseFrame::to_io_buffer_block(size_t limit) const
2455 {
2456   Ptr<IOBufferBlock> block;
2457   size_t n = 0;
2458 
2459   if (limit < this->size()) {
2460     return block;
2461   }
2462 
2463   block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2464   block->alloc(iobuffer_size_to_index(1 + QUICPathResponseFrame::DATA_LEN));
2465   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2466 
2467   // Type
2468   block_start[0] = static_cast<uint8_t>(QUICFrameType::PATH_RESPONSE);
2469   n += 1;
2470 
2471   // Data (64)
2472   memcpy(block_start + n, this->data(), QUICPathChallengeFrame::DATA_LEN);
2473   n += QUICPathChallengeFrame::DATA_LEN;
2474 
2475   block->fill(n);
2476   return block;
2477 }
2478 
2479 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2480 QUICPathResponseFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2481 {
2482   ink_assert(len >= 1);
2483   this->_reset();
2484   this->_packet = packet;
2485   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2486 
2487   if (LEFT_SPACE(pos) < QUICPathChallengeFrame::DATA_LEN) {
2488     return;
2489   }
2490 
2491   this->_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
2492   memcpy(this->_data.get(), pos, QUICPathChallengeFrame::DATA_LEN);
2493   this->_valid = true;
2494   this->_size  = FRAME_SIZE(pos) + QUICPathChallengeFrame::DATA_LEN;
2495 }
2496 
2497 QUICFrameType
type() const2498 QUICPathResponseFrame::type() const
2499 {
2500   return QUICFrameType::PATH_RESPONSE;
2501 }
2502 
2503 size_t
size() const2504 QUICPathResponseFrame::size() const
2505 {
2506   return 1 + 8;
2507 }
2508 
2509 bool
is_probing_frame() const2510 QUICPathResponseFrame::is_probing_frame() const
2511 {
2512   return true;
2513 }
2514 
2515 int
debug_msg(char * msg,size_t msg_len) const2516 QUICPathResponseFrame::debug_msg(char *msg, size_t msg_len) const
2517 {
2518   auto data = this->data();
2519   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],
2520                   data[2], data[3], data[4], data[5], data[6], data[7]);
2521 }
2522 
2523 const uint8_t *
data() const2524 QUICPathResponseFrame::data() const
2525 {
2526   return this->_data.get();
2527 }
2528 
2529 //
2530 // QUICNewTokenFrame
2531 //
QUICNewTokenFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)2532 QUICNewTokenFrame::QUICNewTokenFrame(const uint8_t *buf, size_t len, const QUICPacket *packet) : QUICFrame(0, nullptr, packet)
2533 {
2534   this->parse(buf, len, packet);
2535 }
2536 
2537 void
_reset()2538 QUICNewTokenFrame::_reset()
2539 {
2540   this->_token        = nullptr;
2541   this->_token_length = 0;
2542 
2543   this->_owner = nullptr;
2544   this->_id    = 0;
2545   this->_valid = false;
2546   this->_size  = 0;
2547 }
2548 
2549 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2550 QUICNewTokenFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2551 {
2552   ink_assert(len >= 1);
2553   this->_reset();
2554   this->_packet = packet;
2555   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2556 
2557   size_t field_len = 0;
2558   if (!read_varint(pos, LEFT_SPACE(pos), this->_token_length, field_len)) {
2559     return;
2560   }
2561 
2562   if (LEFT_SPACE(pos) < this->_token_length) {
2563     return;
2564   }
2565 
2566   this->_token = ats_unique_malloc(this->_token_length);
2567   memcpy(this->_token.get(), pos, this->_token_length);
2568   this->_valid = true;
2569   this->_size  = FRAME_SIZE(pos) + this->_token_length;
2570 }
2571 
2572 QUICFrameType
type() const2573 QUICNewTokenFrame::type() const
2574 {
2575   return QUICFrameType::NEW_TOKEN;
2576 }
2577 
2578 size_t
size() const2579 QUICNewTokenFrame::size() const
2580 {
2581   if (this->_size) {
2582     return this->_size;
2583   }
2584 
2585   return 1 + QUICVariableInt::size(this->_token_length) + this->token_length();
2586 }
2587 
2588 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2589 QUICNewTokenFrame::to_io_buffer_block(size_t limit) const
2590 {
2591   Ptr<IOBufferBlock> block;
2592   size_t n = 0;
2593 
2594   if (limit < this->size()) {
2595     return block;
2596   }
2597 
2598   size_t written_len = 0;
2599   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2600   block->alloc(iobuffer_size_to_index(1 + 24));
2601   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2602 
2603   // Type
2604   block_start[0] = static_cast<uint8_t>(QUICFrameType::NEW_TOKEN);
2605   n += 1;
2606 
2607   // Token Length (i)
2608   QUICIntUtil::write_QUICVariableInt(this->_token_length, block_start + n, &written_len);
2609   n += written_len;
2610 
2611   // Token (*)
2612   memcpy(block_start + n, this->token(), this->token_length());
2613   n += this->token_length();
2614 
2615   block->fill(n);
2616   return block;
2617 }
2618 
2619 uint64_t
token_length() const2620 QUICNewTokenFrame::token_length() const
2621 {
2622   return this->_token_length;
2623 }
2624 
2625 const uint8_t *
token() const2626 QUICNewTokenFrame::token() const
2627 {
2628   return this->_token.get();
2629 }
2630 
2631 //
2632 // RETIRE_CONNECTION_ID frame
2633 //
QUICRetireConnectionIdFrame(const uint8_t * buf,size_t len,const QUICPacket * packet)2634 QUICRetireConnectionIdFrame::QUICRetireConnectionIdFrame(const uint8_t *buf, size_t len, const QUICPacket *packet)
2635   : QUICFrame(0, nullptr, packet)
2636 {
2637   this->parse(buf, len, packet);
2638 }
2639 
2640 void
_reset()2641 QUICRetireConnectionIdFrame::_reset()
2642 {
2643   this->_seq_num = 0;
2644 
2645   this->_owner = nullptr;
2646   this->_id    = 0;
2647   this->_valid = false;
2648   this->_size  = 0;
2649   this->_size  = 0;
2650 }
2651 
2652 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2653 QUICRetireConnectionIdFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2654 {
2655   ink_assert(len >= 1);
2656   this->_reset();
2657   this->_packet = packet;
2658   uint8_t *pos  = const_cast<uint8_t *>(buf) + 1;
2659 
2660   size_t field_len = 0;
2661   if (!read_varint(pos, LEFT_SPACE(pos), this->_seq_num, field_len)) {
2662     return;
2663   }
2664 
2665   this->_valid = true;
2666   this->_size  = FRAME_SIZE(pos);
2667 }
2668 
2669 QUICFrameType
type() const2670 QUICRetireConnectionIdFrame::type() const
2671 {
2672   return QUICFrameType::RETIRE_CONNECTION_ID;
2673 }
2674 
2675 size_t
size() const2676 QUICRetireConnectionIdFrame::size() const
2677 {
2678   if (this->_size) {
2679     return this->_size;
2680   }
2681 
2682   return sizeof(QUICFrameType) + QUICVariableInt::size(this->_seq_num);
2683 }
2684 
2685 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2686 QUICRetireConnectionIdFrame::to_io_buffer_block(size_t limit) const
2687 {
2688   Ptr<IOBufferBlock> block;
2689   size_t n = 0;
2690 
2691   if (limit < this->size()) {
2692     return block;
2693   }
2694 
2695   size_t written_len = 0;
2696   block              = make_ptr<IOBufferBlock>(new_IOBufferBlock());
2697   block->alloc(iobuffer_size_to_index(1 + sizeof(uint64_t)));
2698   uint8_t *block_start = reinterpret_cast<uint8_t *>(block->start());
2699 
2700   // Type
2701   block_start[0] = static_cast<uint8_t>(QUICFrameType::RETIRE_CONNECTION_ID);
2702   n += 1;
2703 
2704   // Sequence Number (i)
2705   QUICIntUtil::write_QUICVariableInt(this->_seq_num, block_start + n, &written_len);
2706   n += written_len;
2707 
2708   block->fill(n);
2709   return block;
2710 }
2711 
2712 int
debug_msg(char * msg,size_t msg_len) const2713 QUICRetireConnectionIdFrame::debug_msg(char *msg, size_t msg_len) const
2714 {
2715   return snprintf(msg, msg_len, "RETIRE_CONNECTION_ID size=%zu seq_num=%" PRIu64, this->size(), this->seq_num());
2716 }
2717 
2718 uint64_t
seq_num() const2719 QUICRetireConnectionIdFrame::seq_num() const
2720 {
2721   return this->_seq_num;
2722 }
2723 
2724 //
2725 // UNKNOWN
2726 //
2727 QUICFrameType
type() const2728 QUICUnknownFrame::type() const
2729 {
2730   return QUICFrameType::UNKNOWN;
2731 }
2732 
2733 size_t
size() const2734 QUICUnknownFrame::size() const
2735 {
2736   // FIXME size should be readable
2737   return 0;
2738 }
2739 
2740 Ptr<IOBufferBlock>
to_io_buffer_block(size_t limit) const2741 QUICUnknownFrame::to_io_buffer_block(size_t limit) const
2742 {
2743   Ptr<IOBufferBlock> block;
2744   return block;
2745 }
2746 
2747 void
parse(const uint8_t * buf,size_t len,const QUICPacket * packet)2748 QUICUnknownFrame::parse(const uint8_t *buf, size_t len, const QUICPacket *packet)
2749 {
2750   this->_packet = packet;
2751 }
2752 
2753 int
debug_msg(char * msg,size_t msg_len) const2754 QUICUnknownFrame::debug_msg(char *msg, size_t msg_len) const
2755 {
2756   return 0;
2757 }
2758 
2759 //
2760 // QUICFrameFactory
2761 //
2762 
2763 QUICFrame *
create(uint8_t * buf,const uint8_t * src,size_t len,const QUICPacket * packet)2764 QUICFrameFactory::create(uint8_t *buf, const uint8_t *src, size_t len, const QUICPacket *packet)
2765 {
2766   switch (QUICFrame::type(src)) {
2767   case QUICFrameType::STREAM:
2768     new (buf) QUICStreamFrame(src, len, packet);
2769     return reinterpret_cast<QUICFrame *>(buf);
2770   case QUICFrameType::CRYPTO:
2771     new (buf) QUICCryptoFrame(src, len, packet);
2772     return reinterpret_cast<QUICFrame *>(buf);
2773   case QUICFrameType::ACK:
2774     new (buf) QUICAckFrame(src, len, packet);
2775     return reinterpret_cast<QUICFrame *>(buf);
2776   case QUICFrameType::PADDING:
2777     new (buf) QUICPaddingFrame(src, len, packet);
2778     return reinterpret_cast<QUICFrame *>(buf);
2779   case QUICFrameType::RESET_STREAM:
2780     new (buf) QUICRstStreamFrame(src, len, packet);
2781     return reinterpret_cast<QUICFrame *>(buf);
2782   case QUICFrameType::CONNECTION_CLOSE:
2783     new (buf) QUICConnectionCloseFrame(src, len, packet);
2784     return reinterpret_cast<QUICFrame *>(buf);
2785   case QUICFrameType::MAX_DATA:
2786     new (buf) QUICMaxDataFrame(src, len, packet);
2787     return reinterpret_cast<QUICFrame *>(buf);
2788   case QUICFrameType::MAX_STREAM_DATA:
2789     new (buf) QUICMaxStreamDataFrame(src, len, packet);
2790     return reinterpret_cast<QUICFrame *>(buf);
2791   case QUICFrameType::MAX_STREAMS:
2792     new (buf) QUICMaxStreamsFrame(src, len, packet);
2793     return reinterpret_cast<QUICFrame *>(buf);
2794   case QUICFrameType::PING:
2795     new (buf) QUICPingFrame(src, len, packet);
2796     return reinterpret_cast<QUICFrame *>(buf);
2797   case QUICFrameType::DATA_BLOCKED:
2798     new (buf) QUICDataBlockedFrame(src, len, packet);
2799     return reinterpret_cast<QUICFrame *>(buf);
2800   case QUICFrameType::STREAM_DATA_BLOCKED:
2801     new (buf) QUICStreamDataBlockedFrame(src, len, packet);
2802     return reinterpret_cast<QUICFrame *>(buf);
2803   case QUICFrameType::STREAMS_BLOCKED:
2804     new (buf) QUICStreamIdBlockedFrame(src, len, packet);
2805     return reinterpret_cast<QUICFrame *>(buf);
2806   case QUICFrameType::NEW_CONNECTION_ID:
2807     new (buf) QUICNewConnectionIdFrame(src, len, packet);
2808     return reinterpret_cast<QUICFrame *>(buf);
2809   case QUICFrameType::STOP_SENDING:
2810     new (buf) QUICStopSendingFrame(src, len, packet);
2811     return reinterpret_cast<QUICFrame *>(buf);
2812   case QUICFrameType::PATH_CHALLENGE:
2813     new (buf) QUICPathChallengeFrame(src, len, packet);
2814     return reinterpret_cast<QUICFrame *>(buf);
2815   case QUICFrameType::PATH_RESPONSE:
2816     new (buf) QUICPathResponseFrame(src, len, packet);
2817     return reinterpret_cast<QUICFrame *>(buf);
2818   case QUICFrameType::NEW_TOKEN:
2819     new (buf) QUICNewTokenFrame(src, len, packet);
2820     return reinterpret_cast<QUICFrame *>(buf);
2821   case QUICFrameType::RETIRE_CONNECTION_ID:
2822     new (buf) QUICRetireConnectionIdFrame(src, len, packet);
2823     return reinterpret_cast<QUICFrame *>(buf);
2824   default:
2825     // Unknown frame
2826     Debug("quic_frame_factory", "Unknown frame type %x", src[0]);
2827     return nullptr;
2828   }
2829 }
2830 
2831 const QUICFrame &
fast_create(const uint8_t * buf,size_t len,const QUICPacket * packet)2832 QUICFrameFactory::fast_create(const uint8_t *buf, size_t len, const QUICPacket *packet)
2833 {
2834   if (QUICFrame::type(buf) == QUICFrameType::UNKNOWN) {
2835     return this->_unknown_frame;
2836   }
2837 
2838   ptrdiff_t type_index = static_cast<ptrdiff_t>(QUICFrame::type(buf));
2839   QUICFrame *frame     = this->_reusable_frames[type_index];
2840 
2841   if (frame == nullptr) {
2842     frame = QUICFrameFactory::create(this->_buf_for_fast_create + (type_index * QUICFrame::MAX_INSTANCE_SIZE), buf, len, packet);
2843     if (frame != nullptr) {
2844       this->_reusable_frames[static_cast<ptrdiff_t>(QUICFrame::type(buf))] = frame;
2845     }
2846   } else {
2847     frame->parse(buf, len, packet);
2848   }
2849 
2850   return *frame;
2851 }
2852 
2853 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)2854 QUICFrameFactory::create_stream_frame(uint8_t *buf, Ptr<IOBufferBlock> &block, QUICStreamId stream_id, QUICOffset offset, bool last,
2855                                       bool has_offset_field, bool has_length_field, QUICFrameId id, QUICFrameGenerator *owner)
2856 {
2857   Ptr<IOBufferBlock> new_block = make_ptr<IOBufferBlock>(block->clone());
2858   new (buf) QUICStreamFrame(new_block, stream_id, offset, last, has_offset_field, has_length_field, id, owner);
2859   return reinterpret_cast<QUICStreamFrame *>(buf);
2860 }
2861 
2862 QUICCryptoFrame *
create_crypto_frame(uint8_t * buf,Ptr<IOBufferBlock> & block,QUICOffset offset,QUICFrameId id,QUICFrameGenerator * owner)2863 QUICFrameFactory::create_crypto_frame(uint8_t *buf, Ptr<IOBufferBlock> &block, QUICOffset offset, QUICFrameId id,
2864                                       QUICFrameGenerator *owner)
2865 {
2866   Ptr<IOBufferBlock> new_block = make_ptr<IOBufferBlock>(block->clone());
2867   new (buf) QUICCryptoFrame(new_block, offset, id, owner);
2868   return reinterpret_cast<QUICCryptoFrame *>(buf);
2869 }
2870 
2871 QUICAckFrame *
create_ack_frame(uint8_t * buf,QUICPacketNumber largest_acknowledged,uint64_t ack_delay,uint64_t first_ack_block,QUICFrameId id,QUICFrameGenerator * owner)2872 QUICFrameFactory::create_ack_frame(uint8_t *buf, QUICPacketNumber largest_acknowledged, uint64_t ack_delay,
2873                                    uint64_t first_ack_block, QUICFrameId id, QUICFrameGenerator *owner)
2874 {
2875   new (buf) QUICAckFrame(largest_acknowledged, ack_delay, first_ack_block, id, owner);
2876   return reinterpret_cast<QUICAckFrame *>(buf);
2877 }
2878 
2879 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)2880 QUICFrameFactory::create_connection_close_frame(uint8_t *buf, uint16_t error_code, QUICFrameType frame_type,
2881                                                 uint16_t reason_phrase_length, const char *reason_phrase, QUICFrameId id,
2882                                                 QUICFrameGenerator *owner)
2883 {
2884   new (buf) QUICConnectionCloseFrame(error_code, frame_type, reason_phrase_length, reason_phrase, id, owner);
2885   return reinterpret_cast<QUICConnectionCloseFrame *>(buf);
2886 }
2887 
2888 QUICConnectionCloseFrame *
create_connection_close_frame(uint8_t * buf,QUICConnectionError & error,QUICFrameId id,QUICFrameGenerator * owner)2889 QUICFrameFactory::create_connection_close_frame(uint8_t *buf, QUICConnectionError &error, QUICFrameId id, QUICFrameGenerator *owner)
2890 {
2891   ink_assert(error.cls == QUICErrorClass::TRANSPORT);
2892   if (error.msg) {
2893     return QUICFrameFactory::create_connection_close_frame(buf, error.code, error.frame_type(), strlen(error.msg), error.msg, id,
2894                                                            owner);
2895   } else {
2896     return QUICFrameFactory::create_connection_close_frame(buf, error.code, error.frame_type(), 0, nullptr, id, owner);
2897   }
2898 }
2899 
2900 QUICMaxDataFrame *
create_max_data_frame(uint8_t * buf,uint64_t maximum_data,QUICFrameId id,QUICFrameGenerator * owner)2901 QUICFrameFactory::create_max_data_frame(uint8_t *buf, uint64_t maximum_data, QUICFrameId id, QUICFrameGenerator *owner)
2902 {
2903   new (buf) QUICMaxDataFrame(maximum_data, id, owner);
2904   return reinterpret_cast<QUICMaxDataFrame *>(buf);
2905 }
2906 QUICMaxStreamDataFrame *
create_max_stream_data_frame(uint8_t * buf,QUICStreamId stream_id,uint64_t maximum_data,QUICFrameId id,QUICFrameGenerator * owner)2907 QUICFrameFactory::create_max_stream_data_frame(uint8_t *buf, QUICStreamId stream_id, uint64_t maximum_data, QUICFrameId id,
2908                                                QUICFrameGenerator *owner)
2909 {
2910   new (buf) QUICMaxStreamDataFrame(stream_id, maximum_data, id, owner);
2911   return reinterpret_cast<QUICMaxStreamDataFrame *>(buf);
2912 }
2913 
2914 QUICMaxStreamsFrame *
create_max_streams_frame(uint8_t * buf,QUICStreamId maximum_streams,QUICFrameId id,QUICFrameGenerator * owner)2915 QUICFrameFactory::create_max_streams_frame(uint8_t *buf, QUICStreamId maximum_streams, QUICFrameId id, QUICFrameGenerator *owner)
2916 {
2917   new (buf) QUICMaxStreamsFrame(maximum_streams, id, owner);
2918   return reinterpret_cast<QUICMaxStreamsFrame *>(buf);
2919 }
2920 
2921 QUICPingFrame *
create_ping_frame(uint8_t * buf,QUICFrameId id,QUICFrameGenerator * owner)2922 QUICFrameFactory::create_ping_frame(uint8_t *buf, QUICFrameId id, QUICFrameGenerator *owner)
2923 {
2924   new (buf) QUICPingFrame(id, owner);
2925   return reinterpret_cast<QUICPingFrame *>(buf);
2926 }
2927 
2928 QUICPaddingFrame *
create_padding_frame(uint8_t * buf,size_t size,QUICFrameId id,QUICFrameGenerator * owner)2929 QUICFrameFactory::create_padding_frame(uint8_t *buf, size_t size, QUICFrameId id, QUICFrameGenerator *owner)
2930 {
2931   new (buf) QUICPaddingFrame(size);
2932   return reinterpret_cast<QUICPaddingFrame *>(buf);
2933 }
2934 
2935 QUICPathChallengeFrame *
create_path_challenge_frame(uint8_t * buf,const uint8_t * data,QUICFrameId id,QUICFrameGenerator * owner)2936 QUICFrameFactory::create_path_challenge_frame(uint8_t *buf, const uint8_t *data, QUICFrameId id, QUICFrameGenerator *owner)
2937 {
2938   ats_unique_buf challenge_data = ats_unique_malloc(QUICPathChallengeFrame::DATA_LEN);
2939   memcpy(challenge_data.get(), data, QUICPathChallengeFrame::DATA_LEN);
2940 
2941   new (buf) QUICPathChallengeFrame(std::move(challenge_data), id, owner);
2942   return reinterpret_cast<QUICPathChallengeFrame *>(buf);
2943 }
2944 
2945 QUICPathResponseFrame *
create_path_response_frame(uint8_t * buf,const uint8_t * data,QUICFrameId id,QUICFrameGenerator * owner)2946 QUICFrameFactory::create_path_response_frame(uint8_t *buf, const uint8_t *data, QUICFrameId id, QUICFrameGenerator *owner)
2947 {
2948   ats_unique_buf response_data = ats_unique_malloc(QUICPathResponseFrame::DATA_LEN);
2949   memcpy(response_data.get(), data, QUICPathResponseFrame::DATA_LEN);
2950 
2951   new (buf) QUICPathResponseFrame(std::move(response_data), id, owner);
2952   return reinterpret_cast<QUICPathResponseFrame *>(buf);
2953 }
2954 
2955 QUICDataBlockedFrame *
create_data_blocked_frame(uint8_t * buf,QUICOffset offset,QUICFrameId id,QUICFrameGenerator * owner)2956 QUICFrameFactory::create_data_blocked_frame(uint8_t *buf, QUICOffset offset, QUICFrameId id, QUICFrameGenerator *owner)
2957 {
2958   new (buf) QUICDataBlockedFrame(offset, id, owner);
2959   return reinterpret_cast<QUICDataBlockedFrame *>(buf);
2960 }
2961 
2962 QUICStreamDataBlockedFrame *
create_stream_data_blocked_frame(uint8_t * buf,QUICStreamId stream_id,QUICOffset offset,QUICFrameId id,QUICFrameGenerator * owner)2963 QUICFrameFactory::create_stream_data_blocked_frame(uint8_t *buf, QUICStreamId stream_id, QUICOffset offset, QUICFrameId id,
2964                                                    QUICFrameGenerator *owner)
2965 {
2966   new (buf) QUICStreamDataBlockedFrame(stream_id, offset, id, owner);
2967   return reinterpret_cast<QUICStreamDataBlockedFrame *>(buf);
2968 }
2969 
2970 QUICStreamIdBlockedFrame *
create_stream_id_blocked_frame(uint8_t * buf,QUICStreamId stream_id,QUICFrameId id,QUICFrameGenerator * owner)2971 QUICFrameFactory::create_stream_id_blocked_frame(uint8_t *buf, QUICStreamId stream_id, QUICFrameId id, QUICFrameGenerator *owner)
2972 {
2973   new (buf) QUICStreamIdBlockedFrame(stream_id, id, owner);
2974   return reinterpret_cast<QUICStreamIdBlockedFrame *>(buf);
2975 }
2976 
2977 QUICRstStreamFrame *
create_rst_stream_frame(uint8_t * buf,QUICStreamId stream_id,QUICAppErrorCode error_code,QUICOffset final_offset,QUICFrameId id,QUICFrameGenerator * owner)2978 QUICFrameFactory::create_rst_stream_frame(uint8_t *buf, QUICStreamId stream_id, QUICAppErrorCode error_code,
2979                                           QUICOffset final_offset, QUICFrameId id, QUICFrameGenerator *owner)
2980 {
2981   new (buf) QUICRstStreamFrame(stream_id, error_code, final_offset, id, owner);
2982   return reinterpret_cast<QUICRstStreamFrame *>(buf);
2983 }
2984 
2985 QUICRstStreamFrame *
create_rst_stream_frame(uint8_t * buf,QUICStreamError & error,QUICFrameId id,QUICFrameGenerator * owner)2986 QUICFrameFactory::create_rst_stream_frame(uint8_t *buf, QUICStreamError &error, QUICFrameId id, QUICFrameGenerator *owner)
2987 {
2988   return QUICFrameFactory::create_rst_stream_frame(buf, error.stream->id(), error.code, error.stream->final_offset(), id, owner);
2989 }
2990 
2991 QUICStopSendingFrame *
create_stop_sending_frame(uint8_t * buf,QUICStreamId stream_id,QUICAppErrorCode error_code,QUICFrameId id,QUICFrameGenerator * owner)2992 QUICFrameFactory::create_stop_sending_frame(uint8_t *buf, QUICStreamId stream_id, QUICAppErrorCode error_code, QUICFrameId id,
2993                                             QUICFrameGenerator *owner)
2994 {
2995   new (buf) QUICStopSendingFrame(stream_id, error_code, id, owner