blob: a3e2bf9352ec898038786901643b6a2711bbcbe5 [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) {
fayang04590fc2020-08-31 10:37:55 -0700136 if (close_connection_on_serialization_failure_) {
137 QUIC_RELOADABLE_FLAG_COUNT(quic_close_connection_on_serialization_failure);
138 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500139 SetMaxPacketLength(kDefaultMaxPacketSize);
dschinazied459c02020-05-07 16:12:23 -0700140 if (!framer_->version().UsesTls()) {
141 // QUIC+TLS negotiates the maximum datagram frame size via the
142 // IETF QUIC max_datagram_frame_size transport parameter.
143 // QUIC_CRYPTO however does not negotiate this so we set its value here.
144 SetMaxDatagramFrameSize(kMaxAcceptedDatagramFrameSize);
145 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500146}
147
148QuicPacketCreator::~QuicPacketCreator() {
149 DeleteFrames(&packet_.retransmittable_frames);
150}
151
152void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
153 std::unique_ptr<QuicEncrypter> encrypter) {
154 framer_->SetEncrypter(level, std::move(encrypter));
155 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
156}
157
158bool QuicPacketCreator::CanSetMaxPacketLength() const {
159 // |max_packet_length_| should not be changed mid-packet.
160 return queued_frames_.empty();
161}
162
163void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
164 DCHECK(CanSetMaxPacketLength());
165
166 // Avoid recomputing |max_plaintext_size_| if the length does not actually
167 // change.
168 if (length == max_packet_length_) {
169 return;
170 }
dschinazi6458eb32020-06-23 12:38:41 -0700171 QUIC_DVLOG(1) << "Updating packet creator max packet length from "
172 << max_packet_length_ << " to " << length;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500173
174 max_packet_length_ = length;
175 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
nharper55fa6132019-05-07 19:37:21 -0700176 QUIC_BUG_IF(max_plaintext_size_ - PacketHeaderSize() <
QUICHE team2252b702019-05-14 23:55:14 -0400177 MinPlaintextPacketSize(framer_->version()))
nharper55fa6132019-05-07 19:37:21 -0700178 << "Attempted to set max packet length too small";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500179}
180
dschinazied459c02020-05-07 16:12:23 -0700181void QuicPacketCreator::SetMaxDatagramFrameSize(
182 QuicByteCount max_datagram_frame_size) {
183 constexpr QuicByteCount upper_bound =
184 std::min<QuicByteCount>(std::numeric_limits<QuicPacketLength>::max(),
185 std::numeric_limits<size_t>::max());
186 if (max_datagram_frame_size > upper_bound) {
187 // A value of |max_datagram_frame_size| that is equal or greater than
188 // 2^16-1 is effectively infinite because QUIC packets cannot be that large.
189 // We therefore clamp the value here to allow us to safely cast
190 // |max_datagram_frame_size_| to QuicPacketLength or size_t.
191 max_datagram_frame_size = upper_bound;
192 }
193 max_datagram_frame_size_ = max_datagram_frame_size;
194}
195
fayang2ab1e852019-11-04 11:24:36 -0800196void QuicPacketCreator::SetSoftMaxPacketLength(QuicByteCount length) {
197 DCHECK(CanSetMaxPacketLength());
198 if (length > max_packet_length_) {
199 QUIC_BUG << ENDPOINT
200 << "Try to increase max_packet_length_ in "
201 "SetSoftMaxPacketLength, use SetMaxPacketLength instead.";
202 return;
203 }
204 if (framer_->GetMaxPlaintextSize(length) <
205 PacketHeaderSize() + MinPlaintextPacketSize(framer_->version())) {
fayang04bd30d2020-06-22 15:04:57 -0700206 // Please note: this would not guarantee to fit next packet if the size of
207 // packet header increases (e.g., encryption level changes).
fayang2ab1e852019-11-04 11:24:36 -0800208 QUIC_DLOG(INFO) << length << " is too small to fit packet header";
fayangf5f83e52020-09-14 10:29:29 -0700209 RemoveSoftMaxPacketLength();
fayang2ab1e852019-11-04 11:24:36 -0800210 return;
211 }
212 QUIC_DVLOG(1) << "Setting soft max packet length to: " << length;
213 latched_hard_max_packet_length_ = max_packet_length_;
214 max_packet_length_ = length;
215 max_plaintext_size_ = framer_->GetMaxPlaintextSize(length);
216}
217
QUICHE teama6ef0a62019-03-07 20:34:33 -0500218// Stops serializing version of the protocol in packets sent after this call.
219// A packet that is already open might send kQuicVersionSize bytes less than the
220// maximum packet size if we stop sending version before it is serialized.
221void QuicPacketCreator::StopSendingVersion() {
222 DCHECK(send_version_in_packet_);
fayangd4291e42019-05-30 10:31:21 -0700223 DCHECK(!VersionHasIetfInvariantHeader(framer_->transport_version()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500224 send_version_in_packet_ = false;
225 if (packet_size_ > 0) {
226 DCHECK_LT(kQuicVersionSize, packet_size_);
227 packet_size_ -= kQuicVersionSize;
228 }
229}
230
231void QuicPacketCreator::SetDiversificationNonce(
232 const DiversificationNonce& nonce) {
233 DCHECK(!have_diversification_nonce_);
234 have_diversification_nonce_ = true;
235 diversification_nonce_ = nonce;
236}
237
238void QuicPacketCreator::UpdatePacketNumberLength(
239 QuicPacketNumber least_packet_awaited_by_peer,
240 QuicPacketCount max_packets_in_flight) {
241 if (!queued_frames_.empty()) {
242 // Don't change creator state if there are frames queued.
243 QUIC_BUG << "Called UpdatePacketNumberLength with " << queued_frames_.size()
244 << " queued_frames. First frame type:"
245 << queued_frames_.front().type
246 << " last frame type:" << queued_frames_.back().type;
247 return;
248 }
249
dschinazi101d2eb2020-07-06 19:42:34 -0700250 const QuicPacketNumber next_packet_number = NextSendingPacketNumber();
251 DCHECK_LE(least_packet_awaited_by_peer, next_packet_number);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500252 const uint64_t current_delta =
dschinazi101d2eb2020-07-06 19:42:34 -0700253 next_packet_number - least_packet_awaited_by_peer;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500254 const uint64_t delta = std::max(current_delta, max_packets_in_flight);
dschinazi101d2eb2020-07-06 19:42:34 -0700255 const QuicPacketNumberLength packet_number_length =
renjietang488201d2019-12-17 13:40:49 -0800256 QuicFramer::GetMinPacketNumberLength(QuicPacketNumber(delta * 4));
dschinazi101d2eb2020-07-06 19:42:34 -0700257 if (packet_.packet_number_length == packet_number_length) {
258 return;
259 }
260 QUIC_DLOG(INFO) << ENDPOINT << "Updating packet number length from "
261 << static_cast<int>(packet_.packet_number_length) << " to "
262 << static_cast<int>(packet_number_length)
263 << ", least_packet_awaited_by_peer: "
264 << least_packet_awaited_by_peer
265 << " max_packets_in_flight: " << max_packets_in_flight
266 << " next_packet_number: " << next_packet_number;
267 packet_.packet_number_length = packet_number_length;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500268}
269
fayang4c1c2362019-09-13 07:20:01 -0700270void QuicPacketCreator::SkipNPacketNumbers(
271 QuicPacketCount count,
272 QuicPacketNumber least_packet_awaited_by_peer,
273 QuicPacketCount max_packets_in_flight) {
274 if (!queued_frames_.empty()) {
275 // Don't change creator state if there are frames queued.
276 QUIC_BUG << "Called SkipNPacketNumbers with " << queued_frames_.size()
277 << " queued_frames. First frame type:"
278 << queued_frames_.front().type
279 << " last frame type:" << queued_frames_.back().type;
280 return;
281 }
282 if (packet_.packet_number > packet_.packet_number + count) {
283 // Skipping count packet numbers causes packet number wrapping around,
284 // reject it.
285 QUIC_LOG(WARNING) << "Skipping " << count
286 << " packet numbers causes packet number wrapping "
287 "around, least_packet_awaited_by_peer: "
288 << least_packet_awaited_by_peer
289 << " packet_number:" << packet_.packet_number;
290 return;
291 }
292 packet_.packet_number += count;
293 // Packet number changes, update packet number length if necessary.
294 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight);
295}
296
fayang62b637b2019-09-16 08:40:49 -0700297bool QuicPacketCreator::ConsumeCryptoDataToFillCurrentPacket(
298 EncryptionLevel level,
299 size_t write_length,
300 QuicStreamOffset offset,
301 bool needs_full_padding,
302 TransmissionType transmission_type,
303 QuicFrame* frame) {
dschinazi6458eb32020-06-23 12:38:41 -0700304 QUIC_DVLOG(2) << "ConsumeCryptoDataToFillCurrentPacket " << level
305 << " write_length " << write_length << " offset " << offset
306 << (needs_full_padding ? " needs_full_padding" : "") << " "
307 << transmission_type;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500308 if (!CreateCryptoFrame(level, write_length, offset, frame)) {
309 return false;
310 }
311 // When crypto data was sent in stream frames, ConsumeData is called with
312 // |needs_full_padding = true|. Keep the same behavior here when sending
313 // crypto frames.
314 //
315 // TODO(nharper): Check what the IETF drafts say about padding out initial
316 // messages and change this as appropriate.
nharper51961cf2019-05-13 13:23:24 -0700317 if (needs_full_padding) {
318 needs_full_padding_ = true;
319 }
fayang347ab752019-10-22 11:17:43 -0700320 return AddFrame(*frame, transmission_type);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500321}
322
fayang62b637b2019-09-16 08:40:49 -0700323bool QuicPacketCreator::ConsumeDataToFillCurrentPacket(
324 QuicStreamId id,
325 size_t data_size,
326 QuicStreamOffset offset,
327 bool fin,
328 bool needs_full_padding,
329 TransmissionType transmission_type,
330 QuicFrame* frame) {
QUICHE teamf08778a2019-03-14 08:10:26 -0700331 if (!HasRoomForStreamFrame(id, offset, data_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500332 return false;
333 }
QUICHE teamf08778a2019-03-14 08:10:26 -0700334 CreateStreamFrame(id, data_size, offset, fin, frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500335 // Explicitly disallow multi-packet CHLOs.
danzh88e3e052019-06-13 11:47:18 -0700336 if (GetQuicFlag(FLAGS_quic_enforce_single_packet_chlo) &&
ianswette28f0222019-04-04 13:31:22 -0700337 StreamFrameIsClientHello(frame->stream_frame) &&
338 frame->stream_frame.data_length < data_size) {
vasilvvc48c8712019-03-11 13:38:16 -0700339 const std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500340 "Client hello won't fit in a single packet.";
341 QUIC_BUG << error_details << " Constructed stream frame length: "
342 << frame->stream_frame.data_length
ianswette28f0222019-04-04 13:31:22 -0700343 << " CHLO length: " << data_size;
fkastenholz85f18902019-05-28 12:47:00 -0700344 delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500345 return false;
346 }
fayang347ab752019-10-22 11:17:43 -0700347 if (!AddFrame(*frame, transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500348 // Fails if we try to write unencrypted stream data.
349 return false;
350 }
351 if (needs_full_padding) {
352 needs_full_padding_ = true;
353 }
354
355 return true;
356}
357
358bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
359 QuicStreamOffset offset,
360 size_t data_size) {
fayang2ab1e852019-11-04 11:24:36 -0800361 const size_t min_stream_frame_size = QuicFramer::GetMinStreamFrameSize(
362 framer_->transport_version(), id, offset, /*last_frame_in_packet=*/true,
363 data_size);
364 if (BytesFree() > min_stream_frame_size) {
365 return true;
366 }
367 if (!RemoveSoftMaxPacketLength()) {
368 return false;
369 }
370 return BytesFree() > min_stream_frame_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500371}
372
373bool QuicPacketCreator::HasRoomForMessageFrame(QuicByteCount length) {
fayang2ab1e852019-11-04 11:24:36 -0800374 const size_t message_frame_size = QuicFramer::GetMessageFrameSize(
375 framer_->transport_version(), /*last_frame_in_packet=*/true, length);
dschinazied459c02020-05-07 16:12:23 -0700376 if (static_cast<QuicByteCount>(message_frame_size) >
377 max_datagram_frame_size_) {
378 return false;
379 }
fayang2ab1e852019-11-04 11:24:36 -0800380 if (BytesFree() >= message_frame_size) {
381 return true;
382 }
383 if (!RemoveSoftMaxPacketLength()) {
384 return false;
385 }
386 return BytesFree() >= message_frame_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500387}
388
QUICHE teama6ef0a62019-03-07 20:34:33 -0500389// static
390size_t QuicPacketCreator::StreamFramePacketOverhead(
391 QuicTransportVersion version,
392 QuicConnectionIdLength destination_connection_id_length,
393 QuicConnectionIdLength source_connection_id_length,
394 bool include_version,
395 bool include_diversification_nonce,
396 QuicPacketNumberLength packet_number_length,
397 QuicVariableLengthIntegerLength retry_token_length_length,
398 QuicVariableLengthIntegerLength length_length,
399 QuicStreamOffset offset) {
400 return GetPacketHeaderSize(version, destination_connection_id_length,
401 source_connection_id_length, include_version,
402 include_diversification_nonce,
403 packet_number_length, retry_token_length_length, 0,
404 length_length) +
405
ianswett22781cb2019-12-12 06:45:08 -0800406 // Assumes a packet with a single stream frame, which omits the length,
407 // causing the data length argument to be ignored.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500408 QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true,
ianswett22781cb2019-12-12 06:45:08 -0800409 kMaxOutgoingPacketSize /* unused */);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500410}
411
412void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
QUICHE teamf08778a2019-03-14 08:10:26 -0700413 size_t data_size,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500414 QuicStreamOffset offset,
415 bool fin,
416 QuicFrame* frame) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500417 DCHECK_GT(
418 max_packet_length_,
419 StreamFramePacketOverhead(
420 framer_->transport_version(), GetDestinationConnectionIdLength(),
421 GetSourceConnectionIdLength(), kIncludeVersion,
422 IncludeNonceInPublicHeader(), PACKET_6BYTE_PACKET_NUMBER,
423 GetRetryTokenLengthLength(), GetLengthLength(), offset));
424
425 QUIC_BUG_IF(!HasRoomForStreamFrame(id, offset, data_size))
426 << "No room for Stream frame, BytesFree: " << BytesFree()
427 << " MinStreamFrameSize: "
428 << QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
429 offset, true, data_size);
430
QUICHE teamf08778a2019-03-14 08:10:26 -0700431 QUIC_BUG_IF(data_size == 0 && !fin)
432 << "Creating a stream frame for stream ID:" << id
433 << " with no data or fin.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500434 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
435 framer_->transport_version(), id, offset,
436 /* last_frame_in_packet= */ true, data_size);
437 size_t bytes_consumed =
438 std::min<size_t>(BytesFree() - min_frame_size, data_size);
439
440 bool set_fin = fin && bytes_consumed == data_size; // Last frame.
441 *frame = QuicFrame(QuicStreamFrame(id, set_fin, offset, bytes_consumed));
442}
443
444bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
445 size_t write_length,
446 QuicStreamOffset offset,
447 QuicFrame* frame) {
fayang7cd1d822020-08-25 13:52:19 -0700448 const size_t min_frame_size =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500449 QuicFramer::GetMinCryptoFrameSize(write_length, offset);
fayang7cd1d822020-08-25 13:52:19 -0700450 if (BytesFree() <= min_frame_size &&
451 (!RemoveSoftMaxPacketLength() || BytesFree() <= min_frame_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500452 return false;
453 }
454 size_t max_write_length = BytesFree() - min_frame_size;
455 size_t bytes_consumed = std::min<size_t>(max_write_length, write_length);
456 *frame = QuicFrame(new QuicCryptoFrame(level, offset, bytes_consumed));
457 return true;
458}
459
fayang62b637b2019-09-16 08:40:49 -0700460void QuicPacketCreator::FlushCurrentPacket() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500461 if (!HasPendingFrames() && pending_padding_bytes_ == 0) {
462 return;
463 }
464
dschinazi66dea072019-04-09 11:41:06 -0700465 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
wub50d4c712020-05-19 15:48:28 -0700466 QuicOwnedPacketBuffer external_buffer(delegate_->GetPacketBuffer());
467
wub50d4c712020-05-19 15:48:28 -0700468 if (external_buffer.buffer == nullptr) {
469 external_buffer.buffer = stack_buffer;
470 external_buffer.release_buffer = nullptr;
471 }
472
473 DCHECK_EQ(nullptr, packet_.encrypted_buffer);
fayang04590fc2020-08-31 10:37:55 -0700474 const bool success =
475 SerializePacket(std::move(external_buffer), kMaxOutgoingPacketSize);
476 if (close_connection_on_serialization_failure_ && !success) {
477 return;
478 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500479 OnSerializedPacket();
480}
481
482void QuicPacketCreator::OnSerializedPacket() {
fayang04590fc2020-08-31 10:37:55 -0700483 if (close_connection_on_serialization_failure_) {
484 QUIC_BUG_IF(packet_.encrypted_buffer == nullptr);
485 } else if (packet_.encrypted_buffer == nullptr) {
vasilvvc48c8712019-03-11 13:38:16 -0700486 const std::string error_details = "Failed to SerializePacket.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500487 QUIC_BUG << error_details;
488 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
fkastenholz85f18902019-05-28 12:47:00 -0700489 error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500490 return;
491 }
492
493 SerializedPacket packet(std::move(packet_));
494 ClearPacket();
fayang2ab1e852019-11-04 11:24:36 -0800495 RemoveSoftMaxPacketLength();
wub8a5dafa2020-05-13 12:30:17 -0700496 delegate_->OnSerializedPacket(std::move(packet));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500497}
498
499void QuicPacketCreator::ClearPacket() {
500 packet_.has_ack = false;
501 packet_.has_stop_waiting = false;
502 packet_.has_crypto_handshake = NOT_HANDSHAKE;
wub98669f52019-04-18 10:49:18 -0700503 packet_.transmission_type = NOT_RETRANSMISSION;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500504 packet_.encrypted_buffer = nullptr;
505 packet_.encrypted_length = 0;
haoyuewang5b0f14f2020-09-18 14:31:54 -0700506 packet_.has_ack_frequency = false;
fayang15042962020-07-01 12:14:29 -0700507 packet_.fate = SEND_TO_WRITER;
wubc9c6d582020-07-20 08:45:40 -0700508 QUIC_BUG_IF(packet_.release_encrypted_buffer != nullptr)
509 << "packet_.release_encrypted_buffer should be empty";
510 packet_.release_encrypted_buffer = nullptr;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500511 DCHECK(packet_.retransmittable_frames.empty());
fayang51152fd2019-10-21 06:48:09 -0700512 DCHECK(packet_.nonretransmittable_frames.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500513 packet_.largest_acked.Clear();
514 needs_full_padding_ = false;
515}
516
fayang08750832019-10-24 11:25:34 -0700517size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
518 const SerializedPacket& packet,
519 size_t padding_size,
520 char* buffer,
521 size_t buffer_len) {
522 QUIC_BUG_IF(packet.encryption_level != ENCRYPTION_INITIAL);
523 QUIC_BUG_IF(packet.nonretransmittable_frames.empty() &&
524 packet.retransmittable_frames.empty())
525 << "Attempt to serialize empty ENCRYPTION_INITIAL packet in coalesced "
526 "packet";
527 ScopedPacketContextSwitcher switcher(
528 packet.packet_number -
529 1, // -1 because serialize packet increase packet number.
530 packet.packet_number_length, packet.encryption_level, &packet_);
531 for (const QuicFrame& frame : packet.nonretransmittable_frames) {
532 if (!AddFrame(frame, packet.transmission_type)) {
533 QUIC_BUG << "Failed to serialize frame: " << frame;
534 return 0;
535 }
536 }
537 for (const QuicFrame& frame : packet.retransmittable_frames) {
538 if (!AddFrame(frame, packet.transmission_type)) {
539 QUIC_BUG << "Failed to serialize frame: " << frame;
540 return 0;
541 }
542 }
543 // Add necessary padding.
544 if (padding_size > 0) {
545 QUIC_DVLOG(2) << ENDPOINT << "Add padding of size: " << padding_size;
546 if (!AddFrame(QuicFrame(QuicPaddingFrame(padding_size)),
547 packet.transmission_type)) {
548 QUIC_BUG << "Failed to add padding of size " << padding_size
549 << " when serializing ENCRYPTION_INITIAL "
550 "packet in coalesced packet";
551 return 0;
552 }
553 }
fayang04590fc2020-08-31 10:37:55 -0700554 const bool success =
555 SerializePacket(QuicOwnedPacketBuffer(buffer, nullptr), buffer_len);
556 if (close_connection_on_serialization_failure_ && !success) {
557 return 0;
558 }
fayang08750832019-10-24 11:25:34 -0700559 const size_t encrypted_length = packet_.encrypted_length;
560 // Clear frames in packet_. No need to DeleteFrames since frames are owned by
561 // initial_packet.
562 packet_.retransmittable_frames.clear();
563 packet_.nonretransmittable_frames.clear();
564 ClearPacket();
565 return encrypted_length;
566}
567
QUICHE teama6ef0a62019-03-07 20:34:33 -0500568void QuicPacketCreator::CreateAndSerializeStreamFrame(
569 QuicStreamId id,
570 size_t write_length,
571 QuicStreamOffset iov_offset,
572 QuicStreamOffset stream_offset,
573 bool fin,
574 TransmissionType transmission_type,
575 size_t* num_bytes_consumed) {
fayang04590fc2020-08-31 10:37:55 -0700576 // TODO(b/167222597): consider using ScopedSerializationFailureHandler.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500577 DCHECK(queued_frames_.empty());
dschinazi1c6e5922020-06-19 10:35:03 -0700578 DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500579 // Write out the packet header
580 QuicPacketHeader header;
581 FillPacketHeader(&header);
fayangfe77c032020-08-24 18:21:32 -0700582 packet_.fate = delegate_->GetSerializedPacketFate(
583 /*is_mtu_discovery=*/false, packet_.encryption_level);
584 QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
585 << ": " << SerializedPacketFateToString(packet_.fate) << " of "
586 << EncryptionLevelToString(packet_.encryption_level);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500587
dschinazi66dea072019-04-09 11:41:06 -0700588 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
wub50d4c712020-05-19 15:48:28 -0700589 QuicOwnedPacketBuffer packet_buffer(delegate_->GetPacketBuffer());
590
wub50d4c712020-05-19 15:48:28 -0700591 if (packet_buffer.buffer == nullptr) {
592 packet_buffer.buffer = stack_buffer;
593 packet_buffer.release_buffer = nullptr;
594 }
595
596 char* encrypted_buffer = packet_buffer.buffer;
597
dschinazi66dea072019-04-09 11:41:06 -0700598 QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500599 size_t length_field_offset = 0;
600 if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
601 QUIC_BUG << "AppendPacketHeader failed";
602 return;
603 }
604
605 // Create a Stream frame with the remaining space.
606 QUIC_BUG_IF(iov_offset == write_length && !fin)
607 << "Creating a stream frame with no data or fin.";
608 const size_t remaining_data_size = write_length - iov_offset;
nharperebabffd2019-06-03 17:34:45 -0700609 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500610 framer_->transport_version(), id, stream_offset,
611 /* last_frame_in_packet= */ true, remaining_data_size);
nharperebabffd2019-06-03 17:34:45 -0700612 size_t available_size =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500613 max_plaintext_size_ - writer.length() - min_frame_size;
nharperebabffd2019-06-03 17:34:45 -0700614 size_t bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
615 size_t plaintext_bytes_written = min_frame_size + bytes_consumed;
616 bool needs_padding = false;
617 if (plaintext_bytes_written < MinPlaintextPacketSize(framer_->version())) {
618 needs_padding = true;
619 // Recalculate sizes with the stream frame not being marked as the last
620 // frame in the packet.
621 min_frame_size = QuicFramer::GetMinStreamFrameSize(
622 framer_->transport_version(), id, stream_offset,
623 /* last_frame_in_packet= */ false, remaining_data_size);
624 available_size = max_plaintext_size_ - writer.length() - min_frame_size;
625 bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
626 plaintext_bytes_written = min_frame_size + bytes_consumed;
627 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500628
629 const bool set_fin = fin && (bytes_consumed == remaining_data_size);
630 QuicStreamFrame frame(id, set_fin, stream_offset, bytes_consumed);
rchc76cd742019-03-26 16:00:03 -0700631 if (debug_delegate_ != nullptr) {
632 debug_delegate_->OnFrameAddedToPacket(QuicFrame(frame));
633 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500634 QUIC_DVLOG(1) << ENDPOINT << "Adding frame: " << frame;
635
dschinazi118934b2019-06-13 18:09:08 -0700636 QUIC_DVLOG(2) << ENDPOINT << "Serializing stream packet " << header << frame;
637
QUICHE teama6ef0a62019-03-07 20:34:33 -0500638 // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized
639 // into one method that takes a QuicStreamFrame, if warranted.
nharperebabffd2019-06-03 17:34:45 -0700640 bool omit_frame_length = !needs_padding;
641 if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500642 QUIC_BUG << "AppendTypeByte failed";
643 return;
644 }
nharperebabffd2019-06-03 17:34:45 -0700645 if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500646 QUIC_BUG << "AppendStreamFrame failed";
647 return;
648 }
nharperebabffd2019-06-03 17:34:45 -0700649 if (needs_padding &&
650 plaintext_bytes_written < MinPlaintextPacketSize(framer_->version()) &&
QUICHE team2252b702019-05-14 23:55:14 -0400651 !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) -
nharper55fa6132019-05-07 19:37:21 -0700652 plaintext_bytes_written)) {
653 QUIC_BUG << "Unable to add padding bytes";
654 return;
655 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500656
657 if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset,
658 packet_.encryption_level)) {
659 return;
660 }
661
fayangcff885a2019-10-22 07:39:04 -0700662 packet_.transmission_type = transmission_type;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500663
dschinazi1c6e5922020-06-19 10:35:03 -0700664 DCHECK(packet_.encryption_level == ENCRYPTION_FORWARD_SECURE ||
665 packet_.encryption_level == ENCRYPTION_ZERO_RTT)
666 << packet_.encryption_level;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500667 size_t encrypted_length = framer_->EncryptInPlace(
668 packet_.encryption_level, packet_.packet_number,
669 GetStartOfEncryptedData(framer_->transport_version(), header),
dschinazi66dea072019-04-09 11:41:06 -0700670 writer.length(), kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500671 if (encrypted_length == 0) {
672 QUIC_BUG << "Failed to encrypt packet number " << header.packet_number;
673 return;
674 }
675 // TODO(ianswett): Optimize the storage so RetransmitableFrames can be
676 // unioned with a QuicStreamFrame and a UniqueStreamBuffer.
677 *num_bytes_consumed = bytes_consumed;
678 packet_size_ = 0;
679 packet_.encrypted_buffer = encrypted_buffer;
680 packet_.encrypted_length = encrypted_length;
wubc9c6d582020-07-20 08:45:40 -0700681
682 packet_buffer.buffer = nullptr;
683 packet_.release_encrypted_buffer = std::move(packet_buffer).release_buffer;
684
QUICHE teama6ef0a62019-03-07 20:34:33 -0500685 packet_.retransmittable_frames.push_back(QuicFrame(frame));
686 OnSerializedPacket();
687}
688
689bool QuicPacketCreator::HasPendingFrames() const {
690 return !queued_frames_.empty();
691}
692
693bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
694 return !packet_.retransmittable_frames.empty();
695}
696
697bool QuicPacketCreator::HasPendingStreamFramesOfStream(QuicStreamId id) const {
698 for (const auto& frame : packet_.retransmittable_frames) {
699 if (frame.type == STREAM_FRAME && frame.stream_frame.stream_id == id) {
700 return true;
701 }
702 }
703 return false;
704}
705
706size_t QuicPacketCreator::ExpansionOnNewFrame() const {
707 // If the last frame in the packet is a message frame, then it will expand to
708 // include the varint message length when a new frame is added.
fayang54a38e32020-06-26 07:01:15 -0700709 if (queued_frames_.empty()) {
710 return 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500711 }
bnce5c11c02020-07-29 08:02:21 -0700712 return ExpansionOnNewFrameWithLastFrame(queued_frames_.back(),
713 framer_->transport_version());
fayang54a38e32020-06-26 07:01:15 -0700714}
715
bnce5c11c02020-07-29 08:02:21 -0700716// static
fayang54a38e32020-06-26 07:01:15 -0700717size_t QuicPacketCreator::ExpansionOnNewFrameWithLastFrame(
bnce5c11c02020-07-29 08:02:21 -0700718 const QuicFrame& last_frame,
719 QuicTransportVersion version) {
fayang54a38e32020-06-26 07:01:15 -0700720 if (last_frame.type == MESSAGE_FRAME) {
721 return QuicDataWriter::GetVarInt62Len(
722 last_frame.message_frame->message_length);
723 }
724 if (last_frame.type != STREAM_FRAME) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500725 return 0;
726 }
bnce5c11c02020-07-29 08:02:21 -0700727 if (VersionHasIetfQuicFrames(version)) {
fayang54a38e32020-06-26 07:01:15 -0700728 return QuicDataWriter::GetVarInt62Len(last_frame.stream_frame.data_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500729 }
730 return kQuicStreamPayloadLengthSize;
731}
732
fayang5a3cfcb2020-08-27 12:57:23 -0700733size_t QuicPacketCreator::BytesFree() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500734 DCHECK_GE(max_plaintext_size_, PacketSize());
735 return max_plaintext_size_ -
736 std::min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
737}
738
fayang5a3cfcb2020-08-27 12:57:23 -0700739size_t QuicPacketCreator::PacketSize() const {
740 return queued_frames_.empty() ? PacketHeaderSize() : packet_size_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500741}
742
QUICHE teama6ef0a62019-03-07 20:34:33 -0500743bool QuicPacketCreator::AddPaddedSavedFrame(
744 const QuicFrame& frame,
745 TransmissionType transmission_type) {
fayang347ab752019-10-22 11:17:43 -0700746 if (AddFrame(frame, transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500747 needs_full_padding_ = true;
748 return true;
749 }
750 return false;
751}
752
fayang04590fc2020-08-31 10:37:55 -0700753bool QuicPacketCreator::SerializePacket(QuicOwnedPacketBuffer encrypted_buffer,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500754 size_t encrypted_buffer_len) {
fayang04590fc2020-08-31 10:37:55 -0700755 if (close_connection_on_serialization_failure_ &&
756 packet_.encrypted_buffer != nullptr) {
757 const std::string error_details =
758 "Packet's encrypted buffer is not empty before serialization";
759 QUIC_BUG << error_details;
760 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
761 error_details);
762 return false;
763 }
764 const bool use_handler =
765 GetQuicReloadableFlag(
766 quic_neuter_initial_packet_in_coalescer_with_initial_key_discarded) ||
767 close_connection_on_serialization_failure_;
768 ScopedSerializationFailureHandler handler(use_handler ? this : nullptr);
fayange447bc62020-08-27 13:47:11 -0700769
QUICHE teama6ef0a62019-03-07 20:34:33 -0500770 DCHECK_LT(0u, encrypted_buffer_len);
771 QUIC_BUG_IF(queued_frames_.empty() && pending_padding_bytes_ == 0)
772 << "Attempt to serialize empty packet";
773 QuicPacketHeader header;
774 // FillPacketHeader increments packet_number_.
775 FillPacketHeader(&header);
fayangfe77c032020-08-24 18:21:32 -0700776 if (delegate_ != nullptr) {
fayang15042962020-07-01 12:14:29 -0700777 packet_.fate = delegate_->GetSerializedPacketFate(
778 /*is_mtu_discovery=*/QuicUtils::ContainsFrameType(queued_frames_,
779 MTU_DISCOVERY_FRAME),
780 packet_.encryption_level);
781 QUIC_DVLOG(1) << ENDPOINT << "fate of packet " << packet_.packet_number
782 << ": " << SerializedPacketFateToString(packet_.fate)
783 << " of "
784 << EncryptionLevelToString(packet_.encryption_level);
785 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500786
787 MaybeAddPadding();
788
dschinazi118934b2019-06-13 18:09:08 -0700789 QUIC_DVLOG(2) << ENDPOINT << "Serializing packet " << header
wub031d47c2019-11-21 08:04:07 -0800790 << QuicFramesToString(queued_frames_) << " at encryption_level "
renjietangb4ebb1d2020-05-27 18:15:51 -0700791 << packet_.encryption_level;
dschinazi118934b2019-06-13 18:09:08 -0700792
dschinazida9fafd2020-03-16 15:32:55 -0700793 if (!framer_->HasEncrypterOfEncryptionLevel(packet_.encryption_level)) {
794 QUIC_BUG << ENDPOINT << "Attempting to serialize " << header
795 << QuicFramesToString(queued_frames_)
renjietangb4ebb1d2020-05-27 18:15:51 -0700796 << " at missing encryption_level " << packet_.encryption_level
797 << " using " << framer_->version();
fayang04590fc2020-08-31 10:37:55 -0700798 return false;
dschinazida9fafd2020-03-16 15:32:55 -0700799 }
800
QUICHE teama6ef0a62019-03-07 20:34:33 -0500801 DCHECK_GE(max_plaintext_size_, packet_size_);
802 // Use the packet_size_ instead of the buffer size to ensure smaller
803 // packet sizes are properly used.
804 size_t length =
wub50d4c712020-05-19 15:48:28 -0700805 framer_->BuildDataPacket(header, queued_frames_, encrypted_buffer.buffer,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500806 packet_size_, packet_.encryption_level);
807 if (length == 0) {
fayang36143d92020-05-15 10:19:57 -0700808 QUIC_BUG << "Failed to serialize " << QuicFramesToString(queued_frames_)
renjietangb4ebb1d2020-05-27 18:15:51 -0700809 << " at encryption_level: " << packet_.encryption_level
fayang36143d92020-05-15 10:19:57 -0700810 << ", needs_full_padding_: " << needs_full_padding_
fayangb931ac62020-06-02 11:23:06 -0700811 << ", pending_padding_bytes_: " << pending_padding_bytes_
812 << ", latched_hard_max_packet_length_: "
813 << latched_hard_max_packet_length_
814 << ", max_packet_length_: " << max_packet_length_
815 << ", header: " << header;
fayang04590fc2020-08-31 10:37:55 -0700816 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500817 }
818
819 // ACK Frames will be truncated due to length only if they're the only frame
820 // in the packet, and if packet_size_ was set to max_plaintext_size_. If
821 // truncation due to length occurred, then GetSerializedFrameLength will have
822 // returned all bytes free.
823 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
824 queued_frames_.size() == 1 &&
825 queued_frames_.back().type == ACK_FRAME;
826 // Because of possible truncation, we can't be confident that our
827 // packet size calculation worked correctly.
828 if (!possibly_truncated_by_length) {
829 DCHECK_EQ(packet_size_, length);
830 }
831 const size_t encrypted_length = framer_->EncryptInPlace(
832 packet_.encryption_level, packet_.packet_number,
833 GetStartOfEncryptedData(framer_->transport_version(), header), length,
wub50d4c712020-05-19 15:48:28 -0700834 encrypted_buffer_len, encrypted_buffer.buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500835 if (encrypted_length == 0) {
836 QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number;
fayang04590fc2020-08-31 10:37:55 -0700837 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500838 }
839
840 packet_size_ = 0;
fayang04590fc2020-08-31 10:37:55 -0700841 if (!use_handler) {
fayange447bc62020-08-27 13:47:11 -0700842 queued_frames_.clear();
843 }
wub50d4c712020-05-19 15:48:28 -0700844 packet_.encrypted_buffer = encrypted_buffer.buffer;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500845 packet_.encrypted_length = encrypted_length;
wubc9c6d582020-07-20 08:45:40 -0700846
847 encrypted_buffer.buffer = nullptr;
848 packet_.release_encrypted_buffer = std::move(encrypted_buffer).release_buffer;
fayang04590fc2020-08-31 10:37:55 -0700849 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500850}
851
852std::unique_ptr<QuicEncryptedPacket>
853QuicPacketCreator::SerializeVersionNegotiationPacket(
854 bool ietf_quic,
dschinazi48ac9192019-07-31 00:07:26 -0700855 bool use_length_prefix,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500856 const ParsedQuicVersionVector& supported_versions) {
857 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
858 std::unique_ptr<QuicEncryptedPacket> encrypted =
dschinazi48ac9192019-07-31 00:07:26 -0700859 QuicFramer::BuildVersionNegotiationPacket(
860 server_connection_id_, client_connection_id_, ietf_quic,
861 use_length_prefix, supported_versions);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500862 DCHECK(encrypted);
863 DCHECK_GE(max_packet_length_, encrypted->length());
864 return encrypted;
865}
866
wub8a5dafa2020-05-13 12:30:17 -0700867std::unique_ptr<SerializedPacket>
QUICHE teama6ef0a62019-03-07 20:34:33 -0500868QuicPacketCreator::SerializeConnectivityProbingPacket() {
fkastenholz305e1732019-06-18 05:01:22 -0700869 QUIC_BUG_IF(VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500870 << "Must not be version 99 to serialize padded ping connectivity probe";
fayang2ab1e852019-11-04 11:24:36 -0800871 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500872 QuicPacketHeader header;
873 // FillPacketHeader increments packet_number_.
874 FillPacketHeader(&header);
875
dschinazi118934b2019-06-13 18:09:08 -0700876 QUIC_DVLOG(2) << ENDPOINT << "Serializing connectivity probing packet "
877 << header;
878
dschinazi66dea072019-04-09 11:41:06 -0700879 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700880 size_t length = BuildConnectivityProbingPacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500881 header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
882 DCHECK(length);
883
dschinazi1c6e5922020-06-19 10:35:03 -0700884 DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500885 const size_t encrypted_length = framer_->EncryptInPlace(
886 packet_.encryption_level, packet_.packet_number,
887 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700888 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500889 DCHECK(encrypted_length);
890
wub8a5dafa2020-05-13 12:30:17 -0700891 std::unique_ptr<SerializedPacket> serialize_packet(new SerializedPacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500892 header.packet_number, header.packet_number_length, buffer.release(),
893 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
894
wub8a5dafa2020-05-13 12:30:17 -0700895 serialize_packet->release_encrypted_buffer = [](const char* p) {
896 delete[] p;
897 };
QUICHE teama6ef0a62019-03-07 20:34:33 -0500898 serialize_packet->encryption_level = packet_.encryption_level;
899 serialize_packet->transmission_type = NOT_RETRANSMISSION;
900
901 return serialize_packet;
902}
903
wub8a5dafa2020-05-13 12:30:17 -0700904std::unique_ptr<SerializedPacket>
QUICHE teama6ef0a62019-03-07 20:34:33 -0500905QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
906 QuicPathFrameBuffer* payload) {
fkastenholz305e1732019-06-18 05:01:22 -0700907 QUIC_BUG_IF(!VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500908 << "Must be version 99 to serialize path challenge connectivity probe, "
909 "is version "
910 << framer_->transport_version();
fayang2ab1e852019-11-04 11:24:36 -0800911 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500912 QuicPacketHeader header;
913 // FillPacketHeader increments packet_number_.
914 FillPacketHeader(&header);
915
dschinazi118934b2019-06-13 18:09:08 -0700916 QUIC_DVLOG(2) << ENDPOINT << "Serializing path challenge packet " << header;
917
dschinazi66dea072019-04-09 11:41:06 -0700918 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700919 size_t length = BuildPaddedPathChallengePacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500920 header, buffer.get(), max_plaintext_size_, payload, random_,
921 packet_.encryption_level);
922 DCHECK(length);
923
dschinazi1c6e5922020-06-19 10:35:03 -0700924 DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500925 const size_t encrypted_length = framer_->EncryptInPlace(
926 packet_.encryption_level, packet_.packet_number,
927 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700928 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500929 DCHECK(encrypted_length);
930
wub8a5dafa2020-05-13 12:30:17 -0700931 std::unique_ptr<SerializedPacket> serialize_packet(
932 new SerializedPacket(header.packet_number, header.packet_number_length,
933 buffer.release(), encrypted_length,
934 /*has_ack=*/false, /*has_stop_waiting=*/false));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500935
wub8a5dafa2020-05-13 12:30:17 -0700936 serialize_packet->release_encrypted_buffer = [](const char* p) {
937 delete[] p;
938 };
QUICHE teama6ef0a62019-03-07 20:34:33 -0500939 serialize_packet->encryption_level = packet_.encryption_level;
940 serialize_packet->transmission_type = NOT_RETRANSMISSION;
941
942 return serialize_packet;
943}
944
wub8a5dafa2020-05-13 12:30:17 -0700945std::unique_ptr<SerializedPacket>
QUICHE teama6ef0a62019-03-07 20:34:33 -0500946QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
wuba750aab2020-02-10 06:43:15 -0800947 const QuicCircularDeque<QuicPathFrameBuffer>& payloads,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500948 const bool is_padded) {
fkastenholz305e1732019-06-18 05:01:22 -0700949 QUIC_BUG_IF(!VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500950 << "Must be version 99 to serialize path response connectivity probe, is "
951 "version "
952 << framer_->transport_version();
fayang2ab1e852019-11-04 11:24:36 -0800953 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500954 QuicPacketHeader header;
955 // FillPacketHeader increments packet_number_.
956 FillPacketHeader(&header);
957
dschinazi118934b2019-06-13 18:09:08 -0700958 QUIC_DVLOG(2) << ENDPOINT << "Serializing path response packet " << header;
959
dschinazi66dea072019-04-09 11:41:06 -0700960 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700961 size_t length =
962 BuildPathResponsePacket(header, buffer.get(), max_plaintext_size_,
963 payloads, is_padded, packet_.encryption_level);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500964 DCHECK(length);
965
dschinazi1c6e5922020-06-19 10:35:03 -0700966 DCHECK_EQ(packet_.encryption_level, ENCRYPTION_FORWARD_SECURE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500967 const size_t encrypted_length = framer_->EncryptInPlace(
968 packet_.encryption_level, packet_.packet_number,
969 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700970 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500971 DCHECK(encrypted_length);
972
wub8a5dafa2020-05-13 12:30:17 -0700973 std::unique_ptr<SerializedPacket> serialize_packet(
974 new SerializedPacket(header.packet_number, header.packet_number_length,
975 buffer.release(), encrypted_length,
976 /*has_ack=*/false, /*has_stop_waiting=*/false));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500977
wub8a5dafa2020-05-13 12:30:17 -0700978 serialize_packet->release_encrypted_buffer = [](const char* p) {
979 delete[] p;
980 };
QUICHE teama6ef0a62019-03-07 20:34:33 -0500981 serialize_packet->encryption_level = packet_.encryption_level;
982 serialize_packet->transmission_type = NOT_RETRANSMISSION;
983
984 return serialize_packet;
985}
986
renjietang4c704c82019-10-07 16:39:11 -0700987size_t QuicPacketCreator::BuildPaddedPathChallengePacket(
988 const QuicPacketHeader& header,
989 char* buffer,
990 size_t packet_length,
991 QuicPathFrameBuffer* payload,
992 QuicRandom* randomizer,
993 EncryptionLevel level) {
994 DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()));
995 QuicFrames frames;
996
997 // Write a PATH_CHALLENGE frame, which has a random 8-byte payload
998 randomizer->RandBytes(payload->data(), payload->size());
999 QuicPathChallengeFrame path_challenge_frame(0, *payload);
1000 frames.push_back(QuicFrame(&path_challenge_frame));
1001
1002 if (debug_delegate_ != nullptr) {
1003 debug_delegate_->OnFrameAddedToPacket(QuicFrame(&path_challenge_frame));
1004 }
1005
1006 // Add padding to the rest of the packet in order to assess Path MTU
1007 // characteristics.
1008 QuicPaddingFrame padding_frame;
1009 frames.push_back(QuicFrame(padding_frame));
1010
1011 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
1012}
1013
1014size_t QuicPacketCreator::BuildPathResponsePacket(
1015 const QuicPacketHeader& header,
1016 char* buffer,
1017 size_t packet_length,
wuba750aab2020-02-10 06:43:15 -08001018 const QuicCircularDeque<QuicPathFrameBuffer>& payloads,
renjietang4c704c82019-10-07 16:39:11 -07001019 const bool is_padded,
1020 EncryptionLevel level) {
1021 if (payloads.empty()) {
1022 QUIC_BUG
1023 << "Attempt to generate connectivity response with no request payloads";
1024 return 0;
1025 }
1026 DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()));
1027
1028 std::vector<std::unique_ptr<QuicPathResponseFrame>> path_response_frames;
1029 for (const QuicPathFrameBuffer& payload : payloads) {
1030 // Note that the control frame ID can be 0 since this is not retransmitted.
1031 path_response_frames.push_back(
1032 std::make_unique<QuicPathResponseFrame>(0, payload));
1033 }
1034
1035 QuicFrames frames;
1036 for (const std::unique_ptr<QuicPathResponseFrame>& path_response_frame :
1037 path_response_frames) {
1038 frames.push_back(QuicFrame(path_response_frame.get()));
1039 if (debug_delegate_ != nullptr) {
1040 debug_delegate_->OnFrameAddedToPacket(
1041 QuicFrame(path_response_frame.get()));
1042 }
1043 }
1044
1045 if (is_padded) {
1046 // Add padding to the rest of the packet in order to assess Path MTU
1047 // characteristics.
1048 QuicPaddingFrame padding_frame;
1049 frames.push_back(QuicFrame(padding_frame));
1050 }
1051
1052 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
1053}
1054
1055size_t QuicPacketCreator::BuildConnectivityProbingPacket(
1056 const QuicPacketHeader& header,
1057 char* buffer,
1058 size_t packet_length,
1059 EncryptionLevel level) {
1060 QuicFrames frames;
1061
1062 // Write a PING frame, which has no data payload.
1063 QuicPingFrame ping_frame;
1064 frames.push_back(QuicFrame(ping_frame));
1065
1066 // Add padding to the rest of the packet.
1067 QuicPaddingFrame padding_frame;
1068 frames.push_back(QuicFrame(padding_frame));
1069
1070 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
1071}
1072
fayang08750832019-10-24 11:25:34 -07001073size_t QuicPacketCreator::SerializeCoalescedPacket(
1074 const QuicCoalescedPacket& coalesced,
1075 char* buffer,
1076 size_t buffer_len) {
fayang08750832019-10-24 11:25:34 -07001077 if (HasPendingFrames()) {
1078 QUIC_BUG << "Try to serialize coalesced packet with pending frames";
1079 return 0;
1080 }
fayang58f71072019-11-05 08:47:02 -08001081 RemoveSoftMaxPacketLength();
fayang08750832019-10-24 11:25:34 -07001082 QUIC_BUG_IF(coalesced.length() == 0)
1083 << "Attempt to serialize empty coalesced packet";
1084 size_t packet_length = 0;
1085 if (coalesced.initial_packet() != nullptr) {
fayang9abdfec2020-02-13 12:34:58 -08001086 // Padding coalesced packet containing initial packet to full.
1087 size_t padding_size = coalesced.max_packet_length() - coalesced.length();
1088 if (framer_->perspective() == Perspective::IS_SERVER &&
1089 QuicUtils::ContainsFrameType(
1090 coalesced.initial_packet()->retransmittable_frames,
1091 CONNECTION_CLOSE_FRAME)) {
1092 // Do not pad server initial connection close packet.
1093 padding_size = 0;
1094 }
fayang08750832019-10-24 11:25:34 -07001095 size_t initial_length = ReserializeInitialPacketInCoalescedPacket(
fayang9abdfec2020-02-13 12:34:58 -08001096 *coalesced.initial_packet(), padding_size, buffer, buffer_len);
fayang08750832019-10-24 11:25:34 -07001097 if (initial_length == 0) {
1098 QUIC_BUG << "Failed to reserialize ENCRYPTION_INITIAL packet in "
1099 "coalesced packet";
1100 return 0;
1101 }
1102 buffer += initial_length;
1103 buffer_len -= initial_length;
1104 packet_length += initial_length;
1105 }
1106 size_t length_copied = 0;
1107 if (!coalesced.CopyEncryptedBuffers(buffer, buffer_len, &length_copied)) {
1108 return 0;
1109 }
1110 packet_length += length_copied;
1111 QUIC_DVLOG(1) << ENDPOINT
1112 << "Successfully serialized coalesced packet of length: "
1113 << packet_length;
1114 return packet_length;
1115}
1116
QUICHE teama6ef0a62019-03-07 20:34:33 -05001117// TODO(b/74062209): Make this a public method of framer?
1118SerializedPacket QuicPacketCreator::NoPacket() {
1119 return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
1120 nullptr, 0, false, false);
1121}
1122
QUICHE team2252b702019-05-14 23:55:14 -04001123QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -04001124 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi346b7ce2019-06-05 01:38:18 -07001125 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001126 }
dschinazi7b9278c2019-05-20 07:36:21 -07001127 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001128}
1129
1130QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -04001131 if (framer_->perspective() == Perspective::IS_CLIENT) {
dschinazi346b7ce2019-06-05 01:38:18 -07001132 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001133 }
dschinazi7b9278c2019-05-20 07:36:21 -07001134 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -04001135}
1136
QUICHE teama6ef0a62019-03-07 20:34:33 -05001137QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
1138 const {
dschinazi5e1a7b22019-07-31 12:23:21 -07001139 // In versions that do not support client connection IDs, the destination
1140 // connection ID is only sent from client to server.
1141 return (framer_->perspective() == Perspective::IS_CLIENT ||
1142 framer_->version().SupportsClientConnectionIds())
1143 ? CONNECTION_ID_PRESENT
1144 : CONNECTION_ID_ABSENT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001145}
1146
1147QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
1148 const {
1149 // Long header packets sent by server include source connection ID.
dschinazi346b7ce2019-06-05 01:38:18 -07001150 // Ones sent by the client only include source connection ID if the version
1151 // supports client connection IDs.
1152 if (HasIetfLongHeader() &&
1153 (framer_->perspective() == Perspective::IS_SERVER ||
1154 framer_->version().SupportsClientConnectionIds())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001155 return CONNECTION_ID_PRESENT;
1156 }
dschinazi5e1a7b22019-07-31 12:23:21 -07001157 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi7b9278c2019-05-20 07:36:21 -07001158 return server_connection_id_included_;
QUICHE team2252b702019-05-14 23:55:14 -04001159 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001160 return CONNECTION_ID_ABSENT;
1161}
1162
1163QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
1164 const {
dschinazi7b9278c2019-05-20 07:36:21 -07001165 DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001166 transport_version()));
1167 return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -04001168 ? static_cast<QuicConnectionIdLength>(
1169 GetDestinationConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001170 : PACKET_0BYTE_CONNECTION_ID;
1171}
1172
1173QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
dschinazi7b9278c2019-05-20 07:36:21 -07001174 DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001175 transport_version()));
1176 return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -04001177 ? static_cast<QuicConnectionIdLength>(
1178 GetSourceConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001179 : PACKET_0BYTE_CONNECTION_ID;
1180}
1181
1182QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
fayang3ac15c12019-06-14 14:04:51 -07001183 if (HasIetfLongHeader() &&
1184 !framer_->version().SendsVariableLengthPacketNumberInLongHeader()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001185 return PACKET_4BYTE_PACKET_NUMBER;
1186 }
1187 return packet_.packet_number_length;
1188}
1189
nharper55fa6132019-05-07 19:37:21 -07001190size_t QuicPacketCreator::PacketHeaderSize() const {
1191 return GetPacketHeaderSize(
1192 framer_->transport_version(), GetDestinationConnectionIdLength(),
1193 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
1194 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
1195 GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
1196}
1197
QUICHE teama6ef0a62019-03-07 20:34:33 -05001198QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
1199 const {
1200 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1201 HasIetfLongHeader() &&
1202 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
1203 return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
1204 }
1205 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
1206}
1207
dmcardlecf0bfcf2019-12-13 08:08:21 -08001208quiche::QuicheStringPiece QuicPacketCreator::GetRetryToken() const {
dschinazi0db87092019-05-20 07:59:15 -07001209 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1210 HasIetfLongHeader() &&
1211 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
1212 return retry_token_;
1213 }
dmcardlecf0bfcf2019-12-13 08:08:21 -08001214 return quiche::QuicheStringPiece();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001215}
1216
dmcardlecf0bfcf2019-12-13 08:08:21 -08001217void QuicPacketCreator::SetRetryToken(quiche::QuicheStringPiece retry_token) {
vasilvvc48c8712019-03-11 13:38:16 -07001218 retry_token_ = std::string(retry_token);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001219}
1220
fayang18be79a2019-09-16 15:17:12 -07001221bool QuicPacketCreator::ConsumeRetransmittableControlFrame(
1222 const QuicFrame& frame) {
fayang18be79a2019-09-16 15:17:12 -07001223 QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame))
1224 << "Adding a control frame with no control frame id: " << frame;
1225 DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame;
1226 MaybeBundleAckOpportunistically();
1227 if (HasPendingFrames()) {
renjietangb63005e2019-11-19 23:08:53 -08001228 if (AddFrame(frame, next_transmission_type_)) {
fayang18be79a2019-09-16 15:17:12 -07001229 // There is pending frames and current frame fits.
1230 return true;
1231 }
1232 }
1233 DCHECK(!HasPendingFrames());
1234 if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME &&
1235 !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
1236 NOT_HANDSHAKE)) {
1237 // Do not check congestion window for ping or connection close frames.
1238 return false;
1239 }
renjietangb63005e2019-11-19 23:08:53 -08001240 const bool success = AddFrame(frame, next_transmission_type_);
ianswettbd78ea12019-09-26 06:32:37 -07001241 QUIC_BUG_IF(!success) << "Failed to add frame:" << frame
1242 << " transmission_type:" << next_transmission_type_;
fayang18be79a2019-09-16 15:17:12 -07001243 return success;
1244}
1245
1246QuicConsumedData QuicPacketCreator::ConsumeData(QuicStreamId id,
1247 size_t write_length,
1248 QuicStreamOffset offset,
1249 StreamSendingState state) {
fayang18be79a2019-09-16 15:17:12 -07001250 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1251 "generator tries to write stream data.";
1252 bool has_handshake = QuicUtils::IsCryptoStreamId(transport_version(), id);
1253 MaybeBundleAckOpportunistically();
1254 bool fin = state != NO_FIN;
1255 QUIC_BUG_IF(has_handshake && fin)
1256 << "Handshake packets should never send a fin";
1257 // To make reasoning about crypto frames easier, we don't combine them with
1258 // other retransmittable frames in a single packet.
1259 if (has_handshake && HasPendingRetransmittableFrames()) {
1260 FlushCurrentPacket();
1261 }
1262
1263 size_t total_bytes_consumed = 0;
1264 bool fin_consumed = false;
1265
1266 if (!HasRoomForStreamFrame(id, offset, write_length)) {
1267 FlushCurrentPacket();
1268 }
1269
1270 if (!fin && (write_length == 0)) {
1271 QUIC_BUG << "Attempt to consume empty data without FIN.";
1272 return QuicConsumedData(0, false);
1273 }
1274 // We determine if we can enter the fast path before executing
1275 // the slow path loop.
1276 bool run_fast_path =
1277 !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
fayang2ab1e852019-11-04 11:24:36 -08001278 write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
1279 latched_hard_max_packet_length_ == 0;
fayang18be79a2019-09-16 15:17:12 -07001280
ianswett517beaa2020-05-26 06:05:32 -07001281 while (!run_fast_path &&
1282 (has_handshake || delegate_->ShouldGeneratePacket(
1283 HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE))) {
fayang18be79a2019-09-16 15:17:12 -07001284 QuicFrame frame;
1285 bool needs_full_padding =
1286 has_handshake && fully_pad_crypto_handshake_packets_;
1287
1288 if (!ConsumeDataToFillCurrentPacket(id, write_length - total_bytes_consumed,
1289 offset + total_bytes_consumed, fin,
1290 needs_full_padding,
1291 next_transmission_type_, &frame)) {
1292 // The creator is always flushed if there's not enough room for a new
1293 // stream frame before ConsumeData, so ConsumeData should always succeed.
1294 QUIC_BUG << "Failed to ConsumeData, stream:" << id;
1295 return QuicConsumedData(0, false);
1296 }
1297
1298 // A stream frame is created and added.
1299 size_t bytes_consumed = frame.stream_frame.data_length;
1300 total_bytes_consumed += bytes_consumed;
1301 fin_consumed = fin && total_bytes_consumed == write_length;
1302 if (fin_consumed && state == FIN_AND_PADDING) {
1303 AddRandomPadding();
1304 }
1305 DCHECK(total_bytes_consumed == write_length ||
1306 (bytes_consumed > 0 && HasPendingFrames()));
1307
1308 if (total_bytes_consumed == write_length) {
1309 // We're done writing the data. Exit the loop.
1310 // We don't make this a precondition because we could have 0 bytes of data
1311 // if we're simply writing a fin.
1312 break;
1313 }
1314 FlushCurrentPacket();
1315
1316 run_fast_path =
1317 !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
fayang2ab1e852019-11-04 11:24:36 -08001318 write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
1319 latched_hard_max_packet_length_ == 0;
fayang18be79a2019-09-16 15:17:12 -07001320 }
1321
1322 if (run_fast_path) {
1323 return ConsumeDataFastPath(id, write_length, offset, state != NO_FIN,
1324 total_bytes_consumed);
1325 }
1326
1327 // Don't allow the handshake to be bundled with other retransmittable frames.
1328 if (has_handshake) {
1329 FlushCurrentPacket();
1330 }
1331
1332 return QuicConsumedData(total_bytes_consumed, fin_consumed);
1333}
1334
1335QuicConsumedData QuicPacketCreator::ConsumeDataFastPath(
1336 QuicStreamId id,
1337 size_t write_length,
1338 QuicStreamOffset offset,
1339 bool fin,
1340 size_t total_bytes_consumed) {
fayang18be79a2019-09-16 15:17:12 -07001341 DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
fayanga504d5c2020-09-14 08:26:48 -07001342 if (AttemptingToSendUnencryptedStreamData()) {
1343 return QuicConsumedData(total_bytes_consumed,
1344 fin && (total_bytes_consumed == write_length));
fayang9320ca72020-08-03 13:02:59 -07001345 }
fayang18be79a2019-09-16 15:17:12 -07001346
1347 while (total_bytes_consumed < write_length &&
1348 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
1349 NOT_HANDSHAKE)) {
1350 // Serialize and encrypt the packet.
1351 size_t bytes_consumed = 0;
1352 CreateAndSerializeStreamFrame(id, write_length, total_bytes_consumed,
1353 offset + total_bytes_consumed, fin,
1354 next_transmission_type_, &bytes_consumed);
fayangaf2cdfd2020-01-06 10:52:12 -08001355 if (bytes_consumed == 0) {
1356 const std::string error_details =
1357 "Failed in CreateAndSerializeStreamFrame.";
1358 QUIC_BUG << error_details;
1359 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
1360 error_details);
1361 break;
fayangd99c2c12019-11-08 13:22:51 -08001362 }
fayang18be79a2019-09-16 15:17:12 -07001363 total_bytes_consumed += bytes_consumed;
1364 }
1365
1366 return QuicConsumedData(total_bytes_consumed,
1367 fin && (total_bytes_consumed == write_length));
1368}
1369
1370size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
1371 size_t write_length,
1372 QuicStreamOffset offset) {
dschinazi6458eb32020-06-23 12:38:41 -07001373 QUIC_DVLOG(2) << "ConsumeCryptoData " << level << " write_length "
1374 << write_length << " offset " << offset;
fayang18be79a2019-09-16 15:17:12 -07001375 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1376 "generator tries to write crypto data.";
1377 MaybeBundleAckOpportunistically();
1378 // To make reasoning about crypto frames easier, we don't combine them with
1379 // other retransmittable frames in a single packet.
1380 // TODO(nharper): Once we have separate packet number spaces, everything
1381 // should be driven by encryption level, and we should stop flushing in this
1382 // spot.
1383 if (HasPendingRetransmittableFrames()) {
1384 FlushCurrentPacket();
1385 }
1386
1387 size_t total_bytes_consumed = 0;
1388
fayangd6c5bd02020-06-29 07:25:34 -07001389 while (
1390 total_bytes_consumed < write_length &&
1391 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, IS_HANDSHAKE)) {
fayang18be79a2019-09-16 15:17:12 -07001392 QuicFrame frame;
1393 if (!ConsumeCryptoDataToFillCurrentPacket(
1394 level, write_length - total_bytes_consumed,
1395 offset + total_bytes_consumed, fully_pad_crypto_handshake_packets_,
1396 next_transmission_type_, &frame)) {
1397 // The only pending data in the packet is non-retransmittable frames. I'm
1398 // assuming here that they won't occupy so much of the packet that a
1399 // CRYPTO frame won't fit.
renjietangb4ebb1d2020-05-27 18:15:51 -07001400 QUIC_BUG << "Failed to ConsumeCryptoData at level " << level;
fayang18be79a2019-09-16 15:17:12 -07001401 return 0;
1402 }
1403 total_bytes_consumed += frame.crypto_frame->data_length;
1404 FlushCurrentPacket();
1405 }
1406
1407 // Don't allow the handshake to be bundled with other retransmittable frames.
1408 FlushCurrentPacket();
1409
1410 return total_bytes_consumed;
1411}
1412
1413void QuicPacketCreator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
fayang18be79a2019-09-16 15:17:12 -07001414 // MTU discovery frames must be sent by themselves.
1415 if (!CanSetMaxPacketLength()) {
1416 QUIC_BUG << "MTU discovery packets should only be sent when no other "
1417 << "frames needs to be sent.";
1418 return;
1419 }
1420 const QuicByteCount current_mtu = max_packet_length();
1421
1422 // The MTU discovery frame is allocated on the stack, since it is going to be
1423 // serialized within this function.
1424 QuicMtuDiscoveryFrame mtu_discovery_frame;
1425 QuicFrame frame(mtu_discovery_frame);
1426
1427 // Send the probe packet with the new length.
1428 SetMaxPacketLength(target_mtu);
1429 const bool success = AddPaddedSavedFrame(frame, next_transmission_type_);
1430 FlushCurrentPacket();
1431 // The only reason AddFrame can fail is that the packet is too full to fit in
1432 // a ping. This is not possible for any sane MTU.
ianswettbd78ea12019-09-26 06:32:37 -07001433 QUIC_BUG_IF(!success) << "Failed to send path MTU target_mtu:" << target_mtu
1434 << " transmission_type:" << next_transmission_type_;
fayang18be79a2019-09-16 15:17:12 -07001435
1436 // Reset the packet length back.
1437 SetMaxPacketLength(current_mtu);
1438}
1439
1440void QuicPacketCreator::MaybeBundleAckOpportunistically() {
fayang18be79a2019-09-16 15:17:12 -07001441 if (has_ack()) {
1442 // Ack already queued, nothing to do.
1443 return;
1444 }
1445 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
1446 NOT_HANDSHAKE)) {
1447 return;
1448 }
1449 const bool flushed =
1450 FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
ianswettbd78ea12019-09-26 06:32:37 -07001451 QUIC_BUG_IF(!flushed) << "Failed to flush ACK frame. encryption_level:"
1452 << packet_.encryption_level;
fayang18be79a2019-09-16 15:17:12 -07001453}
1454
1455bool QuicPacketCreator::FlushAckFrame(const QuicFrames& frames) {
fayang18be79a2019-09-16 15:17:12 -07001456 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1457 "generator tries to send ACK frame.";
1458 for (const auto& frame : frames) {
1459 DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME);
1460 if (HasPendingFrames()) {
renjietangb63005e2019-11-19 23:08:53 -08001461 if (AddFrame(frame, next_transmission_type_)) {
fayang18be79a2019-09-16 15:17:12 -07001462 // There is pending frames and current frame fits.
1463 continue;
1464 }
1465 }
1466 DCHECK(!HasPendingFrames());
1467 // There is no pending frames, consult the delegate whether a packet can be
1468 // generated.
1469 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
1470 NOT_HANDSHAKE)) {
1471 return false;
1472 }
renjietangb63005e2019-11-19 23:08:53 -08001473 const bool success = AddFrame(frame, next_transmission_type_);
fayang18be79a2019-09-16 15:17:12 -07001474 QUIC_BUG_IF(!success) << "Failed to flush " << frame;
1475 }
1476 return true;
1477}
1478
1479void QuicPacketCreator::AddRandomPadding() {
fayang18be79a2019-09-16 15:17:12 -07001480 AddPendingPadding(random_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
1481}
1482
1483void QuicPacketCreator::AttachPacketFlusher() {
fayang18be79a2019-09-16 15:17:12 -07001484 flusher_attached_ = true;
1485 if (!write_start_packet_number_.IsInitialized()) {
1486 write_start_packet_number_ = NextSendingPacketNumber();
1487 }
1488}
1489
1490void QuicPacketCreator::Flush() {
fayang18be79a2019-09-16 15:17:12 -07001491 FlushCurrentPacket();
1492 SendRemainingPendingPadding();
1493 flusher_attached_ = false;
1494 if (GetQuicFlag(FLAGS_quic_export_server_num_packets_per_write_histogram)) {
1495 if (!write_start_packet_number_.IsInitialized()) {
1496 QUIC_BUG << "write_start_packet_number is not initialized";
1497 return;
1498 }
1499 QUIC_SERVER_HISTOGRAM_COUNTS(
1500 "quic_server_num_written_packets_per_write",
1501 NextSendingPacketNumber() - write_start_packet_number_, 1, 200, 50,
1502 "Number of QUIC packets written per write operation");
1503 }
1504 write_start_packet_number_.Clear();
1505}
1506
1507void QuicPacketCreator::SendRemainingPendingPadding() {
fayang18be79a2019-09-16 15:17:12 -07001508 while (
1509 pending_padding_bytes() > 0 && !HasPendingFrames() &&
1510 delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) {
1511 FlushCurrentPacket();
1512 }
1513}
1514
1515void QuicPacketCreator::SetServerConnectionIdLength(uint32_t length) {
fayang18be79a2019-09-16 15:17:12 -07001516 if (length == 0) {
1517 SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
1518 } else {
1519 SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
1520 }
1521}
1522
1523void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
fayangcff885a2019-10-22 07:39:04 -07001524 next_transmission_type_ = type;
fayang18be79a2019-09-16 15:17:12 -07001525}
1526
1527MessageStatus QuicPacketCreator::AddMessageFrame(QuicMessageId message_id,
1528 QuicMemSliceSpan message) {
fayang18be79a2019-09-16 15:17:12 -07001529 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1530 "generator tries to add message frame.";
1531 MaybeBundleAckOpportunistically();
1532 const QuicByteCount message_length = message.total_length();
1533 if (message_length > GetCurrentLargestMessagePayload()) {
1534 return MESSAGE_STATUS_TOO_LARGE;
1535 }
1536 if (!HasRoomForMessageFrame(message_length)) {
1537 FlushCurrentPacket();
1538 }
1539 QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
renjietangb63005e2019-11-19 23:08:53 -08001540 const bool success = AddFrame(QuicFrame(frame), next_transmission_type_);
fayang18be79a2019-09-16 15:17:12 -07001541 if (!success) {
1542 QUIC_BUG << "Failed to send message " << message_id;
1543 delete frame;
1544 return MESSAGE_STATUS_INTERNAL_ERROR;
1545 }
1546 return MESSAGE_STATUS_SUCCESS;
1547}
1548
QUICHE teama6ef0a62019-03-07 20:34:33 -05001549QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
1550 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1551 HasIetfLongHeader()) {
1552 QuicLongHeaderType long_header_type =
1553 EncryptionlevelToLongHeaderType(packet_.encryption_level);
1554 if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
1555 long_header_type == HANDSHAKE) {
1556 return VARIABLE_LENGTH_INTEGER_LENGTH_2;
1557 }
1558 }
1559 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
1560}
1561
1562void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
QUICHE team2252b702019-05-14 23:55:14 -04001563 header->destination_connection_id = GetDestinationConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001564 header->destination_connection_id_included =
1565 GetDestinationConnectionIdIncluded();
QUICHE team2252b702019-05-14 23:55:14 -04001566 header->source_connection_id = GetSourceConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001567 header->source_connection_id_included = GetSourceConnectionIdIncluded();
1568 header->reset_flag = false;
1569 header->version_flag = IncludeVersionInHeader();
1570 if (IncludeNonceInPublicHeader()) {
1571 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
1572 header->nonce = &diversification_nonce_;
1573 } else {
1574 header->nonce = nullptr;
1575 }
fayang354c9422019-05-21 08:10:35 -07001576 packet_.packet_number = NextSendingPacketNumber();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001577 header->packet_number = packet_.packet_number;
1578 header->packet_number_length = GetPacketNumberLength();
1579 header->retry_token_length_length = GetRetryTokenLengthLength();
1580 header->retry_token = GetRetryToken();
1581 header->length_length = GetLengthLength();
1582 header->remaining_packet_length = 0;
1583 if (!HasIetfLongHeader()) {
1584 return;
1585 }
1586 header->long_packet_type =
1587 EncryptionlevelToLongHeaderType(packet_.encryption_level);
1588}
1589
fayangfce2f722020-06-26 10:27:32 -07001590size_t QuicPacketCreator::GetSerializedFrameLength(const QuicFrame& frame) {
1591 size_t serialized_frame_length = framer_->GetSerializedFrameLength(
1592 frame, BytesFree(), queued_frames_.empty(),
1593 /* last_frame_in_packet= */ true, GetPacketNumberLength());
fayangfce2f722020-06-26 10:27:32 -07001594 if (!framer_->version().HasHeaderProtection() ||
1595 serialized_frame_length == 0) {
1596 return serialized_frame_length;
1597 }
1598 // Calculate frame bytes and bytes free with this frame added.
1599 const size_t frame_bytes = PacketSize() - PacketHeaderSize() +
1600 ExpansionOnNewFrame() + serialized_frame_length;
1601 if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
1602 // No extra bytes is needed.
1603 return serialized_frame_length;
1604 }
fayangfce2f722020-06-26 10:27:32 -07001605 if (BytesFree() < serialized_frame_length) {
1606 QUIC_BUG << ENDPOINT << "Frame does not fit: " << frame;
1607 return 0;
1608 }
1609 // Please note bytes_free does not take |frame|'s expansion into account.
1610 size_t bytes_free = BytesFree() - serialized_frame_length;
1611 // Extra bytes needed (this is NOT padding needed) should be at least 1
1612 // padding + expansion.
bnce5c11c02020-07-29 08:02:21 -07001613 const size_t extra_bytes_needed = std::max(
1614 1 + ExpansionOnNewFrameWithLastFrame(frame, framer_->transport_version()),
1615 MinPlaintextPacketSize(framer_->version()) - frame_bytes);
fayangfce2f722020-06-26 10:27:32 -07001616 if (bytes_free < extra_bytes_needed) {
1617 // This frame does not fit.
1618 return 0;
1619 }
1620 return serialized_frame_length;
1621}
1622
QUICHE teama6ef0a62019-03-07 20:34:33 -05001623bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001624 TransmissionType transmission_type) {
1625 QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
renjietang2b5e6622020-06-02 15:19:40 -07001626 << transmission_type << ": " << frame;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001627 if (frame.type == STREAM_FRAME &&
nharper46833c32019-05-15 21:33:05 -07001628 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
1629 frame.stream_frame.stream_id) &&
fayang9320ca72020-08-03 13:02:59 -07001630 AttemptingToSendUnencryptedStreamData()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001631 return false;
1632 }
renjietangdbe98342019-10-18 11:00:57 -07001633
renjietange426d622020-01-02 11:58:46 -08001634 if (frame.type == STREAM_FRAME) {
renjietang50ea92a2019-12-26 10:15:01 -08001635 if (MaybeCoalesceStreamFrame(frame.stream_frame)) {
1636 LogCoalesceStreamFrameStatus(true);
renjietang50ea92a2019-12-26 10:15:01 -08001637 return true;
1638 } else {
1639 LogCoalesceStreamFrameStatus(false);
1640 }
renjietangdbe98342019-10-18 11:00:57 -07001641 }
1642
dschinazi87aad8a2020-08-26 17:02:02 -07001643 // If this is an ACK frame, validate that it is non-empty and that
1644 // largest_acked matches the max packet number.
1645 DCHECK(frame.type != ACK_FRAME ||
1646 (!frame.ack_frame->packets.Empty() &&
1647 frame.ack_frame->packets.Max() == frame.ack_frame->largest_acked))
1648 << "Invalid ACK frame: " << frame;
1649
fayangfce2f722020-06-26 10:27:32 -07001650 size_t frame_len = GetSerializedFrameLength(frame);
fayang2ab1e852019-11-04 11:24:36 -08001651 if (frame_len == 0 && RemoveSoftMaxPacketLength()) {
1652 // Remove soft max_packet_length and retry.
fayangfce2f722020-06-26 10:27:32 -07001653 frame_len = GetSerializedFrameLength(frame);
fayang2ab1e852019-11-04 11:24:36 -08001654 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001655 if (frame_len == 0) {
dschinazi6458eb32020-06-23 12:38:41 -07001656 QUIC_DVLOG(1) << "Flushing because current open packet is full when adding "
1657 << frame;
fayang62b637b2019-09-16 08:40:49 -07001658 FlushCurrentPacket();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001659 return false;
1660 }
fayang5a3cfcb2020-08-27 12:57:23 -07001661 if (queued_frames_.empty()) {
fayang7a06f9b2020-06-24 10:23:19 -07001662 packet_size_ = PacketHeaderSize();
1663 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001664 DCHECK_LT(0u, packet_size_);
1665
1666 packet_size_ += ExpansionOnNewFrame() + frame_len;
1667
fayang347ab752019-10-22 11:17:43 -07001668 if (QuicUtils::IsRetransmittableFrame(frame.type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001669 packet_.retransmittable_frames.push_back(frame);
1670 queued_frames_.push_back(frame);
1671 if (QuicUtils::IsHandshakeFrame(frame, framer_->transport_version())) {
1672 packet_.has_crypto_handshake = IS_HANDSHAKE;
1673 }
1674 } else {
fayang02a28742019-12-04 07:09:38 -08001675 if (frame.type == PADDING_FRAME &&
1676 frame.padding_frame.num_padding_bytes == -1) {
1677 // Populate the actual length of full padding frame, such that one can
1678 // know how much padding is actually added.
1679 packet_.nonretransmittable_frames.push_back(
1680 QuicFrame(QuicPaddingFrame(frame_len)));
1681 } else {
1682 packet_.nonretransmittable_frames.push_back(frame);
fayang51152fd2019-10-21 06:48:09 -07001683 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001684 queued_frames_.push_back(frame);
1685 }
1686
1687 if (frame.type == ACK_FRAME) {
1688 packet_.has_ack = true;
1689 packet_.largest_acked = LargestAcked(*frame.ack_frame);
haoyuewang5b0f14f2020-09-18 14:31:54 -07001690 } else if (frame.type == STOP_WAITING_FRAME) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001691 packet_.has_stop_waiting = true;
haoyuewang5b0f14f2020-09-18 14:31:54 -07001692 } else if (frame.type == ACK_FREQUENCY_FRAME) {
1693 packet_.has_ack_frequency = true;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001694 }
1695 if (debug_delegate_ != nullptr) {
1696 debug_delegate_->OnFrameAddedToPacket(frame);
1697 }
1698
1699 // Packet transmission type is determined by the last added retransmittable
1700 // frame.
fayangcff885a2019-10-22 07:39:04 -07001701 if (QuicUtils::IsRetransmittableFrame(frame.type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001702 packet_.transmission_type = transmission_type;
1703 }
1704 return true;
1705}
1706
fayangfce2f722020-06-26 10:27:32 -07001707void QuicPacketCreator::MaybeAddExtraPaddingForHeaderProtection() {
fayangfce2f722020-06-26 10:27:32 -07001708 if (!framer_->version().HasHeaderProtection() || needs_full_padding_) {
1709 return;
1710 }
1711 const size_t frame_bytes = PacketSize() - PacketHeaderSize();
1712 if (frame_bytes >= MinPlaintextPacketSize(framer_->version())) {
1713 return;
1714 }
1715 const QuicByteCount min_header_protection_padding =
1716 std::max(1 + ExpansionOnNewFrame(),
1717 MinPlaintextPacketSize(framer_->version()) - frame_bytes) -
1718 ExpansionOnNewFrame();
fayangfce2f722020-06-26 10:27:32 -07001719 // Update pending_padding_bytes_.
1720 pending_padding_bytes_ =
1721 std::max(pending_padding_bytes_, min_header_protection_padding);
1722}
1723
renjietangdbe98342019-10-18 11:00:57 -07001724bool QuicPacketCreator::MaybeCoalesceStreamFrame(const QuicStreamFrame& frame) {
1725 if (queued_frames_.empty() || queued_frames_.back().type != STREAM_FRAME) {
1726 return false;
1727 }
1728 QuicStreamFrame* candidate = &queued_frames_.back().stream_frame;
1729 if (candidate->stream_id != frame.stream_id ||
1730 candidate->offset + candidate->data_length != frame.offset ||
1731 frame.data_length > BytesFree()) {
1732 return false;
1733 }
1734 candidate->data_length += frame.data_length;
1735 candidate->fin = frame.fin;
1736
1737 // The back of retransmittable frames must be the same as the original
1738 // queued frames' back.
1739 DCHECK_EQ(packet_.retransmittable_frames.back().type, STREAM_FRAME);
1740 QuicStreamFrame* retransmittable =
1741 &packet_.retransmittable_frames.back().stream_frame;
1742 DCHECK_EQ(retransmittable->stream_id, frame.stream_id);
1743 DCHECK_EQ(retransmittable->offset + retransmittable->data_length,
1744 frame.offset);
1745 retransmittable->data_length = candidate->data_length;
1746 retransmittable->fin = candidate->fin;
1747 packet_size_ += frame.data_length;
1748 if (debug_delegate_ != nullptr) {
1749 debug_delegate_->OnStreamFrameCoalesced(*candidate);
1750 }
1751 return true;
1752}
1753
fayang2ab1e852019-11-04 11:24:36 -08001754bool QuicPacketCreator::RemoveSoftMaxPacketLength() {
1755 if (latched_hard_max_packet_length_ == 0) {
1756 return false;
1757 }
1758 if (!CanSetMaxPacketLength()) {
1759 return false;
1760 }
1761 QUIC_DVLOG(1) << "Restoring max packet length to: "
1762 << latched_hard_max_packet_length_;
1763 SetMaxPacketLength(latched_hard_max_packet_length_);
1764 // Reset latched_max_packet_length_.
1765 latched_hard_max_packet_length_ = 0;
1766 return true;
1767}
1768
QUICHE teama6ef0a62019-03-07 20:34:33 -05001769void QuicPacketCreator::MaybeAddPadding() {
1770 // The current packet should have no padding bytes because padding is only
1771 // added when this method is called just before the packet is serialized.
QUICHE teama6ef0a62019-03-07 20:34:33 -05001772 if (BytesFree() == 0) {
1773 // Don't pad full packets.
1774 return;
1775 }
1776
1777 if (packet_.transmission_type == PROBING_RETRANSMISSION) {
1778 needs_full_padding_ = true;
1779 }
1780
fayangfe77c032020-08-24 18:21:32 -07001781 if (packet_.fate == COALESCE || packet_.fate == LEGACY_VERSION_ENCAPSULATE) {
1782 // Do not add full padding if the packet is going to be coalesced or
1783 // encapsulated.
1784 needs_full_padding_ = false;
dschinazi6458eb32020-06-23 12:38:41 -07001785 }
1786
nharper55fa6132019-05-07 19:37:21 -07001787 // Header protection requires a minimum plaintext packet size.
fayang7cd1d822020-08-25 13:52:19 -07001788 MaybeAddExtraPaddingForHeaderProtection();
nharper55fa6132019-05-07 19:37:21 -07001789
fayang7cd1d822020-08-25 13:52:19 -07001790 if (!needs_full_padding_ && pending_padding_bytes_ == 0) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001791 // Do not need padding.
1792 return;
1793 }
1794
nharper55fa6132019-05-07 19:37:21 -07001795 int padding_bytes = -1;
fayang88b87232020-06-24 15:31:08 -07001796 if (!needs_full_padding_) {
1797 padding_bytes = std::min<int16_t>(pending_padding_bytes_, BytesFree());
1798 pending_padding_bytes_ -= padding_bytes;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001799 }
1800
fayang347ab752019-10-22 11:17:43 -07001801 bool success = AddFrame(QuicFrame(QuicPaddingFrame(padding_bytes)),
nharper55fa6132019-05-07 19:37:21 -07001802 packet_.transmission_type);
dschinazief79a5f2019-10-04 10:32:54 -07001803 QUIC_BUG_IF(!success) << "Failed to add padding_bytes: " << padding_bytes
renjietang2b5e6622020-06-02 15:19:40 -07001804 << " transmission_type: " << packet_.transmission_type;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001805}
1806
1807bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
1808 return have_diversification_nonce_ &&
1809 packet_.encryption_level == ENCRYPTION_ZERO_RTT;
1810}
1811
1812bool QuicPacketCreator::IncludeVersionInHeader() const {
fayangd4291e42019-05-30 10:31:21 -07001813 if (VersionHasIetfInvariantHeader(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001814 return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1815 }
1816 return send_version_in_packet_;
1817}
1818
1819void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
1820 pending_padding_bytes_ += size;
1821}
1822
ianswette28f0222019-04-04 13:31:22 -07001823bool QuicPacketCreator::StreamFrameIsClientHello(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001824 const QuicStreamFrame& frame) const {
1825 if (framer_->perspective() == Perspective::IS_SERVER ||
nharper46833c32019-05-15 21:33:05 -07001826 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
1827 frame.stream_id)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001828 return false;
1829 }
ianswette28f0222019-04-04 13:31:22 -07001830 // The ClientHello is always sent with INITIAL encryption.
1831 return packet_.encryption_level == ENCRYPTION_INITIAL;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001832}
1833
dschinazi7b9278c2019-05-20 07:36:21 -07001834void QuicPacketCreator::SetServerConnectionIdIncluded(
1835 QuicConnectionIdIncluded server_connection_id_included) {
1836 DCHECK(server_connection_id_included == CONNECTION_ID_PRESENT ||
1837 server_connection_id_included == CONNECTION_ID_ABSENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001838 DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
dschinazi7b9278c2019-05-20 07:36:21 -07001839 server_connection_id_included != CONNECTION_ID_ABSENT);
1840 server_connection_id_included_ = server_connection_id_included;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001841}
1842
dschinazi7b9278c2019-05-20 07:36:21 -07001843void QuicPacketCreator::SetServerConnectionId(
1844 QuicConnectionId server_connection_id) {
1845 server_connection_id_ = server_connection_id;
QUICHE teamc65d1d12019-03-19 20:58:04 -07001846}
1847
dschinazi346b7ce2019-06-05 01:38:18 -07001848void QuicPacketCreator::SetClientConnectionId(
1849 QuicConnectionId client_connection_id) {
1850 DCHECK(client_connection_id.IsEmpty() ||
1851 framer_->version().SupportsClientConnectionIds());
dschinazi346b7ce2019-06-05 01:38:18 -07001852 client_connection_id_ = client_connection_id;
1853}
1854
ianswettb239f862019-04-05 09:15:06 -07001855QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001856 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001857 return 0;
1858 }
1859 const size_t packet_header_size = GetPacketHeaderSize(
1860 framer_->transport_version(), GetDestinationConnectionIdLength(),
1861 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
1862 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
ianswettb239f862019-04-05 09:15:06 -07001863 // No Retry token on packets containing application data.
1864 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001865 // This is the largest possible message payload when the length field is
1866 // omitted.
fayang2ab1e852019-11-04 11:24:36 -08001867 size_t max_plaintext_size =
1868 latched_hard_max_packet_length_ == 0
1869 ? max_plaintext_size_
1870 : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
dschinazied459c02020-05-07 16:12:23 -07001871 size_t largest_frame =
1872 max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
1873 if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
1874 largest_frame = static_cast<size_t>(max_datagram_frame_size_);
1875 }
1876 return largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001877}
1878
ianswettb239f862019-04-05 09:15:06 -07001879QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001880 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
ianswettb239f862019-04-05 09:15:06 -07001881 return 0;
1882 }
1883 // QUIC Crypto server packets may include a diversification nonce.
1884 const bool may_include_nonce =
1885 framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
1886 framer_->perspective() == Perspective::IS_SERVER;
1887 // IETF QUIC long headers include a length on client 0RTT packets.
1888 QuicVariableLengthIntegerLength length_length =
nharperd43f1d62019-07-01 15:18:20 -07001889 VARIABLE_LENGTH_INTEGER_LENGTH_0;
1890 if (framer_->perspective() == Perspective::IS_CLIENT) {
1891 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
1892 }
nharper405f7192019-09-11 08:28:06 -07001893 if (!QuicVersionHasLongHeaderLengths(framer_->transport_version())) {
nharperd43f1d62019-07-01 15:18:20 -07001894 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
1895 }
ianswettb239f862019-04-05 09:15:06 -07001896 const size_t packet_header_size = GetPacketHeaderSize(
1897 framer_->transport_version(), GetDestinationConnectionIdLength(),
1898 // Assume CID lengths don't change, but version may be present.
1899 GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
1900 PACKET_4BYTE_PACKET_NUMBER,
1901 // No Retry token on packets containing application data.
1902 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
1903 // This is the largest possible message payload when the length field is
1904 // omitted.
fayang2ab1e852019-11-04 11:24:36 -08001905 size_t max_plaintext_size =
1906 latched_hard_max_packet_length_ == 0
1907 ? max_plaintext_size_
1908 : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
dschinazied459c02020-05-07 16:12:23 -07001909 size_t largest_frame =
1910 max_plaintext_size - std::min(max_plaintext_size, packet_header_size);
1911 if (static_cast<QuicByteCount>(largest_frame) > max_datagram_frame_size_) {
1912 largest_frame = static_cast<size_t>(max_datagram_frame_size_);
1913 }
ianswettb239f862019-04-05 09:15:06 -07001914 const QuicPacketLength largest_payload =
dschinazied459c02020-05-07 16:12:23 -07001915 largest_frame - std::min(largest_frame, kQuicFrameTypeSize);
ianswettb239f862019-04-05 09:15:06 -07001916 // This must always be less than or equal to GetCurrentLargestMessagePayload.
1917 DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload());
1918 return largest_payload;
1919}
1920
fayang9320ca72020-08-03 13:02:59 -07001921bool QuicPacketCreator::AttemptingToSendUnencryptedStreamData() {
1922 if (packet_.encryption_level == ENCRYPTION_ZERO_RTT ||
1923 packet_.encryption_level == ENCRYPTION_FORWARD_SECURE) {
1924 return false;
1925 }
1926 const std::string error_details =
1927 quiche::QuicheStrCat("Cannot send stream data with level: ",
1928 EncryptionLevelToString(packet_.encryption_level));
1929 QUIC_BUG << error_details;
1930 delegate_->OnUnrecoverableError(QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA,
1931 error_details);
1932 return true;
1933}
1934
QUICHE teama6ef0a62019-03-07 20:34:33 -05001935bool QuicPacketCreator::HasIetfLongHeader() const {
fayangd4291e42019-05-30 10:31:21 -07001936 return VersionHasIetfInvariantHeader(framer_->transport_version()) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05001937 packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1938}
1939
nharper6f8a7612019-07-08 12:31:20 -07001940// static
QUICHE team2252b702019-05-14 23:55:14 -04001941size_t QuicPacketCreator::MinPlaintextPacketSize(
1942 const ParsedQuicVersion& version) {
1943 if (!version.HasHeaderProtection()) {
nharper55fa6132019-05-07 19:37:21 -07001944 return 0;
1945 }
1946 // Header protection samples 16 bytes of ciphertext starting 4 bytes after the
1947 // packet number. In IETF QUIC, all AEAD algorithms have a 16-byte auth tag
1948 // (i.e. the ciphertext is 16 bytes larger than the plaintext). Since packet
1949 // numbers could be as small as 1 byte, but the sample starts 4 bytes after
1950 // the packet number, at least 3 bytes of plaintext are needed to make sure
1951 // that there is enough ciphertext to sample.
1952 //
1953 // Google QUIC crypto uses different AEAD algorithms - in particular the auth
1954 // tags are only 12 bytes instead of 16 bytes. Since the auth tag is 4 bytes
1955 // shorter, 4 more bytes of plaintext are needed to guarantee there is enough
1956 // ciphertext to sample.
1957 //
1958 // This method could check for PROTOCOL_TLS1_3 vs PROTOCOL_QUIC_CRYPTO and
1959 // return 3 when TLS 1.3 is in use (the use of IETF vs Google QUIC crypters is
1960 // determined based on the handshake protocol used). However, even when TLS
1961 // 1.3 is used, unittests still use NullEncrypter/NullDecrypter (and other
1962 // test crypters) which also only use 12 byte tags.
1963 //
1964 // TODO(nharper): Set this based on the handshake protocol in use.
1965 return 7;
1966}
1967
fayang354c9422019-05-21 08:10:35 -07001968QuicPacketNumber QuicPacketCreator::NextSendingPacketNumber() const {
1969 if (!packet_number().IsInitialized()) {
1970 return framer_->first_sending_packet_number();
1971 }
1972 return packet_number() + 1;
1973}
1974
fayang18be79a2019-09-16 15:17:12 -07001975bool QuicPacketCreator::PacketFlusherAttached() const {
fayang18be79a2019-09-16 15:17:12 -07001976 return flusher_attached_;
1977}
1978
fayangfe963c52020-07-16 06:56:09 -07001979bool QuicPacketCreator::HasSoftMaxPacketLength() const {
1980 return latched_hard_max_packet_length_ != 0;
1981}
1982
danzh051bf772020-08-24 12:30:36 -07001983void QuicPacketCreator::SetDefaultPeerAddress(QuicSocketAddress address) {
1984 if (!packet_.peer_address.IsInitialized()) {
1985 packet_.peer_address = address;
1986 return;
1987 }
1988 if (packet_.peer_address != address) {
1989 FlushCurrentPacket();
1990 packet_.peer_address = address;
1991 }
1992}
1993
1994QuicPacketCreator::ScopedPeerAddressContext::ScopedPeerAddressContext(
1995 QuicPacketCreator* creator,
1996 QuicSocketAddress address)
1997 : creator_(creator), old_peer_address_(creator_->packet_.peer_address) {
1998 QUIC_BUG_IF(!creator_->packet_.peer_address.IsInitialized())
1999 << "Context is used before seralized packet's peer address is "
2000 "initialized.";
2001 creator_->SetDefaultPeerAddress(address);
2002}
2003
2004QuicPacketCreator::ScopedPeerAddressContext::~ScopedPeerAddressContext() {
2005 creator_->SetDefaultPeerAddress(old_peer_address_);
2006}
2007
fayang04590fc2020-08-31 10:37:55 -07002008QuicPacketCreator::ScopedSerializationFailureHandler::
2009 ScopedSerializationFailureHandler(QuicPacketCreator* creator)
fayange447bc62020-08-27 13:47:11 -07002010 : creator_(creator) {}
2011
fayang04590fc2020-08-31 10:37:55 -07002012QuicPacketCreator::ScopedSerializationFailureHandler::
2013 ~ScopedSerializationFailureHandler() {
fayange447bc62020-08-27 13:47:11 -07002014 if (creator_ == nullptr) {
2015 return;
2016 }
fayang04590fc2020-08-31 10:37:55 -07002017 // Always clear queued_frames_.
fayange447bc62020-08-27 13:47:11 -07002018 creator_->queued_frames_.clear();
fayang04590fc2020-08-31 10:37:55 -07002019
2020 if (creator_->close_connection_on_serialization_failure_ &&
2021 creator_->packet_.encrypted_buffer == nullptr) {
2022 const std::string error_details = "Failed to SerializePacket.";
2023 QUIC_BUG << error_details;
2024 creator_->delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
2025 error_details);
2026 }
fayange447bc62020-08-27 13:47:11 -07002027}
2028
dschinazi87aad8a2020-08-26 17:02:02 -07002029void QuicPacketCreator::set_encryption_level(EncryptionLevel level) {
2030 DCHECK(level == packet_.encryption_level || !HasPendingFrames())
2031 << "Cannot update encryption level from " << packet_.encryption_level
2032 << " to " << level << " when we already have pending frames: "
2033 << QuicFramesToString(queued_frames_);
2034 packet_.encryption_level = level;
2035}
2036
danzh8a27a1a2020-09-02 10:26:28 -07002037bool QuicPacketCreator::AddPathResponseFrame(
2038 const QuicPathFrameBuffer& data_buffer) {
2039 auto path_response =
2040 new QuicPathResponseFrame(kInvalidControlFrameId, data_buffer);
2041 QuicFrame frame(path_response);
2042 if (HasPendingFrames()) {
2043 if (AddPaddedSavedFrame(frame, NOT_RETRANSMISSION)) {
2044 // Frame is queued.
2045 return true;
2046 }
2047 }
2048 // Frame was not queued but queued frames were flushed.
2049 DCHECK(!HasPendingFrames());
2050 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
2051 NOT_HANDSHAKE)) {
2052 QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_RESPONSE now";
2053 QUIC_RELOADABLE_FLAG_COUNT_N(quic_send_path_response, 5, 5);
2054 delete path_response;
2055 return false;
2056 }
2057 bool success = AddPaddedSavedFrame(frame, NOT_RETRANSMISSION);
2058 QUIC_BUG_IF(!success);
2059 return true;
2060}
QUICHE teama6ef0a62019-03-07 20:34:33 -05002061#undef ENDPOINT // undef for jumbo builds
2062} // namespace quic