xref: /trafficserver/iocore/net/quic/QUICPacket.cc (revision a80d7794)
1 /** @file
2  *
3  *  A brief file description
4  *
5  *  @section license License
6  *
7  *  Licensed to the Apache Software Foundation (ASF) under one
8  *  or more contributor license agreements.  See the NOTICE file
9  *  distributed with this work for additional information
10  *  regarding copyright ownership.  The ASF licenses this file
11  *  to you under the Apache License, Version 2.0 (the
12  *  "License"); you may not use this file except in compliance
13  *  with the License.  You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  *  Unless required by applicable law or agreed to in writing, software
18  *  distributed under the License is distributed on an "AS IS" BASIS,
19  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  *  See the License for the specific language governing permissions and
21  *  limitations under the License.
22  */
23 
24 #include "QUICPacket.h"
25 
26 #include <tscore/ink_assert.h>
27 #include <tscore/Diags.h>
28 
29 #include "QUICIntUtil.h"
30 #include "QUICDebugNames.h"
31 
32 using namespace std::literals;
33 static constexpr std::string_view tag  = "quic_packet"sv;
34 static constexpr uint64_t aead_tag_len = 16;
35 
36 #define QUICDebug(dcid, scid, fmt, ...) \
37   Debug(tag.data(), "[%08" PRIx32 "-%08" PRIx32 "] " fmt, dcid.h32(), scid.h32(), ##__VA_ARGS__);
38 
39 ClassAllocator<QUICPacket> quicPacketAllocator("quicPacketAllocator");
40 ClassAllocator<QUICPacketLongHeader> quicPacketLongHeaderAllocator("quicPacketLongHeaderAllocator");
41 ClassAllocator<QUICPacketShortHeader> quicPacketShortHeaderAllocator("quicPacketShortHeaderAllocator");
42 
43 static constexpr int LONG_HDR_OFFSET_CONNECTION_ID = 6;
44 static constexpr int LONG_HDR_OFFSET_VERSION       = 1;
45 
46 //
47 // QUICPacketHeader
48 //
49 const uint8_t *
buf()50 QUICPacketHeader::buf()
51 {
52   if (this->_buf) {
53     return this->_buf.get();
54   } else {
55     // TODO Reuse serialzied data if nothing has changed
56     this->store(this->_serialized, &this->_buf_len);
57     if (this->_buf_len > MAX_PACKET_HEADER_LEN) {
58       ink_assert(!"Serialized packet header is too long");
59     }
60 
61     this->_buf_len += this->_payload_length;
62     return this->_serialized;
63   }
64 }
65 
66 const IpEndpoint &
from() const67 QUICPacketHeader::from() const
68 {
69   return this->_from;
70 }
71 
72 const IpEndpoint &
to() const73 QUICPacketHeader::to() const
74 {
75   return this->_to;
76 }
77 
78 bool
is_crypto_packet() const79 QUICPacketHeader::is_crypto_packet() const
80 {
81   return false;
82 }
83 
84 uint16_t
packet_size() const85 QUICPacketHeader::packet_size() const
86 {
87   return this->_buf_len;
88 }
89 
90 QUICPacketHeaderUPtr
load(const IpEndpoint from,const IpEndpoint to,ats_unique_buf buf,size_t len,QUICPacketNumber base)91 QUICPacketHeader::load(const IpEndpoint from, const IpEndpoint to, ats_unique_buf buf, size_t len, QUICPacketNumber base)
92 {
93   QUICPacketHeaderUPtr header = QUICPacketHeaderUPtr(nullptr, &QUICPacketHeaderDeleter::delete_null_header);
94   if (QUICInvariants::is_long_header(buf.get())) {
95     QUICPacketLongHeader *long_header = quicPacketLongHeaderAllocator.alloc();
96     new (long_header) QUICPacketLongHeader(from, to, std::move(buf), len, base);
97     header = QUICPacketHeaderUPtr(long_header, &QUICPacketHeaderDeleter::delete_long_header);
98   } else {
99     QUICPacketShortHeader *short_header = quicPacketShortHeaderAllocator.alloc();
100     new (short_header) QUICPacketShortHeader(from, to, std::move(buf), len, base);
101     header = QUICPacketHeaderUPtr(short_header, &QUICPacketHeaderDeleter::delete_short_header);
102   }
103   return header;
104 }
105 
106 QUICPacketHeaderUPtr
build(QUICPacketType type,QUICKeyPhase key_phase,QUICConnectionId destination_cid,QUICConnectionId source_cid,QUICPacketNumber packet_number,QUICPacketNumber base_packet_number,QUICVersion version,bool crypto,ats_unique_buf payload,size_t len)107 QUICPacketHeader::build(QUICPacketType type, QUICKeyPhase key_phase, QUICConnectionId destination_cid, QUICConnectionId source_cid,
108                         QUICPacketNumber packet_number, QUICPacketNumber base_packet_number, QUICVersion version, bool crypto,
109                         ats_unique_buf payload, size_t len)
110 {
111   QUICPacketLongHeader *long_header = quicPacketLongHeaderAllocator.alloc();
112   new (long_header) QUICPacketLongHeader(type, key_phase, destination_cid, source_cid, packet_number, base_packet_number, version,
113                                          crypto, std::move(payload), len);
114   return QUICPacketHeaderUPtr(long_header, &QUICPacketHeaderDeleter::delete_long_header);
115 }
116 
117 QUICPacketHeaderUPtr
build(QUICPacketType type,QUICKeyPhase key_phase,QUICConnectionId destination_cid,QUICConnectionId source_cid,QUICPacketNumber packet_number,QUICPacketNumber base_packet_number,QUICVersion version,bool crypto,ats_unique_buf payload,size_t len,ats_unique_buf token,size_t token_len)118 QUICPacketHeader::build(QUICPacketType type, QUICKeyPhase key_phase, QUICConnectionId destination_cid, QUICConnectionId source_cid,
119                         QUICPacketNumber packet_number, QUICPacketNumber base_packet_number, QUICVersion version, bool crypto,
120                         ats_unique_buf payload, size_t len, ats_unique_buf token, size_t token_len)
121 {
122   QUICPacketLongHeader *long_header = quicPacketLongHeaderAllocator.alloc();
123   new (long_header) QUICPacketLongHeader(type, key_phase, destination_cid, source_cid, packet_number, base_packet_number, version,
124                                          crypto, std::move(payload), len, std::move(token), token_len);
125   return QUICPacketHeaderUPtr(long_header, &QUICPacketHeaderDeleter::delete_long_header);
126 }
127 
128 QUICPacketHeaderUPtr
build(QUICPacketType type,QUICKeyPhase key_phase,QUICVersion version,QUICConnectionId destination_cid,QUICConnectionId source_cid,QUICConnectionId original_dcid,ats_unique_buf retry_token,size_t retry_token_len)129 QUICPacketHeader::build(QUICPacketType type, QUICKeyPhase key_phase, QUICVersion version, QUICConnectionId destination_cid,
130                         QUICConnectionId source_cid, QUICConnectionId original_dcid, ats_unique_buf retry_token,
131                         size_t retry_token_len)
132 {
133   QUICPacketLongHeader *long_header = quicPacketLongHeaderAllocator.alloc();
134   new (long_header) QUICPacketLongHeader(type, key_phase, version, destination_cid, source_cid, original_dcid,
135                                          std::move(retry_token), retry_token_len);
136   return QUICPacketHeaderUPtr(long_header, &QUICPacketHeaderDeleter::delete_long_header);
137 }
138 
139 QUICPacketHeaderUPtr
build(QUICPacketType type,QUICKeyPhase key_phase,QUICPacketNumber packet_number,QUICPacketNumber base_packet_number,ats_unique_buf payload,size_t len)140 QUICPacketHeader::build(QUICPacketType type, QUICKeyPhase key_phase, QUICPacketNumber packet_number,
141                         QUICPacketNumber base_packet_number, ats_unique_buf payload, size_t len)
142 {
143   QUICPacketShortHeader *short_header = quicPacketShortHeaderAllocator.alloc();
144   new (short_header) QUICPacketShortHeader(type, key_phase, packet_number, base_packet_number, std::move(payload), len);
145   return QUICPacketHeaderUPtr(short_header, &QUICPacketHeaderDeleter::delete_short_header);
146 }
147 
148 QUICPacketHeaderUPtr
build(QUICPacketType type,QUICKeyPhase key_phase,QUICConnectionId connection_id,QUICPacketNumber packet_number,QUICPacketNumber base_packet_number,ats_unique_buf payload,size_t len)149 QUICPacketHeader::build(QUICPacketType type, QUICKeyPhase key_phase, QUICConnectionId connection_id, QUICPacketNumber packet_number,
150                         QUICPacketNumber base_packet_number, ats_unique_buf payload, size_t len)
151 {
152   QUICPacketShortHeader *short_header = quicPacketShortHeaderAllocator.alloc();
153   new (short_header)
154     QUICPacketShortHeader(type, key_phase, connection_id, packet_number, base_packet_number, std::move(payload), len);
155   return QUICPacketHeaderUPtr(short_header, &QUICPacketHeaderDeleter::delete_short_header);
156 }
157 
158 QUICPacketHeaderUPtr
clone() const159 QUICPacketHeader::clone() const
160 {
161   return QUICPacketHeaderUPtr(nullptr, &QUICPacketHeaderDeleter::delete_null_header);
162 }
163 
164 //
165 // QUICPacketLongHeader
166 //
167 
QUICPacketLongHeader(const IpEndpoint from,const IpEndpoint to,ats_unique_buf buf,size_t len,QUICPacketNumber base)168 QUICPacketLongHeader::QUICPacketLongHeader(const IpEndpoint from, const IpEndpoint to, ats_unique_buf buf, size_t len,
169                                            QUICPacketNumber base)
170   : QUICPacketHeader(from, to, std::move(buf), len, base)
171 {
172   this->_key_phase = QUICTypeUtil::key_phase(this->type());
173   uint8_t *raw_buf = this->_buf.get();
174 
175   uint8_t dcil = 0;
176   uint8_t scil = 0;
177   QUICPacketLongHeader::dcil(dcil, raw_buf, len);
178   QUICPacketLongHeader::scil(scil, raw_buf, len);
179 
180   size_t offset          = LONG_HDR_OFFSET_CONNECTION_ID;
181   this->_destination_cid = {raw_buf + offset, dcil};
182   offset += dcil + 1;
183   this->_source_cid = {raw_buf + offset, scil};
184   offset += scil;
185 
186   if (this->type() != QUICPacketType::VERSION_NEGOTIATION) {
187     if (this->type() == QUICPacketType::RETRY) {
188       uint8_t odcil = raw_buf[offset];
189       offset += 1;
190 
191       this->_original_dcid = {raw_buf + offset, odcil};
192       offset += odcil;
193     } else {
194       if (this->type() == QUICPacketType::INITIAL) {
195         // Token Length Field
196         this->_token_len = QUICIntUtil::read_QUICVariableInt(raw_buf + offset);
197         offset += QUICVariableInt::size(raw_buf + offset);
198         // Token Field
199         this->_token_offset = offset;
200         offset += this->_token_len;
201       }
202 
203       // Length Field
204       offset += QUICVariableInt::size(raw_buf + offset);
205 
206       // PN Field
207       int pn_len = QUICTypeUtil::read_QUICPacketNumberLen(raw_buf);
208       QUICPacket::decode_packet_number(this->_packet_number, QUICTypeUtil::read_QUICPacketNumber(raw_buf + offset, pn_len), pn_len,
209                                        this->_base_packet_number);
210       offset += pn_len;
211     }
212   }
213 
214   this->_payload_offset = offset;
215   this->_payload_length = len - this->_payload_offset;
216 }
217 
QUICPacketLongHeader(QUICPacketType type,QUICKeyPhase key_phase,const QUICConnectionId & destination_cid,const QUICConnectionId & source_cid,QUICPacketNumber packet_number,QUICPacketNumber base_packet_number,QUICVersion version,bool crypto,ats_unique_buf buf,size_t len,ats_unique_buf token,size_t token_len)218 QUICPacketLongHeader::QUICPacketLongHeader(QUICPacketType type, QUICKeyPhase key_phase, const QUICConnectionId &destination_cid,
219                                            const QUICConnectionId &source_cid, QUICPacketNumber packet_number,
220                                            QUICPacketNumber base_packet_number, QUICVersion version, bool crypto,
221                                            ats_unique_buf buf, size_t len, ats_unique_buf token, size_t token_len)
222   : QUICPacketHeader(type, packet_number, base_packet_number, true, version, std::move(buf), len, key_phase),
223     _destination_cid(destination_cid),
224     _source_cid(source_cid),
225     _token_len(token_len),
226     _token(std::move(token)),
227     _is_crypto_packet(crypto)
228 {
229   if (this->_type == QUICPacketType::VERSION_NEGOTIATION) {
230     this->_buf_len =
231       LONG_HDR_OFFSET_CONNECTION_ID + this->_destination_cid.length() + 1 + this->_source_cid.length() + this->_payload_length;
232   } else {
233     this->buf();
234   }
235 }
236 
QUICPacketLongHeader(QUICPacketType type,QUICKeyPhase key_phase,QUICVersion version,const QUICConnectionId & destination_cid,const QUICConnectionId & source_cid,const QUICConnectionId & original_dcid,ats_unique_buf retry_token,size_t retry_token_len)237 QUICPacketLongHeader::QUICPacketLongHeader(QUICPacketType type, QUICKeyPhase key_phase, QUICVersion version,
238                                            const QUICConnectionId &destination_cid, const QUICConnectionId &source_cid,
239                                            const QUICConnectionId &original_dcid, ats_unique_buf retry_token,
240                                            size_t retry_token_len)
241   : QUICPacketHeader(type, 0, 0, true, version, std::move(retry_token), retry_token_len, key_phase),
242     _destination_cid(destination_cid),
243     _source_cid(source_cid),
244     _original_dcid(original_dcid)
245 
246 {
247   // this->_buf_len will be set
248   this->buf();
249 }
250 
251 QUICPacketType
type() const252 QUICPacketLongHeader::type() const
253 {
254   if (this->_buf) {
255     QUICPacketType type = QUICPacketType::UNINITIALIZED;
256     QUICPacketLongHeader::type(type, this->_buf.get(), this->_buf_len);
257     return type;
258   } else {
259     return this->_type;
260   }
261 }
262 
263 bool
is_crypto_packet() const264 QUICPacketLongHeader::is_crypto_packet() const
265 {
266   return this->_is_crypto_packet;
267 }
268 
269 bool
type(QUICPacketType & type,const uint8_t * packet,size_t packet_len)270 QUICPacketLongHeader::type(QUICPacketType &type, const uint8_t *packet, size_t packet_len)
271 {
272   if (packet_len < 1) {
273     return false;
274   }
275 
276   QUICVersion version;
277   if (QUICPacketLongHeader::version(version, packet, packet_len) && version == 0x00) {
278     type = QUICPacketType::VERSION_NEGOTIATION;
279   } else {
280     uint8_t raw_type = (packet[0] & 0x30) >> 4;
281     type             = static_cast<QUICPacketType>(raw_type);
282   }
283   return true;
284 }
285 
286 bool
version(QUICVersion & version,const uint8_t * packet,size_t packet_len)287 QUICPacketLongHeader::version(QUICVersion &version, const uint8_t *packet, size_t packet_len)
288 {
289   if (packet_len < 5) {
290     return false;
291   }
292 
293   version = QUICTypeUtil::read_QUICVersion(packet + LONG_HDR_OFFSET_VERSION);
294   return true;
295 }
296 
297 bool
dcil(uint8_t & dcil,const uint8_t * packet,size_t packet_len)298 QUICPacketLongHeader::dcil(uint8_t &dcil, const uint8_t *packet, size_t packet_len)
299 {
300   if (QUICInvariants::dcil(dcil, packet, packet_len)) {
301     return true;
302   } else {
303     return false;
304   }
305 }
306 
307 bool
scil(uint8_t & scil,const uint8_t * packet,size_t packet_len)308 QUICPacketLongHeader::scil(uint8_t &scil, const uint8_t *packet, size_t packet_len)
309 {
310   if (QUICInvariants::scil(scil, packet, packet_len)) {
311     return true;
312   } else {
313     return false;
314   }
315 }
316 
317 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)318 QUICPacketLongHeader::token_length(size_t &token_length, uint8_t &field_len, size_t &token_length_filed_offset,
319                                    const uint8_t *packet, size_t packet_len)
320 {
321   QUICPacketType type = QUICPacketType::UNINITIALIZED;
322   QUICPacketLongHeader::type(type, packet, packet_len);
323 
324   if (type != QUICPacketType::INITIAL) {
325     token_length = 0;
326     field_len    = 0;
327 
328     return true;
329   }
330 
331   uint8_t dcil, scil;
332   QUICPacketLongHeader::dcil(dcil, packet, packet_len);
333   QUICPacketLongHeader::scil(scil, packet, packet_len);
334 
335   token_length_filed_offset = LONG_HDR_OFFSET_CONNECTION_ID + dcil + 1 + scil;
336   if (token_length_filed_offset >= packet_len) {
337     return false;
338   }
339 
340   token_length = QUICIntUtil::read_QUICVariableInt(packet + token_length_filed_offset);
341   field_len    = QUICVariableInt::size(packet + token_length_filed_offset);
342 
343   return true;
344 }
345 
346 bool
length(size_t & length,uint8_t & length_field_len,size_t & length_field_offset,const uint8_t * packet,size_t packet_len)347 QUICPacketLongHeader::length(size_t &length, uint8_t &length_field_len, size_t &length_field_offset, const uint8_t *packet,
348                              size_t packet_len)
349 {
350   uint8_t dcil;
351   if (!QUICPacketLongHeader::dcil(dcil, packet, packet_len)) {
352     return false;
353   }
354 
355   uint8_t scil;
356   if (!QUICPacketLongHeader::scil(scil, packet, packet_len)) {
357     return false;
358   }
359 
360   // Token Length (i) + Token (*) (for INITIAL packet)
361   size_t token_length              = 0;
362   uint8_t token_length_field_len   = 0;
363   size_t token_length_field_offset = 0;
364   if (!QUICPacketLongHeader::token_length(token_length, token_length_field_len, token_length_field_offset, packet, packet_len)) {
365     return false;
366   }
367 
368   // Length (i)
369   length_field_offset = LONG_HDR_OFFSET_CONNECTION_ID + dcil + 1 + scil + token_length_field_len + token_length;
370   if (length_field_offset >= packet_len) {
371     return false;
372   }
373 
374   length_field_len = QUICVariableInt::size(packet + length_field_offset);
375   length           = QUICIntUtil::read_QUICVariableInt(packet + length_field_offset);
376 
377   return true;
378 }
379 
380 bool
packet_number_offset(size_t & pn_offset,const uint8_t * packet,size_t packet_len)381 QUICPacketLongHeader::packet_number_offset(size_t &pn_offset, const uint8_t *packet, size_t packet_len)
382 {
383   size_t length;
384   uint8_t length_field_len;
385   size_t length_field_offset;
386 
387   if (!QUICPacketLongHeader::length(length, length_field_len, length_field_offset, packet, packet_len)) {
388     return false;
389   }
390   pn_offset = length_field_offset + length_field_len;
391 
392   if (pn_offset >= packet_len) {
393     return false;
394   }
395 
396   return true;
397 }
398 
399 bool
packet_length(size_t & packet_len,const uint8_t * buf,size_t buf_len)400 QUICPacketLongHeader::packet_length(size_t &packet_len, const uint8_t *buf, size_t buf_len)
401 {
402   size_t length;
403   uint8_t length_field_len;
404   size_t length_field_offset;
405 
406   if (!QUICPacketLongHeader::length(length, length_field_len, length_field_offset, buf, buf_len)) {
407     return false;
408   }
409   packet_len = length + length_field_offset + length_field_len;
410 
411   if (packet_len > buf_len) {
412     return false;
413   }
414 
415   return true;
416 }
417 
418 bool
key_phase(QUICKeyPhase & phase,const uint8_t * packet,size_t packet_len)419 QUICPacketLongHeader::key_phase(QUICKeyPhase &phase, const uint8_t *packet, size_t packet_len)
420 {
421   QUICPacketType type = QUICPacketType::UNINITIALIZED;
422   QUICPacketLongHeader::type(type, packet, packet_len);
423   phase = QUICTypeUtil::key_phase(type);
424   return true;
425 }
426 
427 QUICConnectionId
destination_cid() const428 QUICPacketLongHeader::destination_cid() const
429 {
430   return this->_destination_cid;
431 }
432 
433 QUICConnectionId
source_cid() const434 QUICPacketLongHeader::source_cid() const
435 {
436   return this->_source_cid;
437 }
438 
439 QUICConnectionId
original_dcid() const440 QUICPacketLongHeader::original_dcid() const
441 {
442   return this->_original_dcid;
443 }
444 
445 QUICPacketNumber
packet_number() const446 QUICPacketLongHeader::packet_number() const
447 {
448   return this->_packet_number;
449 }
450 
451 bool
has_version() const452 QUICPacketLongHeader::has_version() const
453 {
454   return true;
455 }
456 
457 bool
is_valid() const458 QUICPacketLongHeader::is_valid() const
459 {
460   if (this->_buf && this->_buf_len != this->_payload_offset + this->_payload_length) {
461     QUICDebug(this->_source_cid, this->_destination_cid,
462               "Invalid packet: packet_size(%zu) should be header_size(%zu) + payload_size(%zu)", this->_buf_len,
463               this->_payload_offset, this->_payload_length);
464     Warning("Invalid packet: packet_size(%zu) should be header_size(%zu) + payload_size(%zu)", this->_buf_len,
465             this->_payload_offset, this->_payload_length);
466 
467     return false;
468   }
469 
470   return true;
471 }
472 
473 QUICVersion
version() const474 QUICPacketLongHeader::version() const
475 {
476   if (this->_buf) {
477     QUICVersion version = 0;
478     QUICPacketLongHeader::version(version, this->_buf.get(), this->_buf_len);
479     return version;
480   } else {
481     return this->_version;
482   }
483 }
484 
485 const uint8_t *
payload() const486 QUICPacketLongHeader::payload() const
487 {
488   if (this->_buf) {
489     uint8_t *raw = this->_buf.get();
490     return raw + this->_payload_offset;
491   } else {
492     return this->_payload.get();
493   }
494 }
495 
496 uint16_t
payload_size() const497 QUICPacketHeader::payload_size() const
498 {
499   return this->_payload_length;
500 }
501 
502 const uint8_t *
token() const503 QUICPacketLongHeader::token() const
504 {
505   if (this->_buf) {
506     uint8_t *raw = this->_buf.get();
507     return raw + this->_token_offset;
508   } else {
509     return this->_token.get();
510   }
511 }
512 
513 size_t
token_len() const514 QUICPacketLongHeader::token_len() const
515 {
516   return this->_token_len;
517 }
518 
519 QUICKeyPhase
key_phase() const520 QUICPacketLongHeader::key_phase() const
521 {
522   return this->_key_phase;
523 }
524 
525 uint16_t
size() const526 QUICPacketLongHeader::size() const
527 {
528   return this->_buf_len - this->_payload_length;
529 }
530 
531 void
store(uint8_t * buf,size_t * len) const532 QUICPacketLongHeader::store(uint8_t *buf, size_t *len) const
533 {
534   size_t n;
535   *len   = 0;
536   buf[0] = 0xC0;
537   buf[0] += static_cast<uint8_t>(this->_type) << 4;
538   if (this->_type == QUICPacketType::VERSION_NEGOTIATION) {
539     buf[0] |= rand();
540   }
541   *len += 1;
542 
543   QUICTypeUtil::write_QUICVersion(this->_version, buf + *len, &n);
544   *len += n;
545 
546   // DICD
547   if (this->_destination_cid != QUICConnectionId::ZERO()) {
548     // Len
549     buf[*len] = this->_destination_cid.length();
550     *len += 1;
551 
552     // ID
553     QUICTypeUtil::write_QUICConnectionId(this->_destination_cid, buf + *len, &n);
554     *len += n;
555   } else {
556     buf[*len] = 0;
557     *len += 1;
558   }
559 
560   // SCID
561   if (this->_source_cid != QUICConnectionId::ZERO()) {
562     // Len
563     buf[*len] = this->_source_cid.length();
564     *len += 1;
565 
566     // ID
567     QUICTypeUtil::write_QUICConnectionId(this->_source_cid, buf + *len, &n);
568     *len += n;
569   } else {
570     buf[*len] = 0;
571     *len += 1;
572   }
573 
574   if (this->_type != QUICPacketType::VERSION_NEGOTIATION) {
575     if (this->_type == QUICPacketType::RETRY) {
576       // Original Destination Connection ID
577       if (this->_original_dcid != QUICConnectionId::ZERO()) {
578         // Len
579         buf[*len] = this->_original_dcid.length();
580         *len += 1;
581 
582         // ID
583         QUICTypeUtil::write_QUICConnectionId(this->_original_dcid, buf + *len, &n);
584         *len += n;
585       } else {
586         buf[*len] = 0;
587         *len += 1;
588       }
589     } else {
590       if (this->_type == QUICPacketType::INITIAL) {
591         // Token Length Field
592         QUICIntUtil::write_QUICVariableInt(this->_token_len, buf + *len, &n);
593         *len += n;
594 
595         // Token Field
596         memcpy(buf + *len, this->token(), this->token_len());
597         *len += this->token_len();
598       }
599 
600       QUICPacketNumber pn = 0;
601       size_t pn_len       = 4;
602       QUICPacket::encode_packet_number(pn, this->_packet_number, pn_len);
603 
604       if (pn > 0x7FFFFF) {
605         pn_len = 4;
606       } else if (pn > 0x7FFF) {
607         pn_len = 3;
608       } else if (pn > 0x7F) {
609         pn_len = 2;
610       } else {
611         pn_len = 1;
612       }
613 
614       if (this->_type != QUICPacketType::RETRY) {
615         // PN Len field
616         QUICTypeUtil::write_QUICPacketNumberLen(pn_len, buf);
617       }
618 
619       // Length Field
620       QUICIntUtil::write_QUICVariableInt(pn_len + this->_payload_length + aead_tag_len, buf + *len, &n);
621       *len += n;
622 
623       // PN Field
624       QUICTypeUtil::write_QUICPacketNumber(pn, pn_len, buf + *len, &n);
625       *len += n;
626     }
627 
628     // Payload will be stored
629   }
630 }
631 
632 //
633 // QUICPacketShortHeader
634 //
635 
QUICPacketShortHeader(const IpEndpoint from,const IpEndpoint to,ats_unique_buf buf,size_t len,QUICPacketNumber base)636 QUICPacketShortHeader::QUICPacketShortHeader(const IpEndpoint from, const IpEndpoint to, ats_unique_buf buf, size_t len,
637                                              QUICPacketNumber base)
638   : QUICPacketHeader(from, to, std::move(buf), len, base)
639 {
640   QUICInvariants::dcid(this->_connection_id, this->_buf.get(), len);
641 
642   int offset               = 1 + this->_connection_id.length();
643   this->_packet_number_len = QUICTypeUtil::read_QUICPacketNumberLen(this->_buf.get());
644   QUICPacketNumber src     = QUICTypeUtil::read_QUICPacketNumber(this->_buf.get() + offset, this->_packet_number_len);
645   QUICPacket::decode_packet_number(this->_packet_number, src, this->_packet_number_len, this->_base_packet_number);
646   this->_payload_length = len - (1 + QUICConnectionId::SCID_LEN + this->_packet_number_len);
647 }
648 
QUICPacketShortHeader(QUICPacketType type,QUICKeyPhase key_phase,QUICPacketNumber packet_number,QUICPacketNumber base_packet_number,ats_unique_buf buf,size_t len)649 QUICPacketShortHeader::QUICPacketShortHeader(QUICPacketType type, QUICKeyPhase key_phase, QUICPacketNumber packet_number,
650                                              QUICPacketNumber base_packet_number, ats_unique_buf buf, size_t len)
651 {
652   this->_type               = type;
653   this->_key_phase          = key_phase;
654   this->_packet_number      = packet_number;
655   this->_base_packet_number = base_packet_number;
656   this->_packet_number_len  = QUICPacket::calc_packet_number_len(packet_number, base_packet_number);
657   this->_payload            = std::move(buf);
658   this->_payload_length     = len;
659 }
660 
QUICPacketShortHeader(QUICPacketType type,QUICKeyPhase key_phase,const QUICConnectionId & connection_id,QUICPacketNumber packet_number,QUICPacketNumber base_packet_number,ats_unique_buf buf,size_t len)661 QUICPacketShortHeader::QUICPacketShortHeader(QUICPacketType type, QUICKeyPhase key_phase, const QUICConnectionId &connection_id,
662                                              QUICPacketNumber packet_number, QUICPacketNumber base_packet_number,
663                                              ats_unique_buf buf, size_t len)
664 {
665   this->_type               = type;
666   this->_key_phase          = key_phase;
667   this->_connection_id      = connection_id;
668   this->_packet_number      = packet_number;
669   this->_base_packet_number = base_packet_number;
670   this->_packet_number_len  = QUICPacket::calc_packet_number_len(packet_number, base_packet_number);
671   this->_payload            = std::move(buf);
672   this->_payload_length     = len;
673 }
674 
675 QUICPacketType
type() const676 QUICPacketShortHeader::type() const
677 {
678   QUICKeyPhase key_phase = this->key_phase();
679 
680   switch (key_phase) {
681   case QUICKeyPhase::PHASE_0: {
682     return QUICPacketType::PROTECTED;
683   }
684   case QUICKeyPhase::PHASE_1: {
685     return QUICPacketType::PROTECTED;
686   }
687   default:
688     return QUICPacketType::STATELESS_RESET;
689   }
690 }
691 
692 QUICConnectionId
destination_cid() const693 QUICPacketShortHeader::destination_cid() const
694 {
695   if (this->_buf) {
696     QUICConnectionId dcid = QUICConnectionId::ZERO();
697     QUICInvariants::dcid(dcid, this->_buf.get(), this->_buf_len);
698     return dcid;
699   } else {
700     return _connection_id;
701   }
702 }
703 
704 QUICPacketNumber
packet_number() const705 QUICPacketShortHeader::packet_number() const
706 {
707   return this->_packet_number;
708 }
709 
710 bool
has_version() const711 QUICPacketShortHeader::has_version() const
712 {
713   return false;
714 }
715 
716 bool
is_valid() const717 QUICPacketShortHeader::is_valid() const
718 {
719   return true;
720 }
721 
722 QUICVersion
version() const723 QUICPacketShortHeader::version() const
724 {
725   return 0;
726 }
727 
728 const uint8_t *
payload() const729 QUICPacketShortHeader::payload() const
730 {
731   if (this->_buf) {
732     return this->_buf.get() + this->size();
733   } else {
734     return this->_payload.get();
735   }
736 }
737 
738 QUICKeyPhase
key_phase() const739 QUICPacketShortHeader::key_phase() const
740 {
741   if (this->_buf) {
742     QUICKeyPhase phase = QUICKeyPhase::INITIAL;
743     QUICPacketShortHeader::key_phase(phase, this->_buf.get(), this->_buf_len);
744     return phase;
745   } else {
746     return this->_key_phase;
747   }
748 }
749 
750 bool
key_phase(QUICKeyPhase & phase,const uint8_t * packet,size_t packet_len)751 QUICPacketShortHeader::key_phase(QUICKeyPhase &phase, const uint8_t *packet, size_t packet_len)
752 {
753   if (packet_len < 1) {
754     return false;
755   }
756   if (packet[0] & 0x04) {
757     phase = QUICKeyPhase::PHASE_1;
758   } else {
759     phase = QUICKeyPhase::PHASE_0;
760   }
761   return true;
762 }
763 
764 bool
packet_number_offset(size_t & pn_offset,const uint8_t * packet,size_t packet_len,int dcil)765 QUICPacketShortHeader::packet_number_offset(size_t &pn_offset, const uint8_t *packet, size_t packet_len, int dcil)
766 {
767   pn_offset = 1 + dcil;
768   return true;
769 }
770 
771 /**
772  * Header Length (doesn't include payload length)
773  */
774 uint16_t
size() const775 QUICPacketShortHeader::size() const
776 {
777   uint16_t len = 1;
778   if (this->_connection_id != QUICConnectionId::ZERO()) {
779     len += this->_connection_id.length();
780   }
781   len += this->_packet_number_len;
782 
783   return len;
784 }
785 
786 void
store(uint8_t * buf,size_t * len) const787 QUICPacketShortHeader::store(uint8_t *buf, size_t *len) const
788 {
789   size_t n;
790   *len   = 0;
791   buf[0] = 0x40;
792   if (this->_key_phase == QUICKeyPhase::PHASE_1) {
793     buf[0] |= 0x04;
794   }
795   *len += 1;
796 
797   if (this->_connection_id != QUICConnectionId::ZERO()) {
798     QUICTypeUtil::write_QUICConnectionId(this->_connection_id, buf + *len, &n);
799     *len += n;
800   }
801 
802   QUICPacketNumber dst = 0;
803   size_t dst_len       = this->_packet_number_len;
804   QUICPacket::encode_packet_number(dst, this->_packet_number, dst_len);
805   QUICTypeUtil::write_QUICPacketNumber(dst, dst_len, buf + *len, &n);
806   *len += n;
807 
808   QUICTypeUtil::write_QUICPacketNumberLen(n, buf);
809 }
810 
811 //
812 // QUICPacket
813 //
814 
QUICPacket()815 QUICPacket::QUICPacket() {}
816 
QUICPacket(UDPConnection * udp_con,QUICPacketHeaderUPtr header,ats_unique_buf payload,size_t payload_len)817 QUICPacket::QUICPacket(UDPConnection *udp_con, QUICPacketHeaderUPtr header, ats_unique_buf payload, size_t payload_len)
818   : _udp_con(udp_con), _header(std::move(header)), _payload(std::move(payload)), _payload_size(payload_len)
819 {
820 }
821 
QUICPacket(QUICPacketHeaderUPtr header,ats_unique_buf payload,size_t payload_len,bool ack_eliciting,bool probing)822 QUICPacket::QUICPacket(QUICPacketHeaderUPtr header, ats_unique_buf payload, size_t payload_len, bool ack_eliciting, bool probing)
823   : _header(std::move(header)),
824     _payload(std::move(payload)),
825     _payload_size(payload_len),
826     _is_ack_eliciting(ack_eliciting),
827     _is_probing_packet(probing)
828 {
829 }
830 
~QUICPacket()831 QUICPacket::~QUICPacket()
832 {
833   this->_header = nullptr;
834 }
835 
836 const IpEndpoint &
from() const837 QUICPacket::from() const
838 {
839   return this->_header->from();
840 }
841 
842 const IpEndpoint &
to() const843 QUICPacket::to() const
844 {
845   return this->_header->to();
846 }
847 
848 UDPConnection *
udp_con() const849 QUICPacket::udp_con() const
850 {
851   return this->_udp_con;
852 }
853 
854 /**
855  * When packet is "Short Header Packet", QUICPacket::type() will return 1-RTT Protected (key phase 0)
856  * or 1-RTT Protected (key phase 1)
857  */
858 QUICPacketType
type() const859 QUICPacket::type() const
860 {
861   return this->_header->type();
862 }
863 
864 QUICConnectionId
destination_cid() const865 QUICPacket::destination_cid() const
866 {
867   return this->_header->destination_cid();
868 }
869 
870 QUICConnectionId
source_cid() const871 QUICPacket::source_cid() const
872 {
873   return this->_header->source_cid();
874 }
875 
876 QUICPacketNumber
packet_number() const877 QUICPacket::packet_number() const
878 {
879   return this->_header->packet_number();
880 }
881 
882 bool
is_crypto_packet() const883 QUICPacket::is_crypto_packet() const
884 {
885   return this->_header->is_crypto_packet();
886 }
887 
888 const QUICPacketHeader &
header() const889 QUICPacket::header() const
890 {
891   return *this->_header;
892 }
893 
894 const uint8_t *
payload() const895 QUICPacket::payload() const
896 {
897   return this->_payload.get();
898 }
899 
900 QUICVersion
version() const901 QUICPacket::version() const
902 {
903   return this->_header->version();
904 }
905 
906 bool
is_ack_eliciting() const907 QUICPacket::is_ack_eliciting() const
908 {
909   return this->_is_ack_eliciting;
910 }
911 
912 bool
is_probing_packet() const913 QUICPacket::is_probing_packet() const
914 {
915   return this->_is_probing_packet;
916 }
917 
918 uint16_t
size() const919 QUICPacket::size() const
920 {
921   // This includes not only header size and payload size but also AEAD tag length
922   uint16_t size = this->_header->packet_size();
923   if (size == 0) {
924     size = this->header_size() + this->payload_length();
925   }
926   return size;
927 }
928 
929 uint16_t
header_size() const930 QUICPacket::header_size() const
931 {
932   return this->_header->size();
933 }
934 
935 uint16_t
payload_length() const936 QUICPacket::payload_length() const
937 {
938   return this->_payload_size;
939 }
940 
941 QUICKeyPhase
key_phase() const942 QUICPacket::key_phase() const
943 {
944   return this->_header->key_phase();
945 }
946 
947 void
store(uint8_t * buf,size_t * len) const948 QUICPacket::store(uint8_t *buf, size_t *len) const
949 {
950   memcpy(buf, this->_header->buf(), this->_header->size());
951   memcpy(buf + this->_header->size(), this->payload(), this->payload_length());
952   *len = this->_header->size() + this->payload_length();
953 }
954 
955 uint8_t
calc_packet_number_len(QUICPacketNumber num,QUICPacketNumber base)956 QUICPacket::calc_packet_number_len(QUICPacketNumber num, QUICPacketNumber base)
957 {
958   uint64_t d  = (num - base) * 2;
959   uint8_t len = 0;
960 
961   if (d > 0xFFFFFF) {
962     len = 4;
963   } else if (d > 0xFFFF) {
964     len = 3;
965   } else if (d > 0xFF) {
966     len = 2;
967   } else {
968     len = 1;
969   }
970 
971   return len;
972 }
973 
974 bool
encode_packet_number(QUICPacketNumber & dst,QUICPacketNumber src,size_t len)975 QUICPacket::encode_packet_number(QUICPacketNumber &dst, QUICPacketNumber src, size_t len)
976 {
977   uint64_t mask = 0;
978   switch (len) {
979   case 1:
980     mask = 0xFF;
981     break;
982   case 2:
983     mask = 0xFFFF;
984     break;
985   case 3:
986     mask = 0xFFFFFF;
987     break;
988   case 4:
989     mask = 0xFFFFFFFF;
990     break;
991   default:
992     ink_assert(!"len must be 1, 2, or 4");
993     return false;
994   }
995   dst = src & mask;
996 
997   return true;
998 }
999 
1000 bool
decode_packet_number(QUICPacketNumber & dst,QUICPacketNumber src,size_t len,QUICPacketNumber largest_acked)1001 QUICPacket::decode_packet_number(QUICPacketNumber &dst, QUICPacketNumber src, size_t len, QUICPacketNumber largest_acked)
1002 {
1003   ink_assert(len == 1 || len == 2 || len == 3 || len == 4);
1004 
1005   uint64_t maximum_diff = 0;
1006   switch (len) {
1007   case 1:
1008     maximum_diff = 0x100;
1009     break;
1010   case 2:
1011     maximum_diff = 0x10000;
1012     break;
1013   case 3:
1014     maximum_diff = 0x1000000;
1015     break;
1016   case 4:
1017     maximum_diff = 0x100000000;
1018     break;
1019   default:
1020     ink_assert(!"len must be 1, 2, 3 or 4");
1021   }
1022   QUICPacketNumber base       = largest_acked & (~(maximum_diff - 1));
1023   QUICPacketNumber candidate1 = base + src;
1024   QUICPacketNumber candidate2 = base + src + maximum_diff;
1025   QUICPacketNumber expected   = largest_acked + 1;
1026 
1027   if (((candidate1 > expected) ? (candidate1 - expected) : (expected - candidate1)) <
1028       ((candidate2 > expected) ? (candidate2 - expected) : (expected - candidate2))) {
1029     dst = candidate1;
1030   } else {
1031     dst = candidate2;
1032   }
1033 
1034   return true;
1035 }
1036