blob: 35212b5ef25a21cb693e3f9ed234606881dac46f [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
5#include "net/third_party/quiche/src/quic/core/quic_packets.h"
6
7#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
8#include "net/third_party/quiche/src/quic/core/quic_types.h"
9#include "net/third_party/quiche/src/quic/core/quic_utils.h"
10#include "net/third_party/quiche/src/quic/core/quic_versions.h"
rchf0a9f372019-05-15 21:36:43 -070011#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
17
18namespace quic {
19
QUICHE team2252b702019-05-14 23:55:14 -040020QuicConnectionId GetServerConnectionIdAsRecipient(
21 const QuicPacketHeader& header,
22 Perspective perspective) {
23 if (perspective == Perspective::IS_SERVER ||
24 !GetQuicRestartFlag(quic_do_not_override_connection_id)) {
25 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) {
33 DCHECK(GetQuicRestartFlag(quic_do_not_override_connection_id));
34 if (perspective == Perspective::IS_CLIENT) {
35 return header.destination_connection_id;
36 }
37 return header.source_connection_id;
38}
39
QUICHE team2252b702019-05-14 23:55:14 -040040QuicConnectionId GetServerConnectionIdAsSender(const QuicPacketHeader& header,
41 Perspective perspective) {
42 if (perspective == Perspective::IS_CLIENT ||
43 !GetQuicRestartFlag(quic_do_not_override_connection_id)) {
44 return header.destination_connection_id;
45 }
46 QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 3, 5);
47 return header.source_connection_id;
48}
49
50QuicConnectionIdIncluded GetServerConnectionIdIncludedAsSender(
51 const QuicPacketHeader& header,
52 Perspective perspective) {
53 if (perspective == Perspective::IS_CLIENT ||
54 !GetQuicRestartFlag(quic_do_not_override_connection_id)) {
55 return header.destination_connection_id_included;
56 }
57 QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 4, 5);
58 return header.source_connection_id_included;
59}
60
dschinaziac6805d2019-05-30 09:44:27 -070061QuicConnectionId GetClientConnectionIdAsSender(const QuicPacketHeader& header,
62 Perspective perspective) {
63 if (perspective == Perspective::IS_CLIENT ||
64 !GetQuicRestartFlag(quic_do_not_override_connection_id)) {
65 return header.source_connection_id;
66 }
67 QUIC_RESTART_FLAG_COUNT_N(quic_do_not_override_connection_id, 3, 5);
68 return header.destination_connection_id;
69}
70
QUICHE team2252b702019-05-14 23:55:14 -040071QuicConnectionIdIncluded GetClientConnectionIdIncludedAsSender(
72 const QuicPacketHeader& header,
73 Perspective perspective) {
74 if (perspective == Perspective::IS_CLIENT ||
75 !GetQuicRestartFlag(quic_do_not_override_connection_id)) {
76 return header.source_connection_id_included;
77 }
78 return header.destination_connection_id_included;
79}
80
QUICHE teama6ef0a62019-03-07 20:34:33 -050081QuicConnectionIdLength GetIncludedConnectionIdLength(
82 QuicConnectionId connection_id,
83 QuicConnectionIdIncluded connection_id_included) {
84 DCHECK(connection_id_included == CONNECTION_ID_PRESENT ||
85 connection_id_included == CONNECTION_ID_ABSENT);
86 return connection_id_included == CONNECTION_ID_PRESENT
87 ? static_cast<QuicConnectionIdLength>(connection_id.length())
88 : PACKET_0BYTE_CONNECTION_ID;
89}
90
91QuicConnectionIdLength GetIncludedDestinationConnectionIdLength(
92 const QuicPacketHeader& header) {
93 return GetIncludedConnectionIdLength(
94 header.destination_connection_id,
95 header.destination_connection_id_included);
96}
97
98QuicConnectionIdLength GetIncludedSourceConnectionIdLength(
99 const QuicPacketHeader& header) {
100 return GetIncludedConnectionIdLength(header.source_connection_id,
101 header.source_connection_id_included);
102}
103
104size_t GetPacketHeaderSize(QuicTransportVersion version,
105 const QuicPacketHeader& header) {
106 return GetPacketHeaderSize(
107 version, GetIncludedDestinationConnectionIdLength(header),
108 GetIncludedSourceConnectionIdLength(header), header.version_flag,
109 header.nonce != nullptr, header.packet_number_length,
110 header.retry_token_length_length, header.retry_token.length(),
111 header.length_length);
112}
113
114size_t GetPacketHeaderSize(
115 QuicTransportVersion version,
116 QuicConnectionIdLength destination_connection_id_length,
117 QuicConnectionIdLength source_connection_id_length,
118 bool include_version,
119 bool include_diversification_nonce,
120 QuicPacketNumberLength packet_number_length,
121 QuicVariableLengthIntegerLength retry_token_length_length,
122 QuicByteCount retry_token_length,
123 QuicVariableLengthIntegerLength length_length) {
fayangd4291e42019-05-30 10:31:21 -0700124 if (VersionHasIetfInvariantHeader(version)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500125 if (include_version) {
126 // Long header.
127 return kPacketHeaderTypeSize + kConnectionIdLengthSize +
128 destination_connection_id_length + source_connection_id_length +
fayang374888f2019-05-31 06:47:21 -0700129 packet_number_length + kQuicVersionSize +
QUICHE teama6ef0a62019-03-07 20:34:33 -0500130 (include_diversification_nonce ? kDiversificationNonceSize : 0) +
131 retry_token_length_length + retry_token_length + length_length;
132 }
133 // Short header.
134 return kPacketHeaderTypeSize + destination_connection_id_length +
135 packet_number_length;
136 }
QUICHE team2252b702019-05-14 23:55:14 -0400137 // Google QUIC versions <= 43 can only carry one connection ID.
138 DCHECK(destination_connection_id_length == 0 ||
139 source_connection_id_length == 0);
140 DCHECK(source_connection_id_length == 0 ||
141 GetQuicRestartFlag(quic_do_not_override_connection_id));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500142 return kPublicFlagsSize + destination_connection_id_length +
QUICHE team2252b702019-05-14 23:55:14 -0400143 source_connection_id_length +
QUICHE teama6ef0a62019-03-07 20:34:33 -0500144 (include_version ? kQuicVersionSize : 0) + packet_number_length +
145 (include_diversification_nonce ? kDiversificationNonceSize : 0);
146}
147
148size_t GetStartOfEncryptedData(QuicTransportVersion version,
149 const QuicPacketHeader& header) {
150 return GetPacketHeaderSize(version, header);
151}
152
153size_t GetStartOfEncryptedData(
154 QuicTransportVersion version,
155 QuicConnectionIdLength destination_connection_id_length,
156 QuicConnectionIdLength source_connection_id_length,
157 bool include_version,
158 bool include_diversification_nonce,
159 QuicPacketNumberLength packet_number_length,
160 QuicVariableLengthIntegerLength retry_token_length_length,
161 QuicByteCount retry_token_length,
162 QuicVariableLengthIntegerLength length_length) {
163 // Encryption starts before private flags.
164 return GetPacketHeaderSize(
165 version, destination_connection_id_length, source_connection_id_length,
166 include_version, include_diversification_nonce, packet_number_length,
167 retry_token_length_length, retry_token_length, length_length);
168}
169
170QuicPacketHeader::QuicPacketHeader()
171 : destination_connection_id(EmptyQuicConnectionId()),
172 destination_connection_id_included(CONNECTION_ID_PRESENT),
173 source_connection_id(EmptyQuicConnectionId()),
174 source_connection_id_included(CONNECTION_ID_ABSENT),
175 reset_flag(false),
176 version_flag(false),
177 has_possible_stateless_reset_token(false),
178 packet_number_length(PACKET_4BYTE_PACKET_NUMBER),
179 version(UnsupportedQuicVersion()),
180 nonce(nullptr),
181 form(GOOGLE_QUIC_PACKET),
182 long_packet_type(INITIAL),
183 possible_stateless_reset_token(0),
184 retry_token_length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
185 retry_token(QuicStringPiece()),
186 length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
187 remaining_packet_length(0) {}
188
189QuicPacketHeader::QuicPacketHeader(const QuicPacketHeader& other) = default;
190
191QuicPacketHeader::~QuicPacketHeader() {}
192
193QuicPublicResetPacket::QuicPublicResetPacket()
194 : connection_id(EmptyQuicConnectionId()), nonce_proof(0) {}
195
196QuicPublicResetPacket::QuicPublicResetPacket(QuicConnectionId connection_id)
197 : connection_id(connection_id), nonce_proof(0) {}
198
199QuicVersionNegotiationPacket::QuicVersionNegotiationPacket()
200 : connection_id(EmptyQuicConnectionId()) {}
201
202QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
203 QuicConnectionId connection_id)
204 : connection_id(connection_id) {}
205
206QuicVersionNegotiationPacket::QuicVersionNegotiationPacket(
207 const QuicVersionNegotiationPacket& other) = default;
208
209QuicVersionNegotiationPacket::~QuicVersionNegotiationPacket() {}
210
211QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket()
212 : stateless_reset_token(0) {}
213
214QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
215 const QuicPacketHeader& header,
216 QuicUint128 token)
217 : header(header), stateless_reset_token(token) {}
218
219QuicIetfStatelessResetPacket::QuicIetfStatelessResetPacket(
220 const QuicIetfStatelessResetPacket& other) = default;
221
222QuicIetfStatelessResetPacket::~QuicIetfStatelessResetPacket() {}
223
224std::ostream& operator<<(std::ostream& os, const QuicPacketHeader& header) {
225 os << "{ destination_connection_id: " << header.destination_connection_id
226 << " ("
227 << (header.destination_connection_id_included == CONNECTION_ID_PRESENT
228 ? "present"
229 : "absent")
230 << "), source_connection_id: " << header.source_connection_id << " ("
231 << (header.source_connection_id_included == CONNECTION_ID_PRESENT
232 ? "present"
233 : "absent")
234 << "), packet_number_length: " << header.packet_number_length
235 << ", reset_flag: " << header.reset_flag
236 << ", version_flag: " << header.version_flag;
237 if (header.version_flag) {
238 os << ", version: " << ParsedQuicVersionToString(header.version);
239 if (header.long_packet_type != INVALID_PACKET_TYPE) {
240 os << ", long_packet_type: "
241 << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
242 }
243 if (header.retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
244 os << ", retry_token_length_length: "
245 << static_cast<int>(header.retry_token_length_length);
246 }
247 if (header.retry_token.length() != 0) {
248 os << ", retry_token_length: " << header.retry_token.length();
249 }
250 if (header.length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
251 os << ", length_length: " << static_cast<int>(header.length_length);
252 }
253 if (header.remaining_packet_length != 0) {
254 os << ", remaining_packet_length: " << header.remaining_packet_length;
255 }
256 }
257 if (header.nonce != nullptr) {
258 os << ", diversification_nonce: "
259 << QuicTextUtils::HexEncode(
260 QuicStringPiece(header.nonce->data(), header.nonce->size()));
261 }
262 os << ", packet_number: " << header.packet_number << " }\n";
263 return os;
264}
265
266QuicData::QuicData(const char* buffer, size_t length)
267 : buffer_(buffer), length_(length), owns_buffer_(false) {}
268
269QuicData::QuicData(const char* buffer, size_t length, bool owns_buffer)
270 : buffer_(buffer), length_(length), owns_buffer_(owns_buffer) {}
271
272QuicData::~QuicData() {
273 if (owns_buffer_) {
274 delete[] const_cast<char*>(buffer_);
275 }
276}
277
278QuicPacket::QuicPacket(
279 char* buffer,
280 size_t length,
281 bool owns_buffer,
282 QuicConnectionIdLength destination_connection_id_length,
283 QuicConnectionIdLength source_connection_id_length,
284 bool includes_version,
285 bool includes_diversification_nonce,
286 QuicPacketNumberLength packet_number_length,
287 QuicVariableLengthIntegerLength retry_token_length_length,
288 QuicByteCount retry_token_length,
289 QuicVariableLengthIntegerLength 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
301QuicPacket::QuicPacket(QuicTransportVersion version,
302 char* buffer,
303 size_t length,
304 bool owns_buffer,
305 const QuicPacketHeader& header)
306 : QuicPacket(buffer,
307 length,
308 owns_buffer,
309 GetIncludedDestinationConnectionIdLength(header),
310 GetIncludedSourceConnectionIdLength(header),
311 header.version_flag,
312 header.nonce != nullptr,
313 header.packet_number_length,
314 header.retry_token_length_length,
315 header.retry_token.length(),
316 header.length_length) {}
317
318QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length)
319 : QuicData(buffer, length) {}
320
321QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer,
322 size_t length,
323 bool owns_buffer)
324 : QuicData(buffer, length, owns_buffer) {}
325
326std::unique_ptr<QuicEncryptedPacket> QuicEncryptedPacket::Clone() const {
327 char* buffer = new char[this->length()];
328 memcpy(buffer, this->data(), this->length());
329 return QuicMakeUnique<QuicEncryptedPacket>(buffer, this->length(), true);
330}
331
332std::ostream& operator<<(std::ostream& os, const QuicEncryptedPacket& s) {
333 os << s.length() << "-byte data";
334 return os;
335}
336
337QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
338 size_t length,
339 QuicTime receipt_time)
340 : QuicReceivedPacket(buffer,
341 length,
342 receipt_time,
343 false /* owns_buffer */) {}
344
345QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
346 size_t length,
347 QuicTime receipt_time,
348 bool owns_buffer)
349 : QuicReceivedPacket(buffer,
350 length,
351 receipt_time,
352 owns_buffer,
353 0 /* ttl */,
354 true /* ttl_valid */) {}
355
356QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
357 size_t length,
358 QuicTime receipt_time,
359 bool owns_buffer,
360 int ttl,
361 bool ttl_valid)
362 : quic::QuicReceivedPacket(buffer,
363 length,
364 receipt_time,
365 owns_buffer,
366 ttl,
367 ttl_valid,
368 nullptr /* packet_headers */,
369 0 /* headers_length */,
370 false /* owns_header_buffer */) {}
371
372QuicReceivedPacket::QuicReceivedPacket(const char* buffer,
373 size_t length,
374 QuicTime receipt_time,
375 bool owns_buffer,
376 int ttl,
377 bool ttl_valid,
378 char* packet_headers,
379 size_t headers_length,
380 bool owns_header_buffer)
381 : QuicEncryptedPacket(buffer, length, owns_buffer),
382 receipt_time_(receipt_time),
383 ttl_(ttl_valid ? ttl : -1),
384 packet_headers_(packet_headers),
385 headers_length_(headers_length),
386 owns_header_buffer_(owns_header_buffer) {}
387
388QuicReceivedPacket::~QuicReceivedPacket() {
389 if (owns_header_buffer_) {
390 delete[] static_cast<char*>(packet_headers_);
391 }
392}
393
394std::unique_ptr<QuicReceivedPacket> QuicReceivedPacket::Clone() const {
395 char* buffer = new char[this->length()];
396 memcpy(buffer, this->data(), this->length());
397 if (this->packet_headers()) {
398 char* headers_buffer = new char[this->headers_length()];
399 memcpy(headers_buffer, this->packet_headers(), this->headers_length());
400 return QuicMakeUnique<QuicReceivedPacket>(
401 buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0,
402 headers_buffer, this->headers_length(), true);
403 }
404
405 return QuicMakeUnique<QuicReceivedPacket>(
406 buffer, this->length(), receipt_time(), true, ttl(), ttl() >= 0);
407}
408
409std::ostream& operator<<(std::ostream& os, const QuicReceivedPacket& s) {
410 os << s.length() << "-byte data";
411 return os;
412}
413
414QuicStringPiece QuicPacket::AssociatedData(QuicTransportVersion version) const {
415 return QuicStringPiece(
416 data(),
417 GetStartOfEncryptedData(version, destination_connection_id_length_,
418 source_connection_id_length_, includes_version_,
419 includes_diversification_nonce_,
420 packet_number_length_, retry_token_length_length_,
421 retry_token_length_, length_length_));
422}
423
424QuicStringPiece QuicPacket::Plaintext(QuicTransportVersion version) const {
425 const size_t start_of_encrypted_data = GetStartOfEncryptedData(
426 version, destination_connection_id_length_, source_connection_id_length_,
427 includes_version_, includes_diversification_nonce_, packet_number_length_,
428 retry_token_length_length_, retry_token_length_, length_length_);
429 return QuicStringPiece(data() + start_of_encrypted_data,
430 length() - start_of_encrypted_data);
431}
432
433SerializedPacket::SerializedPacket(QuicPacketNumber packet_number,
434 QuicPacketNumberLength packet_number_length,
435 const char* encrypted_buffer,
436 QuicPacketLength encrypted_length,
437 bool has_ack,
438 bool has_stop_waiting)
439 : encrypted_buffer(encrypted_buffer),
440 encrypted_length(encrypted_length),
441 has_crypto_handshake(NOT_HANDSHAKE),
442 num_padding_bytes(0),
443 packet_number(packet_number),
444 packet_number_length(packet_number_length),
QUICHE team6987b4a2019-03-15 16:23:04 -0700445 encryption_level(ENCRYPTION_INITIAL),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500446 has_ack(has_ack),
447 has_stop_waiting(has_stop_waiting),
448 transmission_type(NOT_RETRANSMISSION) {}
449
450SerializedPacket::SerializedPacket(const SerializedPacket& other) = default;
451
452SerializedPacket& SerializedPacket::operator=(const SerializedPacket& other) =
453 default;
454
455SerializedPacket::SerializedPacket(SerializedPacket&& other)
456 : encrypted_buffer(other.encrypted_buffer),
457 encrypted_length(other.encrypted_length),
458 has_crypto_handshake(other.has_crypto_handshake),
459 num_padding_bytes(other.num_padding_bytes),
460 packet_number(other.packet_number),
461 packet_number_length(other.packet_number_length),
462 encryption_level(other.encryption_level),
463 has_ack(other.has_ack),
464 has_stop_waiting(other.has_stop_waiting),
465 transmission_type(other.transmission_type),
466 original_packet_number(other.original_packet_number),
467 largest_acked(other.largest_acked) {
468 retransmittable_frames.swap(other.retransmittable_frames);
469}
470
471SerializedPacket::~SerializedPacket() {}
472
473void ClearSerializedPacket(SerializedPacket* serialized_packet) {
474 if (!serialized_packet->retransmittable_frames.empty()) {
475 DeleteFrames(&serialized_packet->retransmittable_frames);
476 }
477 serialized_packet->encrypted_buffer = nullptr;
478 serialized_packet->encrypted_length = 0;
479 serialized_packet->largest_acked.Clear();
480}
481
482char* CopyBuffer(const SerializedPacket& packet) {
483 char* dst_buffer = new char[packet.encrypted_length];
484 memcpy(dst_buffer, packet.encrypted_buffer, packet.encrypted_length);
485 return dst_buffer;
486}
487
488} // namespace quic