blob: d625b5dcb6aab91675d629ddb899cde893d12d0f [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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
QUICHE team5be974e2020-12-29 18:35:24 -05005#include "quic/core/quic_packets.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05006
bnc463f2352019-10-10 04:49:34 -07007#include <utility>
8
vasilvv72b789c2020-10-27 17:39:17 -07009#include "absl/strings/escaping.h"
vasilvv9edb31e2020-12-03 19:32:58 -080010#include "absl/strings/str_cat.h"
vasilvvc872ee42020-10-07 19:50:22 -070011#include "absl/strings/string_view.h"
QUICHE team5be974e2020-12-29 18:35:24 -050012#include "quic/core/quic_connection_id.h"
13#include "quic/core/quic_types.h"
14#include "quic/core/quic_utils.h"
15#include "quic/core/quic_versions.h"
16#include "quic/platform/api/quic_flag_utils.h"
17#include "quic/platform/api/quic_flags.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050018
19namespace quic {
20
QUICHE team2252b702019-05-14 23:55:14 -040021QuicConnectionId GetServerConnectionIdAsRecipient(
22 const QuicPacketHeader& header,
23 Perspective perspective) {
dschinazi5e1a7b22019-07-31 12:23:21 -070024 if (perspective == Perspective::IS_SERVER) {
QUICHE team2252b702019-05-14 23:55:14 -040025 return header.destination_connection_id;
26 }
27 return header.source_connection_id;
28}
29
dschinaziac6805d2019-05-30 09:44:27 -070030QuicConnectionId GetClientConnectionIdAsRecipient(
31 const QuicPacketHeader& header,
32 Perspective perspective) {
dschinaziac6805d2019-05-30 09:44:27 -070033 if (perspective == Perspective::IS_CLIENT) {
34 return header.destination_connection_id;
35 }
36 return header.source_connection_id;
37}
38
QUICHE team2252b702019-05-14 23:55:14 -040039QuicConnectionId GetServerConnectionIdAsSender(const QuicPacketHeader& header,
40 Perspective perspective) {
dschinazi5e1a7b22019-07-31 12:23:21 -070041 if (perspective == Perspective::IS_CLIENT) {
QUICHE team2252b702019-05-14 23:55:14 -040042 return header.destination_connection_id;
43 }
QUICHE team2252b702019-05-14 23:55:14 -040044 return header.source_connection_id;
45}
46
47QuicConnectionIdIncluded GetServerConnectionIdIncludedAsSender(
48 const QuicPacketHeader& header,
49 Perspective perspective) {
dschinazi5e1a7b22019-07-31 12:23:21 -070050 if (perspective == Perspective::IS_CLIENT) {
QUICHE team2252b702019-05-14 23:55:14 -040051 return header.destination_connection_id_included;
52 }
QUICHE team2252b702019-05-14 23:55:14 -040053 return header.source_connection_id_included;
54}
55
dschinaziac6805d2019-05-30 09:44:27 -070056QuicConnectionId GetClientConnectionIdAsSender(const QuicPacketHeader& header,
57 Perspective perspective) {
dschinazi5e1a7b22019-07-31 12:23:21 -070058 if (perspective == Perspective::IS_CLIENT) {
dschinaziac6805d2019-05-30 09:44:27 -070059 return header.source_connection_id;
60 }
dschinaziac6805d2019-05-30 09:44:27 -070061 return header.destination_connection_id;
62}
63
QUICHE team2252b702019-05-14 23:55:14 -040064QuicConnectionIdIncluded GetClientConnectionIdIncludedAsSender(
65 const QuicPacketHeader& header,
66 Perspective perspective) {
dschinazi5e1a7b22019-07-31 12:23:21 -070067 if (perspective == Perspective::IS_CLIENT) {
QUICHE team2252b702019-05-14 23:55:14 -040068 return header.source_connection_id_included;
69 }
70 return header.destination_connection_id_included;
71}
72
QUICHE teama6ef0a62019-03-07 20:34:33 -050073QuicConnectionIdLength GetIncludedConnectionIdLength(
74 QuicConnectionId connection_id,
75 QuicConnectionIdIncluded connection_id_included) {
vasilvvf8035162021-02-01 14:49:14 -080076 QUICHE_DCHECK(connection_id_included == CONNECTION_ID_PRESENT ||
77 connection_id_included == CONNECTION_ID_ABSENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -050078 return connection_id_included == CONNECTION_ID_PRESENT
79 ? static_cast<QuicConnectionIdLength>(connection_id.length())
80 : PACKET_0BYTE_CONNECTION_ID;
81}
82
83QuicConnectionIdLength GetIncludedDestinationConnectionIdLength(
84 const QuicPacketHeader& header) {
85 return GetIncludedConnectionIdLength(
86 header.destination_connection_id,
87 header.destination_connection_id_included);
88}
89
90QuicConnectionIdLength GetIncludedSourceConnectionIdLength(
91 const QuicPacketHeader& header) {
92 return GetIncludedConnectionIdLength(header.source_connection_id,
93 header.source_connection_id_included);
94}
95
96size_t GetPacketHeaderSize(QuicTransportVersion version,
97 const QuicPacketHeader& header) {
98 return GetPacketHeaderSize(
99 version, GetIncludedDestinationConnectionIdLength(header),
100 GetIncludedSourceConnectionIdLength(header), header.version_flag,
101 header.nonce != nullptr, header.packet_number_length,
102 header.retry_token_length_length, header.retry_token.length(),
103 header.length_length);
104}
105
106size_t GetPacketHeaderSize(
107 QuicTransportVersion version,
108 QuicConnectionIdLength destination_connection_id_length,
109 QuicConnectionIdLength source_connection_id_length,
110 bool include_version,
111 bool include_diversification_nonce,
112 QuicPacketNumberLength packet_number_length,
113 QuicVariableLengthIntegerLength retry_token_length_length,
114 QuicByteCount retry_token_length,
115 QuicVariableLengthIntegerLength length_length) {
fayangd4291e42019-05-30 10:31:21 -0700116 if (VersionHasIetfInvariantHeader(version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500117 if (include_version) {
118 // Long header.
nharperd43f1d62019-07-01 15:18:20 -0700119 size_t size = kPacketHeaderTypeSize + kConnectionIdLengthSize +
120 destination_connection_id_length +
fayang36825da2019-08-21 14:01:27 -0700121 source_connection_id_length + packet_number_length +
nharperd43f1d62019-07-01 15:18:20 -0700122 kQuicVersionSize;
123 if (include_diversification_nonce) {
124 size += kDiversificationNonceSize;
125 }
dschinazi48ac9192019-07-31 00:07:26 -0700126 if (VersionHasLengthPrefixedConnectionIds(version)) {
127 size += kConnectionIdLengthSize;
128 }
vasilvvf8035162021-02-01 14:49:14 -0800129 QUICHE_DCHECK(
130 QuicVersionHasLongHeaderLengths(version) ||
131 retry_token_length_length + retry_token_length + length_length == 0);
nharper405f7192019-09-11 08:28:06 -0700132 if (QuicVersionHasLongHeaderLengths(version)) {
nharperd43f1d62019-07-01 15:18:20 -0700133 size += retry_token_length_length + retry_token_length + length_length;
134 }
135 return size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500136 }
137 // Short header.
138 return kPacketHeaderTypeSize + destination_connection_id_length +
139 packet_number_length;
140 }
QUICHE team2252b702019-05-14 23:55:14 -0400141 // Google QUIC versions <= 43 can only carry one connection ID.
vasilvvf8035162021-02-01 14:49:14 -0800142 QUICHE_DCHECK(destination_connection_id_length == 0 ||
143 source_connection_id_length == 0);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500144 return kPublicFlagsSize + destination_connection_id_length +
QUICHE team2252b702019-05-14 23:55:14 -0400145 source_connection_id_length +
QUICHE teama6ef0a62019-03-07 20:34:33 -0500146 (include_version ? kQuicVersionSize : 0) + packet_number_length +
147 (include_diversification_nonce ? kDiversificationNonceSize : 0);
148}
149
150size_t GetStartOfEncryptedData(QuicTransportVersion version,
151 const QuicPacketHeader& header) {
152 return GetPacketHeaderSize(version, header);
153}
154
155size_t GetStartOfEncryptedData(
156 QuicTransportVersion version,
157 QuicConnectionIdLength destination_connection_id_length,
158 QuicConnectionIdLength source_connection_id_length,
159 bool include_version,
160 bool include_diversification_nonce,
161 QuicPacketNumberLength packet_number_length,
162 QuicVariableLengthIntegerLength retry_token_length_length,
163 QuicByteCount retry_token_length,
164 QuicVariableLengthIntegerLength length_length) {
165 // Encryption starts before private flags.
166 return GetPacketHeaderSize(
167 version, destination_connection_id_length, source_connection_id_length,
168 include_version, include_diversification_nonce, packet_number_length,
169 retry_token_length_length, retry_token_length, length_length);
170}
171
172QuicPacketHeader::QuicPacketHeader()
173 : destination_connection_id(EmptyQuicConnectionId()),
174 destination_connection_id_included(CONNECTION_ID_PRESENT),
175 source_connection_id(EmptyQuicConnectionId()),
176 source_connection_id_included(CONNECTION_ID_ABSENT),
177 reset_flag(false),
178 version_flag(false),
179 has_possible_stateless_reset_token(false),
180 packet_number_length(PACKET_4BYTE_PACKET_NUMBER),
181 version(UnsupportedQuicVersion()),
182 nonce(nullptr),
183 form(GOOGLE_QUIC_PACKET),
184 long_packet_type(INITIAL),
bnc1ccd0bc2021-04-07 10:20:17 -0700185 possible_stateless_reset_token({}),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500186 retry_token_length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
vasilvvc872ee42020-10-07 19:50:22 -0700187 retry_token(absl::string_view()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500188 length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
189 remaining_packet_length(0) {}
190
191QuicPacketHeader::QuicPacketHeader(const QuicPacketHeader& other) = default;
192
193QuicPacketHeader::~QuicPacketHeader() {}
194
danzhddf023a2019-12-20 13:33:36 -0800195QuicPacketHeader& QuicPacketHeader::operator=(const QuicPacketHeader& other) =
196 default;
197
QUICHE teama6ef0a62019-03-07 20:34:33 -0500198QuicPublicResetPacket::QuicPublicResetPacket()
199 : connection_id(EmptyQuicConnectionId()), nonce_proof(0) {}
200
201QuicPublicResetPacket::QuicPublicResetPacket(QuicConnectionId connection_id)
202 : connection_id(connection_id), nonce_proof(0) {}
203
204QuicVersionNegotiationPacket::QuicVersionNegotiationPacket()
205 : connection_id(EmptyQuicConnectionId()) {}
206
207QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
208 QuicConnectionId connection_id)
209 : connection_id(connection_id) {}
210
211QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
212 const QuicVersionNegotiationPacket& other) = default;
213
214QuicVersionNegotiationPacket::~QuicVersionNegotiationPacket() {}
215
216QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket()
bnc1ccd0bc2021-04-07 10:20:17 -0700217 : stateless_reset_token({}) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500218
219QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
220 const QuicPacketHeader& header,
bnc1ccd0bc2021-04-07 10:20:17 -0700221 StatelessResetToken token)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500222 : header(header), stateless_reset_token(token) {}
223
224QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
225 const QuicIetfStatelessResetPacket& other) = default;
226
227QuicIetfStatelessResetPacket::~QuicIetfStatelessResetPacket() {}
228
229std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) {
230 os << "{ destination_connection_id: " << header.destination_connection_id
231 << " ("
232 << (header.destination_connection_id_included == CONNECTION_ID_PRESENT
233 ? "present"
234 : "absent")
235 << "), source_connection_id: " << header.source_connection_id << " ("
236 << (header.source_connection_id_included == CONNECTION_ID_PRESENT
237 ? "present"
238 : "absent")
nharper4437e402020-01-06 16:47:08 -0800239 << "), packet_number_length: "
240 << static_cast<int>(header.packet_number_length)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500241 << ", reset_flag: " << header.reset_flag
242 << ", version_flag: " << header.version_flag;
243 if (header.version_flag) {
244 os << ", version: " << ParsedQuicVersionToString(header.version);
245 if (header.long_packet_type != INVALID_PACKET_TYPE) {
246 os << ", long_packet_type: "
247 << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
248 }
249 if (header.retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
250 os << ", retry_token_length_length: "
251 << static_cast<int>(header.retry_token_length_length);
252 }
253 if (header.retry_token.length() != 0) {
254 os << ", retry_token_length: " << header.retry_token.length();
255 }
256 if (header.length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
257 os << ", length_length: " << static_cast<int>(header.length_length);
258 }
259 if (header.remaining_packet_length != 0) {
260 os << ", remaining_packet_length: " << header.remaining_packet_length;
261 }
262 }
263 if (header.nonce != nullptr) {
264 os << ", diversification_nonce: "
vasilvv72b789c2020-10-27 17:39:17 -0700265 << absl::BytesToHexString(
vasilvvc872ee42020-10-07 19:50:22 -0700266 absl::string_view(header.nonce->data(), header.nonce->size()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500267 }
268 os << ", packet_number: " << header.packet_number << " }\n";
269 return os;
270}
271
272QuicData::QuicData(const char* buffer, size_t length)
273 : buffer_(buffer), length_(length), owns_buffer_(false) {}
274
275QuicData::QuicData(const char* buffer, size_t length, bool owns_buffer)
276 : buffer_(buffer), length_(length), owns_buffer_(owns_buffer) {}
277
vasilvvc872ee42020-10-07 19:50:22 -0700278QuicData::QuicData(absl::string_view packet_data)
dschinazi4b5a68a2019-08-15 15:45:36 -0700279 : buffer_(packet_data.data()),
280 length_(packet_data.length()),
281 owns_buffer_(false) {}
282
QUICHE teama6ef0a62019-03-07 20:34:33 -0500283QuicData::~QuicData() {
284 if (owns_buffer_) {
285 delete[] const_cast<char*>(buffer_);
286 }
287}
288
289QuicPacket::QuicPacket(
290 char* buffer,
291 size_t length,
292 bool owns_buffer,
293 QuicConnectionIdLength destination_connection_id_length,
294 QuicConnectionIdLength source_connection_id_length,
295 bool includes_version,
296 bool includes_diversification_nonce,
297 QuicPacketNumberLength packet_number_length,
298 QuicVariableLengthIntegerLength retry_token_length_length,
299 QuicByteCount retry_token_length,
300 QuicVariableLengthIntegerLength length_length)
301 : QuicData(buffer, length, owns_buffer),
302 buffer_(buffer),
303 destination_connection_id_length_(destination_connection_id_length),
304 source_connection_id_length_(source_connection_id_length),
305 includes_version_(includes_version),
306 includes_diversification_nonce_(includes_diversification_nonce),
307 packet_number_length_(packet_number_length),
308 retry_token_length_length_(retry_token_length_length),
309 retry_token_length_(retry_token_length),
310 length_length_(length_length) {}
311
dschinazi17d42422019-06-18 16:35:07 -0700312QuicPacket::QuicPacket(QuicTransportVersion /*version*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500313 char* buffer,
314 size_t length,
315 bool owns_buffer,
316 const QuicPacketHeader& header)
317 : QuicPacket(buffer,
318 length,
319 owns_buffer,
320 GetIncludedDestinationConnectionIdLength(header),
321 GetIncludedSourceConnectionIdLength(header),
322 header.version_flag,
323 header.nonce != nullptr,
324 header.packet_number_length,
325 header.retry_token_length_length,
326 header.retry_token.length(),
327 header.length_length) {}
328
329QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length)
330 : QuicData(buffer, length) {}
331
332QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer,
333 size_t length,
334 bool owns_buffer)
335 : QuicData(buffer, length, owns_buffer) {}
336
vasilvvc872ee42020-10-07 19:50:22 -0700337QuicEncryptedPacket::QuicEncryptedPacket(absl::string_view data)
dschinazi4b5a68a2019-08-15 15:45:36 -0700338 : QuicData(data) {}
339
QUICHE teama6ef0a62019-03-07 20:34:33 -0500340std::unique_ptr<QuicEncryptedPacket> QuicEncryptedPacket::Clone() const {
341 char* buffer = new char[this->length()];
342 memcpy(buffer, this->data(), this->length());
vasilvv0fc587f2019-09-06 13:33:08 -0700343 return std::make_unique<QuicEncryptedPacket>(buffer, this->length(), true);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500344}
345
346std::ostream& operator<<(std::ostream& os, const QuicEncryptedPacket& s) {
347 os << s.length() << "-byte data";
348 return os;
349}
350
351QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
352 size_t length,
353 QuicTime receipt_time)
354 : QuicReceivedPacket(buffer,
355 length,
356 receipt_time,
357 false /* owns_buffer */) {}
358
359QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
360 size_t length,
361 QuicTime receipt_time,
362 bool owns_buffer)
363 : QuicReceivedPacket(buffer,
364 length,
365 receipt_time,
366 owns_buffer,
367 0 /* ttl */,
368 true /* ttl_valid */) {}
369
370QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
371 size_t length,
372 QuicTime receipt_time,
373 bool owns_buffer,
374 int ttl,
375 bool ttl_valid)
376 : quic::QuicReceivedPacket(buffer,
377 length,
378 receipt_time,
379 owns_buffer,
380 ttl,
381 ttl_valid,
382 nullptr /* packet_headers */,
383 0 /* headers_length */,
384 false /* owns_header_buffer */) {}
385
386QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
387 size_t length,
388 QuicTime receipt_time,
389 bool owns_buffer,
390 int ttl,
391 bool ttl_valid,
392 char* packet_headers,
393 size_t headers_length,
394 bool owns_header_buffer)
395 : QuicEncryptedPacket(buffer, length, owns_buffer),
396 receipt_time_(receipt_time),
397 ttl_(ttl_valid ? ttl : -1),
398 packet_headers_(packet_headers),
399 headers_length_(headers_length),
400 owns_header_buffer_(owns_header_buffer) {}
401
402QuicReceivedPacket::~QuicReceivedPacket() {
403 if (owns_header_buffer_) {
404 delete[] static_cast<char*>(packet_headers_);
405 }
406}
407
408std::unique_ptr<QuicReceivedPacket> QuicReceivedPacket::Clone() const {
409 char* buffer = new char[this->length()];
410 memcpy(buffer, this->data(), this->length());
411 if (this->packet_headers()) {
412 char* headers_buffer = new char[this->headers_length()];
413 memcpy(headers_buffer, this->packet_headers(), this->headers_length());
vasilvv0fc587f2019-09-06 13:33:08 -0700414 return std::make_unique<QuicReceivedPacket>(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500415 buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0,
416 headers_buffer, this->headers_length(), true);
417 }
418
vasilvv0fc587f2019-09-06 13:33:08 -0700419 return std::make_unique<QuicReceivedPacket>(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500420 buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0);
421}
422
423std::ostream& operator<<(std::ostream& os, const QuicReceivedPacket& s) {
424 os << s.length() << "-byte data";
425 return os;
426}
427
vasilvvc872ee42020-10-07 19:50:22 -0700428absl::string_view QuicPacket::AssociatedData(
dmcardlecf0bfcf2019-12-13 08:08:21 -0800429 QuicTransportVersion version) const {
vasilvvc872ee42020-10-07 19:50:22 -0700430 return absl::string_view(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500431 data(),
432 GetStartOfEncryptedData(version, destination_connection_id_length_,
433 source_connection_id_length_, includes_version_,
434 includes_diversification_nonce_,
435 packet_number_length_, retry_token_length_length_,
436 retry_token_length_, length_length_));
437}
438
vasilvvc872ee42020-10-07 19:50:22 -0700439absl::string_view QuicPacket::Plaintext(QuicTransportVersion version) const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500440 const size_t start_of_encrypted_data = GetStartOfEncryptedData(
441 version, destination_connection_id_length_, source_connection_id_length_,
442 includes_version_, includes_diversification_nonce_, packet_number_length_,
443 retry_token_length_length_, retry_token_length_, length_length_);
vasilvvc872ee42020-10-07 19:50:22 -0700444 return absl::string_view(data() + start_of_encrypted_data,
445 length() - start_of_encrypted_data);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500446}
447
448SerializedPacket::SerializedPacket(QuicPacketNumber packet_number,
449 QuicPacketNumberLength packet_number_length,
450 const char* encrypted_buffer,
451 QuicPacketLength encrypted_length,
452 bool has_ack,
453 bool has_stop_waiting)
454 : encrypted_buffer(encrypted_buffer),
455 encrypted_length(encrypted_length),
456 has_crypto_handshake(NOT_HANDSHAKE),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500457 packet_number(packet_number),
458 packet_number_length(packet_number_length),
QUICHE team6987b4a2019-03-15 16:23:04 -0700459 encryption_level(ENCRYPTION_INITIAL),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500460 has_ack(has_ack),
461 has_stop_waiting(has_stop_waiting),
fayangfb5fb612019-10-21 13:19:14 -0700462 transmission_type(NOT_RETRANSMISSION),
fayang15042962020-07-01 12:14:29 -0700463 has_ack_frame_copy(false),
haoyuewang5b0f14f2020-09-18 14:31:54 -0700464 has_ack_frequency(false),
haoyuewang11a54a12020-09-21 14:17:29 -0700465 has_message(false),
fayang15042962020-07-01 12:14:29 -0700466 fate(SEND_TO_WRITER) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500467
QUICHE teama6ef0a62019-03-07 20:34:33 -0500468SerializedPacket::SerializedPacket(SerializedPacket&& other)
wub8a5dafa2020-05-13 12:30:17 -0700469 : has_crypto_handshake(other.has_crypto_handshake),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500470 packet_number(other.packet_number),
471 packet_number_length(other.packet_number_length),
472 encryption_level(other.encryption_level),
473 has_ack(other.has_ack),
474 has_stop_waiting(other.has_stop_waiting),
475 transmission_type(other.transmission_type),
fayangfb5fb612019-10-21 13:19:14 -0700476 largest_acked(other.largest_acked),
fayang15042962020-07-01 12:14:29 -0700477 has_ack_frame_copy(other.has_ack_frame_copy),
haoyuewang5b0f14f2020-09-18 14:31:54 -0700478 has_ack_frequency(other.has_ack_frequency),
haoyuewang11a54a12020-09-21 14:17:29 -0700479 has_message(other.has_message),
danzh051bf772020-08-24 12:30:36 -0700480 fate(other.fate),
481 peer_address(other.peer_address) {
wub8a5dafa2020-05-13 12:30:17 -0700482 if (this != &other) {
483 if (release_encrypted_buffer && encrypted_buffer != nullptr) {
484 release_encrypted_buffer(encrypted_buffer);
485 }
486 encrypted_buffer = other.encrypted_buffer;
487 encrypted_length = other.encrypted_length;
488 release_encrypted_buffer = std::move(other.release_encrypted_buffer);
489 other.release_encrypted_buffer = nullptr;
490
491 retransmittable_frames.swap(other.retransmittable_frames);
492 nonretransmittable_frames.swap(other.nonretransmittable_frames);
493 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500494}
495
wub8a5dafa2020-05-13 12:30:17 -0700496SerializedPacket::~SerializedPacket() {
497 if (release_encrypted_buffer && encrypted_buffer != nullptr) {
498 release_encrypted_buffer(encrypted_buffer);
499 }
500
501 if (!retransmittable_frames.empty()) {
502 DeleteFrames(&retransmittable_frames);
503 }
504 for (auto& frame : nonretransmittable_frames) {
505 if (!has_ack_frame_copy && frame.type == ACK_FRAME) {
506 // Do not delete ack frame if the packet does not own a copy of it.
507 continue;
508 }
509 DeleteFrame(&frame);
510 }
511}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500512
fayangfb5fb612019-10-21 13:19:14 -0700513SerializedPacket* CopySerializedPacket(const SerializedPacket& serialized,
514 QuicBufferAllocator* allocator,
515 bool copy_buffer) {
wub8a5dafa2020-05-13 12:30:17 -0700516 SerializedPacket* copy = new SerializedPacket(
517 serialized.packet_number, serialized.packet_number_length,
518 serialized.encrypted_buffer, serialized.encrypted_length,
519 serialized.has_ack, serialized.has_stop_waiting);
520 copy->has_crypto_handshake = serialized.has_crypto_handshake;
wub8a5dafa2020-05-13 12:30:17 -0700521 copy->encryption_level = serialized.encryption_level;
522 copy->transmission_type = serialized.transmission_type;
523 copy->largest_acked = serialized.largest_acked;
haoyuewang5b0f14f2020-09-18 14:31:54 -0700524 copy->has_ack_frequency = serialized.has_ack_frequency;
haoyuewang11a54a12020-09-21 14:17:29 -0700525 copy->has_message = serialized.has_message;
fayang15042962020-07-01 12:14:29 -0700526 copy->fate = serialized.fate;
danzh051bf772020-08-24 12:30:36 -0700527 copy->peer_address = serialized.peer_address;
wub8a5dafa2020-05-13 12:30:17 -0700528
fayangfb5fb612019-10-21 13:19:14 -0700529 if (copy_buffer) {
530 copy->encrypted_buffer = CopyBuffer(serialized);
wub8a5dafa2020-05-13 12:30:17 -0700531 copy->release_encrypted_buffer = [](const char* p) { delete[] p; };
fayangfb5fb612019-10-21 13:19:14 -0700532 }
533 // Copy underlying frames.
534 copy->retransmittable_frames =
535 CopyQuicFrames(allocator, serialized.retransmittable_frames);
vasilvvf8035162021-02-01 14:49:14 -0800536 QUICHE_DCHECK(copy->nonretransmittable_frames.empty());
fayangfb5fb612019-10-21 13:19:14 -0700537 for (const auto& frame : serialized.nonretransmittable_frames) {
538 if (frame.type == ACK_FRAME) {
539 copy->has_ack_frame_copy = true;
540 }
541 copy->nonretransmittable_frames.push_back(CopyQuicFrame(allocator, frame));
542 }
543 return copy;
544}
545
QUICHE teama6ef0a62019-03-07 20:34:33 -0500546char* CopyBuffer(const SerializedPacket& packet) {
wub8a5dafa2020-05-13 12:30:17 -0700547 return CopyBuffer(packet.encrypted_buffer, packet.encrypted_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500548}
549
fayang58f71072019-11-05 08:47:02 -0800550char* CopyBuffer(const char* encrypted_buffer,
551 QuicPacketLength encrypted_length) {
552 char* dst_buffer = new char[encrypted_length];
553 memcpy(dst_buffer, encrypted_buffer, encrypted_length);
554 return dst_buffer;
555}
556
fayang1ed1f762019-06-24 11:40:04 -0700557ReceivedPacketInfo::ReceivedPacketInfo(const QuicSocketAddress& self_address,
558 const QuicSocketAddress& peer_address,
559 const QuicReceivedPacket& packet)
560 : self_address(self_address),
561 peer_address(peer_address),
562 packet(packet),
563 form(GOOGLE_QUIC_PACKET),
fayange3f2f7b2019-09-19 17:01:57 -0700564 long_packet_type(INVALID_PACKET_TYPE),
fayang1ed1f762019-06-24 11:40:04 -0700565 version_flag(false),
dschinazi48ac9192019-07-31 00:07:26 -0700566 use_length_prefix(false),
fayang1ed1f762019-06-24 11:40:04 -0700567 version_label(0),
dschinazi5c1d7d82020-07-29 16:42:50 -0700568 version(ParsedQuicVersion::Unsupported()),
fayang1ed1f762019-06-24 11:40:04 -0700569 destination_connection_id(EmptyQuicConnectionId()),
570 source_connection_id(EmptyQuicConnectionId()) {}
571
572ReceivedPacketInfo::~ReceivedPacketInfo() {}
573
574std::string ReceivedPacketInfo::ToString() const {
vasilvv9edb31e2020-12-03 19:32:58 -0800575 std::string output =
576 absl::StrCat("{ self_address: ", self_address.ToString(),
577 ", peer_address: ", peer_address.ToString(),
578 ", packet_length: ", packet.length(),
579 ", header_format: ", form, ", version_flag: ", version_flag);
fayang1ed1f762019-06-24 11:40:04 -0700580 if (version_flag) {
vasilvv85577e02020-12-09 15:35:30 -0800581 absl::StrAppend(&output, ", version: ", ParsedQuicVersionToString(version));
fayang1ed1f762019-06-24 11:40:04 -0700582 }
vasilvv85577e02020-12-09 15:35:30 -0800583 absl::StrAppend(
fayang1ed1f762019-06-24 11:40:04 -0700584 &output,
585 ", destination_connection_id: ", destination_connection_id.ToString(),
586 ", source_connection_id: ", source_connection_id.ToString(), " }\n");
587 return output;
588}
589
590std::ostream& operator<<(std::ostream& os,
591 const ReceivedPacketInfo& packet_info) {
592 os << packet_info.ToString();
593 return os;
594}
595
QUICHE teama6ef0a62019-03-07 20:34:33 -0500596} // namespace quic