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