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 "QUICPacket.h"
25
26 #include <algorithm>
27
28 #include <tscore/ink_assert.h>
29 #include <tscore/Diags.h>
30
31 #include "QUICIntUtil.h"
32 #include "QUICDebugNames.h"
33 #include "QUICRetryIntegrityTag.h"
34
35 using namespace std::literals;
36 static constexpr uint64_t aead_tag_len = 16;
37 static constexpr int LONG_HDR_OFFSET_CONNECTION_ID = 6;
38 static constexpr int LONG_HDR_OFFSET_VERSION = 1;
39
40 #define QUICDebug(dcid, scid, fmt, ...) \
41 Debug(tag.data(), "[%08" PRIx32 "-%08" PRIx32 "] " fmt, dcid.h32(), scid.h32(), ##__VA_ARGS__);
42
43 //
44 // QUICPacket
45 //
QUICPacket()46 QUICPacket::QUICPacket() {}
47
QUICPacket(bool ack_eliciting,bool probing)48 QUICPacket::QUICPacket(bool ack_eliciting, bool probing) : _is_ack_eliciting(ack_eliciting), _is_probing_packet(probing) {}
49
~QUICPacket()50 QUICPacket::~QUICPacket() {}
51
52 QUICKeyPhase
key_phase() const53 QUICPacket::key_phase() const
54 {
55 ink_assert(!"This function should not be called");
56 return QUICKeyPhase::INITIAL;
57 }
58
59 bool
is_ack_eliciting() const60 QUICPacket::is_ack_eliciting() const
61 {
62 return this->_is_ack_eliciting;
63 }
64
65 bool
is_probing_packet() const66 QUICPacket::is_probing_packet() const
67 {
68 return this->_is_probing_packet;
69 }
70
71 uint16_t
header_size() const72 QUICPacket::header_size() const
73 {
74 uint16_t size = 0;
75
76 for (auto b = this->header_block(); b; b = b->next) {
77 size += b->size();
78 }
79
80 return size;
81 }
82
83 uint16_t
payload_length() const84 QUICPacket::payload_length() const
85 {
86 uint16_t size = 0;
87
88 for (auto b = this->payload_block(); b; b = b->next) {
89 size += b->size();
90 }
91
92 return size;
93 }
94
95 uint16_t
size() const96 QUICPacket::size() const
97 {
98 return this->header_size() + this->payload_length();
99 }
100
101 void
store(uint8_t * buf,size_t * len) const102 QUICPacket::store(uint8_t *buf, size_t *len) const
103 {
104 size_t written = 0;
105 Ptr<IOBufferBlock> block;
106
107 block = this->header_block();
108 while (block) {
109 memcpy(buf + written, block->start(), block->size());
110 written += block->size();
111 block = block->next;
112 }
113
114 block = this->payload_block();
115 while (block) {
116 memcpy(buf + written, block->start(), block->size());
117 written += block->size();
118 block = block->next;
119 }
120
121 *len = written;
122 }
123
124 uint8_t
calc_packet_number_len(QUICPacketNumber num,QUICPacketNumber base)125 QUICPacket::calc_packet_number_len(QUICPacketNumber num, QUICPacketNumber base)
126 {
127 uint64_t d = (num - base) * 2;
128 uint8_t len = 0;
129
130 if (d > 0xFFFFFF) {
131 len = 4;
132 } else if (d > 0xFFFF) {
133 len = 3;
134 } else if (d > 0xFF) {
135 len = 2;
136 } else {
137 len = 1;
138 }
139
140 return len;
141 }
142
143 bool
encode_packet_number(QUICPacketNumber & dst,QUICPacketNumber src,size_t len)144 QUICPacket::encode_packet_number(QUICPacketNumber &dst, QUICPacketNumber src, size_t len)
145 {
146 uint64_t mask = 0;
147 switch (len) {
148 case 1:
149 mask = 0xFF;
150 break;
151 case 2:
152 mask = 0xFFFF;
153 break;
154 case 3:
155 mask = 0xFFFFFF;
156 break;
157 case 4:
158 mask = 0xFFFFFFFF;
159 break;
160 default:
161 ink_assert(!"len must be 1, 2, or 4");
162 return false;
163 }
164 dst = src & mask;
165
166 return true;
167 }
168
169 bool
decode_packet_number(QUICPacketNumber & dst,QUICPacketNumber src,size_t len,QUICPacketNumber largest_acked)170 QUICPacket::decode_packet_number(QUICPacketNumber &dst, QUICPacketNumber src, size_t len, QUICPacketNumber largest_acked)
171 {
172 ink_assert(len == 1 || len == 2 || len == 3 || len == 4);
173
174 uint64_t maximum_diff = 0;
175 switch (len) {
176 case 1:
177 maximum_diff = 0x100;
178 break;
179 case 2:
180 maximum_diff = 0x10000;
181 break;
182 case 3:
183 maximum_diff = 0x1000000;
184 break;
185 case 4:
186 maximum_diff = 0x100000000;
187 break;
188 default:
189 ink_assert(!"len must be 1, 2, 3 or 4");
190 }
191 QUICPacketNumber base = largest_acked & (~(maximum_diff - 1));
192 QUICPacketNumber candidate1 = base + src;
193 QUICPacketNumber candidate2 = base + src + maximum_diff;
194 QUICPacketNumber expected = largest_acked + 1;
195
196 if (((candidate1 > expected) ? (candidate1 - expected) : (expected - candidate1)) <
197 ((candidate2 > expected) ? (candidate2 - expected) : (expected - candidate2))) {
198 dst = candidate1;
199 } else {
200 dst = candidate2;
201 }
202
203 return true;
204 }
205
206 //
207 // QUICPacketR
208 //
209
QUICPacketR(UDPConnection * udp_con,IpEndpoint from,IpEndpoint to)210 QUICPacketR::QUICPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to) : _udp_con(udp_con), _from(from), _to(to) {}
211
212 UDPConnection *
udp_con() const213 QUICPacketR::udp_con() const
214 {
215 return this->_udp_con;
216 }
217
218 const IpEndpoint &
from() const219 QUICPacketR::from() const
220 {
221 return this->_from;
222 }
223
224 const IpEndpoint &
to() const225 QUICPacketR::to() const
226 {
227 return this->_to;
228 }
229
230 bool
type(QUICPacketType & type,const uint8_t * packet,size_t packet_len)231 QUICPacketR::type(QUICPacketType &type, const uint8_t *packet, size_t packet_len)
232 {
233 if (packet_len < 1) {
234 return false;
235 }
236
237 if (QUICInvariants::is_long_header(packet)) {
238 return QUICLongHeaderPacketR::type(type, packet, packet_len);
239 } else {
240 type = QUICPacketType::PROTECTED;
241 return true;
242 }
243 }
244
245 bool
read_essential_info(Ptr<IOBufferBlock> block,QUICPacketType & type,QUICVersion & version,QUICConnectionId & dcid,QUICConnectionId & scid,QUICPacketNumber & packet_number,QUICPacketNumber base_packet_number,QUICKeyPhase & key_phase)246 QUICPacketR::read_essential_info(Ptr<IOBufferBlock> block, QUICPacketType &type, QUICVersion &version, QUICConnectionId &dcid,
247 QUICConnectionId &scid, QUICPacketNumber &packet_number, QUICPacketNumber base_packet_number,
248 QUICKeyPhase &key_phase)
249 {
250 uint8_t tmp[47 + 64];
251 IOBufferReader reader;
252 reader.block = block;
253 int64_t len = std::min(static_cast<int64_t>(sizeof(tmp)), reader.read_avail());
254
255 if (len < 10) {
256 return false;
257 }
258
259 reader.memcpy(tmp, 1, 0);
260 if (QUICInvariants::is_long_header(tmp)) {
261 reader.memcpy(tmp, len, 0);
262 type = static_cast<QUICPacketType>((0x30 & tmp[0]) >> 4);
263 QUICInvariants::version(version, tmp, len);
264 if (version == 0x00) {
265 type = QUICPacketType::VERSION_NEGOTIATION;
266 }
267 if (!QUICInvariants::dcid(dcid, tmp, len) || !QUICInvariants::scid(scid, tmp, len)) {
268 return false;
269 }
270 if (type != QUICPacketType::RETRY) {
271 int packet_number_len = QUICTypeUtil::read_QUICPacketNumberLen(tmp);
272 size_t length_offset = 7 + dcid.length() + scid.length();
273 if (length_offset >= static_cast<uint64_t>(len)) {
274 return false;
275 }
276 uint64_t value;
277 size_t field_len;
278 QUICVariableInt::decode(value, field_len, tmp + length_offset);
279 switch (type) {
280 case QUICPacketType::INITIAL:
281 length_offset += field_len + value;
282 if (length_offset >= static_cast<uint64_t>(len)) {
283 return false;
284 }
285 QUICVariableInt::decode(value, field_len, tmp + length_offset);
286 if (length_offset + field_len >= static_cast<uint64_t>(len)) {
287 return false;
288 }
289 if (length_offset + field_len + packet_number_len > static_cast<uint64_t>(len)) {
290 return false;
291 }
292 packet_number = QUICTypeUtil::read_QUICPacketNumber(tmp + length_offset + field_len, packet_number_len);
293 key_phase = QUICKeyPhase::INITIAL;
294 break;
295 case QUICPacketType::ZERO_RTT_PROTECTED:
296 if (length_offset + field_len + packet_number_len >= static_cast<uint64_t>(len)) {
297 return false;
298 }
299 packet_number = QUICTypeUtil::read_QUICPacketNumber(tmp + length_offset + field_len, packet_number_len);
300 key_phase = QUICKeyPhase::ZERO_RTT;
301 break;
302 case QUICPacketType::HANDSHAKE:
303 if (length_offset + field_len + packet_number_len >= static_cast<uint64_t>(len)) {
304 return false;
305 }
306 packet_number = QUICTypeUtil::read_QUICPacketNumber(tmp + length_offset + field_len, packet_number_len);
307 key_phase = QUICKeyPhase::INITIAL;
308 break;
309 case QUICPacketType::VERSION_NEGOTIATION:
310 break;
311 default:
312 break;
313 }
314 } else {
315 packet_number = 0;
316 }
317 } else {
318 len = std::min(static_cast<int64_t>(25), len);
319 reader.memcpy(tmp, len, 0);
320 type = QUICPacketType::PROTECTED;
321 QUICInvariants::dcid(dcid, tmp, len);
322 int packet_number_len = QUICTypeUtil::read_QUICPacketNumberLen(tmp);
323 if (tmp[0] & 0x04) {
324 key_phase = QUICKeyPhase::PHASE_1;
325 } else {
326 key_phase = QUICKeyPhase::PHASE_0;
327 }
328 packet_number = QUICTypeUtil::read_QUICPacketNumber(tmp + 1 + dcid.length(), packet_number_len);
329 }
330 return true;
331 }
332
333 //
334 // QUICLongHeaderPacket
335 //
QUICLongHeaderPacket(QUICVersion version,const QUICConnectionId & dcid,const QUICConnectionId & scid,bool ack_eliciting,bool probing,bool crypto)336 QUICLongHeaderPacket::QUICLongHeaderPacket(QUICVersion version, const QUICConnectionId &dcid, const QUICConnectionId &scid,
337 bool ack_eliciting, bool probing, bool crypto)
338 : QUICPacket(ack_eliciting, probing), _version(version), _dcid(dcid), _scid(scid), _is_crypto_packet(crypto)
339 {
340 }
341
342 QUICConnectionId
destination_cid() const343 QUICLongHeaderPacket::destination_cid() const
344 {
345 return this->_dcid;
346 }
347
348 QUICConnectionId
source_cid() const349 QUICLongHeaderPacket::source_cid() const
350 {
351 return this->_scid;
352 }
353
354 uint16_t
payload_length() const355 QUICLongHeaderPacket::payload_length() const
356 {
357 return this->_payload_length;
358 }
359
360 QUICVersion
version() const361 QUICLongHeaderPacket::version() const
362 {
363 return this->_version;
364 }
365
366 size_t
_write_common_header(uint8_t * buf) const367 QUICLongHeaderPacket::_write_common_header(uint8_t *buf) const
368 {
369 size_t n;
370 size_t len = 0;
371
372 buf[0] = 0xC0;
373 buf[0] += static_cast<uint8_t>(this->type()) << 4;
374 len += 1;
375
376 QUICTypeUtil::write_QUICVersion(this->_version, buf + len, &n);
377 len += n;
378
379 // DICD
380 if (this->_dcid != QUICConnectionId::ZERO()) {
381 // Len
382 buf[len] = this->_dcid.length();
383 len += 1;
384
385 // ID
386 QUICTypeUtil::write_QUICConnectionId(this->_dcid, buf + len, &n);
387 len += n;
388 } else {
389 buf[len] = 0;
390 len += 1;
391 }
392
393 // SCID
394 if (this->_scid != QUICConnectionId::ZERO()) {
395 // Len
396 buf[len] = this->_scid.length();
397 len += 1;
398
399 // ID
400 QUICTypeUtil::write_QUICConnectionId(this->_scid, buf + len, &n);
401 len += n;
402 } else {
403 buf[len] = 0;
404 len += 1;
405 }
406
407 return len;
408 }
409
410 bool
is_crypto_packet() const411 QUICLongHeaderPacket::is_crypto_packet() const
412 {
413 return this->_is_crypto_packet;
414 }
415
416 //
417 // QUICLongHeaderPacketR
418 //
QUICLongHeaderPacketR(UDPConnection * udp_con,IpEndpoint from,IpEndpoint to,Ptr<IOBufferBlock> blocks)419 QUICLongHeaderPacketR::QUICLongHeaderPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks)
420 : QUICPacketR(udp_con, from, to)
421 {
422 IOBufferReader reader;
423 uint8_t data[47];
424
425 reader.block = blocks;
426 int64_t data_len = reader.read(data, sizeof(data));
427
428 QUICLongHeaderPacketR::version(this->_version, data, data_len);
429 }
430
431 QUICVersion
version() const432 QUICLongHeaderPacketR::version() const
433 {
434 return this->_version;
435 }
436
437 QUICConnectionId
source_cid() const438 QUICLongHeaderPacketR::source_cid() const
439 {
440 return this->_scid;
441 }
442
443 QUICConnectionId
destination_cid() const444 QUICLongHeaderPacketR::destination_cid() const
445 {
446 return this->_dcid;
447 }
448
449 bool
type(QUICPacketType & type,const uint8_t * packet,size_t packet_len)450 QUICLongHeaderPacketR::type(QUICPacketType &type, const uint8_t *packet, size_t packet_len)
451 {
452 if (packet_len < 1) {
453 return false;
454 }
455
456 QUICVersion version;
457 if (QUICLongHeaderPacketR::version(version, packet, packet_len) && version == 0x00) {
458 type = QUICPacketType::VERSION_NEGOTIATION;
459 } else {
460 uint8_t raw_type = (packet[0] & 0x30) >> 4;
461 type = static_cast<QUICPacketType>(raw_type);
462 }
463 return true;
464 }
465
466 bool
version(QUICVersion & version,const uint8_t * packet,size_t packet_len)467 QUICLongHeaderPacketR::version(QUICVersion &version, const uint8_t *packet, size_t packet_len)
468 {
469 if (packet_len < 5) {
470 return false;
471 }
472
473 version = QUICTypeUtil::read_QUICVersion(packet + LONG_HDR_OFFSET_VERSION);
474 return true;
475 }
476
477 bool
key_phase(QUICKeyPhase & phase,const uint8_t * packet,size_t packet_len)478 QUICLongHeaderPacketR::key_phase(QUICKeyPhase &phase, const uint8_t *packet, size_t packet_len)
479 {
480 QUICPacketType type = QUICPacketType::UNINITIALIZED;
481 QUICLongHeaderPacketR::type(type, packet, packet_len);
482 phase = QUICTypeUtil::key_phase(type);
483 return true;
484 }
485
486 bool
length(size_t & length,uint8_t & length_field_len,size_t & length_field_offset,const uint8_t * packet,size_t packet_len)487 QUICLongHeaderPacketR::length(size_t &length, uint8_t &length_field_len, size_t &length_field_offset, const uint8_t *packet,
488 size_t packet_len)
489 {
490 // FIXME This is not great because each packet types have different formats.
491 // We should remove this function and have length() on each packet type classes instead.
492
493 uint8_t dcil;
494 if (!QUICInvariants::dcil(dcil, packet, packet_len)) {
495 return false;
496 }
497
498 uint8_t scil;
499 if (!QUICInvariants::scil(scil, packet, packet_len)) {
500 return false;
501 }
502
503 length_field_offset = LONG_HDR_OFFSET_CONNECTION_ID + dcil + 1 + scil;
504
505 QUICPacketType type = QUICPacketType::UNINITIALIZED;
506 QUICLongHeaderPacketR::type(type, packet, packet_len);
507 if (type == QUICPacketType::INITIAL) {
508 // Token Length (i) + Token (*) (for INITIAL packet)
509 size_t token_length = 0;
510 uint8_t token_length_field_len = 0;
511 size_t token_length_field_offset = 0;
512 if (!QUICInitialPacketR::token_length(token_length, token_length_field_len, token_length_field_offset, packet, packet_len)) {
513 return false;
514 }
515 length_field_offset += token_length_field_len + token_length;
516 }
517
518 // Length (i)
519 if (length_field_offset >= packet_len) {
520 return false;
521 }
522
523 length_field_len = QUICVariableInt::size(packet + length_field_offset);
524 length = QUICIntUtil::read_QUICVariableInt(packet + length_field_offset, packet_len - length_field_offset);
525
526 return true;
527 }
528
529 bool
packet_length(size_t & packet_len,const uint8_t * buf,size_t buf_len)530 QUICLongHeaderPacketR::packet_length(size_t &packet_len, const uint8_t *buf, size_t buf_len)
531 {
532 size_t length;
533 uint8_t length_field_len;
534 size_t length_field_offset;
535
536 if (!QUICLongHeaderPacketR::length(length, length_field_len, length_field_offset, buf, buf_len)) {
537 return false;
538 }
539 packet_len = length + length_field_offset + length_field_len;
540
541 if (packet_len > buf_len) {
542 return false;
543 }
544
545 return true;
546 }
547
548 bool
packet_number_offset(size_t & pn_offset,const uint8_t * packet,size_t packet_len)549 QUICLongHeaderPacketR::packet_number_offset(size_t &pn_offset, const uint8_t *packet, size_t packet_len)
550 {
551 size_t dummy;
552 uint8_t length_field_len;
553 size_t length_field_offset;
554
555 if (!QUICLongHeaderPacketR::length(dummy, length_field_len, length_field_offset, packet, packet_len)) {
556 return false;
557 }
558 pn_offset = length_field_offset + length_field_len;
559
560 if (pn_offset >= packet_len) {
561 return false;
562 }
563
564 return true;
565 }
566
567 //
568 // QUICShortHeaderPacket
569 //
QUICShortHeaderPacket(const QUICConnectionId & dcid,QUICPacketNumber packet_number,QUICPacketNumber base_packet_number,QUICKeyPhase key_phase,bool ack_eliciting,bool probing)570 QUICShortHeaderPacket::QUICShortHeaderPacket(const QUICConnectionId &dcid, QUICPacketNumber packet_number,
571 QUICPacketNumber base_packet_number, QUICKeyPhase key_phase, bool ack_eliciting,
572 bool probing)
573 : QUICPacket(ack_eliciting, probing), _dcid(dcid), _packet_number(packet_number), _key_phase(key_phase)
574 {
575 this->_packet_number_len = QUICPacket::calc_packet_number_len(packet_number, base_packet_number);
576 }
577
578 QUICPacketType
type() const579 QUICShortHeaderPacket::type() const
580 {
581 return QUICPacketType::PROTECTED;
582 }
583
584 QUICKeyPhase
key_phase() const585 QUICShortHeaderPacket::key_phase() const
586 {
587 return this->_key_phase;
588 }
589
590 QUICConnectionId
destination_cid() const591 QUICShortHeaderPacket::destination_cid() const
592 {
593 return this->_dcid;
594 }
595
596 QUICPacketNumber
packet_number() const597 QUICShortHeaderPacket::packet_number() const
598 {
599 return this->_packet_number;
600 }
601
602 uint16_t
payload_length() const603 QUICShortHeaderPacket::payload_length() const
604 {
605 return this->_payload_length;
606 }
607
608 Ptr<IOBufferBlock>
header_block() const609 QUICShortHeaderPacket::header_block() const
610 {
611 Ptr<IOBufferBlock> block;
612 size_t written_len = 0;
613
614 block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
615 block->alloc(iobuffer_size_to_index(1 + QUICConnectionId::MAX_LENGTH + 4, BUFFER_SIZE_INDEX_32K));
616 uint8_t *buf = reinterpret_cast<uint8_t *>(block->start());
617
618 size_t n;
619 buf[0] = 0x40;
620
621 // Type
622 buf[0] = 0x40;
623
624 // TODO Spin Bit
625
626 // KeyPhase
627 if (this->_key_phase == QUICKeyPhase::PHASE_1) {
628 buf[0] |= 0x04;
629 }
630
631 written_len += 1;
632
633 // Destination Connection ID
634 if (this->_dcid != QUICConnectionId::ZERO()) {
635 QUICTypeUtil::write_QUICConnectionId(this->_dcid, buf + written_len, &n);
636 written_len += n;
637 }
638
639 // Packet Number
640 QUICPacketNumber dst = 0;
641 size_t dst_len = this->_packet_number_len;
642 QUICPacket::encode_packet_number(dst, this->_packet_number, dst_len);
643 QUICTypeUtil::write_QUICPacketNumber(dst, dst_len, buf + written_len, &n);
644 written_len += n;
645
646 // Packet Number Length
647 QUICTypeUtil::write_QUICPacketNumberLen(n, buf);
648
649 block->fill(written_len);
650
651 return block;
652 }
653
654 Ptr<IOBufferBlock>
payload_block() const655 QUICShortHeaderPacket::payload_block() const
656 {
657 return this->_payload_block;
658 }
659
660 void
attach_payload(Ptr<IOBufferBlock> payload,bool unprotected)661 QUICShortHeaderPacket::attach_payload(Ptr<IOBufferBlock> payload, bool unprotected)
662 {
663 this->_payload_block = payload;
664 this->_payload_length = 0;
665 Ptr<IOBufferBlock> tmp = payload;
666 while (tmp) {
667 this->_payload_length += tmp->size();
668 tmp = tmp->next;
669 }
670 if (unprotected) {
671 this->_payload_length += aead_tag_len;
672 }
673 }
674
675 //
676 // QUICShortHeaderPacketR
677 //
QUICShortHeaderPacketR(UDPConnection * udp_con,IpEndpoint from,IpEndpoint to,Ptr<IOBufferBlock> blocks,QUICPacketNumber base_packet_number)678 QUICShortHeaderPacketR::QUICShortHeaderPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks,
679 QUICPacketNumber base_packet_number)
680 : QUICPacketR(udp_con, from, to)
681 {
682 size_t len = 0;
683 for (auto b = blocks; b; b = b->next) {
684 len += b->size();
685 }
686
687 Ptr<IOBufferBlock> concatenated_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
688 concatenated_block->alloc(iobuffer_size_to_index(len, BUFFER_SIZE_INDEX_32K));
689 concatenated_block->fill(len);
690
691 uint8_t *raw_buf = reinterpret_cast<uint8_t *>(concatenated_block->start());
692
693 size_t copied_len = 0;
694 for (auto b = blocks; b; b = b->next) {
695 memcpy(raw_buf + copied_len, b->start(), b->size());
696 copied_len += b->size();
697 }
698
699 if (raw_buf[0] & 0x04) {
700 this->_key_phase = QUICKeyPhase::PHASE_1;
701 } else {
702 this->_key_phase = QUICKeyPhase::PHASE_0;
703 }
704
705 QUICInvariants::dcid(this->_dcid, raw_buf, len);
706
707 int offset = 1 + this->_dcid.length();
708 this->_packet_number_len = QUICTypeUtil::read_QUICPacketNumberLen(raw_buf);
709 QUICPacketNumber src = QUICTypeUtil::read_QUICPacketNumber(raw_buf + offset, this->_packet_number_len);
710 QUICPacket::decode_packet_number(this->_packet_number, src, this->_packet_number_len, base_packet_number);
711 offset += this->_packet_number_len;
712
713 this->_header_block = concatenated_block->clone();
714 this->_header_block->_end = this->_header_block->_start + offset;
715 this->_header_block->next = nullptr;
716 this->_payload_block = concatenated_block->clone();
717 this->_payload_block->_start = this->_payload_block->_start + offset;
718 }
719
720 QUICPacketType
type() const721 QUICShortHeaderPacketR::type() const
722 {
723 return QUICPacketType::PROTECTED;
724 }
725
726 QUICKeyPhase
key_phase() const727 QUICShortHeaderPacketR::key_phase() const
728 {
729 return this->_key_phase;
730 }
731
732 QUICPacketNumber
packet_number() const733 QUICShortHeaderPacketR::packet_number() const
734 {
735 return this->_packet_number;
736 }
737
738 QUICConnectionId
destination_cid() const739 QUICShortHeaderPacketR::destination_cid() const
740 {
741 return this->_dcid;
742 }
743
744 Ptr<IOBufferBlock>
header_block() const745 QUICShortHeaderPacketR::header_block() const
746 {
747 return this->_header_block;
748 }
749
750 Ptr<IOBufferBlock>
payload_block() const751 QUICShortHeaderPacketR::payload_block() const
752 {
753 return this->_payload_block;
754 }
755
756 void
attach_payload(Ptr<IOBufferBlock> payload,bool unprotected)757 QUICShortHeaderPacketR::attach_payload(Ptr<IOBufferBlock> payload, bool unprotected)
758 {
759 this->_payload_block = payload;
760 }
761
762 bool
packet_number_offset(size_t & pn_offset,const uint8_t * packet,size_t packet_len,int dcil)763 QUICShortHeaderPacketR::packet_number_offset(size_t &pn_offset, const uint8_t *packet, size_t packet_len, int dcil)
764 {
765 pn_offset = 1 + dcil;
766 return true;
767 }
768
769 //
770 // QUICStatelessResetPacket
771 //
QUICStatelessResetPacket(QUICStatelessResetToken token,size_t maximum_size)772 QUICStatelessResetPacket::QUICStatelessResetPacket(QUICStatelessResetToken token, size_t maximum_size)
773 : QUICPacket(), _token(token), _maximum_size(maximum_size)
774 {
775 }
776
777 QUICPacketType
type() const778 QUICStatelessResetPacket::type() const
779 {
780 return QUICPacketType::STATELESS_RESET;
781 }
782
783 QUICConnectionId
destination_cid() const784 QUICStatelessResetPacket::destination_cid() const
785 {
786 ink_assert(!"You should not need DCID of Stateless Reset Packet");
787 return QUICConnectionId::ZERO();
788 }
789
790 Ptr<IOBufferBlock>
header_block() const791 QUICStatelessResetPacket::header_block() const
792 {
793 // Required shortest length is 38 bits however less than 41 bytes in total indicates this is stateless reset.
794 constexpr uint8_t MIN_UNPREDICTABLE_FIELD_LEN = 5 + 20;
795
796 std::random_device rnd;
797
798 Ptr<IOBufferBlock> block;
799 size_t written_len = 0;
800
801 size_t random_extra_length = rnd() & 0x07; // Extra 0 to 7 bytes
802
803 if (MIN_UNPREDICTABLE_FIELD_LEN + random_extra_length > this->_maximum_size) {
804 return block;
805 }
806
807 block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
808 block->alloc(iobuffer_size_to_index(MIN_UNPREDICTABLE_FIELD_LEN + random_extra_length, BUFFER_SIZE_INDEX_32K));
809 uint8_t *buf = reinterpret_cast<uint8_t *>(block->start());
810
811 // Generate random octets
812 for (int i = 0; i < MIN_UNPREDICTABLE_FIELD_LEN; ++i) {
813 buf[i] = static_cast<uint8_t>(rnd() & 0xFF);
814 }
815 buf[0] = (buf[0] | 0x40) & 0x7f;
816 written_len += MIN_UNPREDICTABLE_FIELD_LEN;
817
818 block->fill(written_len);
819
820 return block;
821 }
822
823 Ptr<IOBufferBlock>
payload_block() const824 QUICStatelessResetPacket::payload_block() const
825 {
826 Ptr<IOBufferBlock> block;
827 size_t written_len = 0;
828
829 block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
830 block->alloc(iobuffer_size_to_index(QUICStatelessResetToken::LEN, BUFFER_SIZE_INDEX_32K));
831 uint8_t *buf = reinterpret_cast<uint8_t *>(block->start());
832
833 memcpy(buf, this->_token.buf(), QUICStatelessResetToken::LEN);
834 written_len += QUICStatelessResetToken::LEN;
835
836 block->fill(written_len);
837
838 return block;
839 }
840
841 QUICPacketNumber
packet_number() const842 QUICStatelessResetPacket::packet_number() const
843 {
844 ink_assert(!"You should not need packet number of Stateless Reset Packet");
845 return 0;
846 }
847
848 QUICStatelessResetToken
token() const849 QUICStatelessResetPacket::token() const
850 {
851 return this->_token;
852 }
853
854 //
855 // QUICStatelessResetPacketR
856 //
QUICStatelessResetPacketR(UDPConnection * udp_con,IpEndpoint from,IpEndpoint to,Ptr<IOBufferBlock> blocks)857 QUICStatelessResetPacketR::QUICStatelessResetPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to,
858 Ptr<IOBufferBlock> blocks)
859 : QUICPacketR(udp_con, from, to)
860 {
861 }
862
863 QUICPacketType
type() const864 QUICStatelessResetPacketR::type() const
865 {
866 return QUICPacketType::STATELESS_RESET;
867 }
868
869 QUICPacketNumber
packet_number() const870 QUICStatelessResetPacketR::packet_number() const
871 {
872 ink_assert(!"You should not need packet number of Stateless Reset Packet");
873 return 0;
874 }
875
876 QUICConnectionId
destination_cid() const877 QUICStatelessResetPacketR::destination_cid() const
878 {
879 ink_assert(!"You should not need DCID of Stateless Reset Packet");
880 return QUICConnectionId::ZERO();
881 }
882
883 //
884 // QUICVersionNegotiationPacket
885 //
886
QUICVersionNegotiationPacket(const QUICConnectionId & dcid,const QUICConnectionId & scid,const QUICVersion versions[],int nversions,QUICVersion version_in_initial)887 QUICVersionNegotiationPacket::QUICVersionNegotiationPacket(const QUICConnectionId &dcid, const QUICConnectionId &scid,
888 const QUICVersion versions[], int nversions,
889 QUICVersion version_in_initial)
890 : QUICLongHeaderPacket(0, dcid, scid, false, false, false),
891 _versions(versions),
892 _nversions(nversions),
893 _version_in_initial(version_in_initial)
894 {
895 }
896
897 QUICPacketType
type() const898 QUICVersionNegotiationPacket::type() const
899 {
900 return QUICPacketType::VERSION_NEGOTIATION;
901 }
902
903 QUICVersion
version() const904 QUICVersionNegotiationPacket::version() const
905 {
906 return 0;
907 }
908
909 QUICPacketNumber
packet_number() const910 QUICVersionNegotiationPacket::packet_number() const
911 {
912 ink_assert(!"You should not need packet number of Version Negotiation Packet");
913 return 0;
914 }
915
916 uint16_t
payload_length() const917 QUICVersionNegotiationPacket::payload_length() const
918 {
919 uint16_t size = 0;
920
921 for (auto b = this->payload_block(); b; b = b->next) {
922 size += b->size();
923 }
924
925 return size;
926 }
927
928 Ptr<IOBufferBlock>
header_block() const929 QUICVersionNegotiationPacket::header_block() const
930 {
931 Ptr<IOBufferBlock> block;
932 size_t written_len = 0;
933
934 block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
935 block->alloc(iobuffer_size_to_index(2048, BUFFER_SIZE_INDEX_32K));
936 uint8_t *buf = reinterpret_cast<uint8_t *>(block->start());
937
938 // Common Long Header
939 written_len += this->_write_common_header(buf + written_len);
940
941 // Overwrite the first byte
942 buf[0] = 0x80 | rand();
943
944 block->fill(written_len);
945
946 return block;
947 }
948
949 Ptr<IOBufferBlock>
payload_block() const950 QUICVersionNegotiationPacket::payload_block() const
951 {
952 Ptr<IOBufferBlock> block;
953 uint8_t *buf;
954 size_t written_len = 0;
955 size_t n;
956
957 block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
958 block->alloc(iobuffer_size_to_index(sizeof(QUICVersion) * (this->_nversions + 1), BUFFER_SIZE_INDEX_32K));
959 buf = reinterpret_cast<uint8_t *>(block->start());
960
961 for (auto i = 0; i < this->_nversions; ++i) {
962 QUICTypeUtil::write_QUICVersion(*(this->_versions + i), buf + written_len, &n);
963 written_len += n;
964 }
965
966 // [draft-18] 6.3. Using Reserved Versions
967 // To help ensure this, a server SHOULD include a reserved version (see Section 15) while generating a
968 // Version Negotiation packet.
969 QUICVersion exersice_version = QUIC_EXERCISE_VERSION1;
970 if (this->_version_in_initial == QUIC_EXERCISE_VERSION1) {
971 exersice_version = QUIC_EXERCISE_VERSION2;
972 }
973 QUICTypeUtil::write_QUICVersion(exersice_version, buf + written_len, &n);
974 written_len += n;
975
976 block->fill(written_len);
977
978 return block;
979 }
980
981 const QUICVersion *
versions() const982 QUICVersionNegotiationPacket::versions() const
983 {
984 return this->_versions;
985 }
986
987 int
nversions() const988 QUICVersionNegotiationPacket::nversions() const
989 {
990 return this->_nversions;
991 }
992
993 //
994 // QUICVersionNegotiationPacketR
995 //
QUICVersionNegotiationPacketR(UDPConnection * udp_con,IpEndpoint from,IpEndpoint to,Ptr<IOBufferBlock> blocks)996 QUICVersionNegotiationPacketR::QUICVersionNegotiationPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to,
997 Ptr<IOBufferBlock> blocks)
998 : QUICLongHeaderPacketR(udp_con, from, to, blocks)
999 {
1000 size_t len = 0;
1001 for (auto b = blocks; b; b = b->next) {
1002 len += b->size();
1003 }
1004
1005 Ptr<IOBufferBlock> concatenated_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1006 concatenated_block->alloc(iobuffer_size_to_index(len, BUFFER_SIZE_INDEX_32K));
1007 concatenated_block->fill(len);
1008
1009 uint8_t *raw_buf = reinterpret_cast<uint8_t *>(concatenated_block->start());
1010
1011 size_t copied_len = 0;
1012 for (auto b = blocks; b; b = b->next) {
1013 memcpy(raw_buf + copied_len, b->start(), b->size());
1014 copied_len += b->size();
1015 }
1016
1017 uint8_t dcil = 0;
1018 uint8_t scil = 0;
1019 QUICInvariants::dcil(dcil, raw_buf, len);
1020 QUICInvariants::scil(scil, raw_buf, len);
1021
1022 size_t offset = LONG_HDR_OFFSET_CONNECTION_ID;
1023 this->_dcid = {raw_buf + offset, dcil};
1024 offset += dcil + 1;
1025 this->_scid = {raw_buf + offset, scil};
1026 offset += scil;
1027
1028 this->_versions = raw_buf + offset;
1029 this->_nversions = (len - offset) / sizeof(QUICVersion);
1030
1031 this->_header_block = concatenated_block->clone();
1032 this->_header_block->_end = this->_header_block->_start + offset;
1033 this->_header_block->next = nullptr;
1034 this->_payload_block = concatenated_block->clone();
1035 this->_payload_block->_start = this->_payload_block->_start + offset;
1036 }
1037
1038 QUICPacketType
type() const1039 QUICVersionNegotiationPacketR::type() const
1040 {
1041 return QUICPacketType::VERSION_NEGOTIATION;
1042 }
1043
1044 QUICPacketNumber
packet_number() const1045 QUICVersionNegotiationPacketR::packet_number() const
1046 {
1047 ink_assert(!"You should not need packet number of Version Negotiation Packet");
1048 return 0;
1049 }
1050
1051 QUICConnectionId
destination_cid() const1052 QUICVersionNegotiationPacketR::destination_cid() const
1053 {
1054 return this->_dcid;
1055 }
1056
1057 Ptr<IOBufferBlock>
header_block() const1058 QUICVersionNegotiationPacketR::header_block() const
1059 {
1060 return this->_header_block;
1061 }
1062
1063 Ptr<IOBufferBlock>
payload_block() const1064 QUICVersionNegotiationPacketR::payload_block() const
1065 {
1066 return this->_payload_block;
1067 }
1068
1069 const QUICVersion
supported_version(uint8_t index) const1070 QUICVersionNegotiationPacketR::supported_version(uint8_t index) const
1071 {
1072 return QUICTypeUtil::read_QUICVersion(this->_versions + sizeof(QUICVersion) * index);
1073 }
1074
1075 int
nversions() const1076 QUICVersionNegotiationPacketR::nversions() const
1077 {
1078 return this->_nversions;
1079 }
1080
1081 //
1082 // QUICInitialPacket
1083 //
QUICInitialPacket(QUICVersion version,const QUICConnectionId & dcid,const QUICConnectionId & scid,size_t token_len,ats_unique_buf token,size_t length,QUICPacketNumber packet_number,bool ack_eliciting,bool probing,bool crypto)1084 QUICInitialPacket::QUICInitialPacket(QUICVersion version, const QUICConnectionId &dcid, const QUICConnectionId &scid,
1085 size_t token_len, ats_unique_buf token, size_t length, QUICPacketNumber packet_number,
1086 bool ack_eliciting, bool probing, bool crypto)
1087 : QUICLongHeaderPacket(version, dcid, scid, ack_eliciting, probing, crypto),
1088 _token_len(token_len),
1089 _token(std::move(token)),
1090 _packet_number(packet_number)
1091 {
1092 }
1093
1094 QUICPacketType
type() const1095 QUICInitialPacket::type() const
1096 {
1097 return QUICPacketType::INITIAL;
1098 }
1099
1100 QUICKeyPhase
key_phase() const1101 QUICInitialPacket::key_phase() const
1102 {
1103 return QUICKeyPhase::INITIAL;
1104 }
1105
1106 QUICPacketNumber
packet_number() const1107 QUICInitialPacket::packet_number() const
1108 {
1109 return this->_packet_number;
1110 }
1111
1112 Ptr<IOBufferBlock>
header_block() const1113 QUICInitialPacket::header_block() const
1114 {
1115 Ptr<IOBufferBlock> block;
1116 size_t written_len = 0;
1117 size_t n;
1118
1119 block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1120 block->alloc(iobuffer_size_to_index(2048, BUFFER_SIZE_INDEX_32K));
1121 uint8_t *buf = reinterpret_cast<uint8_t *>(block->start());
1122
1123 // Common Long Header
1124 written_len += this->_write_common_header(buf + written_len);
1125
1126 // Token Length
1127 QUICIntUtil::write_QUICVariableInt(this->_token_len, buf + written_len, &n);
1128 written_len += n;
1129
1130 // Token
1131 memcpy(buf + written_len, this->_token.get(), this->_token_len);
1132 written_len += this->_token_len;
1133
1134 QUICPacketNumber pn = 0;
1135 size_t pn_len = 4;
1136 QUICPacket::encode_packet_number(pn, this->_packet_number, pn_len);
1137
1138 if (pn > 0x7FFFFF) {
1139 pn_len = 4;
1140 } else if (pn > 0x7FFF) {
1141 pn_len = 3;
1142 } else if (pn > 0x7F) {
1143 pn_len = 2;
1144 } else {
1145 pn_len = 1;
1146 }
1147
1148 // PN Len
1149 QUICTypeUtil::write_QUICPacketNumberLen(pn_len, buf);
1150
1151 // Length
1152 QUICIntUtil::write_QUICVariableInt(pn_len + this->_payload_length, buf + written_len, &n);
1153 written_len += n;
1154
1155 // PN Field
1156 QUICTypeUtil::write_QUICPacketNumber(pn, pn_len, buf + written_len, &n);
1157 written_len += n;
1158
1159 block->fill(written_len);
1160
1161 return block;
1162 }
1163
1164 Ptr<IOBufferBlock>
payload_block() const1165 QUICInitialPacket::payload_block() const
1166 {
1167 return this->_payload_block;
1168 }
1169
1170 void
attach_payload(Ptr<IOBufferBlock> payload,bool unprotected)1171 QUICInitialPacket::attach_payload(Ptr<IOBufferBlock> payload, bool unprotected)
1172 {
1173 this->_payload_block = payload;
1174 this->_payload_length = 0;
1175 Ptr<IOBufferBlock> tmp = payload;
1176 while (tmp) {
1177 this->_payload_length += tmp->size();
1178 tmp = tmp->next;
1179 }
1180 if (unprotected) {
1181 this->_payload_length += aead_tag_len;
1182 }
1183 }
1184
1185 //
1186 // QUICInitialPacketR
1187 //
QUICInitialPacketR(UDPConnection * udp_con,IpEndpoint from,IpEndpoint to,Ptr<IOBufferBlock> blocks,QUICPacketNumber base_packet_number)1188 QUICInitialPacketR::QUICInitialPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks,
1189 QUICPacketNumber base_packet_number)
1190 : QUICLongHeaderPacketR(udp_con, from, to, blocks)
1191 {
1192 size_t len = 0;
1193 for (auto b = blocks; b; b = b->next) {
1194 len += b->size();
1195 }
1196
1197 Ptr<IOBufferBlock> concatenated_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1198 concatenated_block->alloc(iobuffer_size_to_index(len, BUFFER_SIZE_INDEX_32K));
1199 concatenated_block->fill(len);
1200
1201 uint8_t *raw_buf = reinterpret_cast<uint8_t *>(concatenated_block->start());
1202
1203 size_t copied_len = 0;
1204 for (auto b = blocks; b; b = b->next) {
1205 memcpy(raw_buf + copied_len, b->start(), b->size());
1206 copied_len += b->size();
1207 }
1208
1209 uint8_t dcil = 0;
1210 uint8_t scil = 0;
1211 QUICInvariants::dcil(dcil, raw_buf, len);
1212 QUICInvariants::scil(scil, raw_buf, len);
1213
1214 size_t offset = LONG_HDR_OFFSET_CONNECTION_ID;
1215 this->_dcid = {raw_buf + offset, dcil};
1216 offset += dcil + 1;
1217 this->_scid = {raw_buf + offset, scil};
1218 offset += scil;
1219
1220 // Token Length Field
1221 uint64_t token_len = QUICIntUtil::read_QUICVariableInt(raw_buf + offset, len - offset);
1222 offset += QUICVariableInt::size(raw_buf + offset);
1223
1224 // Token Field
1225 if (token_len) {
1226 this->_token = new QUICAddressValidationToken(raw_buf + offset, token_len);
1227 offset += token_len;
1228 } else {
1229 this->_token = new QUICAddressValidationToken(nullptr, 0);
1230 }
1231
1232 // Length Field
1233 offset += QUICVariableInt::size(raw_buf + offset);
1234
1235 // PN Field
1236 int pn_len = QUICTypeUtil::read_QUICPacketNumberLen(raw_buf);
1237 QUICPacket::decode_packet_number(this->_packet_number, QUICTypeUtil::read_QUICPacketNumber(raw_buf + offset, pn_len), pn_len,
1238 base_packet_number);
1239 offset += pn_len;
1240
1241 this->_header_block = concatenated_block->clone();
1242 this->_header_block->_end = this->_header_block->_start + offset;
1243 this->_header_block->next = nullptr;
1244 this->_payload_block = concatenated_block->clone();
1245 this->_payload_block->_start = this->_payload_block->_start + offset;
1246 }
1247
~QUICInitialPacketR()1248 QUICInitialPacketR::~QUICInitialPacketR()
1249 {
1250 delete this->_token;
1251 }
1252
1253 QUICPacketType
type() const1254 QUICInitialPacketR::type() const
1255 {
1256 return QUICPacketType::INITIAL;
1257 }
1258
1259 QUICPacketNumber
packet_number() const1260 QUICInitialPacketR::packet_number() const
1261 {
1262 return this->_packet_number;
1263 }
1264
1265 QUICKeyPhase
key_phase() const1266 QUICInitialPacketR::key_phase() const
1267 {
1268 return QUICKeyPhase::INITIAL;
1269 }
1270
1271 Ptr<IOBufferBlock>
header_block() const1272 QUICInitialPacketR::header_block() const
1273 {
1274 return this->_header_block;
1275 }
1276
1277 Ptr<IOBufferBlock>
payload_block() const1278 QUICInitialPacketR::payload_block() const
1279 {
1280 return this->_payload_block;
1281 }
1282
1283 void
attach_payload(Ptr<IOBufferBlock> payload,bool unprotected)1284 QUICInitialPacketR::attach_payload(Ptr<IOBufferBlock> payload, bool unprotected)
1285 {
1286 this->_payload_block = payload;
1287 }
1288
1289 const QUICAddressValidationToken &
token() const1290 QUICInitialPacketR::token() const
1291 {
1292 return *(this->_token);
1293 }
1294
1295 bool
token_length(size_t & token_length,uint8_t & field_len,size_t & token_length_filed_offset,const uint8_t * packet,size_t packet_len)1296 QUICInitialPacketR::token_length(size_t &token_length, uint8_t &field_len, size_t &token_length_filed_offset, const uint8_t *packet,
1297 size_t packet_len)
1298 {
1299 QUICPacketType type = QUICPacketType::UNINITIALIZED;
1300 QUICPacketR::type(type, packet, packet_len);
1301
1302 ink_assert(type == QUICPacketType::INITIAL);
1303
1304 uint8_t dcil, scil;
1305 QUICInvariants::dcil(dcil, packet, packet_len);
1306 QUICInvariants::scil(scil, packet, packet_len);
1307
1308 token_length_filed_offset = LONG_HDR_OFFSET_CONNECTION_ID + dcil + 1 + scil;
1309 if (token_length_filed_offset >= packet_len) {
1310 return false;
1311 }
1312
1313 token_length = QUICIntUtil::read_QUICVariableInt(packet + token_length_filed_offset, packet_len - token_length_filed_offset);
1314 field_len = QUICVariableInt::size(packet + token_length_filed_offset);
1315
1316 return true;
1317 }
1318
1319 //
1320 // QUICZeroRttPacket
1321 //
QUICZeroRttPacket(QUICVersion version,const QUICConnectionId & dcid,const QUICConnectionId & scid,size_t length,QUICPacketNumber packet_number,bool ack_eliciting,bool probing)1322 QUICZeroRttPacket::QUICZeroRttPacket(QUICVersion version, const QUICConnectionId &dcid, const QUICConnectionId &scid, size_t length,
1323 QUICPacketNumber packet_number, bool ack_eliciting, bool probing)
1324 : QUICLongHeaderPacket(version, dcid, scid, ack_eliciting, probing, false), _packet_number(packet_number)
1325 {
1326 }
1327
1328 QUICPacketType
type() const1329 QUICZeroRttPacket::type() const
1330 {
1331 return QUICPacketType::ZERO_RTT_PROTECTED;
1332 }
1333
1334 QUICKeyPhase
key_phase() const1335 QUICZeroRttPacket::key_phase() const
1336 {
1337 return QUICKeyPhase::ZERO_RTT;
1338 }
1339
1340 QUICPacketNumber
packet_number() const1341 QUICZeroRttPacket::packet_number() const
1342 {
1343 return this->_packet_number;
1344 }
1345
1346 Ptr<IOBufferBlock>
header_block() const1347 QUICZeroRttPacket::header_block() const
1348 {
1349 Ptr<IOBufferBlock> block;
1350 size_t written_len = 0;
1351 size_t n;
1352
1353 block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1354 block->alloc(iobuffer_size_to_index(2048, BUFFER_SIZE_INDEX_32K));
1355 uint8_t *buf = reinterpret_cast<uint8_t *>(block->start());
1356
1357 // Common Long Header
1358 written_len += this->_write_common_header(buf + written_len);
1359
1360 QUICPacketNumber pn = 0;
1361 size_t pn_len = 4;
1362 QUICPacket::encode_packet_number(pn, this->_packet_number, pn_len);
1363
1364 if (pn > 0x7FFFFF) {
1365 pn_len = 4;
1366 } else if (pn > 0x7FFF) {
1367 pn_len = 3;
1368 } else if (pn > 0x7F) {
1369 pn_len = 2;
1370 } else {
1371 pn_len = 1;
1372 }
1373
1374 // PN Len
1375 QUICTypeUtil::write_QUICPacketNumberLen(pn_len, buf);
1376
1377 // Length
1378 QUICIntUtil::write_QUICVariableInt(pn_len + this->_payload_length, buf + written_len, &n);
1379 written_len += n;
1380
1381 // PN Field
1382 QUICTypeUtil::write_QUICPacketNumber(pn, pn_len, buf + written_len, &n);
1383 written_len += n;
1384
1385 block->fill(written_len);
1386
1387 return block;
1388 }
1389
1390 Ptr<IOBufferBlock>
payload_block() const1391 QUICZeroRttPacket::payload_block() const
1392 {
1393 return this->_payload_block;
1394 }
1395
1396 void
attach_payload(Ptr<IOBufferBlock> payload,bool unprotected)1397 QUICZeroRttPacket::attach_payload(Ptr<IOBufferBlock> payload, bool unprotected)
1398 {
1399 this->_payload_block = payload;
1400 this->_payload_length = 0;
1401 Ptr<IOBufferBlock> tmp = payload;
1402 while (tmp) {
1403 this->_payload_length += tmp->size();
1404 tmp = tmp->next;
1405 }
1406 if (unprotected) {
1407 this->_payload_length += aead_tag_len;
1408 }
1409 }
1410
1411 //
1412 // QUICZeroRttPacketR
1413 //
QUICZeroRttPacketR(UDPConnection * udp_con,IpEndpoint from,IpEndpoint to,Ptr<IOBufferBlock> blocks,QUICPacketNumber base_packet_number)1414 QUICZeroRttPacketR::QUICZeroRttPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks,
1415 QUICPacketNumber base_packet_number)
1416 : QUICLongHeaderPacketR(udp_con, from, to, blocks)
1417 {
1418 size_t len = 0;
1419 for (auto b = blocks; b; b = b->next) {
1420 len += b->size();
1421 }
1422
1423 Ptr<IOBufferBlock> concatenated_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1424 concatenated_block->alloc(iobuffer_size_to_index(len, BUFFER_SIZE_INDEX_32K));
1425 concatenated_block->fill(len);
1426
1427 uint8_t *raw_buf = reinterpret_cast<uint8_t *>(concatenated_block->start());
1428
1429 size_t copied_len = 0;
1430 for (auto b = blocks; b; b = b->next) {
1431 memcpy(raw_buf + copied_len, b->start(), b->size());
1432 copied_len += b->size();
1433 }
1434
1435 uint8_t dcil = 0;
1436 uint8_t scil = 0;
1437 QUICInvariants::dcil(dcil, raw_buf, len);
1438 QUICInvariants::scil(scil, raw_buf, len);
1439
1440 size_t offset = LONG_HDR_OFFSET_CONNECTION_ID;
1441 this->_dcid = {raw_buf + offset, dcil};
1442 offset += dcil + 1;
1443 this->_scid = {raw_buf + offset, scil};
1444 offset += scil;
1445
1446 // Length Field
1447 offset += QUICVariableInt::size(raw_buf + offset);
1448
1449 // PN Field
1450 int pn_len = QUICTypeUtil::read_QUICPacketNumberLen(raw_buf);
1451 QUICPacket::decode_packet_number(this->_packet_number, QUICTypeUtil::read_QUICPacketNumber(raw_buf + offset, pn_len), pn_len,
1452 base_packet_number);
1453 offset += pn_len;
1454
1455 this->_header_block = concatenated_block->clone();
1456 this->_header_block->_end = this->_header_block->_start + offset;
1457 this->_header_block->next = nullptr;
1458 this->_payload_block = concatenated_block->clone();
1459 this->_payload_block->_start = this->_payload_block->_start + offset;
1460 }
1461
1462 QUICPacketType
type() const1463 QUICZeroRttPacketR::type() const
1464 {
1465 return QUICPacketType::ZERO_RTT_PROTECTED;
1466 }
1467
1468 QUICPacketNumber
packet_number() const1469 QUICZeroRttPacketR::packet_number() const
1470 {
1471 return this->_packet_number;
1472 }
1473
1474 QUICKeyPhase
key_phase() const1475 QUICZeroRttPacketR::key_phase() const
1476 {
1477 return QUICKeyPhase::ZERO_RTT;
1478 }
1479
1480 Ptr<IOBufferBlock>
header_block() const1481 QUICZeroRttPacketR::header_block() const
1482 {
1483 return this->_header_block;
1484 }
1485
1486 Ptr<IOBufferBlock>
payload_block() const1487 QUICZeroRttPacketR::payload_block() const
1488 {
1489 return this->_payload_block;
1490 }
1491
1492 void
attach_payload(Ptr<IOBufferBlock> payload,bool unprotected)1493 QUICZeroRttPacketR::attach_payload(Ptr<IOBufferBlock> payload, bool unprotected)
1494 {
1495 this->_payload_block = payload;
1496 }
1497
1498 //
1499 // QUICHandshakePacket
1500 //
QUICHandshakePacket(QUICVersion version,const QUICConnectionId & dcid,const QUICConnectionId & scid,size_t length,QUICPacketNumber packet_number,bool ack_eliciting,bool probing,bool crypto)1501 QUICHandshakePacket::QUICHandshakePacket(QUICVersion version, const QUICConnectionId &dcid, const QUICConnectionId &scid,
1502 size_t length, QUICPacketNumber packet_number, bool ack_eliciting, bool probing,
1503 bool crypto)
1504 : QUICLongHeaderPacket(version, dcid, scid, ack_eliciting, probing, crypto), _packet_number(packet_number)
1505 {
1506 }
1507
1508 QUICPacketType
type() const1509 QUICHandshakePacket::type() const
1510 {
1511 return QUICPacketType::HANDSHAKE;
1512 }
1513
1514 QUICKeyPhase
key_phase() const1515 QUICHandshakePacket::key_phase() const
1516 {
1517 return QUICKeyPhase::HANDSHAKE;
1518 }
1519
1520 QUICPacketNumber
packet_number() const1521 QUICHandshakePacket::packet_number() const
1522 {
1523 return this->_packet_number;
1524 }
1525
1526 Ptr<IOBufferBlock>
header_block() const1527 QUICHandshakePacket::header_block() const
1528 {
1529 Ptr<IOBufferBlock> block;
1530 size_t written_len = 0;
1531 size_t n;
1532
1533 block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1534 block->alloc(iobuffer_size_to_index(2048, BUFFER_SIZE_INDEX_32K));
1535 uint8_t *buf = reinterpret_cast<uint8_t *>(block->start());
1536
1537 // Common Long Header
1538 written_len += this->_write_common_header(buf + written_len);
1539
1540 QUICPacketNumber pn = 0;
1541 size_t pn_len = 4;
1542 QUICPacket::encode_packet_number(pn, this->_packet_number, pn_len);
1543
1544 if (pn > 0x7FFFFF) {
1545 pn_len = 4;
1546 } else if (pn > 0x7FFF) {
1547 pn_len = 3;
1548 } else if (pn > 0x7F) {
1549 pn_len = 2;
1550 } else {
1551 pn_len = 1;
1552 }
1553
1554 // PN Len
1555 QUICTypeUtil::write_QUICPacketNumberLen(pn_len, buf);
1556
1557 // Length
1558 QUICIntUtil::write_QUICVariableInt(pn_len + this->_payload_length, buf + written_len, &n);
1559 written_len += n;
1560
1561 // PN Field
1562 QUICTypeUtil::write_QUICPacketNumber(pn, pn_len, buf + written_len, &n);
1563 written_len += n;
1564
1565 block->fill(written_len);
1566
1567 return block;
1568 }
1569
1570 Ptr<IOBufferBlock>
payload_block() const1571 QUICHandshakePacket::payload_block() const
1572 {
1573 return this->_payload_block;
1574 }
1575
1576 void
attach_payload(Ptr<IOBufferBlock> payload,bool unprotected)1577 QUICHandshakePacket::attach_payload(Ptr<IOBufferBlock> payload, bool unprotected)
1578 {
1579 this->_payload_block = payload;
1580 this->_payload_length = 0;
1581 Ptr<IOBufferBlock> tmp = payload;
1582 while (tmp) {
1583 this->_payload_length += tmp->size();
1584 tmp = tmp->next;
1585 }
1586 if (unprotected) {
1587 this->_payload_length += aead_tag_len;
1588 }
1589 }
1590
1591 //
1592 // QUICHandshakePacketR
1593 //
QUICHandshakePacketR(UDPConnection * udp_con,IpEndpoint from,IpEndpoint to,Ptr<IOBufferBlock> blocks,QUICPacketNumber base_packet_number)1594 QUICHandshakePacketR::QUICHandshakePacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks,
1595 QUICPacketNumber base_packet_number)
1596 : QUICLongHeaderPacketR(udp_con, from, to, blocks)
1597 {
1598 size_t len = 0;
1599 for (auto b = blocks; b; b = b->next) {
1600 len += b->size();
1601 }
1602
1603 Ptr<IOBufferBlock> concatenated_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1604 concatenated_block->alloc(iobuffer_size_to_index(len, BUFFER_SIZE_INDEX_32K));
1605 concatenated_block->fill(len);
1606
1607 uint8_t *raw_buf = reinterpret_cast<uint8_t *>(concatenated_block->start());
1608
1609 size_t copied_len = 0;
1610 for (auto b = blocks; b; b = b->next) {
1611 memcpy(raw_buf + copied_len, b->start(), b->size());
1612 copied_len += b->size();
1613 }
1614
1615 uint8_t dcil = 0;
1616 uint8_t scil = 0;
1617 QUICInvariants::dcil(dcil, raw_buf, len);
1618 QUICInvariants::scil(scil, raw_buf, len);
1619
1620 size_t offset = LONG_HDR_OFFSET_CONNECTION_ID;
1621 this->_dcid = {raw_buf + offset, dcil};
1622 offset += dcil + 1;
1623 this->_scid = {raw_buf + offset, scil};
1624 offset += scil;
1625
1626 // Length Field
1627 offset += QUICVariableInt::size(raw_buf + offset);
1628
1629 // PN Field
1630 int pn_len = QUICTypeUtil::read_QUICPacketNumberLen(raw_buf);
1631 QUICPacket::decode_packet_number(this->_packet_number, QUICTypeUtil::read_QUICPacketNumber(raw_buf + offset, pn_len), pn_len,
1632 base_packet_number);
1633 offset += pn_len;
1634
1635 this->_header_block = concatenated_block->clone();
1636 this->_header_block->_end = this->_header_block->_start + offset;
1637 this->_header_block->next = nullptr;
1638 this->_payload_block = concatenated_block->clone();
1639 this->_payload_block->_start = this->_payload_block->_start + offset;
1640 }
1641
1642 QUICPacketType
type() const1643 QUICHandshakePacketR::type() const
1644 {
1645 return QUICPacketType::HANDSHAKE;
1646 }
1647
1648 QUICKeyPhase
key_phase() const1649 QUICHandshakePacketR::key_phase() const
1650 {
1651 return QUICKeyPhase::HANDSHAKE;
1652 }
1653
1654 QUICPacketNumber
packet_number() const1655 QUICHandshakePacketR::packet_number() const
1656 {
1657 return this->_packet_number;
1658 }
1659
1660 Ptr<IOBufferBlock>
header_block() const1661 QUICHandshakePacketR::header_block() const
1662 {
1663 return this->_header_block;
1664 }
1665
1666 Ptr<IOBufferBlock>
payload_block() const1667 QUICHandshakePacketR::payload_block() const
1668 {
1669 return this->_payload_block;
1670 }
1671
1672 void
attach_payload(Ptr<IOBufferBlock> payload,bool unprotected)1673 QUICHandshakePacketR::attach_payload(Ptr<IOBufferBlock> payload, bool unprotected)
1674 {
1675 this->_payload_block = payload;
1676 }
1677
1678 //
1679 // QUICRetryPacket
1680 //
QUICRetryPacket(QUICVersion version,const QUICConnectionId & dcid,const QUICConnectionId & scid,QUICRetryToken & token)1681 QUICRetryPacket::QUICRetryPacket(QUICVersion version, const QUICConnectionId &dcid, const QUICConnectionId &scid,
1682 QUICRetryToken &token)
1683 : QUICLongHeaderPacket(version, dcid, scid, false, false, false), _token(token)
1684 {
1685 }
1686
1687 QUICPacketType
type() const1688 QUICRetryPacket::type() const
1689 {
1690 return QUICPacketType::RETRY;
1691 }
1692
1693 QUICPacketNumber
packet_number() const1694 QUICRetryPacket::packet_number() const
1695 {
1696 ink_assert(!"You should not need packet number of Retry Packet");
1697 return 0;
1698 }
1699
1700 uint16_t
payload_length() const1701 QUICRetryPacket::payload_length() const
1702 {
1703 uint16_t size = 0;
1704
1705 for (auto b = this->payload_block(); b; b = b->next) {
1706 size += b->size();
1707 }
1708
1709 return size;
1710 }
1711
1712 Ptr<IOBufferBlock>
header_block() const1713 QUICRetryPacket::header_block() const
1714 {
1715 Ptr<IOBufferBlock> block;
1716 size_t written_len = 0;
1717
1718 block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1719 block->alloc(iobuffer_size_to_index(2048, BUFFER_SIZE_INDEX_32K));
1720 uint8_t *buf = reinterpret_cast<uint8_t *>(block->start());
1721
1722 // Common Long Header
1723 written_len += this->_write_common_header(buf + written_len);
1724
1725 block->fill(written_len);
1726
1727 return block;
1728 }
1729
1730 Ptr<IOBufferBlock>
payload_block() const1731 QUICRetryPacket::payload_block() const
1732 {
1733 Ptr<IOBufferBlock> block;
1734 uint8_t *buf;
1735 size_t written_len = 0;
1736
1737 block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1738 block->alloc(iobuffer_size_to_index(QUICConnectionId::MAX_LENGTH + this->_token.length() + QUICRetryIntegrityTag::LEN,
1739 BUFFER_SIZE_INDEX_32K));
1740 buf = reinterpret_cast<uint8_t *>(block->start());
1741
1742 // Retry Token
1743 memcpy(buf + written_len, this->_token.buf(), this->_token.length());
1744 written_len += this->_token.length();
1745 block->fill(written_len);
1746
1747 // Retry Integrity Tag
1748 QUICRetryIntegrityTag::compute(buf + written_len, this->version(), this->_token.original_dcid(), this->header_block(), block);
1749 written_len += QUICRetryIntegrityTag::LEN;
1750 block->fill(QUICRetryIntegrityTag::LEN);
1751
1752 return block;
1753 }
1754
1755 const QUICRetryToken &
token() const1756 QUICRetryPacket::token() const
1757 {
1758 return this->_token;
1759 }
1760
1761 //
1762 // QUICRetryPacketR
1763 //
QUICRetryPacketR(UDPConnection * udp_con,IpEndpoint from,IpEndpoint to,Ptr<IOBufferBlock> blocks)1764 QUICRetryPacketR::QUICRetryPacketR(UDPConnection *udp_con, IpEndpoint from, IpEndpoint to, Ptr<IOBufferBlock> blocks)
1765 : QUICLongHeaderPacketR(udp_con, from, to, blocks)
1766 {
1767 size_t len = 0;
1768 for (auto b = blocks; b; b = b->next) {
1769 len += b->size();
1770 }
1771
1772 Ptr<IOBufferBlock> concatenated_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1773 concatenated_block->alloc(iobuffer_size_to_index(len, BUFFER_SIZE_INDEX_32K));
1774 concatenated_block->fill(len);
1775
1776 uint8_t *raw_buf = reinterpret_cast<uint8_t *>(concatenated_block->start());
1777
1778 size_t copied_len = 0;
1779 for (auto b = blocks; b; b = b->next) {
1780 memcpy(raw_buf + copied_len, b->start(), b->size());
1781 copied_len += b->size();
1782 }
1783
1784 uint8_t dcil = 0;
1785 uint8_t scil = 0;
1786 QUICInvariants::dcil(dcil, raw_buf, len);
1787 QUICInvariants::scil(scil, raw_buf, len);
1788
1789 size_t offset = LONG_HDR_OFFSET_CONNECTION_ID;
1790 this->_dcid = {raw_buf + offset, dcil};
1791 offset += dcil + 1;
1792 this->_scid = {raw_buf + offset, scil};
1793 offset += scil;
1794
1795 // Retry Token field
1796 this->_token = new QUICRetryToken(raw_buf + offset, len - offset - QUICRetryIntegrityTag::LEN);
1797 offset += this->_token->length();
1798
1799 // Retry Integrity Tag
1800 memcpy(this->_integrity_tag, raw_buf + offset, QUICRetryIntegrityTag::LEN);
1801
1802 this->_header_block = concatenated_block->clone();
1803 this->_header_block->_end = this->_header_block->_start + offset;
1804 this->_header_block->next = nullptr;
1805 this->_payload_block = concatenated_block->clone();
1806 this->_payload_block->_start = this->_payload_block->_start + offset;
1807 this->_payload_block_without_tag = this->_payload_block->clone();
1808 this->_payload_block_without_tag->_end = this->_payload_block_without_tag->_end - QUICRetryIntegrityTag::LEN;
1809 }
1810
~QUICRetryPacketR()1811 QUICRetryPacketR::~QUICRetryPacketR()
1812 {
1813 delete this->_token;
1814 }
1815
1816 Ptr<IOBufferBlock>
header_block() const1817 QUICRetryPacketR::header_block() const
1818 {
1819 return this->_header_block;
1820 }
1821
1822 Ptr<IOBufferBlock>
payload_block() const1823 QUICRetryPacketR::payload_block() const
1824 {
1825 return this->_payload_block;
1826 }
1827
1828 QUICPacketType
type() const1829 QUICRetryPacketR::type() const
1830 {
1831 return QUICPacketType::RETRY;
1832 }
1833
1834 QUICPacketNumber
packet_number() const1835 QUICRetryPacketR::packet_number() const
1836 {
1837 return 0;
1838 }
1839
1840 const QUICAddressValidationToken &
token() const1841 QUICRetryPacketR::token() const
1842 {
1843 return *(this->_token);
1844 }
1845
1846 bool
has_valid_tag(const QUICConnectionId & odcid) const1847 QUICRetryPacketR::has_valid_tag(const QUICConnectionId &odcid) const
1848 {
1849 uint8_t tag_computed[QUICRetryIntegrityTag::LEN];
1850 QUICRetryIntegrityTag::compute(tag_computed, this->version(), odcid, this->_header_block, this->_payload_block_without_tag);
1851
1852 return memcmp(this->_integrity_tag, tag_computed, QUICRetryIntegrityTag::LEN) == 0;
1853 }
1854