xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_packets.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/quic_packets.h"
6 
7 #include <algorithm>
8 #include <memory>
9 #include <utility>
10 
11 #include "absl/strings/escaping.h"
12 #include "absl/strings/str_cat.h"
13 #include "absl/strings/string_view.h"
14 #include "quiche/quic/core/quic_connection_id.h"
15 #include "quiche/quic/core/quic_types.h"
16 #include "quiche/quic/core/quic_utils.h"
17 #include "quiche/quic/core/quic_versions.h"
18 #include "quiche/quic/platform/api/quic_flags.h"
19 
20 namespace quic {
21 
GetServerConnectionIdAsRecipient(const QuicPacketHeader & header,Perspective perspective)22 QuicConnectionId GetServerConnectionIdAsRecipient(
23     const QuicPacketHeader& header, Perspective perspective) {
24   if (perspective == Perspective::IS_SERVER) {
25     return header.destination_connection_id;
26   }
27   return header.source_connection_id;
28 }
29 
GetClientConnectionIdAsRecipient(const QuicPacketHeader & header,Perspective perspective)30 QuicConnectionId GetClientConnectionIdAsRecipient(
31     const QuicPacketHeader& header, Perspective perspective) {
32   if (perspective == Perspective::IS_CLIENT) {
33     return header.destination_connection_id;
34   }
35   return header.source_connection_id;
36 }
37 
GetServerConnectionIdAsSender(const QuicPacketHeader & header,Perspective perspective)38 QuicConnectionId GetServerConnectionIdAsSender(const QuicPacketHeader& header,
39                                                Perspective perspective) {
40   if (perspective == Perspective::IS_CLIENT) {
41     return header.destination_connection_id;
42   }
43   return header.source_connection_id;
44 }
45 
GetServerConnectionIdIncludedAsSender(const QuicPacketHeader & header,Perspective perspective)46 QuicConnectionIdIncluded GetServerConnectionIdIncludedAsSender(
47     const QuicPacketHeader& header, Perspective perspective) {
48   if (perspective == Perspective::IS_CLIENT) {
49     return header.destination_connection_id_included;
50   }
51   return header.source_connection_id_included;
52 }
53 
GetClientConnectionIdAsSender(const QuicPacketHeader & header,Perspective perspective)54 QuicConnectionId GetClientConnectionIdAsSender(const QuicPacketHeader& header,
55                                                Perspective perspective) {
56   if (perspective == Perspective::IS_CLIENT) {
57     return header.source_connection_id;
58   }
59   return header.destination_connection_id;
60 }
61 
GetClientConnectionIdIncludedAsSender(const QuicPacketHeader & header,Perspective perspective)62 QuicConnectionIdIncluded GetClientConnectionIdIncludedAsSender(
63     const QuicPacketHeader& header, Perspective perspective) {
64   if (perspective == Perspective::IS_CLIENT) {
65     return header.source_connection_id_included;
66   }
67   return header.destination_connection_id_included;
68 }
69 
GetIncludedConnectionIdLength(QuicConnectionId connection_id,QuicConnectionIdIncluded connection_id_included)70 uint8_t GetIncludedConnectionIdLength(
71     QuicConnectionId connection_id,
72     QuicConnectionIdIncluded connection_id_included) {
73   QUICHE_DCHECK(connection_id_included == CONNECTION_ID_PRESENT ||
74                 connection_id_included == CONNECTION_ID_ABSENT);
75   return connection_id_included == CONNECTION_ID_PRESENT
76              ? connection_id.length()
77              : 0;
78 }
79 
GetIncludedDestinationConnectionIdLength(const QuicPacketHeader & header)80 uint8_t GetIncludedDestinationConnectionIdLength(
81     const QuicPacketHeader& header) {
82   return GetIncludedConnectionIdLength(
83       header.destination_connection_id,
84       header.destination_connection_id_included);
85 }
86 
GetIncludedSourceConnectionIdLength(const QuicPacketHeader & header)87 uint8_t GetIncludedSourceConnectionIdLength(const QuicPacketHeader& header) {
88   return GetIncludedConnectionIdLength(header.source_connection_id,
89                                        header.source_connection_id_included);
90 }
91 
GetPacketHeaderSize(QuicTransportVersion version,const QuicPacketHeader & header)92 size_t GetPacketHeaderSize(QuicTransportVersion version,
93                            const QuicPacketHeader& header) {
94   return GetPacketHeaderSize(
95       version, GetIncludedDestinationConnectionIdLength(header),
96       GetIncludedSourceConnectionIdLength(header), header.version_flag,
97       header.nonce != nullptr, header.packet_number_length,
98       header.retry_token_length_length, header.retry_token.length(),
99       header.length_length);
100 }
101 
GetPacketHeaderSize(QuicTransportVersion version,uint8_t destination_connection_id_length,uint8_t source_connection_id_length,bool include_version,bool include_diversification_nonce,QuicPacketNumberLength packet_number_length,quiche::QuicheVariableLengthIntegerLength retry_token_length_length,QuicByteCount retry_token_length,quiche::QuicheVariableLengthIntegerLength length_length)102 size_t GetPacketHeaderSize(
103     QuicTransportVersion version, uint8_t destination_connection_id_length,
104     uint8_t source_connection_id_length, bool include_version,
105     bool include_diversification_nonce,
106     QuicPacketNumberLength packet_number_length,
107     quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
108     QuicByteCount retry_token_length,
109     quiche::QuicheVariableLengthIntegerLength length_length) {
110   if (include_version) {
111     // Long header.
112     size_t size = kPacketHeaderTypeSize + kConnectionIdLengthSize +
113                   destination_connection_id_length +
114                   source_connection_id_length + packet_number_length +
115                   kQuicVersionSize;
116     if (include_diversification_nonce) {
117       size += kDiversificationNonceSize;
118     }
119     if (VersionHasLengthPrefixedConnectionIds(version)) {
120       size += kConnectionIdLengthSize;
121     }
122     QUICHE_DCHECK(
123         QuicVersionHasLongHeaderLengths(version) ||
124         retry_token_length_length + retry_token_length + length_length == 0);
125     if (QuicVersionHasLongHeaderLengths(version)) {
126       size += retry_token_length_length + retry_token_length + length_length;
127     }
128     return size;
129   }
130   // Short header.
131   return kPacketHeaderTypeSize + destination_connection_id_length +
132          packet_number_length;
133 }
134 
GetStartOfEncryptedData(QuicTransportVersion version,const QuicPacketHeader & header)135 size_t GetStartOfEncryptedData(QuicTransportVersion version,
136                                const QuicPacketHeader& header) {
137   return GetPacketHeaderSize(version, header);
138 }
139 
GetStartOfEncryptedData(QuicTransportVersion version,uint8_t destination_connection_id_length,uint8_t source_connection_id_length,bool include_version,bool include_diversification_nonce,QuicPacketNumberLength packet_number_length,quiche::QuicheVariableLengthIntegerLength retry_token_length_length,QuicByteCount retry_token_length,quiche::QuicheVariableLengthIntegerLength length_length)140 size_t GetStartOfEncryptedData(
141     QuicTransportVersion version, uint8_t destination_connection_id_length,
142     uint8_t source_connection_id_length, bool include_version,
143     bool include_diversification_nonce,
144     QuicPacketNumberLength packet_number_length,
145     quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
146     QuicByteCount retry_token_length,
147     quiche::QuicheVariableLengthIntegerLength length_length) {
148   // Encryption starts before private flags.
149   return GetPacketHeaderSize(
150       version, destination_connection_id_length, source_connection_id_length,
151       include_version, include_diversification_nonce, packet_number_length,
152       retry_token_length_length, retry_token_length, length_length);
153 }
154 
QuicPacketHeader()155 QuicPacketHeader::QuicPacketHeader()
156     : destination_connection_id(EmptyQuicConnectionId()),
157       destination_connection_id_included(CONNECTION_ID_PRESENT),
158       source_connection_id(EmptyQuicConnectionId()),
159       source_connection_id_included(CONNECTION_ID_ABSENT),
160       reset_flag(false),
161       version_flag(false),
162       has_possible_stateless_reset_token(false),
163       packet_number_length(PACKET_4BYTE_PACKET_NUMBER),
164       type_byte(0),
165       version(UnsupportedQuicVersion()),
166       nonce(nullptr),
167       form(GOOGLE_QUIC_PACKET),
168       long_packet_type(INITIAL),
169       possible_stateless_reset_token({}),
170       retry_token_length_length(quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0),
171       retry_token(absl::string_view()),
172       length_length(quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0),
173       remaining_packet_length(0) {}
174 
175 QuicPacketHeader::QuicPacketHeader(const QuicPacketHeader& other) = default;
176 
~QuicPacketHeader()177 QuicPacketHeader::~QuicPacketHeader() {}
178 
179 QuicPacketHeader& QuicPacketHeader::operator=(const QuicPacketHeader& other) =
180     default;
181 
QuicPublicResetPacket()182 QuicPublicResetPacket::QuicPublicResetPacket()
183     : connection_id(EmptyQuicConnectionId()), nonce_proof(0) {}
184 
QuicPublicResetPacket(QuicConnectionId connection_id)185 QuicPublicResetPacket::QuicPublicResetPacket(QuicConnectionId connection_id)
186     : connection_id(connection_id), nonce_proof(0) {}
187 
QuicVersionNegotiationPacket()188 QuicVersionNegotiationPacket::QuicVersionNegotiationPacket()
189     : connection_id(EmptyQuicConnectionId()) {}
190 
QuicVersionNegotiationPacket(QuicConnectionId connection_id)191 QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
192     QuicConnectionId connection_id)
193     : connection_id(connection_id) {}
194 
195 QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
196     const QuicVersionNegotiationPacket& other) = default;
197 
~QuicVersionNegotiationPacket()198 QuicVersionNegotiationPacket::~QuicVersionNegotiationPacket() {}
199 
QuicIetfStatelessResetPacket()200 QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket()
201     : stateless_reset_token({}) {}
202 
QuicIetfStatelessResetPacket(const QuicPacketHeader & header,StatelessResetToken token)203 QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
204     const QuicPacketHeader& header, StatelessResetToken token)
205     : header(header), stateless_reset_token(token) {}
206 
207 QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
208     const QuicIetfStatelessResetPacket& other) = default;
209 
~QuicIetfStatelessResetPacket()210 QuicIetfStatelessResetPacket::~QuicIetfStatelessResetPacket() {}
211 
operator <<(std::ostream & os,const QuicPacketHeader & header)212 std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) {
213   os << "{ destination_connection_id: " << header.destination_connection_id
214      << " ("
215      << (header.destination_connection_id_included == CONNECTION_ID_PRESENT
216              ? "present"
217              : "absent")
218      << "), source_connection_id: " << header.source_connection_id << " ("
219      << (header.source_connection_id_included == CONNECTION_ID_PRESENT
220              ? "present"
221              : "absent")
222      << "), packet_number_length: "
223      << static_cast<int>(header.packet_number_length)
224      << ", reset_flag: " << header.reset_flag
225      << ", version_flag: " << header.version_flag;
226   if (header.version_flag) {
227     os << ", version: " << ParsedQuicVersionToString(header.version);
228     if (header.long_packet_type != INVALID_PACKET_TYPE) {
229       os << ", long_packet_type: "
230          << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
231     }
232     if (header.retry_token_length_length !=
233         quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0) {
234       os << ", retry_token_length_length: "
235          << static_cast<int>(header.retry_token_length_length);
236     }
237     if (header.retry_token.length() != 0) {
238       os << ", retry_token_length: " << header.retry_token.length();
239     }
240     if (header.length_length != quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0) {
241       os << ", length_length: " << static_cast<int>(header.length_length);
242     }
243     if (header.remaining_packet_length != 0) {
244       os << ", remaining_packet_length: " << header.remaining_packet_length;
245     }
246   }
247   if (header.nonce != nullptr) {
248     os << ", diversification_nonce: "
249        << absl::BytesToHexString(
250               absl::string_view(header.nonce->data(), header.nonce->size()));
251   }
252   os << ", packet_number: " << header.packet_number << " }\n";
253   return os;
254 }
255 
QuicData(const char * buffer,size_t length)256 QuicData::QuicData(const char* buffer, size_t length)
257     : buffer_(buffer), length_(length), owns_buffer_(false) {}
258 
QuicData(const char * buffer,size_t length,bool owns_buffer)259 QuicData::QuicData(const char* buffer, size_t length, bool owns_buffer)
260     : buffer_(buffer), length_(length), owns_buffer_(owns_buffer) {}
261 
QuicData(absl::string_view packet_data)262 QuicData::QuicData(absl::string_view packet_data)
263     : buffer_(packet_data.data()),
264       length_(packet_data.length()),
265       owns_buffer_(false) {}
266 
~QuicData()267 QuicData::~QuicData() {
268   if (owns_buffer_) {
269     delete[] const_cast<char*>(buffer_);
270   }
271 }
272 
QuicPacket(char * buffer,size_t length,bool owns_buffer,uint8_t destination_connection_id_length,uint8_t source_connection_id_length,bool includes_version,bool includes_diversification_nonce,QuicPacketNumberLength packet_number_length,quiche::QuicheVariableLengthIntegerLength retry_token_length_length,QuicByteCount retry_token_length,quiche::QuicheVariableLengthIntegerLength length_length)273 QuicPacket::QuicPacket(
274     char* buffer, size_t length, bool owns_buffer,
275     uint8_t destination_connection_id_length,
276     uint8_t source_connection_id_length, bool includes_version,
277     bool includes_diversification_nonce,
278     QuicPacketNumberLength packet_number_length,
279     quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
280     QuicByteCount retry_token_length,
281     quiche::QuicheVariableLengthIntegerLength length_length)
282     : QuicData(buffer, length, owns_buffer),
283       buffer_(buffer),
284       destination_connection_id_length_(destination_connection_id_length),
285       source_connection_id_length_(source_connection_id_length),
286       includes_version_(includes_version),
287       includes_diversification_nonce_(includes_diversification_nonce),
288       packet_number_length_(packet_number_length),
289       retry_token_length_length_(retry_token_length_length),
290       retry_token_length_(retry_token_length),
291       length_length_(length_length) {}
292 
QuicPacket(QuicTransportVersion,char * buffer,size_t length,bool owns_buffer,const QuicPacketHeader & header)293 QuicPacket::QuicPacket(QuicTransportVersion /*version*/, char* buffer,
294                        size_t length, bool owns_buffer,
295                        const QuicPacketHeader& header)
296     : QuicPacket(buffer, length, owns_buffer,
297                  GetIncludedDestinationConnectionIdLength(header),
298                  GetIncludedSourceConnectionIdLength(header),
299                  header.version_flag, header.nonce != nullptr,
300                  header.packet_number_length, header.retry_token_length_length,
301                  header.retry_token.length(), header.length_length) {}
302 
QuicEncryptedPacket(const char * buffer,size_t length)303 QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length)
304     : QuicData(buffer, length) {}
305 
QuicEncryptedPacket(const char * buffer,size_t length,bool owns_buffer)306 QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length,
307                                          bool owns_buffer)
308     : QuicData(buffer, length, owns_buffer) {}
309 
QuicEncryptedPacket(absl::string_view data)310 QuicEncryptedPacket::QuicEncryptedPacket(absl::string_view data)
311     : QuicData(data) {}
312 
Clone() const313 std::unique_ptr<QuicEncryptedPacket> QuicEncryptedPacket::Clone() const {
314   char* buffer = new char[this->length()];
315   std::copy(this->data(), this->data() + this->length(), buffer);
316   return std::make_unique<QuicEncryptedPacket>(buffer, this->length(), true);
317 }
318 
operator <<(std::ostream & os,const QuicEncryptedPacket & s)319 std::ostream& operator<<(std::ostream& os, const QuicEncryptedPacket& s) {
320   os << s.length() << "-byte data";
321   return os;
322 }
323 
QuicReceivedPacket(const char * buffer,size_t length,QuicTime receipt_time)324 QuicReceivedPacket::QuicReceivedPacket(const char* buffer, size_t length,
325                                        QuicTime receipt_time)
326     : QuicReceivedPacket(buffer, length, receipt_time,
327                          false /* owns_buffer */) {}
328 
QuicReceivedPacket(const char * buffer,size_t length,QuicTime receipt_time,bool owns_buffer)329 QuicReceivedPacket::QuicReceivedPacket(const char* buffer, size_t length,
330                                        QuicTime receipt_time, bool owns_buffer)
331     : QuicReceivedPacket(buffer, length, receipt_time, owns_buffer, 0 /* ttl */,
332                          true /* ttl_valid */) {}
333 
QuicReceivedPacket(const char * buffer,size_t length,QuicTime receipt_time,bool owns_buffer,int ttl,bool ttl_valid)334 QuicReceivedPacket::QuicReceivedPacket(const char* buffer, size_t length,
335                                        QuicTime receipt_time, bool owns_buffer,
336                                        int ttl, bool ttl_valid)
337     : quic::QuicReceivedPacket(buffer, length, receipt_time, owns_buffer, ttl,
338                                ttl_valid, nullptr /* packet_headers */,
339                                0 /* headers_length */,
340                                false /* owns_header_buffer */, ECN_NOT_ECT) {}
341 
QuicReceivedPacket(const char * buffer,size_t length,QuicTime receipt_time,bool owns_buffer,int ttl,bool ttl_valid,char * packet_headers,size_t headers_length,bool owns_header_buffer)342 QuicReceivedPacket::QuicReceivedPacket(const char* buffer, size_t length,
343                                        QuicTime receipt_time, bool owns_buffer,
344                                        int ttl, bool ttl_valid,
345                                        char* packet_headers,
346                                        size_t headers_length,
347                                        bool owns_header_buffer)
348     : quic::QuicReceivedPacket(buffer, length, receipt_time, owns_buffer, ttl,
349                                ttl_valid, packet_headers, headers_length,
350                                owns_header_buffer, ECN_NOT_ECT) {}
351 
QuicReceivedPacket(const char * buffer,size_t length,QuicTime receipt_time,bool owns_buffer,int ttl,bool ttl_valid,char * packet_headers,size_t headers_length,bool owns_header_buffer,QuicEcnCodepoint ecn_codepoint)352 QuicReceivedPacket::QuicReceivedPacket(
353     const char* buffer, size_t length, QuicTime receipt_time, bool owns_buffer,
354     int ttl, bool ttl_valid, char* packet_headers, size_t headers_length,
355     bool owns_header_buffer, QuicEcnCodepoint ecn_codepoint)
356     : QuicEncryptedPacket(buffer, length, owns_buffer),
357       receipt_time_(receipt_time),
358       ttl_(ttl_valid ? ttl : -1),
359       packet_headers_(packet_headers),
360       headers_length_(headers_length),
361       owns_header_buffer_(owns_header_buffer),
362       ecn_codepoint_(ecn_codepoint) {}
363 
~QuicReceivedPacket()364 QuicReceivedPacket::~QuicReceivedPacket() {
365   if (owns_header_buffer_) {
366     delete[] static_cast<char*>(packet_headers_);
367   }
368 }
369 
Clone() const370 std::unique_ptr<QuicReceivedPacket> QuicReceivedPacket::Clone() const {
371   char* buffer = new char[this->length()];
372   memcpy(buffer, this->data(), this->length());
373   if (this->packet_headers()) {
374     char* headers_buffer = new char[this->headers_length()];
375     memcpy(headers_buffer, this->packet_headers(), this->headers_length());
376     return std::make_unique<QuicReceivedPacket>(
377         buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0,
378         headers_buffer, this->headers_length(), true, this->ecn_codepoint());
379   }
380 
381   return std::make_unique<QuicReceivedPacket>(
382       buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0, nullptr,
383       0, false, this->ecn_codepoint());
384 }
385 
operator <<(std::ostream & os,const QuicReceivedPacket & s)386 std::ostream& operator<<(std::ostream& os, const QuicReceivedPacket& s) {
387   os << s.length() << "-byte data";
388   return os;
389 }
390 
AssociatedData(QuicTransportVersion version) const391 absl::string_view QuicPacket::AssociatedData(
392     QuicTransportVersion version) const {
393   return absl::string_view(
394       data(),
395       GetStartOfEncryptedData(version, destination_connection_id_length_,
396                               source_connection_id_length_, includes_version_,
397                               includes_diversification_nonce_,
398                               packet_number_length_, retry_token_length_length_,
399                               retry_token_length_, length_length_));
400 }
401 
Plaintext(QuicTransportVersion version) const402 absl::string_view QuicPacket::Plaintext(QuicTransportVersion version) const {
403   const size_t start_of_encrypted_data = GetStartOfEncryptedData(
404       version, destination_connection_id_length_, source_connection_id_length_,
405       includes_version_, includes_diversification_nonce_, packet_number_length_,
406       retry_token_length_length_, retry_token_length_, length_length_);
407   return absl::string_view(data() + start_of_encrypted_data,
408                            length() - start_of_encrypted_data);
409 }
410 
SerializedPacket(QuicPacketNumber packet_number,QuicPacketNumberLength packet_number_length,const char * encrypted_buffer,QuicPacketLength encrypted_length,bool has_ack,bool has_stop_waiting)411 SerializedPacket::SerializedPacket(QuicPacketNumber packet_number,
412                                    QuicPacketNumberLength packet_number_length,
413                                    const char* encrypted_buffer,
414                                    QuicPacketLength encrypted_length,
415                                    bool has_ack, bool has_stop_waiting)
416     : encrypted_buffer(encrypted_buffer),
417       encrypted_length(encrypted_length),
418       has_crypto_handshake(NOT_HANDSHAKE),
419       packet_number(packet_number),
420       packet_number_length(packet_number_length),
421       encryption_level(ENCRYPTION_INITIAL),
422       has_ack(has_ack),
423       has_stop_waiting(has_stop_waiting),
424       transmission_type(NOT_RETRANSMISSION),
425       has_ack_frame_copy(false),
426       has_ack_frequency(false),
427       has_message(false),
428       fate(SEND_TO_WRITER) {}
429 
SerializedPacket(SerializedPacket && other)430 SerializedPacket::SerializedPacket(SerializedPacket&& other)
431     : has_crypto_handshake(other.has_crypto_handshake),
432       packet_number(other.packet_number),
433       packet_number_length(other.packet_number_length),
434       encryption_level(other.encryption_level),
435       has_ack(other.has_ack),
436       has_stop_waiting(other.has_stop_waiting),
437       has_ack_ecn(other.has_ack_ecn),
438       transmission_type(other.transmission_type),
439       largest_acked(other.largest_acked),
440       has_ack_frame_copy(other.has_ack_frame_copy),
441       has_ack_frequency(other.has_ack_frequency),
442       has_message(other.has_message),
443       fate(other.fate),
444       peer_address(other.peer_address),
445       bytes_not_retransmitted(other.bytes_not_retransmitted),
446       initial_header(other.initial_header) {
447   if (this != &other) {
448     if (release_encrypted_buffer && encrypted_buffer != nullptr) {
449       release_encrypted_buffer(encrypted_buffer);
450     }
451     encrypted_buffer = other.encrypted_buffer;
452     encrypted_length = other.encrypted_length;
453     release_encrypted_buffer = std::move(other.release_encrypted_buffer);
454     other.release_encrypted_buffer = nullptr;
455 
456     retransmittable_frames.swap(other.retransmittable_frames);
457     nonretransmittable_frames.swap(other.nonretransmittable_frames);
458   }
459 }
460 
~SerializedPacket()461 SerializedPacket::~SerializedPacket() {
462   if (release_encrypted_buffer && encrypted_buffer != nullptr) {
463     release_encrypted_buffer(encrypted_buffer);
464   }
465 
466   if (!retransmittable_frames.empty()) {
467     DeleteFrames(&retransmittable_frames);
468   }
469   for (auto& frame : nonretransmittable_frames) {
470     if (!has_ack_frame_copy && frame.type == ACK_FRAME) {
471       // Do not delete ack frame if the packet does not own a copy of it.
472       continue;
473     }
474     DeleteFrame(&frame);
475   }
476 }
477 
CopySerializedPacket(const SerializedPacket & serialized,quiche::QuicheBufferAllocator * allocator,bool copy_buffer)478 SerializedPacket* CopySerializedPacket(const SerializedPacket& serialized,
479                                        quiche::QuicheBufferAllocator* allocator,
480                                        bool copy_buffer) {
481   SerializedPacket* copy = new SerializedPacket(
482       serialized.packet_number, serialized.packet_number_length,
483       serialized.encrypted_buffer, serialized.encrypted_length,
484       serialized.has_ack, serialized.has_stop_waiting);
485   copy->has_crypto_handshake = serialized.has_crypto_handshake;
486   copy->encryption_level = serialized.encryption_level;
487   copy->transmission_type = serialized.transmission_type;
488   copy->largest_acked = serialized.largest_acked;
489   copy->has_ack_frequency = serialized.has_ack_frequency;
490   copy->has_message = serialized.has_message;
491   copy->fate = serialized.fate;
492   copy->peer_address = serialized.peer_address;
493   copy->bytes_not_retransmitted = serialized.bytes_not_retransmitted;
494   copy->initial_header = serialized.initial_header;
495   copy->has_ack_ecn = serialized.has_ack_ecn;
496 
497   if (copy_buffer) {
498     copy->encrypted_buffer = CopyBuffer(serialized);
499     copy->release_encrypted_buffer = [](const char* p) { delete[] p; };
500   }
501   // Copy underlying frames.
502   copy->retransmittable_frames =
503       CopyQuicFrames(allocator, serialized.retransmittable_frames);
504   QUICHE_DCHECK(copy->nonretransmittable_frames.empty());
505   for (const auto& frame : serialized.nonretransmittable_frames) {
506     if (frame.type == ACK_FRAME) {
507       copy->has_ack_frame_copy = true;
508     }
509     copy->nonretransmittable_frames.push_back(CopyQuicFrame(allocator, frame));
510   }
511   return copy;
512 }
513 
CopyBuffer(const SerializedPacket & packet)514 char* CopyBuffer(const SerializedPacket& packet) {
515   return CopyBuffer(packet.encrypted_buffer, packet.encrypted_length);
516 }
517 
CopyBuffer(const char * encrypted_buffer,QuicPacketLength encrypted_length)518 char* CopyBuffer(const char* encrypted_buffer,
519                  QuicPacketLength encrypted_length) {
520   char* dst_buffer = new char[encrypted_length];
521   memcpy(dst_buffer, encrypted_buffer, encrypted_length);
522   return dst_buffer;
523 }
524 
ReceivedPacketInfo(const QuicSocketAddress & self_address,const QuicSocketAddress & peer_address,const QuicReceivedPacket & packet)525 ReceivedPacketInfo::ReceivedPacketInfo(const QuicSocketAddress& self_address,
526                                        const QuicSocketAddress& peer_address,
527                                        const QuicReceivedPacket& packet)
528     : self_address(self_address),
529       peer_address(peer_address),
530       packet(packet),
531       form(GOOGLE_QUIC_PACKET),
532       long_packet_type(INVALID_PACKET_TYPE),
533       version_flag(false),
534       use_length_prefix(false),
535       version_label(0),
536       version(ParsedQuicVersion::Unsupported()),
537       destination_connection_id(EmptyQuicConnectionId()),
538       source_connection_id(EmptyQuicConnectionId()) {}
539 
~ReceivedPacketInfo()540 ReceivedPacketInfo::~ReceivedPacketInfo() {}
541 
ToString() const542 std::string ReceivedPacketInfo::ToString() const {
543   std::string output =
544       absl::StrCat("{ self_address: ", self_address.ToString(),
545                    ", peer_address: ", peer_address.ToString(),
546                    ", packet_length: ", packet.length(),
547                    ", header_format: ", form, ", version_flag: ", version_flag);
548   if (version_flag) {
549     absl::StrAppend(&output, ", version: ", ParsedQuicVersionToString(version));
550   }
551   absl::StrAppend(
552       &output,
553       ", destination_connection_id: ", destination_connection_id.ToString(),
554       ", source_connection_id: ", source_connection_id.ToString(), " }\n");
555   return output;
556 }
557 
operator <<(std::ostream & os,const ReceivedPacketInfo & packet_info)558 std::ostream& operator<<(std::ostream& os,
559                          const ReceivedPacketInfo& packet_info) {
560   os << packet_info.ToString();
561   return os;
562 }
563 
operator ==(const QuicPacketHeader & other) const564 bool QuicPacketHeader::operator==(const QuicPacketHeader& other) const {
565   return destination_connection_id == other.destination_connection_id &&
566          destination_connection_id_included ==
567              other.destination_connection_id_included &&
568          source_connection_id == other.source_connection_id &&
569          source_connection_id_included == other.source_connection_id_included &&
570          reset_flag == other.reset_flag && version_flag == other.version_flag &&
571          has_possible_stateless_reset_token ==
572              other.has_possible_stateless_reset_token &&
573          packet_number_length == other.packet_number_length &&
574          type_byte == other.type_byte && version == other.version &&
575          nonce == other.nonce &&
576          ((!packet_number.IsInitialized() &&
577            !other.packet_number.IsInitialized()) ||
578           (packet_number.IsInitialized() &&
579            other.packet_number.IsInitialized() &&
580            packet_number == other.packet_number)) &&
581          form == other.form && long_packet_type == other.long_packet_type &&
582          possible_stateless_reset_token ==
583              other.possible_stateless_reset_token &&
584          retry_token_length_length == other.retry_token_length_length &&
585          retry_token == other.retry_token &&
586          length_length == other.length_length &&
587          remaining_packet_length == other.remaining_packet_length;
588 }
589 
operator !=(const QuicPacketHeader & other) const590 bool QuicPacketHeader::operator!=(const QuicPacketHeader& other) const {
591   return !operator==(other);
592 }
593 
594 }  // namespace quic
595