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