blob: 6674ef4463dcaad3d6c6693915cbf113a4402120 [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_packet_creator.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05006
7#include <algorithm>
renjietang4c704c82019-10-07 16:39:11 -07008#include <cstddef>
QUICHE teama6ef0a62019-03-07 20:34:33 -05009#include <cstdint>
dschinazied459c02020-05-07 16:12:23 -070010#include <limits>
vasilvv872e7a32019-03-12 16:42:44 -070011#include <string>
bnc463f2352019-10-10 04:49:34 -070012#include <utility>
QUICHE teama6ef0a62019-03-07 20:34:33 -050013
vasilvvbed67c62020-10-20 06:38:43 -070014#include "absl/base/macros.h"
vasilvvf903e602020-10-26 18:06:12 -070015#include "absl/base/optimization.h"
vasilvv9edb31e2020-12-03 19:32:58 -080016#include "absl/strings/str_cat.h"
vasilvvc872ee42020-10-07 19:50:22 -070017#include "absl/strings/string_view.h"
dschinazicb6b5102021-04-28 08:16:40 -070018#include "absl/types/optional.h"
QUICHE team5be974e2020-12-29 18:35:24 -050019#include "quic/core/crypto/crypto_protocol.h"
20#include "quic/core/frames/quic_frame.h"
21#include "quic/core/frames/quic_path_challenge_frame.h"
22#include "quic/core/frames/quic_stream_frame.h"
dschinazicb6b5102021-04-28 08:16:40 -070023#include "quic/core/quic_chaos_protector.h"
QUICHE team5be974e2020-12-29 18:35:24 -050024#include "quic/core/quic_connection_id.h"
25#include "quic/core/quic_constants.h"
26#include "quic/core/quic_data_writer.h"
27#include "quic/core/quic_error_codes.h"
28#include "quic/core/quic_types.h"
29#include "quic/core/quic_utils.h"
30#include "quic/core/quic_versions.h"
31#include "quic/platform/api/quic_bug_tracker.h"
32#include "quic/platform/api/quic_exported_stats.h"
33#include "quic/platform/api/quic_flag_utils.h"
34#include "quic/platform/api/quic_flags.h"
35#include "quic/platform/api/quic_logging.h"
36#include "quic/platform/api/quic_server_stats.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050037
38namespace quic {
39namespace {
40
41QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
42 switch (level) {
QUICHE team6987b4a2019-03-15 16:23:04 -070043 case ENCRYPTION_INITIAL:
QUICHE teama6ef0a62019-03-07 20:34:33 -050044 return INITIAL;
QUICHE team88ea0082019-03-15 10:05:26 -070045 case ENCRYPTION_HANDSHAKE:
46 return HANDSHAKE;
QUICHE teama6ef0a62019-03-07 20:34:33 -050047 case ENCRYPTION_ZERO_RTT:
48 return ZERO_RTT_PROTECTED;
49 case ENCRYPTION_FORWARD_SECURE:
QUICHE team7939a6e2021-03-16 19:47:54 -070050 QUIC_BUG(quic_bug_12398_1)
QUICHE teama6ef0a62019-03-07 20:34:33 -050051 << "Try to derive long header type for packet with encryption level: "
renjietangb4ebb1d2020-05-27 18:15:51 -070052 << level;
QUICHE teama6ef0a62019-03-07 20:34:33 -050053 return INVALID_PACKET_TYPE;
54 default:
QUICHE team7939a6e2021-03-16 19:47:54 -070055 QUIC_BUG(quic_bug_10752_1) << level;
QUICHE teama6ef0a62019-03-07 20:34:33 -050056 return INVALID_PACKET_TYPE;
57 }
58}
59
renjietang50ea92a2019-12-26 10:15:01 -080060void LogCoalesceStreamFrameStatus(bool success) {
renjietang261e03d2020-02-18 12:55:24 -080061 QUIC_HISTOGRAM_BOOL("QuicSession.CoalesceStreamFrameStatus", success,
62 "Success rate of coalesing stream frames attempt.");
renjietang50ea92a2019-12-26 10:15:01 -080063}
64
fayang08750832019-10-24 11:25:34 -070065// ScopedPacketContextSwitcher saves |packet|'s states and change states
66// during its construction. When the switcher goes out of scope, it restores
67// saved states.
68class ScopedPacketContextSwitcher {
69 public:
70 ScopedPacketContextSwitcher(QuicPacketNumber packet_number,
71 QuicPacketNumberLength packet_number_length,
72 EncryptionLevel encryption_level,
73 SerializedPacket* packet)
74
75 : saved_packet_number_(packet->packet_number),
76 saved_packet_number_length_(packet->packet_number_length),
77 saved_encryption_level_(packet->encryption_level),
78 packet_(packet) {
79 packet_->packet_number = packet_number,
80 packet_->packet_number_length = packet_number_length;
81 packet_->encryption_level = encryption_level;
82 }
83
84 ~ScopedPacketContextSwitcher() {
85 packet_->packet_number = saved_packet_number_;
86 packet_->packet_number_length = saved_packet_number_length_;
87 packet_->encryption_level = saved_encryption_level_;
88 }
89
90 private:
91 const QuicPacketNumber saved_packet_number_;
92 const QuicPacketNumberLength saved_packet_number_length_;
93 const EncryptionLevel saved_encryption_level_;
94 SerializedPacket* packet_;
95};
96
QUICHE teama6ef0a62019-03-07 20:34:33 -050097} // namespace
98
99#define ENDPOINT \
100 (framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
101
dschinazi7b9278c2019-05-20 07:36:21 -0700102QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500103 QuicFramer* framer,
104 DelegateInterface* delegate)
dschinazi7b9278c2019-05-20 07:36:21 -0700105 : QuicPacketCreator(server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500106 framer,
107 QuicRandom::GetInstance(),
108 delegate) {}
109
dschinazi7b9278c2019-05-20 07:36:21 -0700110QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500111 QuicFramer* framer,
112 QuicRandom* random,
113 DelegateInterface* delegate)
114 : delegate_(delegate),
115 debug_delegate_(nullptr),
116 framer_(framer),
117 random_(random),
118 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
119 have_diversification_nonce_(false),
120 max_packet_length_(0),
dschinazi7b9278c2019-05-20 07:36:21 -0700121 server_connection_id_included_(CONNECTION_ID_PRESENT),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500122 packet_size_(0),
dschinazi7b9278c2019-05-20 07:36:21 -0700123 server_connection_id_(server_connection_id),
dschinazi346b7ce2019-06-05 01:38:18 -0700124 client_connection_id_(EmptyQuicConnectionId()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500125 packet_(QuicPacketNumber(),
126 PACKET_1BYTE_PACKET_NUMBER,
127 nullptr,
128 0,
129 false,
130 false),
131 pending_padding_bytes_(0),
132 needs_full_padding_(false),
fayang18be79a2019-09-16 15:17:12 -0700133 next_transmission_type_(NOT_RETRANSMISSION),
134 flusher_attached_(false),
135 fully_pad_crypto_handshake_packets_(true),
dschinazied459c02020-05-07 16:12:23 -0700136 latched_hard_max_packet_length_(0),
dschinazicb6b5102021-04-28 08:16:40 -0700137 max_datagram_frame_size_(0),
138 chaos_protection_enabled_(false) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500139 SetMaxPacketLength(kDefaultMaxPacketSize);
dschinazied459c02020-05-07 16:12:23 -0700140 if (!framer_->version().UsesTls()) {
141 // QUIC+TLS negotiates the maximum datagram frame size via the
142 // IETF QUIC max_datagram_frame_size transport parameter.
143 // QUIC_CRYPTO however does not negotiate this so we set its value here.
144 SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
145 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500146}
147
148QuicPacketCreator::~QuicPacketCreator() {
149 DeleteFrames(&packet_.retransmittable_frames);
150}
151
152void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
153 std::unique_ptr<QuicEncrypter> encrypter) {
154 framer_->SetEncrypter(level, std::move(encrypter));
155 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
156}
157
158bool QuicPacketCreator::CanSetMaxPacketLength() const {
159 // |max_packet_length_| should not be changed mid-packet.
160 return queued_frames_.empty();
161}
162
163void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
dschinazi640536f2021-04-16 10:31:22 -0700164 QUICHE_DCHECK(CanSetMaxPacketLength()) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500165
166 // Avoid recomputing |max_plaintext_size_| if the length does not actually
167 // change.
168 if (length == max_packet_length_) {
169 return;
170 }
dschinazi640536f2021-04-16 10:31:22 -0700171 QUIC_DVLOG(1) << ENDPOINT << "Updating packet creator max packet length from "
dschinazi6458eb32020-06-23 12:38:41 -0700172 << max_packet_length_ << " to " << length;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500173
174 max_packet_length_ = length;
175 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
QUICHE team7939a6e2021-03-16 19:47:54 -0700176 QUIC_BUG_IF(quic_bug_12398_2, max_plaintext_size_ - PacketHeaderSize() <
177 MinPlaintextPacketSize(framer_->version()))
dschinazi640536f2021-04-16 10:31:22 -0700178 << ENDPOINT << "Attempted to set max packet length too small";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500179}
180
dschinazied459c02020-05-07 16:12:23 -0700181void QuicPacketCreator::SetMaxDatagramFrameSize(
182 QuicByteCount max_datagram_frame_size) {
183 constexpr QuicByteCount upper_bound =
184 std::min<QuicByteCount>(std::numeric_limits<QuicPacketLength>::max(),
185 std::numeric_limits<size_t>::max());
186 if (max_datagram_frame_size > upper_bound) {
187 // A value of |max_datagram_frame_size| that is equal or greater than
188 // 2^16-1 is effectively infinite because QUIC packets cannot be that large.
189 // We therefore clamp the value here to allow us to safely cast
190 // |max_datagram_frame_size_| to QuicPacketLength or size_t.
191 max_datagram_frame_size = upper_bound;
192 }
193 max_datagram_frame_size_ = max_datagram_frame_size;
194}
195
fayang2ab1e852019-11-04 11:24:36 -0800196void QuicPacketCreator::SetSoftMaxPacketLength(QuicByteCount length) {
dschinazi640536f2021-04-16 10:31:22 -0700197 QUICHE_DCHECK(CanSetMaxPacketLength()) << ENDPOINT;
fayang2ab1e852019-11-04 11:24:36 -0800198 if (length > max_packet_length_) {
QUICHE team7939a6e2021-03-16 19:47:54 -0700199 QUIC_BUG(quic_bug_10752_2)
QUICHE team8e6da712021-03-08 10:59:32 -0800200 << ENDPOINT
201 << "Try to increase max_packet_length_ in "
202 "SetSoftMaxPacketLength, use SetMaxPacketLength instead.";
fayang2ab1e852019-11-04 11:24:36 -0800203 return;
204 }
205 if (framer_->GetMaxPlaintextSize(length) <
206 PacketHeaderSize() + MinPlaintextPacketSize(framer_->version())) {
fayang04bd30d2020-06-22 15:04:57 -0700207 // Please note: this would not guarantee to fit next packet if the size of
208 // packet header increases (e.g., encryption level changes).
dschinazi640536f2021-04-16 10:31:22 -0700209 QUIC_DLOG(INFO) << ENDPOINT << length
210 << " is too small to fit packet header";
fayangf5f83e52020-09-14 10:29:29 -0700211 RemoveSoftMaxPacketLength();
fayang2ab1e852019-11-04 11:24:36 -0800212 return;
213 }
dschinazi640536f2021-04-16 10:31:22 -0700214 QUIC_DVLOG(1) << ENDPOINT << "Setting soft max packet length to: " << length;
fayang2ab1e852019-11-04 11:24:36 -0800215 latched_hard_max_packet_length_ = max_packet_length_;
216 max_packet_length_ = length;
217 max_plaintext_size_ = framer_->GetMaxPlaintextSize(length);
218}
219
QUICHE teama6ef0a62019-03-07 20:34:33 -0500220// Stops serializing version of the protocol in packets sent after this call.
221// A packet that is already open might send kQuicVersionSize bytes less than the
222// maximum packet size if we stop sending version before it is serialized.
223void QuicPacketCreator::StopSendingVersion() {
dschinazi640536f2021-04-16 10:31:22 -0700224 QUICHE_DCHECK(send_version_in_packet_) << ENDPOINT;
225 QUICHE_DCHECK(!version().HasIetfInvariantHeader()) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500226 send_version_in_packet_ = false;
227 if (packet_size_ > 0) {
dschinazi640536f2021-04-16 10:31:22 -0700228 QUICHE_DCHECK_LT(kQuicVersionSize, packet_size_) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500229 packet_size_ -= kQuicVersionSize;
230 }
231}
232
233void QuicPacketCreator::SetDiversificationNonce(
234 const DiversificationNonce& nonce) {
dschinazi640536f2021-04-16 10:31:22 -0700235 QUICHE_DCHECK(!have_diversification_nonce_) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500236 have_diversification_nonce_ = true;
237 diversification_nonce_ = nonce;
238}
239
240void QuicPacketCreator::UpdatePacketNumberLength(
241 QuicPacketNumber least_packet_awaited_by_peer,
242 QuicPacketCount max_packets_in_flight) {
243 if (!queued_frames_.empty()) {
244 // Don't change creator state if there are frames queued.
QUICHE team7939a6e2021-03-16 19:47:54 -0700245 QUIC_BUG(quic_bug_10752_3)
dschinazi640536f2021-04-16 10:31:22 -0700246 << ENDPOINT << "Called UpdatePacketNumberLength with "
247 << queued_frames_.size()
QUICHE team8e6da712021-03-08 10:59:32 -0800248 << " queued_frames. First frame type:" << queued_frames_.front().type
249 << " last frame type:" << queued_frames_.back().type;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500250 return;
251 }
252
dschinazi101d2eb2020-07-06 19:42:34 -0700253 const QuicPacketNumber next_packet_number = NextSendingPacketNumber();
dschinazi640536f2021-04-16 10:31:22 -0700254 QUICHE_DCHECK_LE(least_packet_awaited_by_peer, next_packet_number)
255 << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500256 const uint64_t current_delta =
dschinazi101d2eb2020-07-06 19:42:34 -0700257 next_packet_number - least_packet_awaited_by_peer;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500258 const uint64_t delta = std::max(current_delta, max_packets_in_flight);
dschinazi101d2eb2020-07-06 19:42:34 -0700259 const QuicPacketNumberLength packet_number_length =
renjietang488201d2019-12-17 13:40:49 -0800260 QuicFramer::GetMinPacketNumberLength(QuicPacketNumber(delta * 4));
dschinazi101d2eb2020-07-06 19:42:34 -0700261 if (packet_.packet_number_length == packet_number_length) {
262 return;
263 }
ianswettf2bc2962020-12-07 09:48:53 -0800264 QUIC_DVLOG(1) << ENDPOINT << "Updating packet number length from "
265 << static_cast<int>(packet_.packet_number_length) << " to "
266 << static_cast<int>(packet_number_length)
267 << ", least_packet_awaited_by_peer: "
268 << least_packet_awaited_by_peer
269 << " max_packets_in_flight: " << max_packets_in_flight
270 << " next_packet_number: " << next_packet_number;
dschinazi101d2eb2020-07-06 19:42:34 -0700271 packet_.packet_number_length = packet_number_length;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500272}
273
fayang4c1c2362019-09-13 07:20:01 -0700274void QuicPacketCreator::SkipNPacketNumbers(
275 QuicPacketCount count,
276 QuicPacketNumber least_packet_awaited_by_peer,
277 QuicPacketCount max_packets_in_flight) {
278 if (!queued_frames_.empty()) {
279 // Don't change creator state if there are frames queued.
QUICHE team7939a6e2021-03-16 19:47:54 -0700280 QUIC_BUG(quic_bug_10752_4)
dschinazi640536f2021-04-16 10:31:22 -0700281 << ENDPOINT << "Called SkipNPacketNumbers with "
282 << queued_frames_.size()
QUICHE team8e6da712021-03-08 10:59:32 -0800283 << " queued_frames. First frame type:" << queued_frames_.front().type
284 << " last frame type:" << queued_frames_.back().type;
fayang4c1c2362019-09-13 07:20:01 -0700285 return;
286 }
287 if (packet_.packet_number > packet_.packet_number + count) {
288 // Skipping count packet numbers causes packet number wrapping around,
289 // reject it.
dschinazi640536f2021-04-16 10:31:22 -0700290 QUIC_LOG(WARNING) << ENDPOINT << "Skipping " << count
fayang4c1c2362019-09-13 07:20:01 -0700291 << " packet numbers causes packet number wrapping "
292 "around, least_packet_awaited_by_peer: "
293 << least_packet_awaited_by_peer
294 << " packet_number:" << packet_.packet_number;
295 return;
296 }
297 packet_.packet_number += count;
298 // Packet number changes, update packet number length if necessary.
299 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight);
300}
301
fayang62b637b2019-09-16 08:40:49 -0700302bool QuicPacketCreator::ConsumeCryptoDataToFillCurrentPacket(
303 EncryptionLevel level,
304 size_t write_length,
305 QuicStreamOffset offset,
306 bool needs_full_padding,
307 TransmissionType transmission_type,
308 QuicFrame* frame) {
dschinazi640536f2021-04-16 10:31:22 -0700309 QUIC_DVLOG(2) << ENDPOINT << "ConsumeCryptoDataToFillCurrentPacket " << level
dschinazi6458eb32020-06-23 12:38:41 -0700310 << " write_length " << write_length << " offset " << offset
311 << (needs_full_padding ? " needs_full_padding" : "") << " "
312 << transmission_type;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500313 if (!CreateCryptoFrame(level, write_length, offset, frame)) {
314 return false;
315 }
316 // When crypto data was sent in stream frames, ConsumeData is called with
317 // |needs_full_padding = true|. Keep the same behavior here when sending
318 // crypto frames.
319 //
320 // TODO(nharper): Check what the IETF drafts say about padding out initial
321 // messages and change this as appropriate.
nharper51961cf2019-05-13 13:23:24 -0700322 if (needs_full_padding) {
323 needs_full_padding_ = true;
324 }
fayang347ab752019-10-22 11:17:43 -0700325 return AddFrame(*frame, transmission_type);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500326}
327
fayang62b637b2019-09-16 08:40:49 -0700328bool QuicPacketCreator::ConsumeDataToFillCurrentPacket(
329 QuicStreamId id,
330 size_t data_size,
331 QuicStreamOffset offset,
332 bool fin,
333 bool needs_full_padding,
334 TransmissionType transmission_type,
335 QuicFrame* frame) {
QUICHE teamf08778a2019-03-14 08:10:26 -0700336 if (!HasRoomForStreamFrame(id, offset, data_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500337 return false;
338 }
QUICHE teamf08778a2019-03-14 08:10:26 -0700339 CreateStreamFrame(id, data_size, offset, fin, frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500340 // Explicitly disallow multi-packet CHLOs.
danzh88e3e052019-06-13 11:47:18 -0700341 if (GetQuicFlag(FLAGS_quic_enforce_single_packet_chlo) &&
ianswette28f0222019-04-04 13:31:22 -0700342 StreamFrameIsClientHello(frame->stream_frame) &&
343 frame->stream_frame.data_length < data_size) {
vasilvvc48c8712019-03-11 13:38:16 -0700344 const std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500345 "Client hello won't fit in a single packet.";
QUICHE team7939a6e2021-03-16 19:47:54 -0700346 QUIC_BUG(quic_bug_10752_5)
dschinazi640536f2021-04-16 10:31:22 -0700347 << ENDPOINT << error_details << " Constructed stream frame length: "
QUICHE team8e6da712021-03-08 10:59:32 -0800348 << frame->stream_frame.data_length << " CHLO length: " << data_size;
fkastenholz85f18902019-05-28 12:47:00 -0700349 delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500350 return false;
351 }
fayang347ab752019-10-22 11:17:43 -0700352 if (!AddFrame(*frame, transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500353 // Fails if we try to write unencrypted stream data.
354 return false;
355 }
356 if (needs_full_padding) {
357 needs_full_padding_ = true;
358 }
359
360 return true;
361}
362
363bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
364 QuicStreamOffset offset,
365 size_t data_size) {
fayang2ab1e852019-11-04 11:24:36 -0800366 const size_t min_stream_frame_size = QuicFramer::GetMinStreamFrameSize(
367 framer_->transport_version(), id, offset, /*last_frame_in_packet=*/true,
368 data_size);
369 if (BytesFree() > min_stream_frame_size) {
370 return true;
371 }
372 if (!RemoveSoftMaxPacketLength()) {
373 return false;
374 }
375 return BytesFree() > min_stream_frame_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500376}
377
378bool QuicPacketCreator::HasRoomForMessageFrame(QuicByteCount length) {
fayang2ab1e852019-11-04 11:24:36 -0800379 const size_t message_frame_size = QuicFramer::GetMessageFrameSize(
380 framer_->transport_version(), /*last_frame_in_packet=*/true, length);
dschinazied459c02020-05-07 16:12:23 -0700381 if (static_cast<QuicByteCount>(message_frame_size) >
382 max_datagram_frame_size_) {
383 return false;
384 }
fayang2ab1e852019-11-04 11:24:36 -0800385 if (BytesFree() >= message_frame_size) {
386 return true;
387 }
388 if (!RemoveSoftMaxPacketLength()) {
389 return false;
390 }
391 return BytesFree() >= message_frame_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500392}
393
QUICHE teama6ef0a62019-03-07 20:34:33 -0500394// static
395size_t QuicPacketCreator::StreamFramePacketOverhead(
396 QuicTransportVersion version,
397 QuicConnectionIdLength destination_connection_id_length,
398 QuicConnectionIdLength source_connection_id_length,
399 bool include_version,
400 bool include_diversification_nonce,
401 QuicPacketNumberLength packet_number_length,
402 QuicVariableLengthIntegerLength retry_token_length_length,
403 QuicVariableLengthIntegerLength length_length,
404 QuicStreamOffset offset) {
405 return GetPacketHeaderSize(version, destination_connection_id_length,
406 source_connection_id_length, include_version,
407 include_diversification_nonce,
408 packet_number_length, retry_token_length_length, 0,
409 length_length) +
410
ianswett22781cb2019-12-12 06:45:08 -0800411 // Assumes a packet with a single stream frame, which omits the length,
412 // causing the data length argument to be ignored.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500413 QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true,
ianswett22781cb2019-12-12 06:45:08 -0800414 kMaxOutgoingPacketSize /* unused */);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500415}
416
417void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
QUICHE teamf08778a2019-03-14 08:10:26 -0700418 size_t data_size,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500419 QuicStreamOffset offset,
420 bool fin,
421 QuicFrame* frame) {
fayang99f39842020-09-22 12:23:23 -0700422 // Make sure max_packet_length_ is greater than the largest possible overhead
423 // or max_packet_length_ is set to the soft limit.
vasilvvf8035162021-02-01 14:49:14 -0800424 QUICHE_DCHECK(
425 max_packet_length_ >
426 StreamFramePacketOverhead(
427 framer_->transport_version(), GetDestinationConnectionIdLength(),
428 GetSourceConnectionIdLength(), kIncludeVersion,
429 IncludeNonceInPublicHeader(), PACKET_6BYTE_PACKET_NUMBER,
430 GetRetryTokenLengthLength(), GetLengthLength(), offset) ||
dschinazi640536f2021-04-16 10:31:22 -0700431 latched_hard_max_packet_length_ > 0)
432 << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500433
QUICHE team7939a6e2021-03-16 19:47:54 -0700434 QUIC_BUG_IF(quic_bug_12398_3, !HasRoomForStreamFrame(id, offset, data_size))
dschinazi640536f2021-04-16 10:31:22 -0700435 << ENDPOINT << "No room for Stream frame, BytesFree: " << BytesFree()
QUICHE teama6ef0a62019-03-07 20:34:33 -0500436 << " MinStreamFrameSize: "
437 << QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
438 offset, true, data_size);
439
QUICHE team7939a6e2021-03-16 19:47:54 -0700440 QUIC_BUG_IF(quic_bug_12398_4, data_size == 0 && !fin)
dschinazi640536f2021-04-16 10:31:22 -0700441 << ENDPOINT << "Creating a stream frame for stream ID:" << id
QUICHE teamf08778a2019-03-14 08:10:26 -0700442 << " with no data or fin.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500443 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
444 framer_->transport_version(), id, offset,
445 /* last_frame_in_packet= */ true, data_size);
446 size_t bytes_consumed =
447 std::min<size_t>(BytesFree() - min_frame_size, data_size);
448
449 bool set_fin = fin && bytes_consumed == data_size; // Last frame.
450 *frame = QuicFrame(QuicStreamFrame(id, set_fin, offset, bytes_consumed));
451}
452
453bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
454 size_t write_length,
455 QuicStreamOffset offset,
456 QuicFrame* frame) {
fayang7cd1d822020-08-25 13:52:19 -0700457 const size_t min_frame_size =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500458 QuicFramer::GetMinCryptoFrameSize(write_length, offset);
fayang7cd1d822020-08-25 13:52:19 -0700459 if (BytesFree() <= min_frame_size &&
460 (!RemoveSoftMaxPacketLength() || BytesFree() <= min_frame_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500461 return false;
462 }
463 size_t max_write_length = BytesFree() - min_frame_size;
464 size_t bytes_consumed = std::min<size_t>(max_write_length, write_length);
465 *frame = QuicFrame(new QuicCryptoFrame(level, offset, bytes_consumed));
466 return true;
467}
468
fayang62b637b2019-09-16 08:40:49 -0700469void QuicPacketCreator::FlushCurrentPacket() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500470 if (!HasPendingFrames() && pending_padding_bytes_ == 0) {
471 return;
472 }
473
vasilvvf903e602020-10-26 18:06:12 -0700474 ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
wub50d4c712020-05-19 15:48:28 -0700475 QuicOwnedPacketBuffer external_buffer(delegate_->GetPacketBuffer());
476
wub50d4c712020-05-19 15:48:28 -0700477 if (external_buffer.buffer == nullptr) {
478 external_buffer.buffer = stack_buffer;
479 external_buffer.release_buffer = nullptr;
480 }
481
dschinazi640536f2021-04-16 10:31:22 -0700482 QUICHE_DCHECK_EQ(nullptr, packet_.encrypted_buffer) << ENDPOINT;
fayang48e283b2020-10-27 10:42:01 -0700483 if (!SerializePacket(std::move(external_buffer), kMaxOutgoingPacketSize)) {
fayang04590fc2020-08-31 10:37:55 -0700484 return;
485 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500486 OnSerializedPacket();
487}
488
489void QuicPacketCreator::OnSerializedPacket() {
dschinazi640536f2021-04-16 10:31:22 -0700490 QUIC_BUG_IF(quic_bug_12398_5, packet_.encrypted_buffer == nullptr)
491 << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500492
493 SerializedPacket packet(std::move(packet_));
494 ClearPacket();
fayang2ab1e852019-11-04 11:24:36 -0800495 RemoveSoftMaxPacketLength();
wub8a5dafa2020-05-13 12:30:17 -0700496 delegate_->OnSerializedPacket(std::move(packet));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500497}
498
499void QuicPacketCreator::ClearPacket() {
500 packet_.has_ack = false;
501 packet_.has_stop_waiting = false;
502 packet_.has_crypto_handshake = NOT_HANDSHAKE;
wub98669f52019-04-18 10:49:18 -0700503 packet_.transmission_type = NOT_RETRANSMISSION;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500504 packet_.encrypted_buffer = nullptr;
505 packet_.encrypted_length = 0;
haoyuewang5b0f14f2020-09-18 14:31:54 -0700506 packet_.has_ack_frequency = false;
haoyuewang11a54a12020-09-21 14:17:29 -0700507 packet_.has_message = false;
fayang15042962020-07-01 12:14:29 -0700508 packet_.fate = SEND_TO_WRITER;
QUICHE team7939a6e2021-03-16 19:47:54 -0700509 QUIC_BUG_IF(quic_bug_12398_6, packet_.release_encrypted_buffer != nullptr)
dschinazi640536f2021-04-16 10:31:22 -0700510 << ENDPOINT << "packet_.release_encrypted_buffer should be empty";
wubc9c6d582020-07-20 08:45:40 -0700511 packet_.release_encrypted_buffer = nullptr;
dschinazi640536f2021-04-16 10:31:22 -0700512 QUICHE_DCHECK(packet_.retransmittable_frames.empty()) << ENDPOINT;
513 QUICHE_DCHECK(packet_.nonretransmittable_frames.empty()) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500514 packet_.largest_acked.Clear();
515 needs_full_padding_ = false;
516}
517
fayang08750832019-10-24 11:25:34 -0700518size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
519 const SerializedPacket& packet,
520 size_t padding_size,
521 char* buffer,
522 size_t buffer_len) {
QUICHE team7939a6e2021-03-16 19:47:54 -0700523 QUIC_BUG_IF(quic_bug_12398_7, packet.encryption_level != ENCRYPTION_INITIAL);
524 QUIC_BUG_IF(quic_bug_12398_8, packet.nonretransmittable_frames.empty() &&
525 packet.retransmittable_frames.empty())
dschinazi640536f2021-04-16 10:31:22 -0700526 << ENDPOINT
fayang08750832019-10-24 11:25:34 -0700527 << "Attempt to serialize empty ENCRYPTION_INITIAL packet in coalesced "
528 "packet";
529 ScopedPacketContextSwitcher switcher(
530 packet.packet_number -
531 1, // -1 because serialize packet increase packet number.
532 packet.packet_number_length, packet.encryption_level, &packet_);
533 for (const QuicFrame& frame : packet.nonretransmittable_frames) {
534 if (!AddFrame(frame, packet.transmission_type)) {
dschinazi640536f2021-04-16 10:31:22 -0700535 QUIC_BUG(quic_bug_10752_6)
536 << ENDPOINT << "Failed to serialize frame: " << frame;
fayang08750832019-10-24 11:25:34 -0700537 return 0;
538 }
539 }
540 for (const QuicFrame& frame : packet.retransmittable_frames) {
541 if (!AddFrame(frame, packet.transmission_type)) {
dschinazi640536f2021-04-16 10:31:22 -0700542 QUIC_BUG(quic_bug_10752_7)
543 << ENDPOINT << "Failed to serialize frame: " << frame;
fayang08750832019-10-24 11:25:34 -0700544 return 0;
545 }
546 }
547 // Add necessary padding.
548 if (padding_size > 0) {
549 QUIC_DVLOG(2) << ENDPOINT << "Add padding of size: " << padding_size;
550 if (!AddFrame(QuicFrame(QuicPaddingFrame(padding_size)),
551 packet.transmission_type)) {
QUICHE team7939a6e2021-03-16 19:47:54 -0700552 QUIC_BUG(quic_bug_10752_8)
dschinazi640536f2021-04-16 10:31:22 -0700553 << ENDPOINT << "Failed to add padding of size " << padding_size
QUICHE team8e6da712021-03-08 10:59:32 -0800554 << " when serializing ENCRYPTION_INITIAL "
555 "packet in coalesced packet";
fayang08750832019-10-24 11:25:34 -0700556 return 0;
557 }
558 }
fayang48e283b2020-10-27 10:42:01 -0700559 if (!SerializePacket(QuicOwnedPacketBuffer(buffer, nullptr), buffer_len)) {
fayang04590fc2020-08-31 10:37:55 -0700560 return 0;
561 }
fayang08750832019-10-24 11:25:34 -0700562 const size_t encrypted_length = packet_.encrypted_length;
563 // Clear frames in packet_. No need to DeleteFrames since frames are owned by
564 // initial_packet.
565 packet_.retransmittable_frames.clear();
566 packet_.nonretransmittable_frames.clear();
567 ClearPacket();
568 return encrypted_length;
569}
570
QUICHE teama6ef0a62019-03-07 20:34:33 -0500571void QuicPacketCreator::CreateAndSerializeStreamFrame(
572 QuicStreamId id,
573 size_t write_length,
574 QuicStreamOffset iov_offset,
575 QuicStreamOffset stream_offset,
576 bool fin,
577 TransmissionType transmission_type,
578 size_t* num_bytes_consumed) {
fayang04590fc2020-08-31 10:37:55 -0700579 // TODO(b/167222597): consider using ScopedSerializationFailureHandler.
dschinazi640536f2021-04-16 10:31:22 -0700580 QUICHE_DCHECK(queued_frames_.empty()) << ENDPOINT;
581 QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id))
582 << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500583 // Write out the packet header
584 QuicPacketHeader header;
585 FillPacketHeader(&header);
fayangfe77c032020-08-24 18:21:32 -0700586 packet_.fate = delegate_->GetSerializedPacketFate(
587 /*is_mtu_discovery=*/false, packet_.encryption_level);
588 QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
589 << ": " << SerializedPacketFateToString(packet_.fate) << " of "
590 << EncryptionLevelToString(packet_.encryption_level);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500591
vasilvvf903e602020-10-26 18:06:12 -0700592 ABSL_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
wub50d4c712020-05-19 15:48:28 -0700593 QuicOwnedPacketBuffer packet_buffer(delegate_->GetPacketBuffer());
594
wub50d4c712020-05-19 15:48:28 -0700595 if (packet_buffer.buffer == nullptr) {
596 packet_buffer.buffer = stack_buffer;
597 packet_buffer.release_buffer = nullptr;
598 }
599
600 char* encrypted_buffer = packet_buffer.buffer;
601
dschinazi66dea072019-04-09 11:41:06 -0700602 QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500603 size_t length_field_offset = 0;
604 if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
dschinazi640536f2021-04-16 10:31:22 -0700605 QUIC_BUG(quic_bug_10752_9) << ENDPOINT << "AppendPacketHeader failed";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500606 return;
607 }
608
609 // Create a Stream frame with the remaining space.
QUICHE team7939a6e2021-03-16 19:47:54 -0700610 QUIC_BUG_IF(quic_bug_12398_9, iov_offset == write_length && !fin)
dschinazi640536f2021-04-16 10:31:22 -0700611 << ENDPOINT << "Creating a stream frame with no data or fin.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500612 const size_t remaining_data_size = write_length - iov_offset;
nharperebabffd2019-06-03 17:34:45 -0700613 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500614 framer_->transport_version(), id, stream_offset,
615 /* last_frame_in_packet= */ true, remaining_data_size);
nharperebabffd2019-06-03 17:34:45 -0700616 size_t available_size =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500617 max_plaintext_size_ - writer.length() - min_frame_size;
nharperebabffd2019-06-03 17:34:45 -0700618 size_t bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
619 size_t plaintext_bytes_written = min_frame_size + bytes_consumed;
620 bool needs_padding = false;
621 if (plaintext_bytes_written < MinPlaintextPacketSize(framer_->version())) {
622 needs_padding = true;
623 // Recalculate sizes with the stream frame not being marked as the last
624 // frame in the packet.
625 min_frame_size = QuicFramer::GetMinStreamFrameSize(
626 framer_->transport_version(), id, stream_offset,
627 /* last_frame_in_packet= */ false, remaining_data_size);
628 available_size = max_plaintext_size_ - writer.length() - min_frame_size;
629 bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
630 plaintext_bytes_written = min_frame_size + bytes_consumed;
631 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500632
633 const bool set_fin = fin && (bytes_consumed == remaining_data_size);
634 QuicStreamFrame frame(id, set_fin, stream_offset, bytes_consumed);
rchc76cd742019-03-26 16:00:03 -0700635 if (debug_delegate_ != nullptr) {
636 debug_delegate_->OnFrameAddedToPacket(QuicFrame(frame));
637 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500638 QUIC_DVLOG(1) << ENDPOINT << "Adding frame: " << frame;
639
dschinazi118934b2019-06-13 18:09:08 -0700640 QUIC_DVLOG(2) << ENDPOINT << "Serializing stream packet " << header << frame;
641
QUICHE teama6ef0a62019-03-07 20:34:33 -0500642 // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized
643 // into one method that takes a QuicStreamFrame, if warranted.
nharperebabffd2019-06-03 17:34:45 -0700644 bool omit_frame_length = !needs_padding;
645 if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) {
dschinazi640536f2021-04-16 10:31:22 -0700646 QUIC_BUG(quic_bug_10752_10) << ENDPOINT << "AppendTypeByte failed";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500647 return;
648 }
nharperebabffd2019-06-03 17:34:45 -0700649 if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) {
dschinazi640536f2021-04-16 10:31:22 -0700650 QUIC_BUG(quic_bug_10752_11) << ENDPOINT << "AppendStreamFrame failed";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500651 return;
652 }
nharperebabffd2019-06-03 17:34:45 -0700653 if (needs_padding &&
654 plaintext_bytes_written < MinPlaintextPacketSize(framer_->version()) &&
QUICHE team2252b702019-05-14 23:55:14 -0400655 !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) -
nharper55fa6132019-05-07 19:37:21 -0700656 plaintext_bytes_written)) {
dschinazi640536f2021-04-16 10:31:22 -0700657 QUIC_BUG(quic_bug_10752_12) << ENDPOINT << "Unable to add padding bytes";
nharper55fa6132019-05-07 19:37:21 -0700658 return;
659 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500660
661 if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset,
662 packet_.encryption_level)) {
663 return;
664 }
665
fayangcff885a2019-10-22 07:39:04 -0700666 packet_.transmission_type = transmission_type;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500667
vasilvvf8035162021-02-01 14:49:14 -0800668 QUICHE_DCHECK(packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
669 packet_.encryption_level == ENCRYPTION_ZERO_RTT)
dschinazi640536f2021-04-16 10:31:22 -0700670 << ENDPOINT << packet_.encryption_level;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500671 size_t encrypted_length = framer_->EncryptInPlace(
672 packet_.encryption_level, packet_.packet_number,
673 GetStartOfEncryptedData(framer_->transport_version(), header),
dschinazi66dea072019-04-09 11:41:06 -0700674 writer.length(), kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500675 if (encrypted_length == 0) {
QUICHE team7939a6e2021-03-16 19:47:54 -0700676 QUIC_BUG(quic_bug_10752_13)
dschinazi640536f2021-04-16 10:31:22 -0700677 << ENDPOINT << "Failed to encrypt packet number "
678 << header.packet_number;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500679 return;
680 }
681 // TODO(ianswett): Optimize the storage so RetransmitableFrames can be
682 // unioned with a QuicStreamFrame and a UniqueStreamBuffer.
683 *num_bytes_consumed = bytes_consumed;
684 packet_size_ = 0;
685 packet_.encrypted_buffer = encrypted_buffer;
686 packet_.encrypted_length = encrypted_length;
wubc9c6d582020-07-20 08:45:40 -0700687
688 packet_buffer.buffer = nullptr;
689 packet_.release_encrypted_buffer = std::move(packet_buffer).release_buffer;
690
QUICHE teama6ef0a62019-03-07 20:34:33 -0500691 packet_.retransmittable_frames.push_back(QuicFrame(frame));
692 OnSerializedPacket();
693}
694
695bool QuicPacketCreator::HasPendingFrames() const {
696 return !queued_frames_.empty();
697}
698
699bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
700 return !packet_.retransmittable_frames.empty();
701}
702
703bool QuicPacketCreator::HasPendingStreamFramesOfStream(QuicStreamId id) const {
704 for (const auto& frame : packet_.retransmittable_frames) {
705 if (frame.type == STREAM_FRAME && frame.stream_frame.stream_id == id) {
706 return true;
707 }
708 }
709 return false;
710}
711
712size_t QuicPacketCreator::ExpansionOnNewFrame() const {
713 // If the last frame in the packet is a message frame, then it will expand to
714 // include the varint message length when a new frame is added.
fayang54a38e32020-06-26 07:01:15 -0700715 if (queued_frames_.empty()) {
716 return 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500717 }
bnce5c11c02020-07-29 08:02:21 -0700718 return ExpansionOnNewFrameWithLastFrame(queued_frames_.back(),
719 framer_->transport_version());
fayang54a38e32020-06-26 07:01:15 -0700720}
721
bnce5c11c02020-07-29 08:02:21 -0700722// static
fayang54a38e32020-06-26 07:01:15 -0700723size_t QuicPacketCreator::ExpansionOnNewFrameWithLastFrame(
bnce5c11c02020-07-29 08:02:21 -0700724 const QuicFrame& last_frame,
725 QuicTransportVersion version) {
fayang54a38e32020-06-26 07:01:15 -0700726 if (last_frame.type == MESSAGE_FRAME) {
727 return QuicDataWriter::GetVarInt62Len(
728 last_frame.message_frame->message_length);
729 }
730 if (last_frame.type != STREAM_FRAME) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500731 return 0;
732 }
bnce5c11c02020-07-29 08:02:21 -0700733 if (VersionHasIetfQuicFrames(version)) {
fayang54a38e32020-06-26 07:01:15 -0700734 return QuicDataWriter::GetVarInt62Len(last_frame.stream_frame.data_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500735 }
736 return kQuicStreamPayloadLengthSize;
737}
738
fayang5a3cfcb2020-08-27 12:57:23 -0700739size_t QuicPacketCreator::BytesFree() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500740 return max_plaintext_size_ -
741 std::min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
742}
743
fayang5a3cfcb2020-08-27 12:57:23 -0700744size_t QuicPacketCreator::PacketSize() const {
745 return queued_frames_.empty() ? PacketHeaderSize() : packet_size_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500746}
747
QUICHE teama6ef0a62019-03-07 20:34:33 -0500748bool QuicPacketCreator::AddPaddedSavedFrame(
749 const QuicFrame& frame,
750 TransmissionType transmission_type) {
fayang347ab752019-10-22 11:17:43 -0700751 if (AddFrame(frame, transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500752 needs_full_padding_ = true;
753 return true;
754 }
755 return false;
756}
757
dschinazicb6b5102021-04-28 08:16:40 -0700758absl::optional<size_t>
759QuicPacketCreator::MaybeBuildDataPacketWithChaosProtection(
760 const QuicPacketHeader& header,
761 char* buffer) {
762 if (!chaos_protection_enabled_ ||
763 packet_.encryption_level != ENCRYPTION_INITIAL ||
764 !framer_->version().UsesCryptoFrames() || queued_frames_.size() != 2u ||
765 queued_frames_[0].type != CRYPTO_FRAME ||
766 queued_frames_[1].type != PADDING_FRAME ||
767 // Do not perform chaos protection if we do not have a known number of
768 // padding bytes to work with.
769 queued_frames_[1].padding_frame.num_padding_bytes <= 0 ||
770 // Chaos protection relies on the framer using a crypto data producer,
771 // which is always the case in practice.
772 framer_->data_producer() == nullptr) {
773 return absl::nullopt;
774 }
775 const QuicCryptoFrame& crypto_frame = *queued_frames_[0].crypto_frame;
776 if (packet_.encryption_level != crypto_frame.level) {
777 QUIC_BUG(chaos frame level)
778 << ENDPOINT << packet_.encryption_level << " != " << crypto_frame.level;
779 return absl::nullopt;
780 }
781 QuicChaosProtector chaos_protector(
782 crypto_frame, queued_frames_[1].padding_frame.num_padding_bytes,
783 packet_size_, framer_, random_);
784 return chaos_protector.BuildDataPacket(header, buffer);
785}
786
fayang04590fc2020-08-31 10:37:55 -0700787bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500788 size_t encrypted_buffer_len) {
fayang48e283b2020-10-27 10:42:01 -0700789 if (packet_.encrypted_buffer != nullptr) {
fayang04590fc2020-08-31 10:37:55 -0700790 const std::string error_details =
791 "Packet's encrypted buffer is not empty before serialization";
dschinazi640536f2021-04-16 10:31:22 -0700792 QUIC_BUG(quic_bug_10752_14) << ENDPOINT << error_details;
fayang04590fc2020-08-31 10:37:55 -0700793 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
794 error_details);
795 return false;
796 }
fayang48e283b2020-10-27 10:42:01 -0700797 ScopedSerializationFailureHandler handler(this);
fayange447bc62020-08-27 13:47:11 -0700798
dschinazi640536f2021-04-16 10:31:22 -0700799 QUICHE_DCHECK_LT(0u, encrypted_buffer_len) << ENDPOINT;
QUICHE team7939a6e2021-03-16 19:47:54 -0700800 QUIC_BUG_IF(quic_bug_12398_10,
801 queued_frames_.empty() && pending_padding_bytes_ == 0)
dschinazi640536f2021-04-16 10:31:22 -0700802 << ENDPOINT << "Attempt to serialize empty packet";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500803 QuicPacketHeader header;
804 // FillPacketHeader increments packet_number_.
805 FillPacketHeader(&header);
fayangfe77c032020-08-24 18:21:32 -0700806 if (delegate_ != nullptr) {
fayang15042962020-07-01 12:14:29 -0700807 packet_.fate = delegate_->GetSerializedPacketFate(
808 /*is_mtu_discovery=*/QuicUtils::ContainsFrameType(queued_frames_,
809 MTU_DISCOVERY_FRAME),
810 packet_.encryption_level);
811 QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
812 << ": " << SerializedPacketFateToString(packet_.fate)
813 << " of "
814 << EncryptionLevelToString(packet_.encryption_level);
815 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500816
817 MaybeAddPadding();
818
dschinazi118934b2019-06-13 18:09:08 -0700819 QUIC_DVLOG(2) << ENDPOINT << "Serializing packet " << header
wub031d47c2019-11-21 08:04:07 -0800820 << QuicFramesToString(queued_frames_) << " at encryption_level "
renjietangb4ebb1d2020-05-27 18:15:51 -0700821 << packet_.encryption_level;
dschinazi118934b2019-06-13 18:09:08 -0700822
dschinazida9fafd2020-03-16 15:32:55 -0700823 if (!framer_->HasEncrypterOfEncryptionLevel(packet_.encryption_level)) {
fayangd01e9962020-09-24 11:29:31 -0700824 // TODO(fayang): Use QUIC_MISSING_WRITE_KEYS for serialization failures due
825 // to missing keys.
QUICHE team7939a6e2021-03-16 19:47:54 -0700826 QUIC_BUG(quic_bug_10752_15)
QUICHE team8e6da712021-03-08 10:59:32 -0800827 << ENDPOINT << "Attempting to serialize " << header
828 << QuicFramesToString(queued_frames_) << " at missing encryption_level "
829 << packet_.encryption_level << " using " << framer_->version();
fayang04590fc2020-08-31 10:37:55 -0700830 return false;
dschinazida9fafd2020-03-16 15:32:55 -0700831 }
832
dschinazi640536f2021-04-16 10:31:22 -0700833 QUICHE_DCHECK_GE(max_plaintext_size_, packet_size_) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500834 // Use the packet_size_ instead of the buffer size to ensure smaller
835 // packet sizes are properly used.
dschinazicb6b5102021-04-28 08:16:40 -0700836
837 size_t length;
838 absl::optional<size_t> length_with_chaos_protection =
839 MaybeBuildDataPacketWithChaosProtection(header, encrypted_buffer.buffer);
840 if (length_with_chaos_protection.has_value()) {
841 length = length_with_chaos_protection.value();
842 } else {
843 length = framer_->BuildDataPacket(header, queued_frames_,
844 encrypted_buffer.buffer, packet_size_,
845 packet_.encryption_level);
846 }
847
QUICHE teama6ef0a62019-03-07 20:34:33 -0500848 if (length == 0) {
QUICHE team7939a6e2021-03-16 19:47:54 -0700849 QUIC_BUG(quic_bug_10752_16)
dschinazi640536f2021-04-16 10:31:22 -0700850 << ENDPOINT << "Failed to serialize "
851 << QuicFramesToString(queued_frames_)
QUICHE team8e6da712021-03-08 10:59:32 -0800852 << " at encryption_level: " << packet_.encryption_level
853 << ", needs_full_padding_: " << needs_full_padding_
854 << ", pending_padding_bytes_: " << pending_padding_bytes_
855 << ", latched_hard_max_packet_length_: "
856 << latched_hard_max_packet_length_
857 << ", max_packet_length_: " << max_packet_length_
858 << ", header: " << header;
fayang04590fc2020-08-31 10:37:55 -0700859 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500860 }
861
862 // ACK Frames will be truncated due to length only if they're the only frame
863 // in the packet, and if packet_size_ was set to max_plaintext_size_. If
864 // truncation due to length occurred, then GetSerializedFrameLength will have
865 // returned all bytes free.
866 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
867 queued_frames_.size() == 1 &&
868 queued_frames_.back().type == ACK_FRAME;
869 // Because of possible truncation, we can't be confident that our
870 // packet size calculation worked correctly.
871 if (!possibly_truncated_by_length) {
dschinazi640536f2021-04-16 10:31:22 -0700872 QUICHE_DCHECK_EQ(packet_size_, length) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500873 }
874 const size_t encrypted_length = framer_->EncryptInPlace(
875 packet_.encryption_level, packet_.packet_number,
876 GetStartOfEncryptedData(framer_->transport_version(), header), length,
wub50d4c712020-05-19 15:48:28 -0700877 encrypted_buffer_len, encrypted_buffer.buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500878 if (encrypted_length == 0) {
QUICHE team7939a6e2021-03-16 19:47:54 -0700879 QUIC_BUG(quic_bug_10752_17)
dschinazi640536f2021-04-16 10:31:22 -0700880 << ENDPOINT << "Failed to encrypt packet number "
881 << packet_.packet_number;
fayang04590fc2020-08-31 10:37:55 -0700882 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500883 }
884
885 packet_size_ = 0;
wub50d4c712020-05-19 15:48:28 -0700886 packet_.encrypted_buffer = encrypted_buffer.buffer;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500887 packet_.encrypted_length = encrypted_length;
wubc9c6d582020-07-20 08:45:40 -0700888
889 encrypted_buffer.buffer = nullptr;
890 packet_.release_encrypted_buffer = std::move(encrypted_buffer).release_buffer;
fayang04590fc2020-08-31 10:37:55 -0700891 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500892}
893
wub8a5dafa2020-05-13 12:30:17 -0700894std::unique_ptr<SerializedPacket>
QUICHE teama6ef0a62019-03-07 20:34:33 -0500895QuicPacketCreator::SerializeConnectivityProbingPacket() {
QUICHE team7939a6e2021-03-16 19:47:54 -0700896 QUIC_BUG_IF(quic_bug_12398_11,
897 VersionHasIetfQuicFrames(framer_->transport_version()))
dschinazi640536f2021-04-16 10:31:22 -0700898 << ENDPOINT
QUICHE teama6ef0a62019-03-07 20:34:33 -0500899 << "Must not be version 99 to serialize padded ping connectivity probe";
fayang2ab1e852019-11-04 11:24:36 -0800900 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500901 QuicPacketHeader header;
902 // FillPacketHeader increments packet_number_.
903 FillPacketHeader(&header);
904
dschinazi118934b2019-06-13 18:09:08 -0700905 QUIC_DVLOG(2) << ENDPOINT << "Serializing connectivity probing packet "
906 << header;
907
dschinazi66dea072019-04-09 11:41:06 -0700908 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700909 size_t length = BuildConnectivityProbingPacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500910 header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
dschinazi640536f2021-04-16 10:31:22 -0700911 QUICHE_DCHECK(length) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500912
dschinazi640536f2021-04-16 10:31:22 -0700913 QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
914 << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500915 const size_t encrypted_length = framer_->EncryptInPlace(
916 packet_.encryption_level, packet_.packet_number,
917 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700918 kMaxOutgoingPacketSize, buffer.get());
dschinazi640536f2021-04-16 10:31:22 -0700919 QUICHE_DCHECK(encrypted_length) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500920
wub8a5dafa2020-05-13 12:30:17 -0700921 std::unique_ptr<SerializedPacket> serialize_packet(new SerializedPacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500922 header.packet_number, header.packet_number_length, buffer.release(),
923 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
924
wub8a5dafa2020-05-13 12:30:17 -0700925 serialize_packet->release_encrypted_buffer = [](const char* p) {
926 delete[] p;
927 };
QUICHE teama6ef0a62019-03-07 20:34:33 -0500928 serialize_packet->encryption_level = packet_.encryption_level;
929 serialize_packet->transmission_type = NOT_RETRANSMISSION;
930
931 return serialize_packet;
932}
933
wub8a5dafa2020-05-13 12:30:17 -0700934std::unique_ptr<SerializedPacket>
QUICHE teama6ef0a62019-03-07 20:34:33 -0500935QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
danzh28ba4722020-11-12 11:55:39 -0800936 const QuicPathFrameBuffer& payload) {
QUICHE team7939a6e2021-03-16 19:47:54 -0700937 QUIC_BUG_IF(quic_bug_12398_12,
938 !VersionHasIetfQuicFrames(framer_->transport_version()))
dschinazi640536f2021-04-16 10:31:22 -0700939 << ENDPOINT
QUICHE teama6ef0a62019-03-07 20:34:33 -0500940 << "Must be version 99 to serialize path challenge connectivity probe, "
941 "is version "
942 << framer_->transport_version();
fayang2ab1e852019-11-04 11:24:36 -0800943 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500944 QuicPacketHeader header;
945 // FillPacketHeader increments packet_number_.
946 FillPacketHeader(&header);
947
dschinazi118934b2019-06-13 18:09:08 -0700948 QUIC_DVLOG(2) << ENDPOINT << "Serializing path challenge packet " << header;
949
dschinazi66dea072019-04-09 11:41:06 -0700950 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
danzh28ba4722020-11-12 11:55:39 -0800951 size_t length =
952 BuildPaddedPathChallengePacket(header, buffer.get(), max_plaintext_size_,
953 payload, packet_.encryption_level);
dschinazi640536f2021-04-16 10:31:22 -0700954 QUICHE_DCHECK(length) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500955
dschinazi640536f2021-04-16 10:31:22 -0700956 QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
957 << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500958 const size_t encrypted_length = framer_->EncryptInPlace(
959 packet_.encryption_level, packet_.packet_number,
960 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700961 kMaxOutgoingPacketSize, buffer.get());
dschinazi640536f2021-04-16 10:31:22 -0700962 QUICHE_DCHECK(encrypted_length) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500963
wub8a5dafa2020-05-13 12:30:17 -0700964 std::unique_ptr<SerializedPacket> serialize_packet(
965 new SerializedPacket(header.packet_number, header.packet_number_length,
966 buffer.release(), encrypted_length,
967 /*has_ack=*/false, /*has_stop_waiting=*/false));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500968
wub8a5dafa2020-05-13 12:30:17 -0700969 serialize_packet->release_encrypted_buffer = [](const char* p) {
970 delete[] p;
971 };
QUICHE teama6ef0a62019-03-07 20:34:33 -0500972 serialize_packet->encryption_level = packet_.encryption_level;
973 serialize_packet->transmission_type = NOT_RETRANSMISSION;
974
975 return serialize_packet;
976}
977
wub8a5dafa2020-05-13 12:30:17 -0700978std::unique_ptr<SerializedPacket>
QUICHE teama6ef0a62019-03-07 20:34:33 -0500979QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
bnc08fc2ae2021-04-27 14:57:51 -0700980 const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500981 const bool is_padded) {
QUICHE team7939a6e2021-03-16 19:47:54 -0700982 QUIC_BUG_IF(quic_bug_12398_13,
983 !VersionHasIetfQuicFrames(framer_->transport_version()))
dschinazi640536f2021-04-16 10:31:22 -0700984 << ENDPOINT
QUICHE teama6ef0a62019-03-07 20:34:33 -0500985 << "Must be version 99 to serialize path response connectivity probe, is "
986 "version "
987 << framer_->transport_version();
fayang2ab1e852019-11-04 11:24:36 -0800988 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500989 QuicPacketHeader header;
990 // FillPacketHeader increments packet_number_.
991 FillPacketHeader(&header);
992
dschinazi118934b2019-06-13 18:09:08 -0700993 QUIC_DVLOG(2) << ENDPOINT << "Serializing path response packet " << header;
994
dschinazi66dea072019-04-09 11:41:06 -0700995 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700996 size_t length =
997 BuildPathResponsePacket(header, buffer.get(), max_plaintext_size_,
998 payloads, is_padded, packet_.encryption_level);
dschinazi640536f2021-04-16 10:31:22 -0700999 QUICHE_DCHECK(length) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001000
dschinazi640536f2021-04-16 10:31:22 -07001001 QUICHE_DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE)
1002 << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001003 const size_t encrypted_length = framer_->EncryptInPlace(
1004 packet_.encryption_level, packet_.packet_number,
1005 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -07001006 kMaxOutgoingPacketSize, buffer.get());
dschinazi640536f2021-04-16 10:31:22 -07001007 QUICHE_DCHECK(encrypted_length) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001008
wub8a5dafa2020-05-13 12:30:17 -07001009 std::unique_ptr<SerializedPacket> serialize_packet(
1010 new SerializedPacket(header.packet_number, header.packet_number_length,
1011 buffer.release(), encrypted_length,
1012 /*has_ack=*/false, /*has_stop_waiting=*/false));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001013
wub8a5dafa2020-05-13 12:30:17 -07001014 serialize_packet->release_encrypted_buffer = [](const char* p) {
1015 delete[] p;
1016 };
QUICHE teama6ef0a62019-03-07 20:34:33 -05001017 serialize_packet->encryption_level = packet_.encryption_level;
1018 serialize_packet->transmission_type = NOT_RETRANSMISSION;
1019
1020 return serialize_packet;
1021}
1022
renjietang4c704c82019-10-07 16:39:11 -07001023size_t QuicPacketCreator::BuildPaddedPathChallengePacket(
1024 const QuicPacketHeader& header,
1025 char* buffer,
1026 size_t packet_length,
danzh28ba4722020-11-12 11:55:39 -08001027 const QuicPathFrameBuffer& payload,
renjietang4c704c82019-10-07 16:39:11 -07001028 EncryptionLevel level) {
dschinazi640536f2021-04-16 10:31:22 -07001029 QUICHE_DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()))
1030 << ENDPOINT;
renjietang4c704c82019-10-07 16:39:11 -07001031 QuicFrames frames;
1032
1033 // Write a PATH_CHALLENGE frame, which has a random 8-byte payload
danzh28ba4722020-11-12 11:55:39 -08001034 QuicPathChallengeFrame path_challenge_frame(0, payload);
renjietang4c704c82019-10-07 16:39:11 -07001035 frames.push_back(QuicFrame(&path_challenge_frame));
1036
1037 if (debug_delegate_ != nullptr) {
1038 debug_delegate_->OnFrameAddedToPacket(QuicFrame(&path_challenge_frame));
1039 }
1040
1041 // Add padding to the rest of the packet in order to assess Path MTU
1042 // characteristics.
1043 QuicPaddingFrame padding_frame;
1044 frames.push_back(QuicFrame(padding_frame));
1045
1046 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
1047}
1048
1049size_t QuicPacketCreator::BuildPathResponsePacket(
1050 const QuicPacketHeader& header,
1051 char* buffer,
1052 size_t packet_length,
bnc08fc2ae2021-04-27 14:57:51 -07001053 const quiche::QuicheCircularDeque<QuicPathFrameBuffer>& payloads,
renjietang4c704c82019-10-07 16:39:11 -07001054 const bool is_padded,
1055 EncryptionLevel level) {
1056 if (payloads.empty()) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001057 QUIC_BUG(quic_bug_12398_14)
dschinazi640536f2021-04-16 10:31:22 -07001058 << ENDPOINT
renjietang4c704c82019-10-07 16:39:11 -07001059 << "Attempt to generate connectivity response with no request payloads";
1060 return 0;
1061 }
dschinazi640536f2021-04-16 10:31:22 -07001062 QUICHE_DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()))
1063 << ENDPOINT;
renjietang4c704c82019-10-07 16:39:11 -07001064
1065 std::vector<std::unique_ptr<QuicPathResponseFrame>> path_response_frames;
1066 for (const QuicPathFrameBuffer& payload : payloads) {
1067 // Note that the control frame ID can be 0 since this is not retransmitted.
1068 path_response_frames.push_back(
1069 std::make_unique<QuicPathResponseFrame>(0, payload));
1070 }
1071
1072 QuicFrames frames;
1073 for (const std::unique_ptr<QuicPathResponseFrame>& path_response_frame :
1074 path_response_frames) {
1075 frames.push_back(QuicFrame(path_response_frame.get()));
1076 if (debug_delegate_ != nullptr) {
1077 debug_delegate_->OnFrameAddedToPacket(
1078 QuicFrame(path_response_frame.get()));
1079 }
1080 }
1081
1082 if (is_padded) {
1083 // Add padding to the rest of the packet in order to assess Path MTU
1084 // characteristics.
1085 QuicPaddingFrame padding_frame;
1086 frames.push_back(QuicFrame(padding_frame));
1087 }
1088
1089 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
1090}
1091
1092size_t QuicPacketCreator::BuildConnectivityProbingPacket(
1093 const QuicPacketHeader& header,
1094 char* buffer,
1095 size_t packet_length,
1096 EncryptionLevel level) {
1097 QuicFrames frames;
1098
1099 // Write a PING frame, which has no data payload.
1100 QuicPingFrame ping_frame;
1101 frames.push_back(QuicFrame(ping_frame));
1102
1103 // Add padding to the rest of the packet.
1104 QuicPaddingFrame padding_frame;
1105 frames.push_back(QuicFrame(padding_frame));
1106
1107 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
1108}
1109
fayang08750832019-10-24 11:25:34 -07001110size_t QuicPacketCreator::SerializeCoalescedPacket(
1111 const QuicCoalescedPacket& coalesced,
1112 char* buffer,
1113 size_t buffer_len) {
fayang08750832019-10-24 11:25:34 -07001114 if (HasPendingFrames()) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001115 QUIC_BUG(quic_bug_10752_18)
dschinazi640536f2021-04-16 10:31:22 -07001116 << ENDPOINT << "Try to serialize coalesced packet with pending frames";
fayang08750832019-10-24 11:25:34 -07001117 return 0;
1118 }
fayang58f71072019-11-05 08:47:02 -08001119 RemoveSoftMaxPacketLength();
QUICHE team7939a6e2021-03-16 19:47:54 -07001120 QUIC_BUG_IF(quic_bug_12398_15, coalesced.length() == 0)
dschinazi640536f2021-04-16 10:31:22 -07001121 << ENDPOINT << "Attempt to serialize empty coalesced packet";
fayang08750832019-10-24 11:25:34 -07001122 size_t packet_length = 0;
1123 if (coalesced.initial_packet() != nullptr) {
fayang9abdfec2020-02-13 12:34:58 -08001124 // Padding coalesced packet containing initial packet to full.
1125 size_t padding_size = coalesced.max_packet_length() - coalesced.length();
1126 if (framer_->perspective() == Perspective::IS_SERVER &&
1127 QuicUtils::ContainsFrameType(
1128 coalesced.initial_packet()->retransmittable_frames,
1129 CONNECTION_CLOSE_FRAME)) {
1130 // Do not pad server initial connection close packet.
1131 padding_size = 0;
1132 }
fayang08750832019-10-24 11:25:34 -07001133 size_t initial_length = ReserializeInitialPacketInCoalescedPacket(
fayang9abdfec2020-02-13 12:34:58 -08001134 *coalesced.initial_packet(), padding_size, buffer, buffer_len);
fayang08750832019-10-24 11:25:34 -07001135 if (initial_length == 0) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001136 QUIC_BUG(quic_bug_10752_19)
dschinazi640536f2021-04-16 10:31:22 -07001137 << ENDPOINT
QUICHE team8e6da712021-03-08 10:59:32 -08001138 << "Failed to reserialize ENCRYPTION_INITIAL packet in "
1139 "coalesced packet";
fayang08750832019-10-24 11:25:34 -07001140 return 0;
1141 }
1142 buffer += initial_length;
1143 buffer_len -= initial_length;
1144 packet_length += initial_length;
1145 }
1146 size_t length_copied = 0;
1147 if (!coalesced.CopyEncryptedBuffers(buffer, buffer_len, &length_copied)) {
1148 return 0;
1149 }
1150 packet_length += length_copied;
1151 QUIC_DVLOG(1) << ENDPOINT
1152 << "Successfully serialized coalesced packet of length: "
1153 << packet_length;
1154 return packet_length;
1155}
1156
QUICHE teama6ef0a62019-03-07 20:34:33 -05001157// TODO(b/74062209): Make this a public method of framer?
1158SerializedPacket QuicPacketCreator::NoPacket() {
1159 return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
1160 nullptr, 0, false, false);
1161}
1162
QUICHE team2252b702019-05-14 23:55:14 -04001163QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -04001164 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi346b7ce2019-06-05 01:38:18 -07001165 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001166 }
dschinazi7b9278c2019-05-20 07:36:21 -07001167 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001168}
1169
1170QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -04001171 if (framer_->perspective() == Perspective::IS_CLIENT) {
dschinazi346b7ce2019-06-05 01:38:18 -07001172 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001173 }
dschinazi7b9278c2019-05-20 07:36:21 -07001174 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001175}
1176
QUICHE teama6ef0a62019-03-07 20:34:33 -05001177QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
1178 const {
dschinazi5e1a7b22019-07-31 12:23:21 -07001179 // In versions that do not support client connection IDs, the destination
1180 // connection ID is only sent from client to server.
1181 return (framer_->perspective() == Perspective::IS_CLIENT ||
1182 framer_->version().SupportsClientConnectionIds())
1183 ? CONNECTION_ID_PRESENT
1184 : CONNECTION_ID_ABSENT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001185}
1186
1187QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
1188 const {
1189 // Long header packets sent by server include source connection ID.
dschinazi346b7ce2019-06-05 01:38:18 -07001190 // Ones sent by the client only include source connection ID if the version
1191 // supports client connection IDs.
1192 if (HasIetfLongHeader() &&
1193 (framer_->perspective() == Perspective::IS_SERVER ||
1194 framer_->version().SupportsClientConnectionIds())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001195 return CONNECTION_ID_PRESENT;
1196 }
dschinazi5e1a7b22019-07-31 12:23:21 -07001197 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi7b9278c2019-05-20 07:36:21 -07001198 return server_connection_id_included_;
QUICHE team2252b702019-05-14 23:55:14 -04001199 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001200 return CONNECTION_ID_ABSENT;
1201}
1202
1203QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
1204 const {
vasilvvf8035162021-02-01 14:49:14 -08001205 QUICHE_DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
dschinazi640536f2021-04-16 10:31:22 -07001206 transport_version()))
1207 << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001208 return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -04001209 ? static_cast<QuicConnectionIdLength>(
1210 GetDestinationConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001211 : PACKET_0BYTE_CONNECTION_ID;
1212}
1213
1214QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
vasilvvf8035162021-02-01 14:49:14 -08001215 QUICHE_DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
dschinazi640536f2021-04-16 10:31:22 -07001216 transport_version()))
1217 << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001218 return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -04001219 ? static_cast<QuicConnectionIdLength>(
1220 GetSourceConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001221 : PACKET_0BYTE_CONNECTION_ID;
1222}
1223
1224QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
fayang3ac15c12019-06-14 14:04:51 -07001225 if (HasIetfLongHeader() &&
1226 !framer_->version().SendsVariableLengthPacketNumberInLongHeader()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001227 return PACKET_4BYTE_PACKET_NUMBER;
1228 }
1229 return packet_.packet_number_length;
1230}
1231
nharper55fa6132019-05-07 19:37:21 -07001232size_t QuicPacketCreator::PacketHeaderSize() const {
1233 return GetPacketHeaderSize(
1234 framer_->transport_version(), GetDestinationConnectionIdLength(),
1235 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
1236 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
1237 GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
1238}
1239
QUICHE teama6ef0a62019-03-07 20:34:33 -05001240QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
1241 const {
1242 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1243 HasIetfLongHeader() &&
1244 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
1245 return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
1246 }
1247 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
1248}
1249
vasilvvc872ee42020-10-07 19:50:22 -07001250absl::string_view QuicPacketCreator::GetRetryToken() const {
dschinazi0db87092019-05-20 07:59:15 -07001251 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1252 HasIetfLongHeader() &&
1253 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
1254 return retry_token_;
1255 }
vasilvvc872ee42020-10-07 19:50:22 -07001256 return absl::string_view();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001257}
1258
vasilvvc872ee42020-10-07 19:50:22 -07001259void QuicPacketCreator::SetRetryToken(absl::string_view retry_token) {
vasilvvc48c8712019-03-11 13:38:16 -07001260 retry_token_ = std::string(retry_token);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001261}
1262
fayang18be79a2019-09-16 15:17:12 -07001263bool QuicPacketCreator::ConsumeRetransmittableControlFrame(
1264 const QuicFrame& frame) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001265 QUIC_BUG_IF(quic_bug_12398_16, IsControlFrame(frame.type) &&
1266 !GetControlFrameId(frame) &&
1267 frame.type != PING_FRAME)
dschinazi640536f2021-04-16 10:31:22 -07001268 << ENDPOINT
fayang18be79a2019-09-16 15:17:12 -07001269 << "Adding a control frame with no control frame id: " << frame;
dschinazi640536f2021-04-16 10:31:22 -07001270 QUICHE_DCHECK(QuicUtils::IsRetransmittableFrame(frame.type))
1271 << ENDPOINT << frame;
fayang18be79a2019-09-16 15:17:12 -07001272 MaybeBundleAckOpportunistically();
1273 if (HasPendingFrames()) {
renjietangb63005e2019-11-19 23:08:53 -08001274 if (AddFrame(frame, next_transmission_type_)) {
fayang18be79a2019-09-16 15:17:12 -07001275 // There is pending frames and current frame fits.
1276 return true;
1277 }
1278 }
dschinazi640536f2021-04-16 10:31:22 -07001279 QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
fayang18be79a2019-09-16 15:17:12 -07001280 if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME &&
1281 !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
1282 NOT_HANDSHAKE)) {
1283 // Do not check congestion window for ping or connection close frames.
1284 return false;
1285 }
renjietangb63005e2019-11-19 23:08:53 -08001286 const bool success = AddFrame(frame, next_transmission_type_);
QUICHE team7939a6e2021-03-16 19:47:54 -07001287 QUIC_BUG_IF(quic_bug_10752_20, !success)
dschinazi640536f2021-04-16 10:31:22 -07001288 << ENDPOINT << "Failed to add frame:" << frame
QUICHE team8e6da712021-03-08 10:59:32 -08001289 << " transmission_type:" << next_transmission_type_;
fayang18be79a2019-09-16 15:17:12 -07001290 return success;
1291}
1292
1293QuicConsumedData QuicPacketCreator::ConsumeData(QuicStreamId id,
1294 size_t write_length,
1295 QuicStreamOffset offset,
1296 StreamSendingState state) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001297 QUIC_BUG_IF(quic_bug_10752_21, !flusher_attached_)
dschinazi640536f2021-04-16 10:31:22 -07001298 << ENDPOINT
QUICHE team8e6da712021-03-08 10:59:32 -08001299 << "Packet flusher is not attached when "
1300 "generator tries to write stream data.";
fayang18be79a2019-09-16 15:17:12 -07001301 bool has_handshake = QuicUtils::IsCryptoStreamId(transport_version(), id);
1302 MaybeBundleAckOpportunistically();
1303 bool fin = state != NO_FIN;
QUICHE team7939a6e2021-03-16 19:47:54 -07001304 QUIC_BUG_IF(quic_bug_12398_17, has_handshake && fin)
dschinazi640536f2021-04-16 10:31:22 -07001305 << ENDPOINT << "Handshake packets should never send a fin";
fayang18be79a2019-09-16 15:17:12 -07001306 // To make reasoning about crypto frames easier, we don't combine them with
1307 // other retransmittable frames in a single packet.
1308 if (has_handshake && HasPendingRetransmittableFrames()) {
1309 FlushCurrentPacket();
1310 }
1311
1312 size_t total_bytes_consumed = 0;
1313 bool fin_consumed = false;
1314
1315 if (!HasRoomForStreamFrame(id, offset, write_length)) {
1316 FlushCurrentPacket();
1317 }
1318
1319 if (!fin && (write_length == 0)) {
dschinazi640536f2021-04-16 10:31:22 -07001320 QUIC_BUG(quic_bug_10752_22)
1321 << ENDPOINT << "Attempt to consume empty data without FIN.";
fayang18be79a2019-09-16 15:17:12 -07001322 return QuicConsumedData(0, false);
1323 }
1324 // We determine if we can enter the fast path before executing
1325 // the slow path loop.
1326 bool run_fast_path =
1327 !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
fayang2ab1e852019-11-04 11:24:36 -08001328 write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
1329 latched_hard_max_packet_length_ == 0;
fayang18be79a2019-09-16 15:17:12 -07001330
ianswett517beaa2020-05-26 06:05:32 -07001331 while (!run_fast_path &&
1332 (has_handshake || delegate_->ShouldGeneratePacket(
1333 HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE))) {
fayang18be79a2019-09-16 15:17:12 -07001334 QuicFrame frame;
1335 bool needs_full_padding =
1336 has_handshake && fully_pad_crypto_handshake_packets_;
1337
1338 if (!ConsumeDataToFillCurrentPacket(id, write_length - total_bytes_consumed,
1339 offset + total_bytes_consumed, fin,
1340 needs_full_padding,
1341 next_transmission_type_, &frame)) {
1342 // The creator is always flushed if there's not enough room for a new
1343 // stream frame before ConsumeData, so ConsumeData should always succeed.
dschinazi640536f2021-04-16 10:31:22 -07001344 QUIC_BUG(quic_bug_10752_23)
1345 << ENDPOINT << "Failed to ConsumeData, stream:" << id;
fayang18be79a2019-09-16 15:17:12 -07001346 return QuicConsumedData(0, false);
1347 }
1348
1349 // A stream frame is created and added.
1350 size_t bytes_consumed = frame.stream_frame.data_length;
1351 total_bytes_consumed += bytes_consumed;
1352 fin_consumed = fin && total_bytes_consumed == write_length;
1353 if (fin_consumed && state == FIN_AND_PADDING) {
1354 AddRandomPadding();
1355 }
vasilvvf8035162021-02-01 14:49:14 -08001356 QUICHE_DCHECK(total_bytes_consumed == write_length ||
dschinazi640536f2021-04-16 10:31:22 -07001357 (bytes_consumed > 0 && HasPendingFrames()))
1358 << ENDPOINT;
fayang18be79a2019-09-16 15:17:12 -07001359
1360 if (total_bytes_consumed == write_length) {
1361 // We're done writing the data. Exit the loop.
1362 // We don't make this a precondition because we could have 0 bytes of data
1363 // if we're simply writing a fin.
1364 break;
1365 }
1366 FlushCurrentPacket();
1367
1368 run_fast_path =
1369 !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
fayang2ab1e852019-11-04 11:24:36 -08001370 write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
1371 latched_hard_max_packet_length_ == 0;
fayang18be79a2019-09-16 15:17:12 -07001372 }
1373
1374 if (run_fast_path) {
1375 return ConsumeDataFastPath(id, write_length, offset, state != NO_FIN,
1376 total_bytes_consumed);
1377 }
1378
1379 // Don't allow the handshake to be bundled with other retransmittable frames.
1380 if (has_handshake) {
1381 FlushCurrentPacket();
1382 }
1383
1384 return QuicConsumedData(total_bytes_consumed, fin_consumed);
1385}
1386
1387QuicConsumedData QuicPacketCreator::ConsumeDataFastPath(
1388 QuicStreamId id,
1389 size_t write_length,
1390 QuicStreamOffset offset,
1391 bool fin,
1392 size_t total_bytes_consumed) {
dschinazi640536f2021-04-16 10:31:22 -07001393 QUICHE_DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id))
1394 << ENDPOINT;
fayanga504d5c2020-09-14 08:26:48 -07001395 if (AttemptingToSendUnencryptedStreamData()) {
1396 return QuicConsumedData(total_bytes_consumed,
1397 fin && (total_bytes_consumed == write_length));
fayang9320ca72020-08-03 13:02:59 -07001398 }
fayang18be79a2019-09-16 15:17:12 -07001399
1400 while (total_bytes_consumed < write_length &&
1401 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
1402 NOT_HANDSHAKE)) {
1403 // Serialize and encrypt the packet.
1404 size_t bytes_consumed = 0;
1405 CreateAndSerializeStreamFrame(id, write_length, total_bytes_consumed,
1406 offset + total_bytes_consumed, fin,
1407 next_transmission_type_, &bytes_consumed);
fayangaf2cdfd2020-01-06 10:52:12 -08001408 if (bytes_consumed == 0) {
1409 const std::string error_details =
1410 "Failed in CreateAndSerializeStreamFrame.";
dschinazi640536f2021-04-16 10:31:22 -07001411 QUIC_BUG(quic_bug_10752_24) << ENDPOINT << error_details;
fayangaf2cdfd2020-01-06 10:52:12 -08001412 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
1413 error_details);
1414 break;
fayangd99c2c12019-11-08 13:22:51 -08001415 }
fayang18be79a2019-09-16 15:17:12 -07001416 total_bytes_consumed += bytes_consumed;
1417 }
1418
1419 return QuicConsumedData(total_bytes_consumed,
1420 fin && (total_bytes_consumed == write_length));
1421}
1422
1423size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
1424 size_t write_length,
1425 QuicStreamOffset offset) {
dschinazi640536f2021-04-16 10:31:22 -07001426 QUIC_DVLOG(2) << ENDPOINT << "ConsumeCryptoData " << level << " write_length "
dschinazi6458eb32020-06-23 12:38:41 -07001427 << write_length << " offset " << offset;
QUICHE team7939a6e2021-03-16 19:47:54 -07001428 QUIC_BUG_IF(quic_bug_10752_25, !flusher_attached_)
dschinazi640536f2021-04-16 10:31:22 -07001429 << ENDPOINT
QUICHE team8e6da712021-03-08 10:59:32 -08001430 << "Packet flusher is not attached when "
1431 "generator tries to write crypto data.";
fayang18be79a2019-09-16 15:17:12 -07001432 MaybeBundleAckOpportunistically();
1433 // To make reasoning about crypto frames easier, we don't combine them with
1434 // other retransmittable frames in a single packet.
1435 // TODO(nharper): Once we have separate packet number spaces, everything
1436 // should be driven by encryption level, and we should stop flushing in this
1437 // spot.
1438 if (HasPendingRetransmittableFrames()) {
1439 FlushCurrentPacket();
1440 }
1441
1442 size_t total_bytes_consumed = 0;
1443
fayangd6c5bd02020-06-29 07:25:34 -07001444 while (
1445 total_bytes_consumed < write_length &&
1446 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, IS_HANDSHAKE)) {
fayang18be79a2019-09-16 15:17:12 -07001447 QuicFrame frame;
1448 if (!ConsumeCryptoDataToFillCurrentPacket(
1449 level, write_length - total_bytes_consumed,
1450 offset + total_bytes_consumed, fully_pad_crypto_handshake_packets_,
1451 next_transmission_type_, &frame)) {
1452 // The only pending data in the packet is non-retransmittable frames. I'm
1453 // assuming here that they won't occupy so much of the packet that a
1454 // CRYPTO frame won't fit.
QUICHE team7939a6e2021-03-16 19:47:54 -07001455 QUIC_BUG(quic_bug_10752_26)
dschinazi640536f2021-04-16 10:31:22 -07001456 << ENDPOINT << "Failed to ConsumeCryptoData at level " << level;
fayang18be79a2019-09-16 15:17:12 -07001457 return 0;
1458 }
1459 total_bytes_consumed += frame.crypto_frame->data_length;
1460 FlushCurrentPacket();
1461 }
1462
1463 // Don't allow the handshake to be bundled with other retransmittable frames.
1464 FlushCurrentPacket();
1465
1466 return total_bytes_consumed;
1467}
1468
1469void QuicPacketCreator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
fayang18be79a2019-09-16 15:17:12 -07001470 // MTU discovery frames must be sent by themselves.
1471 if (!CanSetMaxPacketLength()) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001472 QUIC_BUG(quic_bug_10752_27)
dschinazi640536f2021-04-16 10:31:22 -07001473 << ENDPOINT
QUICHE team8e6da712021-03-08 10:59:32 -08001474 << "MTU discovery packets should only be sent when no other "
1475 << "frames needs to be sent.";
fayang18be79a2019-09-16 15:17:12 -07001476 return;
1477 }
1478 const QuicByteCount current_mtu = max_packet_length();
1479
1480 // The MTU discovery frame is allocated on the stack, since it is going to be
1481 // serialized within this function.
1482 QuicMtuDiscoveryFrame mtu_discovery_frame;
1483 QuicFrame frame(mtu_discovery_frame);
1484
1485 // Send the probe packet with the new length.
1486 SetMaxPacketLength(target_mtu);
1487 const bool success = AddPaddedSavedFrame(frame, next_transmission_type_);
1488 FlushCurrentPacket();
1489 // The only reason AddFrame can fail is that the packet is too full to fit in
1490 // a ping. This is not possible for any sane MTU.
QUICHE team7939a6e2021-03-16 19:47:54 -07001491 QUIC_BUG_IF(quic_bug_10752_28, !success)
dschinazi640536f2021-04-16 10:31:22 -07001492 << ENDPOINT << "Failed to send path MTU target_mtu:" << target_mtu
QUICHE team8e6da712021-03-08 10:59:32 -08001493 << " transmission_type:" << next_transmission_type_;
fayang18be79a2019-09-16 15:17:12 -07001494
1495 // Reset the packet length back.
1496 SetMaxPacketLength(current_mtu);
1497}
1498
1499void QuicPacketCreator::MaybeBundleAckOpportunistically() {
fayang18be79a2019-09-16 15:17:12 -07001500 if (has_ack()) {
1501 // Ack already queued, nothing to do.
1502 return;
1503 }
1504 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
1505 NOT_HANDSHAKE)) {
1506 return;
1507 }
1508 const bool flushed =
1509 FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
QUICHE team7939a6e2021-03-16 19:47:54 -07001510 QUIC_BUG_IF(quic_bug_10752_29, !flushed)
dschinazi640536f2021-04-16 10:31:22 -07001511 << ENDPOINT << "Failed to flush ACK frame. encryption_level:"
QUICHE team8e6da712021-03-08 10:59:32 -08001512 << packet_.encryption_level;
fayang18be79a2019-09-16 15:17:12 -07001513}
1514
1515bool QuicPacketCreator::FlushAckFrame(const QuicFrames& frames) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001516 QUIC_BUG_IF(quic_bug_10752_30, !flusher_attached_)
dschinazi640536f2021-04-16 10:31:22 -07001517 << ENDPOINT
QUICHE team8e6da712021-03-08 10:59:32 -08001518 << "Packet flusher is not attached when "
1519 "generator tries to send ACK frame.";
fayangbe9a85e2020-12-30 11:49:25 -08001520 // MaybeBundleAckOpportunistically could be called nestedly when sending a
1521 // control frame causing another control frame to be sent.
QUICHE team7939a6e2021-03-16 19:47:54 -07001522 QUIC_BUG_IF(quic_bug_12398_18,
1523 GetQuicReloadableFlag(quic_single_ack_in_packet2) &&
1524 !frames.empty() && has_ack())
dschinazi640536f2021-04-16 10:31:22 -07001525 << ENDPOINT << "Trying to flush " << frames
1526 << " when there is ACK queued";
fayang18be79a2019-09-16 15:17:12 -07001527 for (const auto& frame : frames) {
dschinazi640536f2021-04-16 10:31:22 -07001528 QUICHE_DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME)
1529 << ENDPOINT;
fayang18be79a2019-09-16 15:17:12 -07001530 if (HasPendingFrames()) {
renjietangb63005e2019-11-19 23:08:53 -08001531 if (AddFrame(frame, next_transmission_type_)) {
fayang18be79a2019-09-16 15:17:12 -07001532 // There is pending frames and current frame fits.
1533 continue;
1534 }
1535 }
dschinazi640536f2021-04-16 10:31:22 -07001536 QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
fayang18be79a2019-09-16 15:17:12 -07001537 // There is no pending frames, consult the delegate whether a packet can be
1538 // generated.
1539 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
1540 NOT_HANDSHAKE)) {
1541 return false;
1542 }
renjietangb63005e2019-11-19 23:08:53 -08001543 const bool success = AddFrame(frame, next_transmission_type_);
dschinazi640536f2021-04-16 10:31:22 -07001544 QUIC_BUG_IF(quic_bug_10752_31, !success)
1545 << ENDPOINT << "Failed to flush " << frame;
fayang18be79a2019-09-16 15:17:12 -07001546 }
1547 return true;
1548}
1549
1550void QuicPacketCreator::AddRandomPadding() {
fayang18be79a2019-09-16 15:17:12 -07001551 AddPendingPadding(random_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
1552}
1553
1554void QuicPacketCreator::AttachPacketFlusher() {
fayang18be79a2019-09-16 15:17:12 -07001555 flusher_attached_ = true;
1556 if (!write_start_packet_number_.IsInitialized()) {
1557 write_start_packet_number_ = NextSendingPacketNumber();
1558 }
1559}
1560
1561void QuicPacketCreator::Flush() {
fayang18be79a2019-09-16 15:17:12 -07001562 FlushCurrentPacket();
1563 SendRemainingPendingPadding();
1564 flusher_attached_ = false;
wubbf4b8ac2020-10-27 13:03:33 -07001565 if (GetQuicFlag(FLAGS_quic_export_write_path_stats_at_server)) {
fayang18be79a2019-09-16 15:17:12 -07001566 if (!write_start_packet_number_.IsInitialized()) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001567 QUIC_BUG(quic_bug_10752_32)
dschinazi640536f2021-04-16 10:31:22 -07001568 << ENDPOINT << "write_start_packet_number is not initialized";
fayang18be79a2019-09-16 15:17:12 -07001569 return;
1570 }
1571 QUIC_SERVER_HISTOGRAM_COUNTS(
1572 "quic_server_num_written_packets_per_write",
1573 NextSendingPacketNumber() - write_start_packet_number_, 1, 200, 50,
1574 "Number of QUIC packets written per write operation");
1575 }
1576 write_start_packet_number_.Clear();
1577}
1578
1579void QuicPacketCreator::SendRemainingPendingPadding() {
fayang18be79a2019-09-16 15:17:12 -07001580 while (
1581 pending_padding_bytes() > 0 && !HasPendingFrames() &&
1582 delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) {
1583 FlushCurrentPacket();
1584 }
1585}
1586
1587void QuicPacketCreator::SetServerConnectionIdLength(uint32_t length) {
fayang18be79a2019-09-16 15:17:12 -07001588 if (length == 0) {
1589 SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
1590 } else {
1591 SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
1592 }
1593}
1594
1595void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
fayangcff885a2019-10-22 07:39:04 -07001596 next_transmission_type_ = type;
fayang18be79a2019-09-16 15:17:12 -07001597}
1598
1599MessageStatus QuicPacketCreator::AddMessageFrame(QuicMessageId message_id,
1600 QuicMemSliceSpan message) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001601 QUIC_BUG_IF(quic_bug_10752_33, !flusher_attached_)
dschinazi640536f2021-04-16 10:31:22 -07001602 << ENDPOINT
QUICHE team8e6da712021-03-08 10:59:32 -08001603 << "Packet flusher is not attached when "
1604 "generator tries to add message frame.";
fayang18be79a2019-09-16 15:17:12 -07001605 MaybeBundleAckOpportunistically();
1606 const QuicByteCount message_length = message.total_length();
1607 if (message_length > GetCurrentLargestMessagePayload()) {
1608 return MESSAGE_STATUS_TOO_LARGE;
1609 }
1610 if (!HasRoomForMessageFrame(message_length)) {
1611 FlushCurrentPacket();
1612 }
1613 QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
renjietangb63005e2019-11-19 23:08:53 -08001614 const bool success = AddFrame(QuicFrame(frame), next_transmission_type_);
fayang18be79a2019-09-16 15:17:12 -07001615 if (!success) {
dschinazi640536f2021-04-16 10:31:22 -07001616 QUIC_BUG(quic_bug_10752_34)
1617 << ENDPOINT << "Failed to send message " << message_id;
fayang18be79a2019-09-16 15:17:12 -07001618 delete frame;
1619 return MESSAGE_STATUS_INTERNAL_ERROR;
1620 }
1621 return MESSAGE_STATUS_SUCCESS;
1622}
1623
QUICHE teama6ef0a62019-03-07 20:34:33 -05001624QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
1625 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1626 HasIetfLongHeader()) {
1627 QuicLongHeaderType long_header_type =
1628 EncryptionlevelToLongHeaderType(packet_.encryption_level);
1629 if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
1630 long_header_type == HANDSHAKE) {
1631 return VARIABLE_LENGTH_INTEGER_LENGTH_2;
1632 }
1633 }
1634 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
1635}
1636
1637void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
QUICHE team2252b702019-05-14 23:55:14 -04001638 header->destination_connection_id = GetDestinationConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001639 header->destination_connection_id_included =
1640 GetDestinationConnectionIdIncluded();
QUICHE team2252b702019-05-14 23:55:14 -04001641 header->source_connection_id = GetSourceConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001642 header->source_connection_id_included = GetSourceConnectionIdIncluded();
1643 header->reset_flag = false;
1644 header->version_flag = IncludeVersionInHeader();
1645 if (IncludeNonceInPublicHeader()) {
dschinazi640536f2021-04-16 10:31:22 -07001646 QUICHE_DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective())
1647 << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001648 header->nonce = &diversification_nonce_;
1649 } else {
1650 header->nonce = nullptr;
1651 }
fayang354c9422019-05-21 08:10:35 -07001652 packet_.packet_number = NextSendingPacketNumber();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001653 header->packet_number = packet_.packet_number;
1654 header->packet_number_length = GetPacketNumberLength();
1655 header->retry_token_length_length = GetRetryTokenLengthLength();
1656 header->retry_token = GetRetryToken();
1657 header->length_length = GetLengthLength();
1658 header->remaining_packet_length = 0;
1659 if (!HasIetfLongHeader()) {
1660 return;
1661 }
1662 header->long_packet_type =
1663 EncryptionlevelToLongHeaderType(packet_.encryption_level);
1664}
1665
fayangfce2f722020-06-26 10:27:32 -07001666size_t QuicPacketCreator::GetSerializedFrameLength(const QuicFrame& frame) {
1667 size_t serialized_frame_length = framer_->GetSerializedFrameLength(
1668 frame, BytesFree(), queued_frames_.empty(),
1669 /* last_frame_in_packet= */ true, GetPacketNumberLength());
fayangfce2f722020-06-26 10:27:32 -07001670 if (!framer_->version().HasHeaderProtection() ||
1671 serialized_frame_length == 0) {
1672 return serialized_frame_length;
1673 }
1674 // Calculate frame bytes and bytes free with this frame added.
1675 const size_t frame_bytes = PacketSize() - PacketHeaderSize() +
1676 ExpansionOnNewFrame() + serialized_frame_length;
1677 if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
1678 // No extra bytes is needed.
1679 return serialized_frame_length;
1680 }
fayangfce2f722020-06-26 10:27:32 -07001681 if (BytesFree() < serialized_frame_length) {
QUICHE team7939a6e2021-03-16 19:47:54 -07001682 QUIC_BUG(quic_bug_10752_35) << ENDPOINT << "Frame does not fit: " << frame;
fayangfce2f722020-06-26 10:27:32 -07001683 return 0;
1684 }
1685 // Please note bytes_free does not take |frame|'s expansion into account.
1686 size_t bytes_free = BytesFree() - serialized_frame_length;
1687 // Extra bytes needed (this is NOT padding needed) should be at least 1
1688 // padding + expansion.
bnce5c11c02020-07-29 08:02:21 -07001689 const size_t extra_bytes_needed = std::max(
1690 1 + ExpansionOnNewFrameWithLastFrame(frame, framer_->transport_version()),
1691 MinPlaintextPacketSize(framer_->version()) - frame_bytes);
fayangfce2f722020-06-26 10:27:32 -07001692 if (bytes_free < extra_bytes_needed) {
1693 // This frame does not fit.
1694 return 0;
1695 }
1696 return serialized_frame_length;
1697}
1698
QUICHE teama6ef0a62019-03-07 20:34:33 -05001699bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001700 TransmissionType transmission_type) {
1701 QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
renjietang2b5e6622020-06-02 15:19:40 -07001702 << transmission_type << ": " << frame;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001703 if (frame.type == STREAM_FRAME &&
nharper46833c32019-05-15 21:33:05 -07001704 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
1705 frame.stream_frame.stream_id) &&
fayang9320ca72020-08-03 13:02:59 -07001706 AttemptingToSendUnencryptedStreamData()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001707 return false;
1708 }
renjietangdbe98342019-10-18 11:00:57 -07001709
dschinazi6de961b2021-03-04 08:38:47 -08001710 // Sanity check to ensure we don't send frames at the wrong encryption level.
1711 QUICHE_DCHECK(
1712 packet_.encryption_level == ENCRYPTION_ZERO_RTT ||
1713 packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
1714 (frame.type != GOAWAY_FRAME && frame.type != WINDOW_UPDATE_FRAME &&
1715 frame.type != HANDSHAKE_DONE_FRAME &&
1716 frame.type != NEW_CONNECTION_ID_FRAME &&
1717 frame.type != MAX_STREAMS_FRAME && frame.type != STREAMS_BLOCKED_FRAME &&
1718 frame.type != PATH_RESPONSE_FRAME &&
1719 frame.type != PATH_CHALLENGE_FRAME && frame.type != STOP_SENDING_FRAME &&
1720 frame.type != MESSAGE_FRAME && frame.type != NEW_TOKEN_FRAME &&
1721 frame.type != RETIRE_CONNECTION_ID_FRAME &&
1722 frame.type != ACK_FREQUENCY_FRAME))
dschinazi640536f2021-04-16 10:31:22 -07001723 << ENDPOINT << frame.type << " not allowed at "
1724 << packet_.encryption_level;
dschinazi6de961b2021-03-04 08:38:47 -08001725
renjietange426d622020-01-02 11:58:46 -08001726 if (frame.type == STREAM_FRAME) {
renjietang50ea92a2019-12-26 10:15:01 -08001727 if (MaybeCoalesceStreamFrame(frame.stream_frame)) {
1728 LogCoalesceStreamFrameStatus(true);
renjietang50ea92a2019-12-26 10:15:01 -08001729 return true;
1730 } else {
1731 LogCoalesceStreamFrameStatus(false);
1732 }
renjietangdbe98342019-10-18 11:00:57 -07001733 }
1734
dschinazi87aad8a2020-08-26 17:02:02 -07001735 // If this is an ACK frame, validate that it is non-empty and that
1736 // largest_acked matches the max packet number.
vasilvvf8035162021-02-01 14:49:14 -08001737 QUICHE_DCHECK(frame.type != ACK_FRAME || (!frame.ack_frame->packets.Empty() &&
1738 frame.ack_frame->packets.Max() ==
1739 frame.ack_frame->largest_acked))
dschinazi640536f2021-04-16 10:31:22 -07001740 << ENDPOINT << "Invalid ACK frame: " << frame;
dschinazi87aad8a2020-08-26 17:02:02 -07001741
fayangfce2f722020-06-26 10:27:32 -07001742 size_t frame_len = GetSerializedFrameLength(frame);
fayang2ab1e852019-11-04 11:24:36 -08001743 if (frame_len == 0 && RemoveSoftMaxPacketLength()) {
1744 // Remove soft max_packet_length and retry.
fayangfce2f722020-06-26 10:27:32 -07001745 frame_len = GetSerializedFrameLength(frame);
fayang2ab1e852019-11-04 11:24:36 -08001746 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001747 if (frame_len == 0) {
dschinazi640536f2021-04-16 10:31:22 -07001748 QUIC_DVLOG(1) << ENDPOINT
1749 << "Flushing because current open packet is full when adding "
dschinazi6458eb32020-06-23 12:38:41 -07001750 << frame;
fayang62b637b2019-09-16 08:40:49 -07001751 FlushCurrentPacket();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001752 return false;
1753 }
fayang5a3cfcb2020-08-27 12:57:23 -07001754 if (queued_frames_.empty()) {
fayang7a06f9b2020-06-24 10:23:19 -07001755 packet_size_ = PacketHeaderSize();
1756 }
dschinazi640536f2021-04-16 10:31:22 -07001757 QUICHE_DCHECK_LT(0u, packet_size_) << ENDPOINT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001758
1759 packet_size_ += ExpansionOnNewFrame() + frame_len;
1760
fayang347ab752019-10-22 11:17:43 -07001761 if (QuicUtils::IsRetransmittableFrame(frame.type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001762 packet_.retransmittable_frames.push_back(frame);
1763 queued_frames_.push_back(frame);
1764 if (QuicUtils::IsHandshakeFrame(frame, framer_->transport_version())) {
1765 packet_.has_crypto_handshake = IS_HANDSHAKE;
1766 }
1767 } else {
fayang02a28742019-12-04 07:09:38 -08001768 if (frame.type == PADDING_FRAME &&
1769 frame.padding_frame.num_padding_bytes == -1) {
1770 // Populate the actual length of full padding frame, such that one can
1771 // know how much padding is actually added.
1772 packet_.nonretransmittable_frames.push_back(
1773 QuicFrame(QuicPaddingFrame(frame_len)));
1774 } else {
1775 packet_.nonretransmittable_frames.push_back(frame);
fayang51152fd2019-10-21 06:48:09 -07001776 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001777 queued_frames_.push_back(frame);
1778 }
1779
1780 if (frame.type == ACK_FRAME) {
1781 packet_.has_ack = true;
1782 packet_.largest_acked = LargestAcked(*frame.ack_frame);
haoyuewang5b0f14f2020-09-18 14:31:54 -07001783 } else if (frame.type == STOP_WAITING_FRAME) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001784 packet_.has_stop_waiting = true;
haoyuewang5b0f14f2020-09-18 14:31:54 -07001785 } else if (frame.type == ACK_FREQUENCY_FRAME) {
1786 packet_.has_ack_frequency = true;
haoyuewang11a54a12020-09-21 14:17:29 -07001787 } else if (frame.type == MESSAGE_FRAME) {
1788 packet_.has_message = true;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001789 }
1790 if (debug_delegate_ != nullptr) {
1791 debug_delegate_->OnFrameAddedToPacket(frame);
1792 }
1793
1794 // Packet transmission type is determined by the last added retransmittable
1795 // frame.
fayangcff885a2019-10-22 07:39:04 -07001796 if (QuicUtils::IsRetransmittableFrame(frame.type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001797 packet_.transmission_type = transmission_type;
1798 }
1799 return true;
1800}
1801
fayangfce2f722020-06-26 10:27:32 -07001802void QuicPacketCreator::MaybeAddExtraPaddingForHeaderProtection() {
fayangfce2f722020-06-26 10:27:32 -07001803 if (!framer_->version().HasHeaderProtection() || needs_full_padding_) {
1804 return;
1805 }
1806 const size_t frame_bytes = PacketSize() - PacketHeaderSize();
1807 if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
1808 return;
1809 }
1810 const QuicByteCount min_header_protection_padding =
1811 std::max(1 + ExpansionOnNewFrame(),
1812 MinPlaintextPacketSize(framer_->version()) - frame_bytes) -
1813 ExpansionOnNewFrame();
fayangfce2f722020-06-26 10:27:32 -07001814 // Update pending_padding_bytes_.
1815 pending_padding_bytes_ =
1816 std::max(pending_padding_bytes_, min_header_protection_padding);
1817}
1818
renjietangdbe98342019-10-18 11:00:57 -07001819bool QuicPacketCreator::MaybeCoalesceStreamFrame(const QuicStreamFrame& frame) {
1820 if (queued_frames_.empty() || queued_frames_.back().type != STREAM_FRAME) {
1821 return false;
1822 }
1823 QuicStreamFrame* candidate = &queued_frames_.back().stream_frame;
1824 if (candidate->stream_id != frame.stream_id ||
1825 candidate->offset + candidate->data_length != frame.offset ||
1826 frame.data_length > BytesFree()) {
1827 return false;
1828 }
1829 candidate->data_length += frame.data_length;
1830 candidate->fin = frame.fin;
1831
1832 // The back of retransmittable frames must be the same as the original
1833 // queued frames' back.
dschinazi640536f2021-04-16 10:31:22 -07001834 QUICHE_DCHECK_EQ(packet_.retransmittable_frames.back().type, STREAM_FRAME)
1835 << ENDPOINT;
renjietangdbe98342019-10-18 11:00:57 -07001836 QuicStreamFrame* retransmittable =
1837 &packet_.retransmittable_frames.back().stream_frame;
dschinazi640536f2021-04-16 10:31:22 -07001838 QUICHE_DCHECK_EQ(retransmittable->stream_id, frame.stream_id) << ENDPOINT;
vasilvvf8035162021-02-01 14:49:14 -08001839 QUICHE_DCHECK_EQ(retransmittable->offset + retransmittable->data_length,
dschinazi640536f2021-04-16 10:31:22 -07001840 frame.offset)
1841 << ENDPOINT;
renjietangdbe98342019-10-18 11:00:57 -07001842 retransmittable->data_length = candidate->data_length;
1843 retransmittable->fin = candidate->fin;
1844 packet_size_ += frame.data_length;
1845 if (debug_delegate_ != nullptr) {
1846 debug_delegate_->OnStreamFrameCoalesced(*candidate);
1847 }
1848 return true;
1849}
1850
fayang2ab1e852019-11-04 11:24:36 -08001851bool QuicPacketCreator::RemoveSoftMaxPacketLength() {
1852 if (latched_hard_max_packet_length_ == 0) {
1853 return false;
1854 }
1855 if (!CanSetMaxPacketLength()) {
1856 return false;
1857 }
dschinazi640536f2021-04-16 10:31:22 -07001858 QUIC_DVLOG(1) << ENDPOINT << "Restoring max packet length to: "
fayang2ab1e852019-11-04 11:24:36 -08001859 << latched_hard_max_packet_length_;
1860 SetMaxPacketLength(latched_hard_max_packet_length_);
1861 // Reset latched_max_packet_length_.
1862 latched_hard_max_packet_length_ = 0;
1863 return true;
1864}
1865
QUICHE teama6ef0a62019-03-07 20:34:33 -05001866void QuicPacketCreator::MaybeAddPadding() {
1867 // The current packet should have no padding bytes because padding is only
1868 // added when this method is called just before the packet is serialized.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001869 if (BytesFree() == 0) {
1870 // Don't pad full packets.
1871 return;
1872 }
1873
1874 if (packet_.transmission_type == PROBING_RETRANSMISSION) {
1875 needs_full_padding_ = true;
1876 }
1877
fayangfe77c032020-08-24 18:21:32 -07001878 if (packet_.fate == COALESCE || packet_.fate == LEGACY_VERSION_ENCAPSULATE) {
1879 // Do not add full padding if the packet is going to be coalesced or
1880 // encapsulated.
1881 needs_full_padding_ = false;
dschinazi6458eb32020-06-23 12:38:41 -07001882 }
1883
nharper55fa6132019-05-07 19:37:21 -07001884 // Header protection requires a minimum plaintext packet size.
fayang7cd1d822020-08-25 13:52:19 -07001885 MaybeAddExtraPaddingForHeaderProtection();
nharper55fa6132019-05-07 19:37:21 -07001886
fayang7cd1d822020-08-25 13:52:19 -07001887 if (!needs_full_padding_ && pending_padding_bytes_ == 0) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001888 // Do not need padding.
1889 return;
1890 }
1891
nharper55fa6132019-05-07 19:37:21 -07001892 int padding_bytes = -1;
fayang88b87232020-06-24 15:31:08 -07001893 if (!needs_full_padding_) {
1894 padding_bytes = std::min<int16_t>(pending_padding_bytes_, BytesFree());
1895 pending_padding_bytes_ -= padding_bytes;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001896 }
1897
fayang347ab752019-10-22 11:17:43 -07001898 bool success = AddFrame(QuicFrame(QuicPaddingFrame(padding_bytes)),
nharper55fa6132019-05-07 19:37:21 -07001899 packet_.transmission_type);
QUICHE team7939a6e2021-03-16 19:47:54 -07001900 QUIC_BUG_IF(quic_bug_10752_36, !success)
dschinazi640536f2021-04-16 10:31:22 -07001901 << ENDPOINT << "Failed to add padding_bytes: " << padding_bytes
QUICHE team8e6da712021-03-08 10:59:32 -08001902 << " transmission_type: " << packet_.transmission_type;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001903}
1904
1905bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
1906 return have_diversification_nonce_ &&
1907 packet_.encryption_level == ENCRYPTION_ZERO_RTT;
1908}
1909
1910bool QuicPacketCreator::IncludeVersionInHeader() const {
dschinazicc7d40d2020-12-02 11:28:18 -08001911 if (version().HasIetfInvariantHeader()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001912 return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1913 }
1914 return send_version_in_packet_;
1915}
1916
1917void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
1918 pending_padding_bytes_ += size;
1919}
1920
ianswette28f0222019-04-04 13:31:22 -07001921bool QuicPacketCreator::StreamFrameIsClientHello(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001922 const QuicStreamFrame& frame) const {
1923 if (framer_->perspective() == Perspective::IS_SERVER ||
nharper46833c32019-05-15 21:33:05 -07001924 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
1925 frame.stream_id)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001926 return false;
1927 }
ianswette28f0222019-04-04 13:31:22 -07001928 // The ClientHello is always sent with INITIAL encryption.
1929 return packet_.encryption_level == ENCRYPTION_INITIAL;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001930}
1931
dschinazi7b9278c2019-05-20 07:36:21 -07001932void QuicPacketCreator::SetServerConnectionIdIncluded(
1933 QuicConnectionIdIncluded server_connection_id_included) {
vasilvvf8035162021-02-01 14:49:14 -08001934 QUICHE_DCHECK(server_connection_id_included == CONNECTION_ID_PRESENT ||
dschinazi640536f2021-04-16 10:31:22 -07001935 server_connection_id_included == CONNECTION_ID_ABSENT)
1936 << ENDPOINT;
vasilvvf8035162021-02-01 14:49:14 -08001937 QUICHE_DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
dschinazi640536f2021-04-16 10:31:22 -07001938 server_connection_id_included != CONNECTION_ID_ABSENT)
1939 << ENDPOINT;
dschinazi7b9278c2019-05-20 07:36:21 -07001940 server_connection_id_included_ = server_connection_id_included;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001941}
1942
dschinazi7b9278c2019-05-20 07:36:21 -07001943void QuicPacketCreator::SetServerConnectionId(
1944 QuicConnectionId server_connection_id) {
1945 server_connection_id_ = server_connection_id;
QUICHE teamc65d1d12019-03-19 20:58:04 -07001946}
1947
dschinazi346b7ce2019-06-05 01:38:18 -07001948void QuicPacketCreator::SetClientConnectionId(
1949 QuicConnectionId client_connection_id) {
vasilvvf8035162021-02-01 14:49:14 -08001950 QUICHE_DCHECK(client_connection_id.IsEmpty() ||
dschinazi640536f2021-04-16 10:31:22 -07001951 framer_->version().SupportsClientConnectionIds())
1952 << ENDPOINT;
dschinazi346b7ce2019-06-05 01:38:18 -07001953 client_connection_id_ = client_connection_id;
1954}
1955
ianswettb239f862019-04-05 09:15:06 -07001956QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001957 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001958 return 0;
1959 }
1960 const size_t packet_header_size = GetPacketHeaderSize(
1961 framer_->transport_version(), GetDestinationConnectionIdLength(),
1962 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
1963 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
ianswettb239f862019-04-05 09:15:06 -07001964 // No Retry token on packets containing application data.
1965 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001966 // This is the largest possible message payload when the length field is
1967 // omitted.
fayang2ab1e852019-11-04 11:24:36 -08001968 size_t max_plaintext_size =
1969 latched_hard_max_packet_length_ == 0
1970 ? max_plaintext_size_
1971 : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
dschinazied459c02020-05-07 16:12:23 -07001972 size_t largest_frame =
1973 max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
1974 if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
1975 largest_frame = static_cast<size_t>(max_datagram_frame_size_);
1976 }
1977 return largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001978}
1979
ianswettb239f862019-04-05 09:15:06 -07001980QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001981 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
ianswettb239f862019-04-05 09:15:06 -07001982 return 0;
1983 }
1984 // QUIC Crypto server packets may include a diversification nonce.
1985 const bool may_include_nonce =
1986 framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
1987 framer_->perspective() == Perspective::IS_SERVER;
1988 // IETF QUIC long headers include a length on client 0RTT packets.
1989 QuicVariableLengthIntegerLength length_length =
nharperd43f1d62019-07-01 15:18:20 -07001990 VARIABLE_LENGTH_INTEGER_LENGTH_0;
1991 if (framer_->perspective() == Perspective::IS_CLIENT) {
1992 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
1993 }
nharper405f7192019-09-11 08:28:06 -07001994 if (!QuicVersionHasLongHeaderLengths(framer_->transport_version())) {
nharperd43f1d62019-07-01 15:18:20 -07001995 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
1996 }
ianswettb239f862019-04-05 09:15:06 -07001997 const size_t packet_header_size = GetPacketHeaderSize(
1998 framer_->transport_version(), GetDestinationConnectionIdLength(),
1999 // Assume CID lengths don't change, but version may be present.
2000 GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
2001 PACKET_4BYTE_PACKET_NUMBER,
2002 // No Retry token on packets containing application data.
2003 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
2004 // This is the largest possible message payload when the length field is
2005 // omitted.
fayang2ab1e852019-11-04 11:24:36 -08002006 size_t max_plaintext_size =
2007 latched_hard_max_packet_length_ == 0
2008 ? max_plaintext_size_
2009 : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
dschinazied459c02020-05-07 16:12:23 -07002010 size_t largest_frame =
2011 max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
2012 if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
2013 largest_frame = static_cast<size_t>(max_datagram_frame_size_);
2014 }
ianswettb239f862019-04-05 09:15:06 -07002015 const QuicPacketLength largest_payload =
dschinazied459c02020-05-07 16:12:23 -07002016 largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
ianswettb239f862019-04-05 09:15:06 -07002017 // This must always be less than or equal to GetCurrentLargestMessagePayload.
dschinazi640536f2021-04-16 10:31:22 -07002018 QUICHE_DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload())
2019 << ENDPOINT;
ianswettb239f862019-04-05 09:15:06 -07002020 return largest_payload;
2021}
2022
fayang9320ca72020-08-03 13:02:59 -07002023bool QuicPacketCreator::AttemptingToSendUnencryptedStreamData() {
2024 if (packet_.encryption_level == ENCRYPTION_ZERO_RTT ||
2025 packet_.encryption_level == ENCRYPTION_FORWARD_SECURE) {
2026 return false;
2027 }
2028 const std::string error_details =
vasilvv9edb31e2020-12-03 19:32:58 -08002029 absl::StrCat("Cannot send stream data with level: ",
2030 EncryptionLevelToString(packet_.encryption_level));
dschinazi640536f2021-04-16 10:31:22 -07002031 QUIC_BUG(quic_bug_10752_37) << ENDPOINT << error_details;
fayang9320ca72020-08-03 13:02:59 -07002032 delegate_->OnUnrecoverableError(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA,
2033 error_details);
2034 return true;
2035}
2036
QUICHE teama6ef0a62019-03-07 20:34:33 -05002037bool QuicPacketCreator::HasIetfLongHeader() const {
dschinazicc7d40d2020-12-02 11:28:18 -08002038 return version().HasIetfInvariantHeader() &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05002039 packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
2040}
2041
nharper6f8a7612019-07-08 12:31:20 -07002042// static
QUICHE team2252b702019-05-14 23:55:14 -04002043size_t QuicPacketCreator::MinPlaintextPacketSize(
2044 const ParsedQuicVersion& version) {
2045 if (!version.HasHeaderProtection()) {
nharper55fa6132019-05-07 19:37:21 -07002046 return 0;
2047 }
2048 // Header protection samples 16 bytes of ciphertext starting 4 bytes after the
2049 // packet number. In IETF QUIC, all AEAD algorithms have a 16-byte auth tag
2050 // (i.e. the ciphertext is 16 bytes larger than the plaintext). Since packet
2051 // numbers could be as small as 1 byte, but the sample starts 4 bytes after
2052 // the packet number, at least 3 bytes of plaintext are needed to make sure
2053 // that there is enough ciphertext to sample.
2054 //
2055 // Google QUIC crypto uses different AEAD algorithms - in particular the auth
2056 // tags are only 12 bytes instead of 16 bytes. Since the auth tag is 4 bytes
2057 // shorter, 4 more bytes of plaintext are needed to guarantee there is enough
2058 // ciphertext to sample.
2059 //
2060 // This method could check for PROTOCOL_TLS1_3 vs PROTOCOL_QUIC_CRYPTO and
2061 // return 3 when TLS 1.3 is in use (the use of IETF vs Google QUIC crypters is
2062 // determined based on the handshake protocol used). However, even when TLS
2063 // 1.3 is used, unittests still use NullEncrypter/NullDecrypter (and other
2064 // test crypters) which also only use 12 byte tags.
2065 //
2066 // TODO(nharper): Set this based on the handshake protocol in use.
2067 return 7;
2068}
2069
fayang354c9422019-05-21 08:10:35 -07002070QuicPacketNumber QuicPacketCreator::NextSendingPacketNumber() const {
2071 if (!packet_number().IsInitialized()) {
2072 return framer_->first_sending_packet_number();
2073 }
2074 return packet_number() + 1;
2075}
2076
fayang18be79a2019-09-16 15:17:12 -07002077bool QuicPacketCreator::PacketFlusherAttached() const {
fayang18be79a2019-09-16 15:17:12 -07002078 return flusher_attached_;
2079}
2080
fayangfe963c52020-07-16 06:56:09 -07002081bool QuicPacketCreator::HasSoftMaxPacketLength() const {
2082 return latched_hard_max_packet_length_ != 0;
2083}
2084
danzh051bf772020-08-24 12:30:36 -07002085void QuicPacketCreator::SetDefaultPeerAddress(QuicSocketAddress address) {
2086 if (!packet_.peer_address.IsInitialized()) {
2087 packet_.peer_address = address;
2088 return;
2089 }
2090 if (packet_.peer_address != address) {
2091 FlushCurrentPacket();
2092 packet_.peer_address = address;
2093 }
2094}
2095
dschinazi640536f2021-04-16 10:31:22 -07002096#define ENDPOINT2 \
2097 (creator_->framer_->perspective() == Perspective::IS_SERVER ? "Server: " \
2098 : "Client: ")
2099
danzh051bf772020-08-24 12:30:36 -07002100QuicPacketCreator::ScopedPeerAddressContext::ScopedPeerAddressContext(
2101 QuicPacketCreator* creator,
haoyuewangd8aa40a2021-04-14 12:15:36 -07002102 QuicSocketAddress address,
2103 bool update_connection_id)
2104 : ScopedPeerAddressContext(creator,
2105 address,
2106 EmptyQuicConnectionId(),
2107 EmptyQuicConnectionId(),
2108 update_connection_id) {}
2109
2110QuicPacketCreator::ScopedPeerAddressContext::ScopedPeerAddressContext(
2111 QuicPacketCreator* creator,
2112 QuicSocketAddress address,
2113 const QuicConnectionId& client_connection_id,
2114 const QuicConnectionId& server_connection_id,
2115 bool update_connection_id)
2116 : creator_(creator),
2117 old_peer_address_(creator_->packet_.peer_address),
2118 old_client_connection_id_(creator_->GetClientConnectionId()),
2119 old_server_connection_id_(creator_->GetServerConnectionId()),
2120 update_connection_id_(update_connection_id) {
2121 QUIC_BUG_IF(quic_bug_12398_19, !old_peer_address_.IsInitialized())
dschinazi640536f2021-04-16 10:31:22 -07002122 << ENDPOINT2
2123 << "Context is used before serialized packet's peer address is "
danzh051bf772020-08-24 12:30:36 -07002124 "initialized.";
2125 creator_->SetDefaultPeerAddress(address);
haoyuewangd8aa40a2021-04-14 12:15:36 -07002126 if (update_connection_id_) {
haoyuewang23d20ac2021-04-29 10:55:34 -04002127 // Flush current packet if connection ID changes.
2128 if (address == old_peer_address_ &&
2129 ((client_connection_id != old_client_connection_id_) ||
2130 (server_connection_id != old_server_connection_id_))) {
2131 creator_->FlushCurrentPacket();
2132 }
haoyuewangd8aa40a2021-04-14 12:15:36 -07002133 creator_->SetClientConnectionId(client_connection_id);
2134 creator_->SetServerConnectionId(server_connection_id);
2135 }
danzh051bf772020-08-24 12:30:36 -07002136}
2137
2138QuicPacketCreator::ScopedPeerAddressContext::~ScopedPeerAddressContext() {
2139 creator_->SetDefaultPeerAddress(old_peer_address_);
haoyuewangd8aa40a2021-04-14 12:15:36 -07002140 if (update_connection_id_) {
2141 creator_->SetClientConnectionId(old_client_connection_id_);
2142 creator_->SetServerConnectionId(old_server_connection_id_);
2143 }
danzh051bf772020-08-24 12:30:36 -07002144}
2145
fayang04590fc2020-08-31 10:37:55 -07002146QuicPacketCreator::ScopedSerializationFailureHandler::
2147 ScopedSerializationFailureHandler(QuicPacketCreator* creator)
fayange447bc62020-08-27 13:47:11 -07002148 : creator_(creator) {}
2149
fayang04590fc2020-08-31 10:37:55 -07002150QuicPacketCreator::ScopedSerializationFailureHandler::
2151 ~ScopedSerializationFailureHandler() {
fayange447bc62020-08-27 13:47:11 -07002152 if (creator_ == nullptr) {
2153 return;
2154 }
fayang04590fc2020-08-31 10:37:55 -07002155 // Always clear queued_frames_.
fayange447bc62020-08-27 13:47:11 -07002156 creator_->queued_frames_.clear();
fayang04590fc2020-08-31 10:37:55 -07002157
fayang48e283b2020-10-27 10:42:01 -07002158 if (creator_->packet_.encrypted_buffer == nullptr) {
fayang04590fc2020-08-31 10:37:55 -07002159 const std::string error_details = "Failed to SerializePacket.";
dschinazi640536f2021-04-16 10:31:22 -07002160 QUIC_BUG(quic_bug_10752_38) << ENDPOINT2 << error_details;
fayang04590fc2020-08-31 10:37:55 -07002161 creator_->delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
2162 error_details);
2163 }
fayange447bc62020-08-27 13:47:11 -07002164}
2165
dschinazi640536f2021-04-16 10:31:22 -07002166#undef ENDPOINT2
2167
dschinazi87aad8a2020-08-26 17:02:02 -07002168void QuicPacketCreator::set_encryption_level(EncryptionLevel level) {
vasilvvf8035162021-02-01 14:49:14 -08002169 QUICHE_DCHECK(level == packet_.encryption_level || !HasPendingFrames())
dschinazi640536f2021-04-16 10:31:22 -07002170 << ENDPOINT << "Cannot update encryption level from "
2171 << packet_.encryption_level << " to " << level
2172 << " when we already have pending frames: "
dschinazi87aad8a2020-08-26 17:02:02 -07002173 << QuicFramesToString(queued_frames_);
2174 packet_.encryption_level = level;
2175}
2176
danzh28ba4722020-11-12 11:55:39 -08002177void QuicPacketCreator::AddPathChallengeFrame(
2178 const QuicPathFrameBuffer& payload) {
danzha1c08152021-03-15 10:29:40 -07002179 // TODO(danzh) Unify similar checks at several entry points into one in
2180 // AddFrame(). Sort out test helper functions and peer class that don't
2181 // enforce this check.
QUICHE team7939a6e2021-03-16 19:47:54 -07002182 QUIC_BUG_IF(quic_bug_10752_39, !flusher_attached_)
dschinazi640536f2021-04-16 10:31:22 -07002183 << ENDPOINT
danzha1c08152021-03-15 10:29:40 -07002184 << "Packet flusher is not attached when "
2185 "generator tries to write stream data.";
danzhe919b002020-10-14 14:44:46 -07002186 // Write a PATH_CHALLENGE frame, which has a random 8-byte payload.
danzh28ba4722020-11-12 11:55:39 -08002187 auto path_challenge_frame = new QuicPathChallengeFrame(0, payload);
danzhe919b002020-10-14 14:44:46 -07002188 QuicFrame frame(path_challenge_frame);
2189 if (AddPaddedFrameWithRetry(frame)) {
2190 return;
2191 }
2192 // Fail silently if the probing packet cannot be written, path validation
2193 // initiator will retry sending automatically.
2194 // TODO(danzh) This will consume retry budget, if it causes performance
2195 // regression, consider to notify the caller about the sending failure and let
2196 // the caller to decide if it worth retrying.
2197 QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_CHALLENGE now";
2198 delete path_challenge_frame;
2199}
2200
danzh8a27a1a2020-09-02 10:26:28 -07002201bool QuicPacketCreator::AddPathResponseFrame(
2202 const QuicPathFrameBuffer& data_buffer) {
2203 auto path_response =
2204 new QuicPathResponseFrame(kInvalidControlFrameId, data_buffer);
2205 QuicFrame frame(path_response);
danzhe919b002020-10-14 14:44:46 -07002206 if (AddPaddedFrameWithRetry(frame)) {
2207 return true;
2208 }
2209
2210 QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_RESPONSE now";
danzh8efd70d2021-03-09 13:00:27 -08002211 QUIC_RELOADABLE_FLAG_COUNT_N(quic_send_path_response2, 5, 5);
danzhe919b002020-10-14 14:44:46 -07002212 delete path_response;
2213 return false;
2214}
2215
2216bool QuicPacketCreator::AddPaddedFrameWithRetry(const QuicFrame& frame) {
danzh8a27a1a2020-09-02 10:26:28 -07002217 if (HasPendingFrames()) {
2218 if (AddPaddedSavedFrame(frame, NOT_RETRANSMISSION)) {
2219 // Frame is queued.
2220 return true;
2221 }
2222 }
2223 // Frame was not queued but queued frames were flushed.
dschinazi640536f2021-04-16 10:31:22 -07002224 QUICHE_DCHECK(!HasPendingFrames()) << ENDPOINT;
danzh8a27a1a2020-09-02 10:26:28 -07002225 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
2226 NOT_HANDSHAKE)) {
danzh8a27a1a2020-09-02 10:26:28 -07002227 return false;
2228 }
2229 bool success = AddPaddedSavedFrame(frame, NOT_RETRANSMISSION);
dschinazi640536f2021-04-16 10:31:22 -07002230 QUIC_BUG_IF(quic_bug_12398_20, !success) << ENDPOINT;
danzh8a27a1a2020-09-02 10:26:28 -07002231 return true;
2232}
danzhe919b002020-10-14 14:44:46 -07002233
fayang133b8682020-12-08 05:50:33 -08002234bool QuicPacketCreator::HasRetryToken() const {
2235 return !retry_token_.empty();
2236}
2237
QUICHE teama6ef0a62019-03-07 20:34:33 -05002238#undef ENDPOINT // undef for jumbo builds
2239} // namespace quic