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