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