blob: 109042fa3763a994858dbeec2c19f782ede51fbb [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/quic_packet_creator.h"
6
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
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
renjietangdbe98342019-10-18 11:00:57 -070015#include "net/third_party/quiche/src/quic/core/frames/quic_frame.h"
renjietang4c704c82019-10-07 16:39:11 -070016#include "net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h"
renjietangdbe98342019-10-18 11:00:57 -070017#include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050018#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
ianswettb239f862019-04-05 09:15:06 -070019#include "net/third_party/quiche/src/quic/core/quic_constants.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050020#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
21#include "net/third_party/quiche/src/quic/core/quic_types.h"
22#include "net/third_party/quiche/src/quic/core/quic_utils.h"
ianswettb239f862019-04-05 09:15:06 -070023#include "net/third_party/quiche/src/quic/core/quic_versions.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050024#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050025#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
renjietang50ea92a2019-12-26 10:15:01 -080026#include "net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050027#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
28#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
29#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
fayang18be79a2019-09-16 15:17:12 -070030#include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h"
bnc4e9283d2019-12-17 07:08:57 -080031#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080032#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
33#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
34#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050035
36namespace quic {
37namespace {
38
39QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
40 switch (level) {
QUICHE team6987b4a2019-03-15 16:23:04 -070041 case ENCRYPTION_INITIAL:
QUICHE teama6ef0a62019-03-07 20:34:33 -050042 return INITIAL;
QUICHE team88ea0082019-03-15 10:05:26 -070043 case ENCRYPTION_HANDSHAKE:
44 return HANDSHAKE;
QUICHE teama6ef0a62019-03-07 20:34:33 -050045 case ENCRYPTION_ZERO_RTT:
46 return ZERO_RTT_PROTECTED;
47 case ENCRYPTION_FORWARD_SECURE:
48 QUIC_BUG
49 << "Try to derive long header type for packet with encryption level: "
renjietangb4ebb1d2020-05-27 18:15:51 -070050 << level;
QUICHE teama6ef0a62019-03-07 20:34:33 -050051 return INVALID_PACKET_TYPE;
52 default:
renjietangb4ebb1d2020-05-27 18:15:51 -070053 QUIC_BUG << level;
QUICHE teama6ef0a62019-03-07 20:34:33 -050054 return INVALID_PACKET_TYPE;
55 }
56}
57
renjietang50ea92a2019-12-26 10:15:01 -080058void LogCoalesceStreamFrameStatus(bool success) {
renjietang261e03d2020-02-18 12:55:24 -080059 QUIC_HISTOGRAM_BOOL("QuicSession.CoalesceStreamFrameStatus", success,
60 "Success rate of coalesing stream frames attempt.");
renjietang50ea92a2019-12-26 10:15:01 -080061}
62
fayang08750832019-10-24 11:25:34 -070063// ScopedPacketContextSwitcher saves |packet|'s states and change states
64// during its construction. When the switcher goes out of scope, it restores
65// saved states.
66class ScopedPacketContextSwitcher {
67 public:
68 ScopedPacketContextSwitcher(QuicPacketNumber packet_number,
69 QuicPacketNumberLength packet_number_length,
70 EncryptionLevel encryption_level,
71 SerializedPacket* packet)
72
73 : saved_packet_number_(packet->packet_number),
74 saved_packet_number_length_(packet->packet_number_length),
75 saved_encryption_level_(packet->encryption_level),
76 packet_(packet) {
77 packet_->packet_number = packet_number,
78 packet_->packet_number_length = packet_number_length;
79 packet_->encryption_level = encryption_level;
80 }
81
82 ~ScopedPacketContextSwitcher() {
83 packet_->packet_number = saved_packet_number_;
84 packet_->packet_number_length = saved_packet_number_length_;
85 packet_->encryption_level = saved_encryption_level_;
86 }
87
88 private:
89 const QuicPacketNumber saved_packet_number_;
90 const QuicPacketNumberLength saved_packet_number_length_;
91 const EncryptionLevel saved_encryption_level_;
92 SerializedPacket* packet_;
93};
94
QUICHE teama6ef0a62019-03-07 20:34:33 -050095} // namespace
96
97#define ENDPOINT \
98 (framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
99
dschinazi7b9278c2019-05-20 07:36:21 -0700100QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500101 QuicFramer* framer,
102 DelegateInterface* delegate)
dschinazi7b9278c2019-05-20 07:36:21 -0700103 : QuicPacketCreator(server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500104 framer,
105 QuicRandom::GetInstance(),
106 delegate) {}
107
dschinazi7b9278c2019-05-20 07:36:21 -0700108QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500109 QuicFramer* framer,
110 QuicRandom* random,
111 DelegateInterface* delegate)
112 : delegate_(delegate),
113 debug_delegate_(nullptr),
114 framer_(framer),
115 random_(random),
116 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
117 have_diversification_nonce_(false),
118 max_packet_length_(0),
dschinazi7b9278c2019-05-20 07:36:21 -0700119 server_connection_id_included_(CONNECTION_ID_PRESENT),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500120 packet_size_(0),
dschinazi7b9278c2019-05-20 07:36:21 -0700121 server_connection_id_(server_connection_id),
dschinazi346b7ce2019-06-05 01:38:18 -0700122 client_connection_id_(EmptyQuicConnectionId()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500123 packet_(QuicPacketNumber(),
124 PACKET_1BYTE_PACKET_NUMBER,
125 nullptr,
126 0,
127 false,
128 false),
129 pending_padding_bytes_(0),
130 needs_full_padding_(false),
fayang18be79a2019-09-16 15:17:12 -0700131 next_transmission_type_(NOT_RETRANSMISSION),
132 flusher_attached_(false),
133 fully_pad_crypto_handshake_packets_(true),
dschinazied459c02020-05-07 16:12:23 -0700134 latched_hard_max_packet_length_(0),
135 max_datagram_frame_size_(0) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500136 SetMaxPacketLength(kDefaultMaxPacketSize);
dschinazied459c02020-05-07 16:12:23 -0700137 if (!framer_->version().UsesTls()) {
138 // QUIC+TLS negotiates the maximum datagram frame size via the
139 // IETF QUIC max_datagram_frame_size transport parameter.
140 // QUIC_CRYPTO however does not negotiate this so we set its value here.
141 SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
142 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500143}
144
145QuicPacketCreator::~QuicPacketCreator() {
146 DeleteFrames(&packet_.retransmittable_frames);
147}
148
149void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
150 std::unique_ptr<QuicEncrypter> encrypter) {
151 framer_->SetEncrypter(level, std::move(encrypter));
152 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
153}
154
155bool QuicPacketCreator::CanSetMaxPacketLength() const {
156 // |max_packet_length_| should not be changed mid-packet.
157 return queued_frames_.empty();
158}
159
160void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
161 DCHECK(CanSetMaxPacketLength());
162
163 // Avoid recomputing |max_plaintext_size_| if the length does not actually
164 // change.
165 if (length == max_packet_length_) {
166 return;
167 }
dschinazi6458eb32020-06-23 12:38:41 -0700168 QUIC_DVLOG(1) << "Updating packet creator max packet length from "
169 << max_packet_length_ << " to " << length;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500170
171 max_packet_length_ = length;
172 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
nharper55fa6132019-05-07 19:37:21 -0700173 QUIC_BUG_IF(max_plaintext_size_ - PacketHeaderSize() <
QUICHE team2252b702019-05-14 23:55:14 -0400174 MinPlaintextPacketSize(framer_->version()))
nharper55fa6132019-05-07 19:37:21 -0700175 << "Attempted to set max packet length too small";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500176}
177
dschinazied459c02020-05-07 16:12:23 -0700178void QuicPacketCreator::SetMaxDatagramFrameSize(
179 QuicByteCount max_datagram_frame_size) {
180 constexpr QuicByteCount upper_bound =
181 std::min<QuicByteCount>(std::numeric_limits<QuicPacketLength>::max(),
182 std::numeric_limits<size_t>::max());
183 if (max_datagram_frame_size > upper_bound) {
184 // A value of |max_datagram_frame_size| that is equal or greater than
185 // 2^16-1 is effectively infinite because QUIC packets cannot be that large.
186 // We therefore clamp the value here to allow us to safely cast
187 // |max_datagram_frame_size_| to QuicPacketLength or size_t.
188 max_datagram_frame_size = upper_bound;
189 }
190 max_datagram_frame_size_ = max_datagram_frame_size;
191}
192
fayang2ab1e852019-11-04 11:24:36 -0800193void QuicPacketCreator::SetSoftMaxPacketLength(QuicByteCount length) {
194 DCHECK(CanSetMaxPacketLength());
195 if (length > max_packet_length_) {
196 QUIC_BUG << ENDPOINT
197 << "Try to increase max_packet_length_ in "
198 "SetSoftMaxPacketLength, use SetMaxPacketLength instead.";
199 return;
200 }
201 if (framer_->GetMaxPlaintextSize(length) <
202 PacketHeaderSize() + MinPlaintextPacketSize(framer_->version())) {
fayang04bd30d2020-06-22 15:04:57 -0700203 // Please note: this would not guarantee to fit next packet if the size of
204 // packet header increases (e.g., encryption level changes).
fayang2ab1e852019-11-04 11:24:36 -0800205 QUIC_DLOG(INFO) << length << " is too small to fit packet header";
fayangfe963c52020-07-16 06:56:09 -0700206 if (coalesced_packet_of_higher_space_) {
207 RemoveSoftMaxPacketLength();
208 }
fayang2ab1e852019-11-04 11:24:36 -0800209 return;
210 }
211 QUIC_DVLOG(1) << "Setting soft max packet length to: " << length;
212 latched_hard_max_packet_length_ = max_packet_length_;
213 max_packet_length_ = length;
214 max_plaintext_size_ = framer_->GetMaxPlaintextSize(length);
215}
216
QUICHE teama6ef0a62019-03-07 20:34:33 -0500217// Stops serializing version of the protocol in packets sent after this call.
218// A packet that is already open might send kQuicVersionSize bytes less than the
219// maximum packet size if we stop sending version before it is serialized.
220void QuicPacketCreator::StopSendingVersion() {
221 DCHECK(send_version_in_packet_);
fayangd4291e42019-05-30 10:31:21 -0700222 DCHECK(!VersionHasIetfInvariantHeader(framer_->transport_version()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500223 send_version_in_packet_ = false;
224 if (packet_size_ > 0) {
225 DCHECK_LT(kQuicVersionSize, packet_size_);
226 packet_size_ -= kQuicVersionSize;
227 }
228}
229
230void QuicPacketCreator::SetDiversificationNonce(
231 const DiversificationNonce& nonce) {
232 DCHECK(!have_diversification_nonce_);
233 have_diversification_nonce_ = true;
234 diversification_nonce_ = nonce;
235}
236
237void QuicPacketCreator::UpdatePacketNumberLength(
238 QuicPacketNumber least_packet_awaited_by_peer,
239 QuicPacketCount max_packets_in_flight) {
240 if (!queued_frames_.empty()) {
241 // Don't change creator state if there are frames queued.
242 QUIC_BUG << "Called UpdatePacketNumberLength with " << queued_frames_.size()
243 << " queued_frames. First frame type:"
244 << queued_frames_.front().type
245 << " last frame type:" << queued_frames_.back().type;
246 return;
247 }
248
dschinazi101d2eb2020-07-06 19:42:34 -0700249 const QuicPacketNumber next_packet_number = NextSendingPacketNumber();
250 DCHECK_LE(least_packet_awaited_by_peer, next_packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500251 const uint64_t current_delta =
dschinazi101d2eb2020-07-06 19:42:34 -0700252 next_packet_number - least_packet_awaited_by_peer;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500253 const uint64_t delta = std::max(current_delta, max_packets_in_flight);
dschinazi101d2eb2020-07-06 19:42:34 -0700254 const QuicPacketNumberLength packet_number_length =
renjietang488201d2019-12-17 13:40:49 -0800255 QuicFramer::GetMinPacketNumberLength(QuicPacketNumber(delta * 4));
dschinazi101d2eb2020-07-06 19:42:34 -0700256 if (packet_.packet_number_length == packet_number_length) {
257 return;
258 }
259 QUIC_DLOG(INFO) << ENDPOINT << "Updating packet number length from "
260 << static_cast<int>(packet_.packet_number_length) << " to "
261 << static_cast<int>(packet_number_length)
262 << ", least_packet_awaited_by_peer: "
263 << least_packet_awaited_by_peer
264 << " max_packets_in_flight: " << max_packets_in_flight
265 << " next_packet_number: " << next_packet_number;
266 packet_.packet_number_length = packet_number_length;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500267}
268
fayang4c1c2362019-09-13 07:20:01 -0700269void QuicPacketCreator::SkipNPacketNumbers(
270 QuicPacketCount count,
271 QuicPacketNumber least_packet_awaited_by_peer,
272 QuicPacketCount max_packets_in_flight) {
273 if (!queued_frames_.empty()) {
274 // Don't change creator state if there are frames queued.
275 QUIC_BUG << "Called SkipNPacketNumbers with " << queued_frames_.size()
276 << " queued_frames. First frame type:"
277 << queued_frames_.front().type
278 << " last frame type:" << queued_frames_.back().type;
279 return;
280 }
281 if (packet_.packet_number > packet_.packet_number + count) {
282 // Skipping count packet numbers causes packet number wrapping around,
283 // reject it.
284 QUIC_LOG(WARNING) << "Skipping " << count
285 << " packet numbers causes packet number wrapping "
286 "around, least_packet_awaited_by_peer: "
287 << least_packet_awaited_by_peer
288 << " packet_number:" << packet_.packet_number;
289 return;
290 }
291 packet_.packet_number += count;
292 // Packet number changes, update packet number length if necessary.
293 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight);
294}
295
fayang62b637b2019-09-16 08:40:49 -0700296bool QuicPacketCreator::ConsumeCryptoDataToFillCurrentPacket(
297 EncryptionLevel level,
298 size_t write_length,
299 QuicStreamOffset offset,
300 bool needs_full_padding,
301 TransmissionType transmission_type,
302 QuicFrame* frame) {
dschinazi6458eb32020-06-23 12:38:41 -0700303 QUIC_DVLOG(2) << "ConsumeCryptoDataToFillCurrentPacket " << level
304 << " write_length " << write_length << " offset " << offset
305 << (needs_full_padding ? " needs_full_padding" : "") << " "
306 << transmission_type;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500307 if (!CreateCryptoFrame(level, write_length, offset, frame)) {
308 return false;
309 }
310 // When crypto data was sent in stream frames, ConsumeData is called with
311 // |needs_full_padding = true|. Keep the same behavior here when sending
312 // crypto frames.
313 //
314 // TODO(nharper): Check what the IETF drafts say about padding out initial
315 // messages and change this as appropriate.
nharper51961cf2019-05-13 13:23:24 -0700316 if (needs_full_padding) {
317 needs_full_padding_ = true;
318 }
fayang347ab752019-10-22 11:17:43 -0700319 return AddFrame(*frame, transmission_type);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500320}
321
fayang62b637b2019-09-16 08:40:49 -0700322bool QuicPacketCreator::ConsumeDataToFillCurrentPacket(
323 QuicStreamId id,
324 size_t data_size,
325 QuicStreamOffset offset,
326 bool fin,
327 bool needs_full_padding,
328 TransmissionType transmission_type,
329 QuicFrame* frame) {
QUICHE teamf08778a2019-03-14 08:10:26 -0700330 if (!HasRoomForStreamFrame(id, offset, data_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500331 return false;
332 }
QUICHE teamf08778a2019-03-14 08:10:26 -0700333 CreateStreamFrame(id, data_size, offset, fin, frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500334 // Explicitly disallow multi-packet CHLOs.
danzh88e3e052019-06-13 11:47:18 -0700335 if (GetQuicFlag(FLAGS_quic_enforce_single_packet_chlo) &&
ianswette28f0222019-04-04 13:31:22 -0700336 StreamFrameIsClientHello(frame->stream_frame) &&
337 frame->stream_frame.data_length < data_size) {
vasilvvc48c8712019-03-11 13:38:16 -0700338 const std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500339 "Client hello won't fit in a single packet.";
340 QUIC_BUG << error_details << " Constructed stream frame length: "
341 << frame->stream_frame.data_length
ianswette28f0222019-04-04 13:31:22 -0700342 << " CHLO length: " << data_size;
fkastenholz85f18902019-05-28 12:47:00 -0700343 delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500344 return false;
345 }
fayang347ab752019-10-22 11:17:43 -0700346 if (!AddFrame(*frame, transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500347 // Fails if we try to write unencrypted stream data.
348 return false;
349 }
350 if (needs_full_padding) {
351 needs_full_padding_ = true;
352 }
353
354 return true;
355}
356
357bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
358 QuicStreamOffset offset,
359 size_t data_size) {
fayang2ab1e852019-11-04 11:24:36 -0800360 const size_t min_stream_frame_size = QuicFramer::GetMinStreamFrameSize(
361 framer_->transport_version(), id, offset, /*last_frame_in_packet=*/true,
362 data_size);
363 if (BytesFree() > min_stream_frame_size) {
364 return true;
365 }
366 if (!RemoveSoftMaxPacketLength()) {
367 return false;
368 }
369 return BytesFree() > min_stream_frame_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500370}
371
372bool QuicPacketCreator::HasRoomForMessageFrame(QuicByteCount length) {
fayang2ab1e852019-11-04 11:24:36 -0800373 const size_t message_frame_size = QuicFramer::GetMessageFrameSize(
374 framer_->transport_version(), /*last_frame_in_packet=*/true, length);
dschinazied459c02020-05-07 16:12:23 -0700375 if (static_cast<QuicByteCount>(message_frame_size) >
376 max_datagram_frame_size_) {
377 return false;
378 }
fayang2ab1e852019-11-04 11:24:36 -0800379 if (BytesFree() >= message_frame_size) {
380 return true;
381 }
382 if (!RemoveSoftMaxPacketLength()) {
383 return false;
384 }
385 return BytesFree() >= message_frame_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500386}
387
QUICHE teama6ef0a62019-03-07 20:34:33 -0500388// static
389size_t QuicPacketCreator::StreamFramePacketOverhead(
390 QuicTransportVersion version,
391 QuicConnectionIdLength destination_connection_id_length,
392 QuicConnectionIdLength source_connection_id_length,
393 bool include_version,
394 bool include_diversification_nonce,
395 QuicPacketNumberLength packet_number_length,
396 QuicVariableLengthIntegerLength retry_token_length_length,
397 QuicVariableLengthIntegerLength length_length,
398 QuicStreamOffset offset) {
399 return GetPacketHeaderSize(version, destination_connection_id_length,
400 source_connection_id_length, include_version,
401 include_diversification_nonce,
402 packet_number_length, retry_token_length_length, 0,
403 length_length) +
404
ianswett22781cb2019-12-12 06:45:08 -0800405 // Assumes a packet with a single stream frame, which omits the length,
406 // causing the data length argument to be ignored.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500407 QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true,
ianswett22781cb2019-12-12 06:45:08 -0800408 kMaxOutgoingPacketSize /* unused */);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500409}
410
411void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
QUICHE teamf08778a2019-03-14 08:10:26 -0700412 size_t data_size,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500413 QuicStreamOffset offset,
414 bool fin,
415 QuicFrame* frame) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500416 DCHECK_GT(
417 max_packet_length_,
418 StreamFramePacketOverhead(
419 framer_->transport_version(), GetDestinationConnectionIdLength(),
420 GetSourceConnectionIdLength(), kIncludeVersion,
421 IncludeNonceInPublicHeader(), PACKET_6BYTE_PACKET_NUMBER,
422 GetRetryTokenLengthLength(), GetLengthLength(), offset));
423
424 QUIC_BUG_IF(!HasRoomForStreamFrame(id, offset, data_size))
425 << "No room for Stream frame, BytesFree: " << BytesFree()
426 << " MinStreamFrameSize: "
427 << QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
428 offset, true, data_size);
429
QUICHE teamf08778a2019-03-14 08:10:26 -0700430 QUIC_BUG_IF(data_size == 0 && !fin)
431 << "Creating a stream frame for stream ID:" << id
432 << " with no data or fin.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500433 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
434 framer_->transport_version(), id, offset,
435 /* last_frame_in_packet= */ true, data_size);
436 size_t bytes_consumed =
437 std::min<size_t>(BytesFree() - min_frame_size, data_size);
438
439 bool set_fin = fin && bytes_consumed == data_size; // Last frame.
440 *frame = QuicFrame(QuicStreamFrame(id, set_fin, offset, bytes_consumed));
441}
442
443bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
444 size_t write_length,
445 QuicStreamOffset offset,
446 QuicFrame* frame) {
447 size_t min_frame_size =
448 QuicFramer::GetMinCryptoFrameSize(write_length, offset);
fayang04bd30d2020-06-22 15:04:57 -0700449 size_t min_plaintext_bytes = min_frame_size;
fayangf627e012020-07-13 08:10:44 -0700450 if (!fix_extra_padding_bytes_ && queued_frames_.empty()) {
fayang04bd30d2020-06-22 15:04:57 -0700451 min_plaintext_bytes =
452 std::max(min_frame_size, MinPlaintextPacketSize(framer_->version()));
453 }
454 if (BytesFree() <= min_plaintext_bytes &&
455 (!RemoveSoftMaxPacketLength() || BytesFree() <= min_plaintext_bytes)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500456 return false;
457 }
458 size_t max_write_length = BytesFree() - min_frame_size;
459 size_t bytes_consumed = std::min<size_t>(max_write_length, write_length);
460 *frame = QuicFrame(new QuicCryptoFrame(level, offset, bytes_consumed));
461 return true;
462}
463
fayang62b637b2019-09-16 08:40:49 -0700464void QuicPacketCreator::FlushCurrentPacket() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500465 if (!HasPendingFrames() && pending_padding_bytes_ == 0) {
466 return;
467 }
468
dschinazi66dea072019-04-09 11:41:06 -0700469 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
wub50d4c712020-05-19 15:48:28 -0700470 QuicOwnedPacketBuffer external_buffer(delegate_->GetPacketBuffer());
471
wub50d4c712020-05-19 15:48:28 -0700472 if (external_buffer.buffer == nullptr) {
473 external_buffer.buffer = stack_buffer;
474 external_buffer.release_buffer = nullptr;
475 }
476
477 DCHECK_EQ(nullptr, packet_.encrypted_buffer);
478 SerializePacket(std::move(external_buffer), kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500479 OnSerializedPacket();
480}
481
482void QuicPacketCreator::OnSerializedPacket() {
483 if (packet_.encrypted_buffer == nullptr) {
vasilvvc48c8712019-03-11 13:38:16 -0700484 const std::string error_details = "Failed to SerializePacket.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500485 QUIC_BUG << error_details;
486 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
fkastenholz85f18902019-05-28 12:47:00 -0700487 error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500488 return;
489 }
490
491 SerializedPacket packet(std::move(packet_));
492 ClearPacket();
fayang2ab1e852019-11-04 11:24:36 -0800493 RemoveSoftMaxPacketLength();
wub8a5dafa2020-05-13 12:30:17 -0700494 delegate_->OnSerializedPacket(std::move(packet));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500495}
496
497void QuicPacketCreator::ClearPacket() {
498 packet_.has_ack = false;
499 packet_.has_stop_waiting = false;
500 packet_.has_crypto_handshake = NOT_HANDSHAKE;
wub98669f52019-04-18 10:49:18 -0700501 packet_.transmission_type = NOT_RETRANSMISSION;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500502 packet_.encrypted_buffer = nullptr;
503 packet_.encrypted_length = 0;
fayang15042962020-07-01 12:14:29 -0700504 packet_.fate = SEND_TO_WRITER;
wubc9c6d582020-07-20 08:45:40 -0700505 QUIC_BUG_IF(packet_.release_encrypted_buffer != nullptr)
506 << "packet_.release_encrypted_buffer should be empty";
507 packet_.release_encrypted_buffer = nullptr;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500508 DCHECK(packet_.retransmittable_frames.empty());
fayang51152fd2019-10-21 06:48:09 -0700509 DCHECK(packet_.nonretransmittable_frames.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500510 packet_.largest_acked.Clear();
511 needs_full_padding_ = false;
512}
513
fayang08750832019-10-24 11:25:34 -0700514size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
515 const SerializedPacket& packet,
516 size_t padding_size,
517 char* buffer,
518 size_t buffer_len) {
519 QUIC_BUG_IF(packet.encryption_level != ENCRYPTION_INITIAL);
520 QUIC_BUG_IF(packet.nonretransmittable_frames.empty() &&
521 packet.retransmittable_frames.empty())
522 << "Attempt to serialize empty ENCRYPTION_INITIAL packet in coalesced "
523 "packet";
524 ScopedPacketContextSwitcher switcher(
525 packet.packet_number -
526 1, // -1 because serialize packet increase packet number.
527 packet.packet_number_length, packet.encryption_level, &packet_);
528 for (const QuicFrame& frame : packet.nonretransmittable_frames) {
529 if (!AddFrame(frame, packet.transmission_type)) {
530 QUIC_BUG << "Failed to serialize frame: " << frame;
531 return 0;
532 }
533 }
534 for (const QuicFrame& frame : packet.retransmittable_frames) {
535 if (!AddFrame(frame, packet.transmission_type)) {
536 QUIC_BUG << "Failed to serialize frame: " << frame;
537 return 0;
538 }
539 }
540 // Add necessary padding.
541 if (padding_size > 0) {
542 QUIC_DVLOG(2) << ENDPOINT << "Add padding of size: " << padding_size;
543 if (!AddFrame(QuicFrame(QuicPaddingFrame(padding_size)),
544 packet.transmission_type)) {
545 QUIC_BUG << "Failed to add padding of size " << padding_size
546 << " when serializing ENCRYPTION_INITIAL "
547 "packet in coalesced packet";
548 return 0;
549 }
550 }
wub50d4c712020-05-19 15:48:28 -0700551 SerializePacket(QuicOwnedPacketBuffer(buffer, nullptr), buffer_len);
fayang08750832019-10-24 11:25:34 -0700552 const size_t encrypted_length = packet_.encrypted_length;
553 // Clear frames in packet_. No need to DeleteFrames since frames are owned by
554 // initial_packet.
555 packet_.retransmittable_frames.clear();
556 packet_.nonretransmittable_frames.clear();
557 ClearPacket();
558 return encrypted_length;
559}
560
QUICHE teama6ef0a62019-03-07 20:34:33 -0500561void QuicPacketCreator::CreateAndSerializeStreamFrame(
562 QuicStreamId id,
563 size_t write_length,
564 QuicStreamOffset iov_offset,
565 QuicStreamOffset stream_offset,
566 bool fin,
567 TransmissionType transmission_type,
568 size_t* num_bytes_consumed) {
569 DCHECK(queued_frames_.empty());
dschinazi1c6e5922020-06-19 10:35:03 -0700570 DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500571 // Write out the packet header
572 QuicPacketHeader header;
573 FillPacketHeader(&header);
fayang15042962020-07-01 12:14:29 -0700574 if (determine_serialized_packet_fate_early_) {
575 packet_.fate = delegate_->GetSerializedPacketFate(
576 /*is_mtu_discovery=*/false, packet_.encryption_level);
577 QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
578 << ": " << SerializedPacketFateToString(packet_.fate)
579 << " of "
580 << EncryptionLevelToString(packet_.encryption_level);
581 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500582
dschinazi66dea072019-04-09 11:41:06 -0700583 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
wub50d4c712020-05-19 15:48:28 -0700584 QuicOwnedPacketBuffer packet_buffer(delegate_->GetPacketBuffer());
585
wub50d4c712020-05-19 15:48:28 -0700586 if (packet_buffer.buffer == nullptr) {
587 packet_buffer.buffer = stack_buffer;
588 packet_buffer.release_buffer = nullptr;
589 }
590
591 char* encrypted_buffer = packet_buffer.buffer;
592
dschinazi66dea072019-04-09 11:41:06 -0700593 QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500594 size_t length_field_offset = 0;
595 if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
596 QUIC_BUG << "AppendPacketHeader failed";
597 return;
598 }
599
600 // Create a Stream frame with the remaining space.
601 QUIC_BUG_IF(iov_offset == write_length && !fin)
602 << "Creating a stream frame with no data or fin.";
603 const size_t remaining_data_size = write_length - iov_offset;
nharperebabffd2019-06-03 17:34:45 -0700604 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500605 framer_->transport_version(), id, stream_offset,
606 /* last_frame_in_packet= */ true, remaining_data_size);
nharperebabffd2019-06-03 17:34:45 -0700607 size_t available_size =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500608 max_plaintext_size_ - writer.length() - min_frame_size;
nharperebabffd2019-06-03 17:34:45 -0700609 size_t bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
610 size_t plaintext_bytes_written = min_frame_size + bytes_consumed;
611 bool needs_padding = false;
612 if (plaintext_bytes_written < MinPlaintextPacketSize(framer_->version())) {
613 needs_padding = true;
614 // Recalculate sizes with the stream frame not being marked as the last
615 // frame in the packet.
616 min_frame_size = QuicFramer::GetMinStreamFrameSize(
617 framer_->transport_version(), id, stream_offset,
618 /* last_frame_in_packet= */ false, remaining_data_size);
619 available_size = max_plaintext_size_ - writer.length() - min_frame_size;
620 bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
621 plaintext_bytes_written = min_frame_size + bytes_consumed;
622 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500623
624 const bool set_fin = fin && (bytes_consumed == remaining_data_size);
625 QuicStreamFrame frame(id, set_fin, stream_offset, bytes_consumed);
rchc76cd742019-03-26 16:00:03 -0700626 if (debug_delegate_ != nullptr) {
627 debug_delegate_->OnFrameAddedToPacket(QuicFrame(frame));
628 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500629 QUIC_DVLOG(1) << ENDPOINT << "Adding frame: " << frame;
630
dschinazi118934b2019-06-13 18:09:08 -0700631 QUIC_DVLOG(2) << ENDPOINT << "Serializing stream packet " << header << frame;
632
QUICHE teama6ef0a62019-03-07 20:34:33 -0500633 // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized
634 // into one method that takes a QuicStreamFrame, if warranted.
nharperebabffd2019-06-03 17:34:45 -0700635 bool omit_frame_length = !needs_padding;
636 if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500637 QUIC_BUG << "AppendTypeByte failed";
638 return;
639 }
nharperebabffd2019-06-03 17:34:45 -0700640 if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500641 QUIC_BUG << "AppendStreamFrame failed";
642 return;
643 }
nharperebabffd2019-06-03 17:34:45 -0700644 if (needs_padding &&
645 plaintext_bytes_written < MinPlaintextPacketSize(framer_->version()) &&
QUICHE team2252b702019-05-14 23:55:14 -0400646 !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) -
nharper55fa6132019-05-07 19:37:21 -0700647 plaintext_bytes_written)) {
648 QUIC_BUG << "Unable to add padding bytes";
649 return;
650 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500651
652 if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset,
653 packet_.encryption_level)) {
654 return;
655 }
656
fayangcff885a2019-10-22 07:39:04 -0700657 packet_.transmission_type = transmission_type;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500658
dschinazi1c6e5922020-06-19 10:35:03 -0700659 DCHECK(packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
660 packet_.encryption_level == ENCRYPTION_ZERO_RTT)
661 << packet_.encryption_level;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500662 size_t encrypted_length = framer_->EncryptInPlace(
663 packet_.encryption_level, packet_.packet_number,
664 GetStartOfEncryptedData(framer_->transport_version(), header),
dschinazi66dea072019-04-09 11:41:06 -0700665 writer.length(), kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500666 if (encrypted_length == 0) {
667 QUIC_BUG << "Failed to encrypt packet number " << header.packet_number;
668 return;
669 }
670 // TODO(ianswett): Optimize the storage so RetransmitableFrames can be
671 // unioned with a QuicStreamFrame and a UniqueStreamBuffer.
672 *num_bytes_consumed = bytes_consumed;
673 packet_size_ = 0;
674 packet_.encrypted_buffer = encrypted_buffer;
675 packet_.encrypted_length = encrypted_length;
wubc9c6d582020-07-20 08:45:40 -0700676
677 packet_buffer.buffer = nullptr;
678 packet_.release_encrypted_buffer = std::move(packet_buffer).release_buffer;
679
QUICHE teama6ef0a62019-03-07 20:34:33 -0500680 packet_.retransmittable_frames.push_back(QuicFrame(frame));
681 OnSerializedPacket();
682}
683
684bool QuicPacketCreator::HasPendingFrames() const {
685 return !queued_frames_.empty();
686}
687
688bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
689 return !packet_.retransmittable_frames.empty();
690}
691
692bool QuicPacketCreator::HasPendingStreamFramesOfStream(QuicStreamId id) const {
693 for (const auto& frame : packet_.retransmittable_frames) {
694 if (frame.type == STREAM_FRAME && frame.stream_frame.stream_id == id) {
695 return true;
696 }
697 }
698 return false;
699}
700
701size_t QuicPacketCreator::ExpansionOnNewFrame() const {
702 // If the last frame in the packet is a message frame, then it will expand to
703 // include the varint message length when a new frame is added.
fayang54a38e32020-06-26 07:01:15 -0700704 if (queued_frames_.empty()) {
705 return 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500706 }
bnce5c11c02020-07-29 08:02:21 -0700707 return ExpansionOnNewFrameWithLastFrame(queued_frames_.back(),
708 framer_->transport_version());
fayang54a38e32020-06-26 07:01:15 -0700709}
710
bnce5c11c02020-07-29 08:02:21 -0700711// static
fayang54a38e32020-06-26 07:01:15 -0700712size_t QuicPacketCreator::ExpansionOnNewFrameWithLastFrame(
bnce5c11c02020-07-29 08:02:21 -0700713 const QuicFrame& last_frame,
714 QuicTransportVersion version) {
fayang54a38e32020-06-26 07:01:15 -0700715 if (last_frame.type == MESSAGE_FRAME) {
716 return QuicDataWriter::GetVarInt62Len(
717 last_frame.message_frame->message_length);
718 }
719 if (last_frame.type != STREAM_FRAME) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500720 return 0;
721 }
bnce5c11c02020-07-29 08:02:21 -0700722 if (VersionHasIetfQuicFrames(version)) {
fayang54a38e32020-06-26 07:01:15 -0700723 return QuicDataWriter::GetVarInt62Len(last_frame.stream_frame.data_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500724 }
725 return kQuicStreamPayloadLengthSize;
726}
727
728size_t QuicPacketCreator::BytesFree() {
729 DCHECK_GE(max_plaintext_size_, PacketSize());
730 return max_plaintext_size_ -
731 std::min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
732}
733
734size_t QuicPacketCreator::PacketSize() {
fayang7a06f9b2020-06-24 10:23:19 -0700735 if (update_packet_size_) {
736 return queued_frames_.empty() ? PacketHeaderSize() : packet_size_;
737 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500738 if (!queued_frames_.empty()) {
739 return packet_size_;
740 }
nharper55fa6132019-05-07 19:37:21 -0700741 packet_size_ = PacketHeaderSize();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500742 return packet_size_;
743}
744
QUICHE teama6ef0a62019-03-07 20:34:33 -0500745bool QuicPacketCreator::AddPaddedSavedFrame(
746 const QuicFrame& frame,
747 TransmissionType transmission_type) {
fayang347ab752019-10-22 11:17:43 -0700748 if (AddFrame(frame, transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500749 needs_full_padding_ = true;
750 return true;
751 }
752 return false;
753}
754
wub50d4c712020-05-19 15:48:28 -0700755void QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500756 size_t encrypted_buffer_len) {
757 DCHECK_LT(0u, encrypted_buffer_len);
758 QUIC_BUG_IF(queued_frames_.empty() && pending_padding_bytes_ == 0)
759 << "Attempt to serialize empty packet";
760 QuicPacketHeader header;
761 // FillPacketHeader increments packet_number_.
762 FillPacketHeader(&header);
fayang15042962020-07-01 12:14:29 -0700763 if (determine_serialized_packet_fate_early_ && delegate_ != nullptr) {
764 QUIC_RELOADABLE_FLAG_COUNT(quic_determine_serialized_packet_fate_early);
765 packet_.fate = delegate_->GetSerializedPacketFate(
766 /*is_mtu_discovery=*/QuicUtils::ContainsFrameType(queued_frames_,
767 MTU_DISCOVERY_FRAME),
768 packet_.encryption_level);
769 QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
770 << ": " << SerializedPacketFateToString(packet_.fate)
771 << " of "
772 << EncryptionLevelToString(packet_.encryption_level);
773 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500774
775 MaybeAddPadding();
776
dschinazi118934b2019-06-13 18:09:08 -0700777 QUIC_DVLOG(2) << ENDPOINT << "Serializing packet " << header
wub031d47c2019-11-21 08:04:07 -0800778 << QuicFramesToString(queued_frames_) << " at encryption_level "
renjietangb4ebb1d2020-05-27 18:15:51 -0700779 << packet_.encryption_level;
dschinazi118934b2019-06-13 18:09:08 -0700780
dschinazida9fafd2020-03-16 15:32:55 -0700781 if (!framer_->HasEncrypterOfEncryptionLevel(packet_.encryption_level)) {
782 QUIC_BUG << ENDPOINT << "Attempting to serialize " << header
783 << QuicFramesToString(queued_frames_)
renjietangb4ebb1d2020-05-27 18:15:51 -0700784 << " at missing encryption_level " << packet_.encryption_level
785 << " using " << framer_->version();
dschinazida9fafd2020-03-16 15:32:55 -0700786 return;
787 }
788
QUICHE teama6ef0a62019-03-07 20:34:33 -0500789 DCHECK_GE(max_plaintext_size_, packet_size_);
790 // Use the packet_size_ instead of the buffer size to ensure smaller
791 // packet sizes are properly used.
792 size_t length =
wub50d4c712020-05-19 15:48:28 -0700793 framer_->BuildDataPacket(header, queued_frames_, encrypted_buffer.buffer,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500794 packet_size_, packet_.encryption_level);
795 if (length == 0) {
fayang36143d92020-05-15 10:19:57 -0700796 QUIC_BUG << "Failed to serialize " << QuicFramesToString(queued_frames_)
renjietangb4ebb1d2020-05-27 18:15:51 -0700797 << " at encryption_level: " << packet_.encryption_level
fayang36143d92020-05-15 10:19:57 -0700798 << ", needs_full_padding_: " << needs_full_padding_
fayangb931ac62020-06-02 11:23:06 -0700799 << ", pending_padding_bytes_: " << pending_padding_bytes_
800 << ", latched_hard_max_packet_length_: "
801 << latched_hard_max_packet_length_
802 << ", max_packet_length_: " << max_packet_length_
803 << ", header: " << header;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500804 return;
805 }
806
807 // ACK Frames will be truncated due to length only if they're the only frame
808 // in the packet, and if packet_size_ was set to max_plaintext_size_. If
809 // truncation due to length occurred, then GetSerializedFrameLength will have
810 // returned all bytes free.
811 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
812 queued_frames_.size() == 1 &&
813 queued_frames_.back().type == ACK_FRAME;
814 // Because of possible truncation, we can't be confident that our
815 // packet size calculation worked correctly.
816 if (!possibly_truncated_by_length) {
817 DCHECK_EQ(packet_size_, length);
818 }
819 const size_t encrypted_length = framer_->EncryptInPlace(
820 packet_.encryption_level, packet_.packet_number,
821 GetStartOfEncryptedData(framer_->transport_version(), header), length,
wub50d4c712020-05-19 15:48:28 -0700822 encrypted_buffer_len, encrypted_buffer.buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500823 if (encrypted_length == 0) {
824 QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number;
825 return;
826 }
827
828 packet_size_ = 0;
829 queued_frames_.clear();
wub50d4c712020-05-19 15:48:28 -0700830 packet_.encrypted_buffer = encrypted_buffer.buffer;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500831 packet_.encrypted_length = encrypted_length;
wubc9c6d582020-07-20 08:45:40 -0700832
833 encrypted_buffer.buffer = nullptr;
834 packet_.release_encrypted_buffer = std::move(encrypted_buffer).release_buffer;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500835}
836
837std::unique_ptr<QuicEncryptedPacket>
838QuicPacketCreator::SerializeVersionNegotiationPacket(
839 bool ietf_quic,
dschinazi48ac9192019-07-31 00:07:26 -0700840 bool use_length_prefix,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500841 const ParsedQuicVersionVector& supported_versions) {
842 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
843 std::unique_ptr<QuicEncryptedPacket> encrypted =
dschinazi48ac9192019-07-31 00:07:26 -0700844 QuicFramer::BuildVersionNegotiationPacket(
845 server_connection_id_, client_connection_id_, ietf_quic,
846 use_length_prefix, supported_versions);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500847 DCHECK(encrypted);
848 DCHECK_GE(max_packet_length_, encrypted->length());
849 return encrypted;
850}
851
wub8a5dafa2020-05-13 12:30:17 -0700852std::unique_ptr<SerializedPacket>
QUICHE teama6ef0a62019-03-07 20:34:33 -0500853QuicPacketCreator::SerializeConnectivityProbingPacket() {
fkastenholz305e1732019-06-18 05:01:22 -0700854 QUIC_BUG_IF(VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500855 << "Must not be version 99 to serialize padded ping connectivity probe";
fayang2ab1e852019-11-04 11:24:36 -0800856 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500857 QuicPacketHeader header;
858 // FillPacketHeader increments packet_number_.
859 FillPacketHeader(&header);
860
dschinazi118934b2019-06-13 18:09:08 -0700861 QUIC_DVLOG(2) << ENDPOINT << "Serializing connectivity probing packet "
862 << header;
863
dschinazi66dea072019-04-09 11:41:06 -0700864 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700865 size_t length = BuildConnectivityProbingPacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500866 header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
867 DCHECK(length);
868
dschinazi1c6e5922020-06-19 10:35:03 -0700869 DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500870 const size_t encrypted_length = framer_->EncryptInPlace(
871 packet_.encryption_level, packet_.packet_number,
872 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700873 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500874 DCHECK(encrypted_length);
875
wub8a5dafa2020-05-13 12:30:17 -0700876 std::unique_ptr<SerializedPacket> serialize_packet(new SerializedPacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500877 header.packet_number, header.packet_number_length, buffer.release(),
878 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
879
wub8a5dafa2020-05-13 12:30:17 -0700880 serialize_packet->release_encrypted_buffer = [](const char* p) {
881 delete[] p;
882 };
QUICHE teama6ef0a62019-03-07 20:34:33 -0500883 serialize_packet->encryption_level = packet_.encryption_level;
884 serialize_packet->transmission_type = NOT_RETRANSMISSION;
885
886 return serialize_packet;
887}
888
wub8a5dafa2020-05-13 12:30:17 -0700889std::unique_ptr<SerializedPacket>
QUICHE teama6ef0a62019-03-07 20:34:33 -0500890QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
891 QuicPathFrameBuffer* payload) {
fkastenholz305e1732019-06-18 05:01:22 -0700892 QUIC_BUG_IF(!VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500893 << "Must be version 99 to serialize path challenge connectivity probe, "
894 "is version "
895 << framer_->transport_version();
fayang2ab1e852019-11-04 11:24:36 -0800896 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500897 QuicPacketHeader header;
898 // FillPacketHeader increments packet_number_.
899 FillPacketHeader(&header);
900
dschinazi118934b2019-06-13 18:09:08 -0700901 QUIC_DVLOG(2) << ENDPOINT << "Serializing path challenge packet " << header;
902
dschinazi66dea072019-04-09 11:41:06 -0700903 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700904 size_t length = BuildPaddedPathChallengePacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500905 header, buffer.get(), max_plaintext_size_, payload, random_,
906 packet_.encryption_level);
907 DCHECK(length);
908
dschinazi1c6e5922020-06-19 10:35:03 -0700909 DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500910 const size_t encrypted_length = framer_->EncryptInPlace(
911 packet_.encryption_level, packet_.packet_number,
912 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700913 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500914 DCHECK(encrypted_length);
915
wub8a5dafa2020-05-13 12:30:17 -0700916 std::unique_ptr<SerializedPacket> serialize_packet(
917 new SerializedPacket(header.packet_number, header.packet_number_length,
918 buffer.release(), encrypted_length,
919 /*has_ack=*/false, /*has_stop_waiting=*/false));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500920
wub8a5dafa2020-05-13 12:30:17 -0700921 serialize_packet->release_encrypted_buffer = [](const char* p) {
922 delete[] p;
923 };
QUICHE teama6ef0a62019-03-07 20:34:33 -0500924 serialize_packet->encryption_level = packet_.encryption_level;
925 serialize_packet->transmission_type = NOT_RETRANSMISSION;
926
927 return serialize_packet;
928}
929
wub8a5dafa2020-05-13 12:30:17 -0700930std::unique_ptr<SerializedPacket>
QUICHE teama6ef0a62019-03-07 20:34:33 -0500931QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
wuba750aab2020-02-10 06:43:15 -0800932 const QuicCircularDeque<QuicPathFrameBuffer>& payloads,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500933 const bool is_padded) {
fkastenholz305e1732019-06-18 05:01:22 -0700934 QUIC_BUG_IF(!VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500935 << "Must be version 99 to serialize path response connectivity probe, is "
936 "version "
937 << framer_->transport_version();
fayang2ab1e852019-11-04 11:24:36 -0800938 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500939 QuicPacketHeader header;
940 // FillPacketHeader increments packet_number_.
941 FillPacketHeader(&header);
942
dschinazi118934b2019-06-13 18:09:08 -0700943 QUIC_DVLOG(2) << ENDPOINT << "Serializing path response packet " << header;
944
dschinazi66dea072019-04-09 11:41:06 -0700945 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700946 size_t length =
947 BuildPathResponsePacket(header, buffer.get(), max_plaintext_size_,
948 payloads, is_padded, packet_.encryption_level);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500949 DCHECK(length);
950
dschinazi1c6e5922020-06-19 10:35:03 -0700951 DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500952 const size_t encrypted_length = framer_->EncryptInPlace(
953 packet_.encryption_level, packet_.packet_number,
954 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700955 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500956 DCHECK(encrypted_length);
957
wub8a5dafa2020-05-13 12:30:17 -0700958 std::unique_ptr<SerializedPacket> serialize_packet(
959 new SerializedPacket(header.packet_number, header.packet_number_length,
960 buffer.release(), encrypted_length,
961 /*has_ack=*/false, /*has_stop_waiting=*/false));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500962
wub8a5dafa2020-05-13 12:30:17 -0700963 serialize_packet->release_encrypted_buffer = [](const char* p) {
964 delete[] p;
965 };
QUICHE teama6ef0a62019-03-07 20:34:33 -0500966 serialize_packet->encryption_level = packet_.encryption_level;
967 serialize_packet->transmission_type = NOT_RETRANSMISSION;
968
969 return serialize_packet;
970}
971
renjietang4c704c82019-10-07 16:39:11 -0700972size_t QuicPacketCreator::BuildPaddedPathChallengePacket(
973 const QuicPacketHeader& header,
974 char* buffer,
975 size_t packet_length,
976 QuicPathFrameBuffer* payload,
977 QuicRandom* randomizer,
978 EncryptionLevel level) {
979 DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()));
980 QuicFrames frames;
981
982 // Write a PATH_CHALLENGE frame, which has a random 8-byte payload
983 randomizer->RandBytes(payload->data(), payload->size());
984 QuicPathChallengeFrame path_challenge_frame(0, *payload);
985 frames.push_back(QuicFrame(&path_challenge_frame));
986
987 if (debug_delegate_ != nullptr) {
988 debug_delegate_->OnFrameAddedToPacket(QuicFrame(&path_challenge_frame));
989 }
990
991 // Add padding to the rest of the packet in order to assess Path MTU
992 // characteristics.
993 QuicPaddingFrame padding_frame;
994 frames.push_back(QuicFrame(padding_frame));
995
996 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
997}
998
999size_t QuicPacketCreator::BuildPathResponsePacket(
1000 const QuicPacketHeader& header,
1001 char* buffer,
1002 size_t packet_length,
wuba750aab2020-02-10 06:43:15 -08001003 const QuicCircularDeque<QuicPathFrameBuffer>& payloads,
renjietang4c704c82019-10-07 16:39:11 -07001004 const bool is_padded,
1005 EncryptionLevel level) {
1006 if (payloads.empty()) {
1007 QUIC_BUG
1008 << "Attempt to generate connectivity response with no request payloads";
1009 return 0;
1010 }
1011 DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()));
1012
1013 std::vector<std::unique_ptr<QuicPathResponseFrame>> path_response_frames;
1014 for (const QuicPathFrameBuffer& payload : payloads) {
1015 // Note that the control frame ID can be 0 since this is not retransmitted.
1016 path_response_frames.push_back(
1017 std::make_unique<QuicPathResponseFrame>(0, payload));
1018 }
1019
1020 QuicFrames frames;
1021 for (const std::unique_ptr<QuicPathResponseFrame>& path_response_frame :
1022 path_response_frames) {
1023 frames.push_back(QuicFrame(path_response_frame.get()));
1024 if (debug_delegate_ != nullptr) {
1025 debug_delegate_->OnFrameAddedToPacket(
1026 QuicFrame(path_response_frame.get()));
1027 }
1028 }
1029
1030 if (is_padded) {
1031 // Add padding to the rest of the packet in order to assess Path MTU
1032 // characteristics.
1033 QuicPaddingFrame padding_frame;
1034 frames.push_back(QuicFrame(padding_frame));
1035 }
1036
1037 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
1038}
1039
1040size_t QuicPacketCreator::BuildConnectivityProbingPacket(
1041 const QuicPacketHeader& header,
1042 char* buffer,
1043 size_t packet_length,
1044 EncryptionLevel level) {
1045 QuicFrames frames;
1046
1047 // Write a PING frame, which has no data payload.
1048 QuicPingFrame ping_frame;
1049 frames.push_back(QuicFrame(ping_frame));
1050
1051 // Add padding to the rest of the packet.
1052 QuicPaddingFrame padding_frame;
1053 frames.push_back(QuicFrame(padding_frame));
1054
1055 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
1056}
1057
fayang08750832019-10-24 11:25:34 -07001058size_t QuicPacketCreator::SerializeCoalescedPacket(
1059 const QuicCoalescedPacket& coalesced,
1060 char* buffer,
1061 size_t buffer_len) {
fayang08750832019-10-24 11:25:34 -07001062 if (HasPendingFrames()) {
1063 QUIC_BUG << "Try to serialize coalesced packet with pending frames";
1064 return 0;
1065 }
fayang58f71072019-11-05 08:47:02 -08001066 RemoveSoftMaxPacketLength();
fayang08750832019-10-24 11:25:34 -07001067 QUIC_BUG_IF(coalesced.length() == 0)
1068 << "Attempt to serialize empty coalesced packet";
1069 size_t packet_length = 0;
1070 if (coalesced.initial_packet() != nullptr) {
fayang9abdfec2020-02-13 12:34:58 -08001071 // Padding coalesced packet containing initial packet to full.
1072 size_t padding_size = coalesced.max_packet_length() - coalesced.length();
1073 if (framer_->perspective() == Perspective::IS_SERVER &&
1074 QuicUtils::ContainsFrameType(
1075 coalesced.initial_packet()->retransmittable_frames,
1076 CONNECTION_CLOSE_FRAME)) {
1077 // Do not pad server initial connection close packet.
1078 padding_size = 0;
1079 }
fayang08750832019-10-24 11:25:34 -07001080 size_t initial_length = ReserializeInitialPacketInCoalescedPacket(
fayang9abdfec2020-02-13 12:34:58 -08001081 *coalesced.initial_packet(), padding_size, buffer, buffer_len);
fayang08750832019-10-24 11:25:34 -07001082 if (initial_length == 0) {
1083 QUIC_BUG << "Failed to reserialize ENCRYPTION_INITIAL packet in "
1084 "coalesced packet";
1085 return 0;
1086 }
1087 buffer += initial_length;
1088 buffer_len -= initial_length;
1089 packet_length += initial_length;
1090 }
1091 size_t length_copied = 0;
1092 if (!coalesced.CopyEncryptedBuffers(buffer, buffer_len, &length_copied)) {
1093 return 0;
1094 }
1095 packet_length += length_copied;
1096 QUIC_DVLOG(1) << ENDPOINT
1097 << "Successfully serialized coalesced packet of length: "
1098 << packet_length;
1099 return packet_length;
1100}
1101
QUICHE teama6ef0a62019-03-07 20:34:33 -05001102// TODO(b/74062209): Make this a public method of framer?
1103SerializedPacket QuicPacketCreator::NoPacket() {
1104 return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
1105 nullptr, 0, false, false);
1106}
1107
QUICHE team2252b702019-05-14 23:55:14 -04001108QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -04001109 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi346b7ce2019-06-05 01:38:18 -07001110 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001111 }
dschinazi7b9278c2019-05-20 07:36:21 -07001112 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001113}
1114
1115QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -04001116 if (framer_->perspective() == Perspective::IS_CLIENT) {
dschinazi346b7ce2019-06-05 01:38:18 -07001117 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001118 }
dschinazi7b9278c2019-05-20 07:36:21 -07001119 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001120}
1121
QUICHE teama6ef0a62019-03-07 20:34:33 -05001122QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
1123 const {
dschinazi5e1a7b22019-07-31 12:23:21 -07001124 // In versions that do not support client connection IDs, the destination
1125 // connection ID is only sent from client to server.
1126 return (framer_->perspective() == Perspective::IS_CLIENT ||
1127 framer_->version().SupportsClientConnectionIds())
1128 ? CONNECTION_ID_PRESENT
1129 : CONNECTION_ID_ABSENT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001130}
1131
1132QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
1133 const {
1134 // Long header packets sent by server include source connection ID.
dschinazi346b7ce2019-06-05 01:38:18 -07001135 // Ones sent by the client only include source connection ID if the version
1136 // supports client connection IDs.
1137 if (HasIetfLongHeader() &&
1138 (framer_->perspective() == Perspective::IS_SERVER ||
1139 framer_->version().SupportsClientConnectionIds())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001140 return CONNECTION_ID_PRESENT;
1141 }
dschinazi5e1a7b22019-07-31 12:23:21 -07001142 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi7b9278c2019-05-20 07:36:21 -07001143 return server_connection_id_included_;
QUICHE team2252b702019-05-14 23:55:14 -04001144 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001145 return CONNECTION_ID_ABSENT;
1146}
1147
1148QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
1149 const {
dschinazi7b9278c2019-05-20 07:36:21 -07001150 DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001151 transport_version()));
1152 return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -04001153 ? static_cast<QuicConnectionIdLength>(
1154 GetDestinationConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001155 : PACKET_0BYTE_CONNECTION_ID;
1156}
1157
1158QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
dschinazi7b9278c2019-05-20 07:36:21 -07001159 DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001160 transport_version()));
1161 return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -04001162 ? static_cast<QuicConnectionIdLength>(
1163 GetSourceConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001164 : PACKET_0BYTE_CONNECTION_ID;
1165}
1166
1167QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
fayang3ac15c12019-06-14 14:04:51 -07001168 if (HasIetfLongHeader() &&
1169 !framer_->version().SendsVariableLengthPacketNumberInLongHeader()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001170 return PACKET_4BYTE_PACKET_NUMBER;
1171 }
1172 return packet_.packet_number_length;
1173}
1174
nharper55fa6132019-05-07 19:37:21 -07001175size_t QuicPacketCreator::PacketHeaderSize() const {
1176 return GetPacketHeaderSize(
1177 framer_->transport_version(), GetDestinationConnectionIdLength(),
1178 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
1179 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
1180 GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
1181}
1182
QUICHE teama6ef0a62019-03-07 20:34:33 -05001183QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
1184 const {
1185 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1186 HasIetfLongHeader() &&
1187 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
1188 return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
1189 }
1190 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
1191}
1192
dmcardlecf0bfcf2019-12-13 08:08:21 -08001193quiche::QuicheStringPiece QuicPacketCreator::GetRetryToken() const {
dschinazi0db87092019-05-20 07:59:15 -07001194 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1195 HasIetfLongHeader() &&
1196 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
1197 return retry_token_;
1198 }
dmcardlecf0bfcf2019-12-13 08:08:21 -08001199 return quiche::QuicheStringPiece();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001200}
1201
dmcardlecf0bfcf2019-12-13 08:08:21 -08001202void QuicPacketCreator::SetRetryToken(quiche::QuicheStringPiece retry_token) {
vasilvvc48c8712019-03-11 13:38:16 -07001203 retry_token_ = std::string(retry_token);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001204}
1205
fayang18be79a2019-09-16 15:17:12 -07001206bool QuicPacketCreator::ConsumeRetransmittableControlFrame(
1207 const QuicFrame& frame) {
fayang18be79a2019-09-16 15:17:12 -07001208 QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame))
1209 << "Adding a control frame with no control frame id: " << frame;
1210 DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame;
1211 MaybeBundleAckOpportunistically();
1212 if (HasPendingFrames()) {
renjietangb63005e2019-11-19 23:08:53 -08001213 if (AddFrame(frame, next_transmission_type_)) {
fayang18be79a2019-09-16 15:17:12 -07001214 // There is pending frames and current frame fits.
1215 return true;
1216 }
1217 }
1218 DCHECK(!HasPendingFrames());
1219 if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME &&
1220 !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
1221 NOT_HANDSHAKE)) {
1222 // Do not check congestion window for ping or connection close frames.
1223 return false;
1224 }
renjietangb63005e2019-11-19 23:08:53 -08001225 const bool success = AddFrame(frame, next_transmission_type_);
ianswettbd78ea12019-09-26 06:32:37 -07001226 QUIC_BUG_IF(!success) << "Failed to add frame:" << frame
1227 << " transmission_type:" << next_transmission_type_;
fayang18be79a2019-09-16 15:17:12 -07001228 return success;
1229}
1230
1231QuicConsumedData QuicPacketCreator::ConsumeData(QuicStreamId id,
1232 size_t write_length,
1233 QuicStreamOffset offset,
1234 StreamSendingState state) {
fayang18be79a2019-09-16 15:17:12 -07001235 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1236 "generator tries to write stream data.";
1237 bool has_handshake = QuicUtils::IsCryptoStreamId(transport_version(), id);
1238 MaybeBundleAckOpportunistically();
1239 bool fin = state != NO_FIN;
1240 QUIC_BUG_IF(has_handshake && fin)
1241 << "Handshake packets should never send a fin";
1242 // To make reasoning about crypto frames easier, we don't combine them with
1243 // other retransmittable frames in a single packet.
1244 if (has_handshake && HasPendingRetransmittableFrames()) {
1245 FlushCurrentPacket();
1246 }
1247
1248 size_t total_bytes_consumed = 0;
1249 bool fin_consumed = false;
1250
1251 if (!HasRoomForStreamFrame(id, offset, write_length)) {
1252 FlushCurrentPacket();
1253 }
1254
1255 if (!fin && (write_length == 0)) {
1256 QUIC_BUG << "Attempt to consume empty data without FIN.";
1257 return QuicConsumedData(0, false);
1258 }
1259 // We determine if we can enter the fast path before executing
1260 // the slow path loop.
1261 bool run_fast_path =
1262 !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
fayang2ab1e852019-11-04 11:24:36 -08001263 write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
1264 latched_hard_max_packet_length_ == 0;
fayang18be79a2019-09-16 15:17:12 -07001265
ianswett517beaa2020-05-26 06:05:32 -07001266 while (!run_fast_path &&
1267 (has_handshake || delegate_->ShouldGeneratePacket(
1268 HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE))) {
fayang18be79a2019-09-16 15:17:12 -07001269 QuicFrame frame;
1270 bool needs_full_padding =
1271 has_handshake && fully_pad_crypto_handshake_packets_;
1272
1273 if (!ConsumeDataToFillCurrentPacket(id, write_length - total_bytes_consumed,
1274 offset + total_bytes_consumed, fin,
1275 needs_full_padding,
1276 next_transmission_type_, &frame)) {
1277 // The creator is always flushed if there's not enough room for a new
1278 // stream frame before ConsumeData, so ConsumeData should always succeed.
1279 QUIC_BUG << "Failed to ConsumeData, stream:" << id;
1280 return QuicConsumedData(0, false);
1281 }
1282
1283 // A stream frame is created and added.
1284 size_t bytes_consumed = frame.stream_frame.data_length;
1285 total_bytes_consumed += bytes_consumed;
1286 fin_consumed = fin && total_bytes_consumed == write_length;
1287 if (fin_consumed && state == FIN_AND_PADDING) {
1288 AddRandomPadding();
1289 }
1290 DCHECK(total_bytes_consumed == write_length ||
1291 (bytes_consumed > 0 && HasPendingFrames()));
1292
1293 if (total_bytes_consumed == write_length) {
1294 // We're done writing the data. Exit the loop.
1295 // We don't make this a precondition because we could have 0 bytes of data
1296 // if we're simply writing a fin.
1297 break;
1298 }
1299 FlushCurrentPacket();
1300
1301 run_fast_path =
1302 !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
fayang2ab1e852019-11-04 11:24:36 -08001303 write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
1304 latched_hard_max_packet_length_ == 0;
fayang18be79a2019-09-16 15:17:12 -07001305 }
1306
1307 if (run_fast_path) {
1308 return ConsumeDataFastPath(id, write_length, offset, state != NO_FIN,
1309 total_bytes_consumed);
1310 }
1311
1312 // Don't allow the handshake to be bundled with other retransmittable frames.
1313 if (has_handshake) {
1314 FlushCurrentPacket();
1315 }
1316
1317 return QuicConsumedData(total_bytes_consumed, fin_consumed);
1318}
1319
1320QuicConsumedData QuicPacketCreator::ConsumeDataFastPath(
1321 QuicStreamId id,
1322 size_t write_length,
1323 QuicStreamOffset offset,
1324 bool fin,
1325 size_t total_bytes_consumed) {
fayang18be79a2019-09-16 15:17:12 -07001326 DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
1327
1328 while (total_bytes_consumed < write_length &&
1329 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
1330 NOT_HANDSHAKE)) {
1331 // Serialize and encrypt the packet.
1332 size_t bytes_consumed = 0;
1333 CreateAndSerializeStreamFrame(id, write_length, total_bytes_consumed,
1334 offset + total_bytes_consumed, fin,
1335 next_transmission_type_, &bytes_consumed);
fayangaf2cdfd2020-01-06 10:52:12 -08001336 if (bytes_consumed == 0) {
1337 const std::string error_details =
1338 "Failed in CreateAndSerializeStreamFrame.";
1339 QUIC_BUG << error_details;
1340 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
1341 error_details);
1342 break;
fayangd99c2c12019-11-08 13:22:51 -08001343 }
fayang18be79a2019-09-16 15:17:12 -07001344 total_bytes_consumed += bytes_consumed;
1345 }
1346
1347 return QuicConsumedData(total_bytes_consumed,
1348 fin && (total_bytes_consumed == write_length));
1349}
1350
1351size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
1352 size_t write_length,
1353 QuicStreamOffset offset) {
dschinazi6458eb32020-06-23 12:38:41 -07001354 QUIC_DVLOG(2) << "ConsumeCryptoData " << level << " write_length "
1355 << write_length << " offset " << offset;
fayang18be79a2019-09-16 15:17:12 -07001356 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1357 "generator tries to write crypto data.";
1358 MaybeBundleAckOpportunistically();
1359 // To make reasoning about crypto frames easier, we don't combine them with
1360 // other retransmittable frames in a single packet.
1361 // TODO(nharper): Once we have separate packet number spaces, everything
1362 // should be driven by encryption level, and we should stop flushing in this
1363 // spot.
1364 if (HasPendingRetransmittableFrames()) {
1365 FlushCurrentPacket();
1366 }
1367
1368 size_t total_bytes_consumed = 0;
1369
fayangd6c5bd02020-06-29 07:25:34 -07001370 while (
1371 total_bytes_consumed < write_length &&
1372 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, IS_HANDSHAKE)) {
fayang18be79a2019-09-16 15:17:12 -07001373 QuicFrame frame;
1374 if (!ConsumeCryptoDataToFillCurrentPacket(
1375 level, write_length - total_bytes_consumed,
1376 offset + total_bytes_consumed, fully_pad_crypto_handshake_packets_,
1377 next_transmission_type_, &frame)) {
1378 // The only pending data in the packet is non-retransmittable frames. I'm
1379 // assuming here that they won't occupy so much of the packet that a
1380 // CRYPTO frame won't fit.
renjietangb4ebb1d2020-05-27 18:15:51 -07001381 QUIC_BUG << "Failed to ConsumeCryptoData at level " << level;
fayang18be79a2019-09-16 15:17:12 -07001382 return 0;
1383 }
1384 total_bytes_consumed += frame.crypto_frame->data_length;
1385 FlushCurrentPacket();
1386 }
1387
1388 // Don't allow the handshake to be bundled with other retransmittable frames.
1389 FlushCurrentPacket();
1390
1391 return total_bytes_consumed;
1392}
1393
1394void QuicPacketCreator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
fayang18be79a2019-09-16 15:17:12 -07001395 // MTU discovery frames must be sent by themselves.
1396 if (!CanSetMaxPacketLength()) {
1397 QUIC_BUG << "MTU discovery packets should only be sent when no other "
1398 << "frames needs to be sent.";
1399 return;
1400 }
1401 const QuicByteCount current_mtu = max_packet_length();
1402
1403 // The MTU discovery frame is allocated on the stack, since it is going to be
1404 // serialized within this function.
1405 QuicMtuDiscoveryFrame mtu_discovery_frame;
1406 QuicFrame frame(mtu_discovery_frame);
1407
1408 // Send the probe packet with the new length.
1409 SetMaxPacketLength(target_mtu);
1410 const bool success = AddPaddedSavedFrame(frame, next_transmission_type_);
1411 FlushCurrentPacket();
1412 // The only reason AddFrame can fail is that the packet is too full to fit in
1413 // a ping. This is not possible for any sane MTU.
ianswettbd78ea12019-09-26 06:32:37 -07001414 QUIC_BUG_IF(!success) << "Failed to send path MTU target_mtu:" << target_mtu
1415 << " transmission_type:" << next_transmission_type_;
fayang18be79a2019-09-16 15:17:12 -07001416
1417 // Reset the packet length back.
1418 SetMaxPacketLength(current_mtu);
1419}
1420
1421void QuicPacketCreator::MaybeBundleAckOpportunistically() {
fayang18be79a2019-09-16 15:17:12 -07001422 if (has_ack()) {
1423 // Ack already queued, nothing to do.
1424 return;
1425 }
1426 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
1427 NOT_HANDSHAKE)) {
1428 return;
1429 }
1430 const bool flushed =
1431 FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
ianswettbd78ea12019-09-26 06:32:37 -07001432 QUIC_BUG_IF(!flushed) << "Failed to flush ACK frame. encryption_level:"
1433 << packet_.encryption_level;
fayang18be79a2019-09-16 15:17:12 -07001434}
1435
1436bool QuicPacketCreator::FlushAckFrame(const QuicFrames& frames) {
fayang18be79a2019-09-16 15:17:12 -07001437 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1438 "generator tries to send ACK frame.";
1439 for (const auto& frame : frames) {
1440 DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME);
1441 if (HasPendingFrames()) {
renjietangb63005e2019-11-19 23:08:53 -08001442 if (AddFrame(frame, next_transmission_type_)) {
fayang18be79a2019-09-16 15:17:12 -07001443 // There is pending frames and current frame fits.
1444 continue;
1445 }
1446 }
1447 DCHECK(!HasPendingFrames());
1448 // There is no pending frames, consult the delegate whether a packet can be
1449 // generated.
1450 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
1451 NOT_HANDSHAKE)) {
1452 return false;
1453 }
renjietangb63005e2019-11-19 23:08:53 -08001454 const bool success = AddFrame(frame, next_transmission_type_);
fayang18be79a2019-09-16 15:17:12 -07001455 QUIC_BUG_IF(!success) << "Failed to flush " << frame;
1456 }
1457 return true;
1458}
1459
1460void QuicPacketCreator::AddRandomPadding() {
fayang18be79a2019-09-16 15:17:12 -07001461 AddPendingPadding(random_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
1462}
1463
1464void QuicPacketCreator::AttachPacketFlusher() {
fayang18be79a2019-09-16 15:17:12 -07001465 flusher_attached_ = true;
1466 if (!write_start_packet_number_.IsInitialized()) {
1467 write_start_packet_number_ = NextSendingPacketNumber();
1468 }
1469}
1470
1471void QuicPacketCreator::Flush() {
fayang18be79a2019-09-16 15:17:12 -07001472 FlushCurrentPacket();
1473 SendRemainingPendingPadding();
1474 flusher_attached_ = false;
1475 if (GetQuicFlag(FLAGS_quic_export_server_num_packets_per_write_histogram)) {
1476 if (!write_start_packet_number_.IsInitialized()) {
1477 QUIC_BUG << "write_start_packet_number is not initialized";
1478 return;
1479 }
1480 QUIC_SERVER_HISTOGRAM_COUNTS(
1481 "quic_server_num_written_packets_per_write",
1482 NextSendingPacketNumber() - write_start_packet_number_, 1, 200, 50,
1483 "Number of QUIC packets written per write operation");
1484 }
1485 write_start_packet_number_.Clear();
1486}
1487
1488void QuicPacketCreator::SendRemainingPendingPadding() {
fayang18be79a2019-09-16 15:17:12 -07001489 while (
1490 pending_padding_bytes() > 0 && !HasPendingFrames() &&
1491 delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) {
1492 FlushCurrentPacket();
1493 }
1494}
1495
1496void QuicPacketCreator::SetServerConnectionIdLength(uint32_t length) {
fayang18be79a2019-09-16 15:17:12 -07001497 if (length == 0) {
1498 SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
1499 } else {
1500 SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
1501 }
1502}
1503
1504void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
fayangcff885a2019-10-22 07:39:04 -07001505 next_transmission_type_ = type;
fayang18be79a2019-09-16 15:17:12 -07001506}
1507
1508MessageStatus QuicPacketCreator::AddMessageFrame(QuicMessageId message_id,
1509 QuicMemSliceSpan message) {
fayang18be79a2019-09-16 15:17:12 -07001510 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1511 "generator tries to add message frame.";
1512 MaybeBundleAckOpportunistically();
1513 const QuicByteCount message_length = message.total_length();
1514 if (message_length > GetCurrentLargestMessagePayload()) {
1515 return MESSAGE_STATUS_TOO_LARGE;
1516 }
1517 if (!HasRoomForMessageFrame(message_length)) {
1518 FlushCurrentPacket();
1519 }
1520 QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
renjietangb63005e2019-11-19 23:08:53 -08001521 const bool success = AddFrame(QuicFrame(frame), next_transmission_type_);
fayang18be79a2019-09-16 15:17:12 -07001522 if (!success) {
1523 QUIC_BUG << "Failed to send message " << message_id;
1524 delete frame;
1525 return MESSAGE_STATUS_INTERNAL_ERROR;
1526 }
1527 return MESSAGE_STATUS_SUCCESS;
1528}
1529
QUICHE teama6ef0a62019-03-07 20:34:33 -05001530QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
1531 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1532 HasIetfLongHeader()) {
1533 QuicLongHeaderType long_header_type =
1534 EncryptionlevelToLongHeaderType(packet_.encryption_level);
1535 if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
1536 long_header_type == HANDSHAKE) {
1537 return VARIABLE_LENGTH_INTEGER_LENGTH_2;
1538 }
1539 }
1540 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
1541}
1542
1543void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
QUICHE team2252b702019-05-14 23:55:14 -04001544 header->destination_connection_id = GetDestinationConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001545 header->destination_connection_id_included =
1546 GetDestinationConnectionIdIncluded();
QUICHE team2252b702019-05-14 23:55:14 -04001547 header->source_connection_id = GetSourceConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001548 header->source_connection_id_included = GetSourceConnectionIdIncluded();
1549 header->reset_flag = false;
1550 header->version_flag = IncludeVersionInHeader();
1551 if (IncludeNonceInPublicHeader()) {
1552 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
1553 header->nonce = &diversification_nonce_;
1554 } else {
1555 header->nonce = nullptr;
1556 }
fayang354c9422019-05-21 08:10:35 -07001557 packet_.packet_number = NextSendingPacketNumber();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001558 header->packet_number = packet_.packet_number;
1559 header->packet_number_length = GetPacketNumberLength();
1560 header->retry_token_length_length = GetRetryTokenLengthLength();
1561 header->retry_token = GetRetryToken();
1562 header->length_length = GetLengthLength();
1563 header->remaining_packet_length = 0;
1564 if (!HasIetfLongHeader()) {
1565 return;
1566 }
1567 header->long_packet_type =
1568 EncryptionlevelToLongHeaderType(packet_.encryption_level);
1569}
1570
fayangfce2f722020-06-26 10:27:32 -07001571size_t QuicPacketCreator::GetSerializedFrameLength(const QuicFrame& frame) {
1572 size_t serialized_frame_length = framer_->GetSerializedFrameLength(
1573 frame, BytesFree(), queued_frames_.empty(),
1574 /* last_frame_in_packet= */ true, GetPacketNumberLength());
1575 if (!fix_extra_padding_bytes_) {
1576 return serialized_frame_length;
1577 }
1578 if (!framer_->version().HasHeaderProtection() ||
1579 serialized_frame_length == 0) {
1580 return serialized_frame_length;
1581 }
1582 // Calculate frame bytes and bytes free with this frame added.
1583 const size_t frame_bytes = PacketSize() - PacketHeaderSize() +
1584 ExpansionOnNewFrame() + serialized_frame_length;
1585 if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
1586 // No extra bytes is needed.
1587 return serialized_frame_length;
1588 }
1589 QUIC_RELOADABLE_FLAG_COUNT_N(quic_fix_extra_padding_bytes, 1, 3);
1590 if (BytesFree() < serialized_frame_length) {
1591 QUIC_BUG << ENDPOINT << "Frame does not fit: " << frame;
1592 return 0;
1593 }
1594 // Please note bytes_free does not take |frame|'s expansion into account.
1595 size_t bytes_free = BytesFree() - serialized_frame_length;
1596 // Extra bytes needed (this is NOT padding needed) should be at least 1
1597 // padding + expansion.
bnce5c11c02020-07-29 08:02:21 -07001598 const size_t extra_bytes_needed = std::max(
1599 1 + ExpansionOnNewFrameWithLastFrame(frame, framer_->transport_version()),
1600 MinPlaintextPacketSize(framer_->version()) - frame_bytes);
fayangfce2f722020-06-26 10:27:32 -07001601 if (bytes_free < extra_bytes_needed) {
1602 // This frame does not fit.
1603 return 0;
1604 }
1605 return serialized_frame_length;
1606}
1607
QUICHE teama6ef0a62019-03-07 20:34:33 -05001608bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001609 TransmissionType transmission_type) {
1610 QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
renjietang2b5e6622020-06-02 15:19:40 -07001611 << transmission_type << ": " << frame;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001612 if (frame.type == STREAM_FRAME &&
nharper46833c32019-05-15 21:33:05 -07001613 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
1614 frame.stream_frame.stream_id) &&
fayang49523232019-05-03 06:28:22 -07001615 (packet_.encryption_level == ENCRYPTION_INITIAL ||
1616 packet_.encryption_level == ENCRYPTION_HANDSHAKE)) {
dschinazief79a5f2019-10-04 10:32:54 -07001617 const std::string error_details =
dmcardlecf0bfcf2019-12-13 08:08:21 -08001618 quiche::QuicheStrCat("Cannot send stream data with level: ",
1619 EncryptionLevelToString(packet_.encryption_level));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001620 QUIC_BUG << error_details;
1621 delegate_->OnUnrecoverableError(
fkastenholz85f18902019-05-28 12:47:00 -07001622 QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001623 return false;
1624 }
renjietangdbe98342019-10-18 11:00:57 -07001625
renjietange426d622020-01-02 11:58:46 -08001626 if (frame.type == STREAM_FRAME) {
renjietang50ea92a2019-12-26 10:15:01 -08001627 if (MaybeCoalesceStreamFrame(frame.stream_frame)) {
1628 LogCoalesceStreamFrameStatus(true);
renjietang50ea92a2019-12-26 10:15:01 -08001629 return true;
1630 } else {
1631 LogCoalesceStreamFrameStatus(false);
1632 }
renjietangdbe98342019-10-18 11:00:57 -07001633 }
1634
fayangfce2f722020-06-26 10:27:32 -07001635 size_t frame_len = GetSerializedFrameLength(frame);
fayang2ab1e852019-11-04 11:24:36 -08001636 if (frame_len == 0 && RemoveSoftMaxPacketLength()) {
1637 // Remove soft max_packet_length and retry.
fayangfce2f722020-06-26 10:27:32 -07001638 frame_len = GetSerializedFrameLength(frame);
fayang2ab1e852019-11-04 11:24:36 -08001639 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001640 if (frame_len == 0) {
dschinazi6458eb32020-06-23 12:38:41 -07001641 QUIC_DVLOG(1) << "Flushing because current open packet is full when adding "
1642 << frame;
fayang62b637b2019-09-16 08:40:49 -07001643 FlushCurrentPacket();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001644 return false;
1645 }
fayang7a06f9b2020-06-24 10:23:19 -07001646 if (update_packet_size_ && queued_frames_.empty()) {
1647 QUIC_RELOADABLE_FLAG_COUNT(quic_update_packet_size);
1648 packet_size_ = PacketHeaderSize();
1649 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001650 DCHECK_LT(0u, packet_size_);
1651
1652 packet_size_ += ExpansionOnNewFrame() + frame_len;
1653
fayang347ab752019-10-22 11:17:43 -07001654 if (QuicUtils::IsRetransmittableFrame(frame.type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001655 packet_.retransmittable_frames.push_back(frame);
1656 queued_frames_.push_back(frame);
1657 if (QuicUtils::IsHandshakeFrame(frame, framer_->transport_version())) {
1658 packet_.has_crypto_handshake = IS_HANDSHAKE;
1659 }
1660 } else {
fayang02a28742019-12-04 07:09:38 -08001661 if (frame.type == PADDING_FRAME &&
1662 frame.padding_frame.num_padding_bytes == -1) {
1663 // Populate the actual length of full padding frame, such that one can
1664 // know how much padding is actually added.
1665 packet_.nonretransmittable_frames.push_back(
1666 QuicFrame(QuicPaddingFrame(frame_len)));
1667 } else {
1668 packet_.nonretransmittable_frames.push_back(frame);
fayang51152fd2019-10-21 06:48:09 -07001669 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001670 queued_frames_.push_back(frame);
1671 }
1672
1673 if (frame.type == ACK_FRAME) {
1674 packet_.has_ack = true;
1675 packet_.largest_acked = LargestAcked(*frame.ack_frame);
1676 }
1677 if (frame.type == STOP_WAITING_FRAME) {
1678 packet_.has_stop_waiting = true;
1679 }
1680 if (debug_delegate_ != nullptr) {
1681 debug_delegate_->OnFrameAddedToPacket(frame);
1682 }
1683
1684 // Packet transmission type is determined by the last added retransmittable
1685 // frame.
fayangcff885a2019-10-22 07:39:04 -07001686 if (QuicUtils::IsRetransmittableFrame(frame.type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001687 packet_.transmission_type = transmission_type;
1688 }
1689 return true;
1690}
1691
fayangfce2f722020-06-26 10:27:32 -07001692void QuicPacketCreator::MaybeAddExtraPaddingForHeaderProtection() {
1693 DCHECK(fix_extra_padding_bytes_);
1694 if (!framer_->version().HasHeaderProtection() || needs_full_padding_) {
1695 return;
1696 }
1697 const size_t frame_bytes = PacketSize() - PacketHeaderSize();
1698 if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
1699 return;
1700 }
1701 const QuicByteCount min_header_protection_padding =
1702 std::max(1 + ExpansionOnNewFrame(),
1703 MinPlaintextPacketSize(framer_->version()) - frame_bytes) -
1704 ExpansionOnNewFrame();
1705 QUIC_RELOADABLE_FLAG_COUNT_N(quic_fix_extra_padding_bytes, 2, 3);
1706 // Update pending_padding_bytes_.
1707 pending_padding_bytes_ =
1708 std::max(pending_padding_bytes_, min_header_protection_padding);
1709}
1710
renjietangdbe98342019-10-18 11:00:57 -07001711bool QuicPacketCreator::MaybeCoalesceStreamFrame(const QuicStreamFrame& frame) {
1712 if (queued_frames_.empty() || queued_frames_.back().type != STREAM_FRAME) {
1713 return false;
1714 }
1715 QuicStreamFrame* candidate = &queued_frames_.back().stream_frame;
1716 if (candidate->stream_id != frame.stream_id ||
1717 candidate->offset + candidate->data_length != frame.offset ||
1718 frame.data_length > BytesFree()) {
1719 return false;
1720 }
1721 candidate->data_length += frame.data_length;
1722 candidate->fin = frame.fin;
1723
1724 // The back of retransmittable frames must be the same as the original
1725 // queued frames' back.
1726 DCHECK_EQ(packet_.retransmittable_frames.back().type, STREAM_FRAME);
1727 QuicStreamFrame* retransmittable =
1728 &packet_.retransmittable_frames.back().stream_frame;
1729 DCHECK_EQ(retransmittable->stream_id, frame.stream_id);
1730 DCHECK_EQ(retransmittable->offset + retransmittable->data_length,
1731 frame.offset);
1732 retransmittable->data_length = candidate->data_length;
1733 retransmittable->fin = candidate->fin;
1734 packet_size_ += frame.data_length;
1735 if (debug_delegate_ != nullptr) {
1736 debug_delegate_->OnStreamFrameCoalesced(*candidate);
1737 }
1738 return true;
1739}
1740
fayang2ab1e852019-11-04 11:24:36 -08001741bool QuicPacketCreator::RemoveSoftMaxPacketLength() {
1742 if (latched_hard_max_packet_length_ == 0) {
1743 return false;
1744 }
1745 if (!CanSetMaxPacketLength()) {
1746 return false;
1747 }
1748 QUIC_DVLOG(1) << "Restoring max packet length to: "
1749 << latched_hard_max_packet_length_;
1750 SetMaxPacketLength(latched_hard_max_packet_length_);
1751 // Reset latched_max_packet_length_.
1752 latched_hard_max_packet_length_ = 0;
1753 return true;
1754}
1755
QUICHE teama6ef0a62019-03-07 20:34:33 -05001756void QuicPacketCreator::MaybeAddPadding() {
1757 // The current packet should have no padding bytes because padding is only
1758 // added when this method is called just before the packet is serialized.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001759 if (BytesFree() == 0) {
1760 // Don't pad full packets.
1761 return;
1762 }
1763
1764 if (packet_.transmission_type == PROBING_RETRANSMISSION) {
1765 needs_full_padding_ = true;
1766 }
1767
fayang15042962020-07-01 12:14:29 -07001768 if (determine_serialized_packet_fate_early_) {
1769 if (packet_.fate == COALESCE ||
1770 packet_.fate == LEGACY_VERSION_ENCAPSULATE) {
1771 // Do not add full padding if the packet is going to be coalesced or
1772 // encapsulated.
fayang58f71072019-11-05 08:47:02 -08001773 needs_full_padding_ = false;
1774 }
fayang15042962020-07-01 12:14:29 -07001775 } else {
1776 // Packet coalescer pads INITIAL packets, so the creator should not.
1777 if (framer_->version().CanSendCoalescedPackets() &&
1778 (packet_.encryption_level == ENCRYPTION_INITIAL ||
1779 packet_.encryption_level == ENCRYPTION_HANDSHAKE)) {
1780 // TODO(fayang): MTU discovery packets should not ever be sent as
1781 // ENCRYPTION_INITIAL or ENCRYPTION_HANDSHAKE.
1782 bool is_mtu_discovery = false;
1783 for (const auto& frame : packet_.nonretransmittable_frames) {
1784 if (frame.type == MTU_DISCOVERY_FRAME) {
1785 is_mtu_discovery = true;
1786 break;
1787 }
1788 }
1789 if (!is_mtu_discovery) {
1790 // Do not add full padding if connection tries to coalesce packet.
1791 needs_full_padding_ = false;
1792 }
1793 }
fayang58f71072019-11-05 08:47:02 -08001794
fayang15042962020-07-01 12:14:29 -07001795 if (disable_padding_override_) {
1796 needs_full_padding_ = false;
1797 }
dschinazi6458eb32020-06-23 12:38:41 -07001798 }
1799
nharper55fa6132019-05-07 19:37:21 -07001800 // Header protection requires a minimum plaintext packet size.
fayangfce2f722020-06-26 10:27:32 -07001801 // TODO(fayang): remove extra_padding_bytes when deprecating
1802 // quic_fix_extra_padding_bytes.
nharper55fa6132019-05-07 19:37:21 -07001803 size_t extra_padding_bytes = 0;
fayangfce2f722020-06-26 10:27:32 -07001804 if (fix_extra_padding_bytes_) {
1805 MaybeAddExtraPaddingForHeaderProtection();
1806 } else {
1807 if (framer_->version().HasHeaderProtection()) {
1808 size_t frame_bytes = PacketSize() - PacketHeaderSize();
nharper55fa6132019-05-07 19:37:21 -07001809
fayangfce2f722020-06-26 10:27:32 -07001810 if (frame_bytes + pending_padding_bytes_ <
1811 MinPlaintextPacketSize(framer_->version()) &&
1812 !needs_full_padding_) {
1813 extra_padding_bytes =
1814 MinPlaintextPacketSize(framer_->version()) - frame_bytes;
1815 }
nharper55fa6132019-05-07 19:37:21 -07001816 }
1817 }
1818
1819 if (!needs_full_padding_ && pending_padding_bytes_ == 0 &&
1820 extra_padding_bytes == 0) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001821 // Do not need padding.
1822 return;
1823 }
1824
nharper55fa6132019-05-07 19:37:21 -07001825 int padding_bytes = -1;
fayang88b87232020-06-24 15:31:08 -07001826 if (!needs_full_padding_) {
1827 padding_bytes = std::min<int16_t>(pending_padding_bytes_, BytesFree());
1828 pending_padding_bytes_ -= padding_bytes;
1829 padding_bytes = std::max<int16_t>(padding_bytes, extra_padding_bytes);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001830 }
1831
fayang347ab752019-10-22 11:17:43 -07001832 bool success = AddFrame(QuicFrame(QuicPaddingFrame(padding_bytes)),
nharper55fa6132019-05-07 19:37:21 -07001833 packet_.transmission_type);
dschinazief79a5f2019-10-04 10:32:54 -07001834 QUIC_BUG_IF(!success) << "Failed to add padding_bytes: " << padding_bytes
renjietang2b5e6622020-06-02 15:19:40 -07001835 << " transmission_type: " << packet_.transmission_type;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001836}
1837
1838bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
1839 return have_diversification_nonce_ &&
1840 packet_.encryption_level == ENCRYPTION_ZERO_RTT;
1841}
1842
1843bool QuicPacketCreator::IncludeVersionInHeader() const {
fayangd4291e42019-05-30 10:31:21 -07001844 if (VersionHasIetfInvariantHeader(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001845 return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1846 }
1847 return send_version_in_packet_;
1848}
1849
1850void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
1851 pending_padding_bytes_ += size;
1852}
1853
ianswette28f0222019-04-04 13:31:22 -07001854bool QuicPacketCreator::StreamFrameIsClientHello(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001855 const QuicStreamFrame& frame) const {
1856 if (framer_->perspective() == Perspective::IS_SERVER ||
nharper46833c32019-05-15 21:33:05 -07001857 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
1858 frame.stream_id)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001859 return false;
1860 }
ianswette28f0222019-04-04 13:31:22 -07001861 // The ClientHello is always sent with INITIAL encryption.
1862 return packet_.encryption_level == ENCRYPTION_INITIAL;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001863}
1864
dschinazi7b9278c2019-05-20 07:36:21 -07001865void QuicPacketCreator::SetServerConnectionIdIncluded(
1866 QuicConnectionIdIncluded server_connection_id_included) {
1867 DCHECK(server_connection_id_included == CONNECTION_ID_PRESENT ||
1868 server_connection_id_included == CONNECTION_ID_ABSENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001869 DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
dschinazi7b9278c2019-05-20 07:36:21 -07001870 server_connection_id_included != CONNECTION_ID_ABSENT);
1871 server_connection_id_included_ = server_connection_id_included;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001872}
1873
dschinazi7b9278c2019-05-20 07:36:21 -07001874void QuicPacketCreator::SetServerConnectionId(
1875 QuicConnectionId server_connection_id) {
1876 server_connection_id_ = server_connection_id;
QUICHE teamc65d1d12019-03-19 20:58:04 -07001877}
1878
dschinazi346b7ce2019-06-05 01:38:18 -07001879void QuicPacketCreator::SetClientConnectionId(
1880 QuicConnectionId client_connection_id) {
1881 DCHECK(client_connection_id.IsEmpty() ||
1882 framer_->version().SupportsClientConnectionIds());
dschinazi346b7ce2019-06-05 01:38:18 -07001883 client_connection_id_ = client_connection_id;
1884}
1885
ianswettb239f862019-04-05 09:15:06 -07001886QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001887 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001888 return 0;
1889 }
1890 const size_t packet_header_size = GetPacketHeaderSize(
1891 framer_->transport_version(), GetDestinationConnectionIdLength(),
1892 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
1893 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
ianswettb239f862019-04-05 09:15:06 -07001894 // No Retry token on packets containing application data.
1895 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001896 // This is the largest possible message payload when the length field is
1897 // omitted.
fayang2ab1e852019-11-04 11:24:36 -08001898 size_t max_plaintext_size =
1899 latched_hard_max_packet_length_ == 0
1900 ? max_plaintext_size_
1901 : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
dschinazied459c02020-05-07 16:12:23 -07001902 size_t largest_frame =
1903 max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
1904 if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
1905 largest_frame = static_cast<size_t>(max_datagram_frame_size_);
1906 }
1907 return largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001908}
1909
ianswettb239f862019-04-05 09:15:06 -07001910QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001911 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
ianswettb239f862019-04-05 09:15:06 -07001912 return 0;
1913 }
1914 // QUIC Crypto server packets may include a diversification nonce.
1915 const bool may_include_nonce =
1916 framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
1917 framer_->perspective() == Perspective::IS_SERVER;
1918 // IETF QUIC long headers include a length on client 0RTT packets.
1919 QuicVariableLengthIntegerLength length_length =
nharperd43f1d62019-07-01 15:18:20 -07001920 VARIABLE_LENGTH_INTEGER_LENGTH_0;
1921 if (framer_->perspective() == Perspective::IS_CLIENT) {
1922 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
1923 }
nharper405f7192019-09-11 08:28:06 -07001924 if (!QuicVersionHasLongHeaderLengths(framer_->transport_version())) {
nharperd43f1d62019-07-01 15:18:20 -07001925 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
1926 }
ianswettb239f862019-04-05 09:15:06 -07001927 const size_t packet_header_size = GetPacketHeaderSize(
1928 framer_->transport_version(), GetDestinationConnectionIdLength(),
1929 // Assume CID lengths don't change, but version may be present.
1930 GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
1931 PACKET_4BYTE_PACKET_NUMBER,
1932 // No Retry token on packets containing application data.
1933 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
1934 // This is the largest possible message payload when the length field is
1935 // omitted.
fayang2ab1e852019-11-04 11:24:36 -08001936 size_t max_plaintext_size =
1937 latched_hard_max_packet_length_ == 0
1938 ? max_plaintext_size_
1939 : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
dschinazied459c02020-05-07 16:12:23 -07001940 size_t largest_frame =
1941 max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
1942 if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
1943 largest_frame = static_cast<size_t>(max_datagram_frame_size_);
1944 }
ianswettb239f862019-04-05 09:15:06 -07001945 const QuicPacketLength largest_payload =
dschinazied459c02020-05-07 16:12:23 -07001946 largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
ianswettb239f862019-04-05 09:15:06 -07001947 // This must always be less than or equal to GetCurrentLargestMessagePayload.
1948 DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload());
1949 return largest_payload;
1950}
1951
QUICHE teama6ef0a62019-03-07 20:34:33 -05001952bool QuicPacketCreator::HasIetfLongHeader() const {
fayangd4291e42019-05-30 10:31:21 -07001953 return VersionHasIetfInvariantHeader(framer_->transport_version()) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05001954 packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1955}
1956
nharper6f8a7612019-07-08 12:31:20 -07001957// static
QUICHE team2252b702019-05-14 23:55:14 -04001958size_t QuicPacketCreator::MinPlaintextPacketSize(
1959 const ParsedQuicVersion& version) {
1960 if (!version.HasHeaderProtection()) {
nharper55fa6132019-05-07 19:37:21 -07001961 return 0;
1962 }
1963 // Header protection samples 16 bytes of ciphertext starting 4 bytes after the
1964 // packet number. In IETF QUIC, all AEAD algorithms have a 16-byte auth tag
1965 // (i.e. the ciphertext is 16 bytes larger than the plaintext). Since packet
1966 // numbers could be as small as 1 byte, but the sample starts 4 bytes after
1967 // the packet number, at least 3 bytes of plaintext are needed to make sure
1968 // that there is enough ciphertext to sample.
1969 //
1970 // Google QUIC crypto uses different AEAD algorithms - in particular the auth
1971 // tags are only 12 bytes instead of 16 bytes. Since the auth tag is 4 bytes
1972 // shorter, 4 more bytes of plaintext are needed to guarantee there is enough
1973 // ciphertext to sample.
1974 //
1975 // This method could check for PROTOCOL_TLS1_3 vs PROTOCOL_QUIC_CRYPTO and
1976 // return 3 when TLS 1.3 is in use (the use of IETF vs Google QUIC crypters is
1977 // determined based on the handshake protocol used). However, even when TLS
1978 // 1.3 is used, unittests still use NullEncrypter/NullDecrypter (and other
1979 // test crypters) which also only use 12 byte tags.
1980 //
1981 // TODO(nharper): Set this based on the handshake protocol in use.
1982 return 7;
1983}
1984
fayang354c9422019-05-21 08:10:35 -07001985QuicPacketNumber QuicPacketCreator::NextSendingPacketNumber() const {
1986 if (!packet_number().IsInitialized()) {
1987 return framer_->first_sending_packet_number();
1988 }
1989 return packet_number() + 1;
1990}
1991
fayang18be79a2019-09-16 15:17:12 -07001992bool QuicPacketCreator::PacketFlusherAttached() const {
fayang18be79a2019-09-16 15:17:12 -07001993 return flusher_attached_;
1994}
1995
fayangfe963c52020-07-16 06:56:09 -07001996bool QuicPacketCreator::HasSoftMaxPacketLength() const {
1997 return latched_hard_max_packet_length_ != 0;
1998}
1999
QUICHE teama6ef0a62019-03-07 20:34:33 -05002000#undef ENDPOINT // undef for jumbo builds
2001} // namespace quic