blob: 923b219ded48566725de738c4b4f1b278b4caa36 [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>
vasilvv872e7a32019-03-12 16:42:44 -070010#include <string>
bnc463f2352019-10-10 04:49:34 -070011#include <utility>
QUICHE teama6ef0a62019-03-07 20:34:33 -050012
QUICHE teama6ef0a62019-03-07 20:34:33 -050013#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
renjietangdbe98342019-10-18 11:00:57 -070014#include "net/third_party/quiche/src/quic/core/frames/quic_frame.h"
renjietang4c704c82019-10-07 16:39:11 -070015#include "net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h"
renjietangdbe98342019-10-18 11:00:57 -070016#include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050017#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
ianswettb239f862019-04-05 09:15:06 -070018#include "net/third_party/quiche/src/quic/core/quic_constants.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050019#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
20#include "net/third_party/quiche/src/quic/core/quic_types.h"
21#include "net/third_party/quiche/src/quic/core/quic_utils.h"
ianswettb239f862019-04-05 09:15:06 -070022#include "net/third_party/quiche/src/quic/core/quic_versions.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050023#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050024#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
renjietang50ea92a2019-12-26 10:15:01 -080025#include "net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050026#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
27#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
28#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
fayang18be79a2019-09-16 15:17:12 -070029#include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h"
bnc4e9283d2019-12-17 07:08:57 -080030#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080031#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
32#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
33#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050034
35namespace quic {
36namespace {
37
38QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
39 switch (level) {
QUICHE team6987b4a2019-03-15 16:23:04 -070040 case ENCRYPTION_INITIAL:
QUICHE teama6ef0a62019-03-07 20:34:33 -050041 return INITIAL;
QUICHE team88ea0082019-03-15 10:05:26 -070042 case ENCRYPTION_HANDSHAKE:
43 return HANDSHAKE;
QUICHE teama6ef0a62019-03-07 20:34:33 -050044 case ENCRYPTION_ZERO_RTT:
45 return ZERO_RTT_PROTECTED;
46 case ENCRYPTION_FORWARD_SECURE:
47 QUIC_BUG
48 << "Try to derive long header type for packet with encryption level: "
dschinazief79a5f2019-10-04 10:32:54 -070049 << EncryptionLevelToString(level);
QUICHE teama6ef0a62019-03-07 20:34:33 -050050 return INVALID_PACKET_TYPE;
51 default:
dschinazief79a5f2019-10-04 10:32:54 -070052 QUIC_BUG << EncryptionLevelToString(level);
QUICHE teama6ef0a62019-03-07 20:34:33 -050053 return INVALID_PACKET_TYPE;
54 }
55}
56
renjietang50ea92a2019-12-26 10:15:01 -080057void LogCoalesceStreamFrameStatus(bool success) {
renjietang261e03d2020-02-18 12:55:24 -080058 QUIC_HISTOGRAM_BOOL("QuicSession.CoalesceStreamFrameStatus", success,
59 "Success rate of coalesing stream frames attempt.");
renjietang50ea92a2019-12-26 10:15:01 -080060}
61
fayang08750832019-10-24 11:25:34 -070062// ScopedPacketContextSwitcher saves |packet|'s states and change states
63// during its construction. When the switcher goes out of scope, it restores
64// saved states.
65class ScopedPacketContextSwitcher {
66 public:
67 ScopedPacketContextSwitcher(QuicPacketNumber packet_number,
68 QuicPacketNumberLength packet_number_length,
69 EncryptionLevel encryption_level,
70 SerializedPacket* packet)
71
72 : saved_packet_number_(packet->packet_number),
73 saved_packet_number_length_(packet->packet_number_length),
74 saved_encryption_level_(packet->encryption_level),
75 packet_(packet) {
76 packet_->packet_number = packet_number,
77 packet_->packet_number_length = packet_number_length;
78 packet_->encryption_level = encryption_level;
79 }
80
81 ~ScopedPacketContextSwitcher() {
82 packet_->packet_number = saved_packet_number_;
83 packet_->packet_number_length = saved_packet_number_length_;
84 packet_->encryption_level = saved_encryption_level_;
85 }
86
87 private:
88 const QuicPacketNumber saved_packet_number_;
89 const QuicPacketNumberLength saved_packet_number_length_;
90 const EncryptionLevel saved_encryption_level_;
91 SerializedPacket* packet_;
92};
93
QUICHE teama6ef0a62019-03-07 20:34:33 -050094} // namespace
95
96#define ENDPOINT \
97 (framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
98
dschinazi7b9278c2019-05-20 07:36:21 -070099QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500100 QuicFramer* framer,
101 DelegateInterface* delegate)
dschinazi7b9278c2019-05-20 07:36:21 -0700102 : QuicPacketCreator(server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500103 framer,
104 QuicRandom::GetInstance(),
105 delegate) {}
106
dschinazi7b9278c2019-05-20 07:36:21 -0700107QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500108 QuicFramer* framer,
109 QuicRandom* random,
110 DelegateInterface* delegate)
111 : delegate_(delegate),
112 debug_delegate_(nullptr),
113 framer_(framer),
114 random_(random),
115 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
116 have_diversification_nonce_(false),
117 max_packet_length_(0),
dschinazi7b9278c2019-05-20 07:36:21 -0700118 server_connection_id_included_(CONNECTION_ID_PRESENT),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500119 packet_size_(0),
dschinazi7b9278c2019-05-20 07:36:21 -0700120 server_connection_id_(server_connection_id),
dschinazi346b7ce2019-06-05 01:38:18 -0700121 client_connection_id_(EmptyQuicConnectionId()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500122 packet_(QuicPacketNumber(),
123 PACKET_1BYTE_PACKET_NUMBER,
124 nullptr,
125 0,
126 false,
127 false),
128 pending_padding_bytes_(0),
129 needs_full_padding_(false),
fayang18be79a2019-09-16 15:17:12 -0700130 next_transmission_type_(NOT_RETRANSMISSION),
131 flusher_attached_(false),
132 fully_pad_crypto_handshake_packets_(true),
fayang02a28742019-12-04 07:09:38 -0800133 latched_hard_max_packet_length_(0) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500134 SetMaxPacketLength(kDefaultMaxPacketSize);
135}
136
137QuicPacketCreator::~QuicPacketCreator() {
138 DeleteFrames(&packet_.retransmittable_frames);
139}
140
141void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
142 std::unique_ptr<QuicEncrypter> encrypter) {
143 framer_->SetEncrypter(level, std::move(encrypter));
144 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
145}
146
147bool QuicPacketCreator::CanSetMaxPacketLength() const {
148 // |max_packet_length_| should not be changed mid-packet.
149 return queued_frames_.empty();
150}
151
152void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
153 DCHECK(CanSetMaxPacketLength());
154
155 // Avoid recomputing |max_plaintext_size_| if the length does not actually
156 // change.
157 if (length == max_packet_length_) {
158 return;
159 }
160
161 max_packet_length_ = length;
162 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
nharper55fa6132019-05-07 19:37:21 -0700163 QUIC_BUG_IF(max_plaintext_size_ - PacketHeaderSize() <
QUICHE team2252b702019-05-14 23:55:14 -0400164 MinPlaintextPacketSize(framer_->version()))
nharper55fa6132019-05-07 19:37:21 -0700165 << "Attempted to set max packet length too small";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500166}
167
fayang2ab1e852019-11-04 11:24:36 -0800168void QuicPacketCreator::SetSoftMaxPacketLength(QuicByteCount length) {
169 DCHECK(CanSetMaxPacketLength());
170 if (length > max_packet_length_) {
171 QUIC_BUG << ENDPOINT
172 << "Try to increase max_packet_length_ in "
173 "SetSoftMaxPacketLength, use SetMaxPacketLength instead.";
174 return;
175 }
176 if (framer_->GetMaxPlaintextSize(length) <
177 PacketHeaderSize() + MinPlaintextPacketSize(framer_->version())) {
178 QUIC_DLOG(INFO) << length << " is too small to fit packet header";
179 return;
180 }
181 QUIC_DVLOG(1) << "Setting soft max packet length to: " << length;
182 latched_hard_max_packet_length_ = max_packet_length_;
183 max_packet_length_ = length;
184 max_plaintext_size_ = framer_->GetMaxPlaintextSize(length);
185}
186
QUICHE teama6ef0a62019-03-07 20:34:33 -0500187// Stops serializing version of the protocol in packets sent after this call.
188// A packet that is already open might send kQuicVersionSize bytes less than the
189// maximum packet size if we stop sending version before it is serialized.
190void QuicPacketCreator::StopSendingVersion() {
191 DCHECK(send_version_in_packet_);
fayangd4291e42019-05-30 10:31:21 -0700192 DCHECK(!VersionHasIetfInvariantHeader(framer_->transport_version()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500193 send_version_in_packet_ = false;
194 if (packet_size_ > 0) {
195 DCHECK_LT(kQuicVersionSize, packet_size_);
196 packet_size_ -= kQuicVersionSize;
197 }
198}
199
200void QuicPacketCreator::SetDiversificationNonce(
201 const DiversificationNonce& nonce) {
202 DCHECK(!have_diversification_nonce_);
203 have_diversification_nonce_ = true;
204 diversification_nonce_ = nonce;
205}
206
207void QuicPacketCreator::UpdatePacketNumberLength(
208 QuicPacketNumber least_packet_awaited_by_peer,
209 QuicPacketCount max_packets_in_flight) {
210 if (!queued_frames_.empty()) {
211 // Don't change creator state if there are frames queued.
212 QUIC_BUG << "Called UpdatePacketNumberLength with " << queued_frames_.size()
213 << " queued_frames. First frame type:"
214 << queued_frames_.front().type
215 << " last frame type:" << queued_frames_.back().type;
216 return;
217 }
218
219 DCHECK_LE(least_packet_awaited_by_peer, packet_.packet_number + 1);
220 const uint64_t current_delta =
221 packet_.packet_number + 1 - least_packet_awaited_by_peer;
222 const uint64_t delta = std::max(current_delta, max_packets_in_flight);
renjietang488201d2019-12-17 13:40:49 -0800223 packet_.packet_number_length =
224 QuicFramer::GetMinPacketNumberLength(QuicPacketNumber(delta * 4));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500225}
226
fayang4c1c2362019-09-13 07:20:01 -0700227void QuicPacketCreator::SkipNPacketNumbers(
228 QuicPacketCount count,
229 QuicPacketNumber least_packet_awaited_by_peer,
230 QuicPacketCount max_packets_in_flight) {
231 if (!queued_frames_.empty()) {
232 // Don't change creator state if there are frames queued.
233 QUIC_BUG << "Called SkipNPacketNumbers with " << queued_frames_.size()
234 << " queued_frames. First frame type:"
235 << queued_frames_.front().type
236 << " last frame type:" << queued_frames_.back().type;
237 return;
238 }
239 if (packet_.packet_number > packet_.packet_number + count) {
240 // Skipping count packet numbers causes packet number wrapping around,
241 // reject it.
242 QUIC_LOG(WARNING) << "Skipping " << count
243 << " packet numbers causes packet number wrapping "
244 "around, least_packet_awaited_by_peer: "
245 << least_packet_awaited_by_peer
246 << " packet_number:" << packet_.packet_number;
247 return;
248 }
249 packet_.packet_number += count;
250 // Packet number changes, update packet number length if necessary.
251 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight);
252}
253
fayang62b637b2019-09-16 08:40:49 -0700254bool QuicPacketCreator::ConsumeCryptoDataToFillCurrentPacket(
255 EncryptionLevel level,
256 size_t write_length,
257 QuicStreamOffset offset,
258 bool needs_full_padding,
259 TransmissionType transmission_type,
260 QuicFrame* frame) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500261 if (!CreateCryptoFrame(level, write_length, offset, frame)) {
262 return false;
263 }
264 // When crypto data was sent in stream frames, ConsumeData is called with
265 // |needs_full_padding = true|. Keep the same behavior here when sending
266 // crypto frames.
267 //
268 // TODO(nharper): Check what the IETF drafts say about padding out initial
269 // messages and change this as appropriate.
nharper51961cf2019-05-13 13:23:24 -0700270 if (needs_full_padding) {
271 needs_full_padding_ = true;
272 }
fayang347ab752019-10-22 11:17:43 -0700273 return AddFrame(*frame, transmission_type);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500274}
275
fayang62b637b2019-09-16 08:40:49 -0700276bool QuicPacketCreator::ConsumeDataToFillCurrentPacket(
277 QuicStreamId id,
278 size_t data_size,
279 QuicStreamOffset offset,
280 bool fin,
281 bool needs_full_padding,
282 TransmissionType transmission_type,
283 QuicFrame* frame) {
QUICHE teamf08778a2019-03-14 08:10:26 -0700284 if (!HasRoomForStreamFrame(id, offset, data_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500285 return false;
286 }
QUICHE teamf08778a2019-03-14 08:10:26 -0700287 CreateStreamFrame(id, data_size, offset, fin, frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500288 // Explicitly disallow multi-packet CHLOs.
danzh88e3e052019-06-13 11:47:18 -0700289 if (GetQuicFlag(FLAGS_quic_enforce_single_packet_chlo) &&
ianswette28f0222019-04-04 13:31:22 -0700290 StreamFrameIsClientHello(frame->stream_frame) &&
291 frame->stream_frame.data_length < data_size) {
vasilvvc48c8712019-03-11 13:38:16 -0700292 const std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500293 "Client hello won't fit in a single packet.";
294 QUIC_BUG << error_details << " Constructed stream frame length: "
295 << frame->stream_frame.data_length
ianswette28f0222019-04-04 13:31:22 -0700296 << " CHLO length: " << data_size;
fkastenholz85f18902019-05-28 12:47:00 -0700297 delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500298 return false;
299 }
fayang347ab752019-10-22 11:17:43 -0700300 if (!AddFrame(*frame, transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500301 // Fails if we try to write unencrypted stream data.
302 return false;
303 }
304 if (needs_full_padding) {
305 needs_full_padding_ = true;
306 }
307
308 return true;
309}
310
311bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
312 QuicStreamOffset offset,
313 size_t data_size) {
fayang2ab1e852019-11-04 11:24:36 -0800314 const size_t min_stream_frame_size = QuicFramer::GetMinStreamFrameSize(
315 framer_->transport_version(), id, offset, /*last_frame_in_packet=*/true,
316 data_size);
317 if (BytesFree() > min_stream_frame_size) {
318 return true;
319 }
320 if (!RemoveSoftMaxPacketLength()) {
321 return false;
322 }
323 return BytesFree() > min_stream_frame_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500324}
325
326bool QuicPacketCreator::HasRoomForMessageFrame(QuicByteCount length) {
fayang2ab1e852019-11-04 11:24:36 -0800327 const size_t message_frame_size = QuicFramer::GetMessageFrameSize(
328 framer_->transport_version(), /*last_frame_in_packet=*/true, length);
329 if (BytesFree() >= message_frame_size) {
330 return true;
331 }
332 if (!RemoveSoftMaxPacketLength()) {
333 return false;
334 }
335 return BytesFree() >= message_frame_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500336}
337
QUICHE teama6ef0a62019-03-07 20:34:33 -0500338// static
339size_t QuicPacketCreator::StreamFramePacketOverhead(
340 QuicTransportVersion version,
341 QuicConnectionIdLength destination_connection_id_length,
342 QuicConnectionIdLength source_connection_id_length,
343 bool include_version,
344 bool include_diversification_nonce,
345 QuicPacketNumberLength packet_number_length,
346 QuicVariableLengthIntegerLength retry_token_length_length,
347 QuicVariableLengthIntegerLength length_length,
348 QuicStreamOffset offset) {
349 return GetPacketHeaderSize(version, destination_connection_id_length,
350 source_connection_id_length, include_version,
351 include_diversification_nonce,
352 packet_number_length, retry_token_length_length, 0,
353 length_length) +
354
ianswett22781cb2019-12-12 06:45:08 -0800355 // Assumes a packet with a single stream frame, which omits the length,
356 // causing the data length argument to be ignored.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500357 QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true,
ianswett22781cb2019-12-12 06:45:08 -0800358 kMaxOutgoingPacketSize /* unused */);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500359}
360
361void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
QUICHE teamf08778a2019-03-14 08:10:26 -0700362 size_t data_size,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500363 QuicStreamOffset offset,
364 bool fin,
365 QuicFrame* frame) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500366 DCHECK_GT(
367 max_packet_length_,
368 StreamFramePacketOverhead(
369 framer_->transport_version(), GetDestinationConnectionIdLength(),
370 GetSourceConnectionIdLength(), kIncludeVersion,
371 IncludeNonceInPublicHeader(), PACKET_6BYTE_PACKET_NUMBER,
372 GetRetryTokenLengthLength(), GetLengthLength(), offset));
373
374 QUIC_BUG_IF(!HasRoomForStreamFrame(id, offset, data_size))
375 << "No room for Stream frame, BytesFree: " << BytesFree()
376 << " MinStreamFrameSize: "
377 << QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
378 offset, true, data_size);
379
QUICHE teamf08778a2019-03-14 08:10:26 -0700380 QUIC_BUG_IF(data_size == 0 && !fin)
381 << "Creating a stream frame for stream ID:" << id
382 << " with no data or fin.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500383 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
384 framer_->transport_version(), id, offset,
385 /* last_frame_in_packet= */ true, data_size);
386 size_t bytes_consumed =
387 std::min<size_t>(BytesFree() - min_frame_size, data_size);
388
389 bool set_fin = fin && bytes_consumed == data_size; // Last frame.
390 *frame = QuicFrame(QuicStreamFrame(id, set_fin, offset, bytes_consumed));
391}
392
393bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
394 size_t write_length,
395 QuicStreamOffset offset,
396 QuicFrame* frame) {
397 size_t min_frame_size =
398 QuicFramer::GetMinCryptoFrameSize(write_length, offset);
fayang2ab1e852019-11-04 11:24:36 -0800399 if (BytesFree() <= min_frame_size &&
400 (!RemoveSoftMaxPacketLength() || BytesFree() <= min_frame_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500401 return false;
402 }
403 size_t max_write_length = BytesFree() - min_frame_size;
404 size_t bytes_consumed = std::min<size_t>(max_write_length, write_length);
405 *frame = QuicFrame(new QuicCryptoFrame(level, offset, bytes_consumed));
406 return true;
407}
408
fayang62b637b2019-09-16 08:40:49 -0700409void QuicPacketCreator::FlushCurrentPacket() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500410 if (!HasPendingFrames() && pending_padding_bytes_ == 0) {
411 return;
412 }
413
dschinazi66dea072019-04-09 11:41:06 -0700414 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500415 char* serialized_packet_buffer = delegate_->GetPacketBuffer();
416 if (serialized_packet_buffer == nullptr) {
417 serialized_packet_buffer = stack_buffer;
418 }
419
dschinazi66dea072019-04-09 11:41:06 -0700420 SerializePacket(serialized_packet_buffer, kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500421 OnSerializedPacket();
422}
423
424void QuicPacketCreator::OnSerializedPacket() {
425 if (packet_.encrypted_buffer == nullptr) {
vasilvvc48c8712019-03-11 13:38:16 -0700426 const std::string error_details = "Failed to SerializePacket.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500427 QUIC_BUG << error_details;
428 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
fkastenholz85f18902019-05-28 12:47:00 -0700429 error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500430 return;
431 }
432
433 SerializedPacket packet(std::move(packet_));
434 ClearPacket();
fayang2ab1e852019-11-04 11:24:36 -0800435 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500436 delegate_->OnSerializedPacket(&packet);
437}
438
439void QuicPacketCreator::ClearPacket() {
440 packet_.has_ack = false;
441 packet_.has_stop_waiting = false;
442 packet_.has_crypto_handshake = NOT_HANDSHAKE;
443 packet_.num_padding_bytes = 0;
wub98669f52019-04-18 10:49:18 -0700444 packet_.transmission_type = NOT_RETRANSMISSION;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500445 packet_.encrypted_buffer = nullptr;
446 packet_.encrypted_length = 0;
447 DCHECK(packet_.retransmittable_frames.empty());
fayang51152fd2019-10-21 06:48:09 -0700448 DCHECK(packet_.nonretransmittable_frames.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500449 packet_.largest_acked.Clear();
450 needs_full_padding_ = false;
451}
452
fayang08750832019-10-24 11:25:34 -0700453size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
454 const SerializedPacket& packet,
455 size_t padding_size,
456 char* buffer,
457 size_t buffer_len) {
458 QUIC_BUG_IF(packet.encryption_level != ENCRYPTION_INITIAL);
459 QUIC_BUG_IF(packet.nonretransmittable_frames.empty() &&
460 packet.retransmittable_frames.empty())
461 << "Attempt to serialize empty ENCRYPTION_INITIAL packet in coalesced "
462 "packet";
463 ScopedPacketContextSwitcher switcher(
464 packet.packet_number -
465 1, // -1 because serialize packet increase packet number.
466 packet.packet_number_length, packet.encryption_level, &packet_);
467 for (const QuicFrame& frame : packet.nonretransmittable_frames) {
468 if (!AddFrame(frame, packet.transmission_type)) {
469 QUIC_BUG << "Failed to serialize frame: " << frame;
470 return 0;
471 }
472 }
473 for (const QuicFrame& frame : packet.retransmittable_frames) {
474 if (!AddFrame(frame, packet.transmission_type)) {
475 QUIC_BUG << "Failed to serialize frame: " << frame;
476 return 0;
477 }
478 }
479 // Add necessary padding.
480 if (padding_size > 0) {
481 QUIC_DVLOG(2) << ENDPOINT << "Add padding of size: " << padding_size;
482 if (!AddFrame(QuicFrame(QuicPaddingFrame(padding_size)),
483 packet.transmission_type)) {
484 QUIC_BUG << "Failed to add padding of size " << padding_size
485 << " when serializing ENCRYPTION_INITIAL "
486 "packet in coalesced packet";
487 return 0;
488 }
489 }
490 SerializePacket(buffer, buffer_len);
491 const size_t encrypted_length = packet_.encrypted_length;
492 // Clear frames in packet_. No need to DeleteFrames since frames are owned by
493 // initial_packet.
494 packet_.retransmittable_frames.clear();
495 packet_.nonretransmittable_frames.clear();
496 ClearPacket();
497 return encrypted_length;
498}
499
QUICHE teama6ef0a62019-03-07 20:34:33 -0500500void QuicPacketCreator::CreateAndSerializeStreamFrame(
501 QuicStreamId id,
502 size_t write_length,
503 QuicStreamOffset iov_offset,
504 QuicStreamOffset stream_offset,
505 bool fin,
506 TransmissionType transmission_type,
507 size_t* num_bytes_consumed) {
508 DCHECK(queued_frames_.empty());
509 // Write out the packet header
510 QuicPacketHeader header;
511 FillPacketHeader(&header);
512
dschinazi66dea072019-04-09 11:41:06 -0700513 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500514 char* encrypted_buffer = delegate_->GetPacketBuffer();
515 if (encrypted_buffer == nullptr) {
516 encrypted_buffer = stack_buffer;
517 }
518
dschinazi66dea072019-04-09 11:41:06 -0700519 QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500520 size_t length_field_offset = 0;
521 if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
522 QUIC_BUG << "AppendPacketHeader failed";
523 return;
524 }
525
526 // Create a Stream frame with the remaining space.
527 QUIC_BUG_IF(iov_offset == write_length && !fin)
528 << "Creating a stream frame with no data or fin.";
529 const size_t remaining_data_size = write_length - iov_offset;
nharperebabffd2019-06-03 17:34:45 -0700530 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500531 framer_->transport_version(), id, stream_offset,
532 /* last_frame_in_packet= */ true, remaining_data_size);
nharperebabffd2019-06-03 17:34:45 -0700533 size_t available_size =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500534 max_plaintext_size_ - writer.length() - min_frame_size;
nharperebabffd2019-06-03 17:34:45 -0700535 size_t bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
536 size_t plaintext_bytes_written = min_frame_size + bytes_consumed;
537 bool needs_padding = false;
538 if (plaintext_bytes_written < MinPlaintextPacketSize(framer_->version())) {
539 needs_padding = true;
540 // Recalculate sizes with the stream frame not being marked as the last
541 // frame in the packet.
542 min_frame_size = QuicFramer::GetMinStreamFrameSize(
543 framer_->transport_version(), id, stream_offset,
544 /* last_frame_in_packet= */ false, remaining_data_size);
545 available_size = max_plaintext_size_ - writer.length() - min_frame_size;
546 bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
547 plaintext_bytes_written = min_frame_size + bytes_consumed;
548 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500549
550 const bool set_fin = fin && (bytes_consumed == remaining_data_size);
551 QuicStreamFrame frame(id, set_fin, stream_offset, bytes_consumed);
rchc76cd742019-03-26 16:00:03 -0700552 if (debug_delegate_ != nullptr) {
553 debug_delegate_->OnFrameAddedToPacket(QuicFrame(frame));
554 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500555 QUIC_DVLOG(1) << ENDPOINT << "Adding frame: " << frame;
556
dschinazi118934b2019-06-13 18:09:08 -0700557 QUIC_DVLOG(2) << ENDPOINT << "Serializing stream packet " << header << frame;
558
QUICHE teama6ef0a62019-03-07 20:34:33 -0500559 // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized
560 // into one method that takes a QuicStreamFrame, if warranted.
nharperebabffd2019-06-03 17:34:45 -0700561 bool omit_frame_length = !needs_padding;
562 if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500563 QUIC_BUG << "AppendTypeByte failed";
564 return;
565 }
nharperebabffd2019-06-03 17:34:45 -0700566 if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500567 QUIC_BUG << "AppendStreamFrame failed";
568 return;
569 }
nharperebabffd2019-06-03 17:34:45 -0700570 if (needs_padding &&
571 plaintext_bytes_written < MinPlaintextPacketSize(framer_->version()) &&
QUICHE team2252b702019-05-14 23:55:14 -0400572 !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) -
nharper55fa6132019-05-07 19:37:21 -0700573 plaintext_bytes_written)) {
574 QUIC_BUG << "Unable to add padding bytes";
575 return;
576 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500577
578 if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset,
579 packet_.encryption_level)) {
580 return;
581 }
582
fayangcff885a2019-10-22 07:39:04 -0700583 packet_.transmission_type = transmission_type;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500584
585 size_t encrypted_length = framer_->EncryptInPlace(
586 packet_.encryption_level, packet_.packet_number,
587 GetStartOfEncryptedData(framer_->transport_version(), header),
dschinazi66dea072019-04-09 11:41:06 -0700588 writer.length(), kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500589 if (encrypted_length == 0) {
590 QUIC_BUG << "Failed to encrypt packet number " << header.packet_number;
591 return;
592 }
593 // TODO(ianswett): Optimize the storage so RetransmitableFrames can be
594 // unioned with a QuicStreamFrame and a UniqueStreamBuffer.
595 *num_bytes_consumed = bytes_consumed;
596 packet_size_ = 0;
597 packet_.encrypted_buffer = encrypted_buffer;
598 packet_.encrypted_length = encrypted_length;
599 packet_.retransmittable_frames.push_back(QuicFrame(frame));
600 OnSerializedPacket();
601}
602
603bool QuicPacketCreator::HasPendingFrames() const {
604 return !queued_frames_.empty();
605}
606
607bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
608 return !packet_.retransmittable_frames.empty();
609}
610
611bool QuicPacketCreator::HasPendingStreamFramesOfStream(QuicStreamId id) const {
612 for (const auto& frame : packet_.retransmittable_frames) {
613 if (frame.type == STREAM_FRAME && frame.stream_frame.stream_id == id) {
614 return true;
615 }
616 }
617 return false;
618}
619
620size_t QuicPacketCreator::ExpansionOnNewFrame() const {
621 // If the last frame in the packet is a message frame, then it will expand to
622 // include the varint message length when a new frame is added.
623 const bool has_trailing_message_frame =
624 !queued_frames_.empty() && queued_frames_.back().type == MESSAGE_FRAME;
625 if (has_trailing_message_frame) {
626 return QuicDataWriter::GetVarInt62Len(
627 queued_frames_.back().message_frame->message_length);
628 }
629 // If the last frame in the packet is a stream frame, then it will expand to
630 // include the stream_length field when a new frame is added.
631 const bool has_trailing_stream_frame =
632 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME;
633 if (!has_trailing_stream_frame) {
634 return 0;
635 }
fkastenholz305e1732019-06-18 05:01:22 -0700636 if (VersionHasIetfQuicFrames(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500637 return QuicDataWriter::GetVarInt62Len(
638 queued_frames_.back().stream_frame.data_length);
639 }
640 return kQuicStreamPayloadLengthSize;
641}
642
643size_t QuicPacketCreator::BytesFree() {
644 DCHECK_GE(max_plaintext_size_, PacketSize());
645 return max_plaintext_size_ -
646 std::min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
647}
648
649size_t QuicPacketCreator::PacketSize() {
650 if (!queued_frames_.empty()) {
651 return packet_size_;
652 }
nharper55fa6132019-05-07 19:37:21 -0700653 packet_size_ = PacketHeaderSize();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500654 return packet_size_;
655}
656
QUICHE teama6ef0a62019-03-07 20:34:33 -0500657bool QuicPacketCreator::AddPaddedSavedFrame(
658 const QuicFrame& frame,
659 TransmissionType transmission_type) {
fayang347ab752019-10-22 11:17:43 -0700660 if (AddFrame(frame, transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500661 needs_full_padding_ = true;
662 return true;
663 }
664 return false;
665}
666
667void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
668 size_t encrypted_buffer_len) {
669 DCHECK_LT(0u, encrypted_buffer_len);
670 QUIC_BUG_IF(queued_frames_.empty() && pending_padding_bytes_ == 0)
671 << "Attempt to serialize empty packet";
672 QuicPacketHeader header;
673 // FillPacketHeader increments packet_number_.
674 FillPacketHeader(&header);
675
676 MaybeAddPadding();
677
dschinazi118934b2019-06-13 18:09:08 -0700678 QUIC_DVLOG(2) << ENDPOINT << "Serializing packet " << header
wub031d47c2019-11-21 08:04:07 -0800679 << QuicFramesToString(queued_frames_) << " at encryption_level "
680 << EncryptionLevelToString(packet_.encryption_level);
dschinazi118934b2019-06-13 18:09:08 -0700681
QUICHE teama6ef0a62019-03-07 20:34:33 -0500682 DCHECK_GE(max_plaintext_size_, packet_size_);
683 // Use the packet_size_ instead of the buffer size to ensure smaller
684 // packet sizes are properly used.
685 size_t length =
686 framer_->BuildDataPacket(header, queued_frames_, encrypted_buffer,
687 packet_size_, packet_.encryption_level);
688 if (length == 0) {
689 QUIC_BUG << "Failed to serialize " << queued_frames_.size() << " frames.";
690 return;
691 }
692
693 // ACK Frames will be truncated due to length only if they're the only frame
694 // in the packet, and if packet_size_ was set to max_plaintext_size_. If
695 // truncation due to length occurred, then GetSerializedFrameLength will have
696 // returned all bytes free.
697 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
698 queued_frames_.size() == 1 &&
699 queued_frames_.back().type == ACK_FRAME;
700 // Because of possible truncation, we can't be confident that our
701 // packet size calculation worked correctly.
702 if (!possibly_truncated_by_length) {
703 DCHECK_EQ(packet_size_, length);
704 }
705 const size_t encrypted_length = framer_->EncryptInPlace(
706 packet_.encryption_level, packet_.packet_number,
707 GetStartOfEncryptedData(framer_->transport_version(), header), length,
708 encrypted_buffer_len, encrypted_buffer);
709 if (encrypted_length == 0) {
710 QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number;
711 return;
712 }
713
714 packet_size_ = 0;
715 queued_frames_.clear();
716 packet_.encrypted_buffer = encrypted_buffer;
717 packet_.encrypted_length = encrypted_length;
718}
719
720std::unique_ptr<QuicEncryptedPacket>
721QuicPacketCreator::SerializeVersionNegotiationPacket(
722 bool ietf_quic,
dschinazi48ac9192019-07-31 00:07:26 -0700723 bool use_length_prefix,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500724 const ParsedQuicVersionVector& supported_versions) {
725 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
726 std::unique_ptr<QuicEncryptedPacket> encrypted =
dschinazi48ac9192019-07-31 00:07:26 -0700727 QuicFramer::BuildVersionNegotiationPacket(
728 server_connection_id_, client_connection_id_, ietf_quic,
729 use_length_prefix, supported_versions);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500730 DCHECK(encrypted);
731 DCHECK_GE(max_packet_length_, encrypted->length());
732 return encrypted;
733}
734
735OwningSerializedPacketPointer
736QuicPacketCreator::SerializeConnectivityProbingPacket() {
fkastenholz305e1732019-06-18 05:01:22 -0700737 QUIC_BUG_IF(VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500738 << "Must not be version 99 to serialize padded ping connectivity probe";
fayang2ab1e852019-11-04 11:24:36 -0800739 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500740 QuicPacketHeader header;
741 // FillPacketHeader increments packet_number_.
742 FillPacketHeader(&header);
743
dschinazi118934b2019-06-13 18:09:08 -0700744 QUIC_DVLOG(2) << ENDPOINT << "Serializing connectivity probing packet "
745 << header;
746
dschinazi66dea072019-04-09 11:41:06 -0700747 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700748 size_t length = BuildConnectivityProbingPacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500749 header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
750 DCHECK(length);
751
752 const size_t encrypted_length = framer_->EncryptInPlace(
753 packet_.encryption_level, packet_.packet_number,
754 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700755 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500756 DCHECK(encrypted_length);
757
758 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
759 header.packet_number, header.packet_number_length, buffer.release(),
760 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
761
762 serialize_packet->encryption_level = packet_.encryption_level;
763 serialize_packet->transmission_type = NOT_RETRANSMISSION;
764
765 return serialize_packet;
766}
767
768OwningSerializedPacketPointer
769QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
770 QuicPathFrameBuffer* payload) {
fkastenholz305e1732019-06-18 05:01:22 -0700771 QUIC_BUG_IF(!VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500772 << "Must be version 99 to serialize path challenge connectivity probe, "
773 "is version "
774 << framer_->transport_version();
fayang2ab1e852019-11-04 11:24:36 -0800775 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500776 QuicPacketHeader header;
777 // FillPacketHeader increments packet_number_.
778 FillPacketHeader(&header);
779
dschinazi118934b2019-06-13 18:09:08 -0700780 QUIC_DVLOG(2) << ENDPOINT << "Serializing path challenge packet " << header;
781
dschinazi66dea072019-04-09 11:41:06 -0700782 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700783 size_t length = BuildPaddedPathChallengePacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500784 header, buffer.get(), max_plaintext_size_, payload, random_,
785 packet_.encryption_level);
786 DCHECK(length);
787
788 const size_t encrypted_length = framer_->EncryptInPlace(
789 packet_.encryption_level, packet_.packet_number,
790 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700791 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500792 DCHECK(encrypted_length);
793
794 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
795 header.packet_number, header.packet_number_length, buffer.release(),
796 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
797
798 serialize_packet->encryption_level = packet_.encryption_level;
799 serialize_packet->transmission_type = NOT_RETRANSMISSION;
800
801 return serialize_packet;
802}
803
804OwningSerializedPacketPointer
805QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
wuba750aab2020-02-10 06:43:15 -0800806 const QuicCircularDeque<QuicPathFrameBuffer>& payloads,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500807 const bool is_padded) {
fkastenholz305e1732019-06-18 05:01:22 -0700808 QUIC_BUG_IF(!VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500809 << "Must be version 99 to serialize path response connectivity probe, is "
810 "version "
811 << framer_->transport_version();
fayang2ab1e852019-11-04 11:24:36 -0800812 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500813 QuicPacketHeader header;
814 // FillPacketHeader increments packet_number_.
815 FillPacketHeader(&header);
816
dschinazi118934b2019-06-13 18:09:08 -0700817 QUIC_DVLOG(2) << ENDPOINT << "Serializing path response packet " << header;
818
dschinazi66dea072019-04-09 11:41:06 -0700819 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700820 size_t length =
821 BuildPathResponsePacket(header, buffer.get(), max_plaintext_size_,
822 payloads, is_padded, packet_.encryption_level);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500823 DCHECK(length);
824
825 const size_t encrypted_length = framer_->EncryptInPlace(
826 packet_.encryption_level, packet_.packet_number,
827 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700828 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500829 DCHECK(encrypted_length);
830
831 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
832 header.packet_number, header.packet_number_length, buffer.release(),
833 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
834
835 serialize_packet->encryption_level = packet_.encryption_level;
836 serialize_packet->transmission_type = NOT_RETRANSMISSION;
837
838 return serialize_packet;
839}
840
renjietang4c704c82019-10-07 16:39:11 -0700841size_t QuicPacketCreator::BuildPaddedPathChallengePacket(
842 const QuicPacketHeader& header,
843 char* buffer,
844 size_t packet_length,
845 QuicPathFrameBuffer* payload,
846 QuicRandom* randomizer,
847 EncryptionLevel level) {
848 DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()));
849 QuicFrames frames;
850
851 // Write a PATH_CHALLENGE frame, which has a random 8-byte payload
852 randomizer->RandBytes(payload->data(), payload->size());
853 QuicPathChallengeFrame path_challenge_frame(0, *payload);
854 frames.push_back(QuicFrame(&path_challenge_frame));
855
856 if (debug_delegate_ != nullptr) {
857 debug_delegate_->OnFrameAddedToPacket(QuicFrame(&path_challenge_frame));
858 }
859
860 // Add padding to the rest of the packet in order to assess Path MTU
861 // characteristics.
862 QuicPaddingFrame padding_frame;
863 frames.push_back(QuicFrame(padding_frame));
864
865 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
866}
867
868size_t QuicPacketCreator::BuildPathResponsePacket(
869 const QuicPacketHeader& header,
870 char* buffer,
871 size_t packet_length,
wuba750aab2020-02-10 06:43:15 -0800872 const QuicCircularDeque<QuicPathFrameBuffer>& payloads,
renjietang4c704c82019-10-07 16:39:11 -0700873 const bool is_padded,
874 EncryptionLevel level) {
875 if (payloads.empty()) {
876 QUIC_BUG
877 << "Attempt to generate connectivity response with no request payloads";
878 return 0;
879 }
880 DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()));
881
882 std::vector<std::unique_ptr<QuicPathResponseFrame>> path_response_frames;
883 for (const QuicPathFrameBuffer& payload : payloads) {
884 // Note that the control frame ID can be 0 since this is not retransmitted.
885 path_response_frames.push_back(
886 std::make_unique<QuicPathResponseFrame>(0, payload));
887 }
888
889 QuicFrames frames;
890 for (const std::unique_ptr<QuicPathResponseFrame>& path_response_frame :
891 path_response_frames) {
892 frames.push_back(QuicFrame(path_response_frame.get()));
893 if (debug_delegate_ != nullptr) {
894 debug_delegate_->OnFrameAddedToPacket(
895 QuicFrame(path_response_frame.get()));
896 }
897 }
898
899 if (is_padded) {
900 // Add padding to the rest of the packet in order to assess Path MTU
901 // characteristics.
902 QuicPaddingFrame padding_frame;
903 frames.push_back(QuicFrame(padding_frame));
904 }
905
906 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
907}
908
909size_t QuicPacketCreator::BuildConnectivityProbingPacket(
910 const QuicPacketHeader& header,
911 char* buffer,
912 size_t packet_length,
913 EncryptionLevel level) {
914 QuicFrames frames;
915
916 // Write a PING frame, which has no data payload.
917 QuicPingFrame ping_frame;
918 frames.push_back(QuicFrame(ping_frame));
919
920 // Add padding to the rest of the packet.
921 QuicPaddingFrame padding_frame;
922 frames.push_back(QuicFrame(padding_frame));
923
924 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
925}
926
fayang08750832019-10-24 11:25:34 -0700927size_t QuicPacketCreator::SerializeCoalescedPacket(
928 const QuicCoalescedPacket& coalesced,
929 char* buffer,
930 size_t buffer_len) {
931 QUIC_BUG_IF(packet_.num_padding_bytes != 0);
932 if (HasPendingFrames()) {
933 QUIC_BUG << "Try to serialize coalesced packet with pending frames";
934 return 0;
935 }
fayang58f71072019-11-05 08:47:02 -0800936 RemoveSoftMaxPacketLength();
fayang08750832019-10-24 11:25:34 -0700937 QUIC_BUG_IF(coalesced.length() == 0)
938 << "Attempt to serialize empty coalesced packet";
939 size_t packet_length = 0;
940 if (coalesced.initial_packet() != nullptr) {
fayang9abdfec2020-02-13 12:34:58 -0800941 // Padding coalesced packet containing initial packet to full.
942 size_t padding_size = coalesced.max_packet_length() - coalesced.length();
943 if (framer_->perspective() == Perspective::IS_SERVER &&
944 QuicUtils::ContainsFrameType(
945 coalesced.initial_packet()->retransmittable_frames,
946 CONNECTION_CLOSE_FRAME)) {
947 // Do not pad server initial connection close packet.
948 padding_size = 0;
949 }
fayang08750832019-10-24 11:25:34 -0700950 size_t initial_length = ReserializeInitialPacketInCoalescedPacket(
fayang9abdfec2020-02-13 12:34:58 -0800951 *coalesced.initial_packet(), padding_size, buffer, buffer_len);
fayang08750832019-10-24 11:25:34 -0700952 if (initial_length == 0) {
953 QUIC_BUG << "Failed to reserialize ENCRYPTION_INITIAL packet in "
954 "coalesced packet";
955 return 0;
956 }
957 buffer += initial_length;
958 buffer_len -= initial_length;
959 packet_length += initial_length;
960 }
961 size_t length_copied = 0;
962 if (!coalesced.CopyEncryptedBuffers(buffer, buffer_len, &length_copied)) {
963 return 0;
964 }
965 packet_length += length_copied;
966 QUIC_DVLOG(1) << ENDPOINT
967 << "Successfully serialized coalesced packet of length: "
968 << packet_length;
969 return packet_length;
970}
971
QUICHE teama6ef0a62019-03-07 20:34:33 -0500972// TODO(b/74062209): Make this a public method of framer?
973SerializedPacket QuicPacketCreator::NoPacket() {
974 return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
975 nullptr, 0, false, false);
976}
977
QUICHE team2252b702019-05-14 23:55:14 -0400978QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -0400979 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi346b7ce2019-06-05 01:38:18 -0700980 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400981 }
dschinazi7b9278c2019-05-20 07:36:21 -0700982 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400983}
984
985QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -0400986 if (framer_->perspective() == Perspective::IS_CLIENT) {
dschinazi346b7ce2019-06-05 01:38:18 -0700987 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400988 }
dschinazi7b9278c2019-05-20 07:36:21 -0700989 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400990}
991
QUICHE teama6ef0a62019-03-07 20:34:33 -0500992QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
993 const {
dschinazi5e1a7b22019-07-31 12:23:21 -0700994 // In versions that do not support client connection IDs, the destination
995 // connection ID is only sent from client to server.
996 return (framer_->perspective() == Perspective::IS_CLIENT ||
997 framer_->version().SupportsClientConnectionIds())
998 ? CONNECTION_ID_PRESENT
999 : CONNECTION_ID_ABSENT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001000}
1001
1002QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
1003 const {
1004 // Long header packets sent by server include source connection ID.
dschinazi346b7ce2019-06-05 01:38:18 -07001005 // Ones sent by the client only include source connection ID if the version
1006 // supports client connection IDs.
1007 if (HasIetfLongHeader() &&
1008 (framer_->perspective() == Perspective::IS_SERVER ||
1009 framer_->version().SupportsClientConnectionIds())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001010 return CONNECTION_ID_PRESENT;
1011 }
dschinazi5e1a7b22019-07-31 12:23:21 -07001012 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi7b9278c2019-05-20 07:36:21 -07001013 return server_connection_id_included_;
QUICHE team2252b702019-05-14 23:55:14 -04001014 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001015 return CONNECTION_ID_ABSENT;
1016}
1017
1018QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
1019 const {
dschinazi7b9278c2019-05-20 07:36:21 -07001020 DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001021 transport_version()));
1022 return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -04001023 ? static_cast<QuicConnectionIdLength>(
1024 GetDestinationConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001025 : PACKET_0BYTE_CONNECTION_ID;
1026}
1027
1028QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
dschinazi7b9278c2019-05-20 07:36:21 -07001029 DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001030 transport_version()));
1031 return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -04001032 ? static_cast<QuicConnectionIdLength>(
1033 GetSourceConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001034 : PACKET_0BYTE_CONNECTION_ID;
1035}
1036
1037QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
fayang3ac15c12019-06-14 14:04:51 -07001038 if (HasIetfLongHeader() &&
1039 !framer_->version().SendsVariableLengthPacketNumberInLongHeader()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001040 return PACKET_4BYTE_PACKET_NUMBER;
1041 }
1042 return packet_.packet_number_length;
1043}
1044
nharper55fa6132019-05-07 19:37:21 -07001045size_t QuicPacketCreator::PacketHeaderSize() const {
1046 return GetPacketHeaderSize(
1047 framer_->transport_version(), GetDestinationConnectionIdLength(),
1048 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
1049 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
1050 GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
1051}
1052
QUICHE teama6ef0a62019-03-07 20:34:33 -05001053QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
1054 const {
1055 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1056 HasIetfLongHeader() &&
1057 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
1058 return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
1059 }
1060 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
1061}
1062
dmcardlecf0bfcf2019-12-13 08:08:21 -08001063quiche::QuicheStringPiece QuicPacketCreator::GetRetryToken() const {
dschinazi0db87092019-05-20 07:59:15 -07001064 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1065 HasIetfLongHeader() &&
1066 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
1067 return retry_token_;
1068 }
dmcardlecf0bfcf2019-12-13 08:08:21 -08001069 return quiche::QuicheStringPiece();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001070}
1071
dmcardlecf0bfcf2019-12-13 08:08:21 -08001072void QuicPacketCreator::SetRetryToken(quiche::QuicheStringPiece retry_token) {
vasilvvc48c8712019-03-11 13:38:16 -07001073 retry_token_ = std::string(retry_token);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001074}
1075
fayang18be79a2019-09-16 15:17:12 -07001076bool QuicPacketCreator::ConsumeRetransmittableControlFrame(
1077 const QuicFrame& frame) {
fayang18be79a2019-09-16 15:17:12 -07001078 QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame))
1079 << "Adding a control frame with no control frame id: " << frame;
1080 DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame;
1081 MaybeBundleAckOpportunistically();
1082 if (HasPendingFrames()) {
renjietangb63005e2019-11-19 23:08:53 -08001083 if (AddFrame(frame, next_transmission_type_)) {
fayang18be79a2019-09-16 15:17:12 -07001084 // There is pending frames and current frame fits.
1085 return true;
1086 }
1087 }
1088 DCHECK(!HasPendingFrames());
1089 if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME &&
1090 !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
1091 NOT_HANDSHAKE)) {
1092 // Do not check congestion window for ping or connection close frames.
1093 return false;
1094 }
renjietangb63005e2019-11-19 23:08:53 -08001095 const bool success = AddFrame(frame, next_transmission_type_);
ianswettbd78ea12019-09-26 06:32:37 -07001096 QUIC_BUG_IF(!success) << "Failed to add frame:" << frame
1097 << " transmission_type:" << next_transmission_type_;
fayang18be79a2019-09-16 15:17:12 -07001098 return success;
1099}
1100
1101QuicConsumedData QuicPacketCreator::ConsumeData(QuicStreamId id,
1102 size_t write_length,
1103 QuicStreamOffset offset,
1104 StreamSendingState state) {
fayang18be79a2019-09-16 15:17:12 -07001105 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1106 "generator tries to write stream data.";
1107 bool has_handshake = QuicUtils::IsCryptoStreamId(transport_version(), id);
1108 MaybeBundleAckOpportunistically();
1109 bool fin = state != NO_FIN;
1110 QUIC_BUG_IF(has_handshake && fin)
1111 << "Handshake packets should never send a fin";
1112 // To make reasoning about crypto frames easier, we don't combine them with
1113 // other retransmittable frames in a single packet.
1114 if (has_handshake && HasPendingRetransmittableFrames()) {
1115 FlushCurrentPacket();
1116 }
1117
1118 size_t total_bytes_consumed = 0;
1119 bool fin_consumed = false;
1120
1121 if (!HasRoomForStreamFrame(id, offset, write_length)) {
1122 FlushCurrentPacket();
1123 }
1124
1125 if (!fin && (write_length == 0)) {
1126 QUIC_BUG << "Attempt to consume empty data without FIN.";
1127 return QuicConsumedData(0, false);
1128 }
1129 // We determine if we can enter the fast path before executing
1130 // the slow path loop.
1131 bool run_fast_path =
1132 !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
fayang2ab1e852019-11-04 11:24:36 -08001133 write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
1134 latched_hard_max_packet_length_ == 0;
fayang18be79a2019-09-16 15:17:12 -07001135
1136 while (!run_fast_path && delegate_->ShouldGeneratePacket(
1137 HAS_RETRANSMITTABLE_DATA,
1138 has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) {
1139 QuicFrame frame;
1140 bool needs_full_padding =
1141 has_handshake && fully_pad_crypto_handshake_packets_;
1142
1143 if (!ConsumeDataToFillCurrentPacket(id, write_length - total_bytes_consumed,
1144 offset + total_bytes_consumed, fin,
1145 needs_full_padding,
1146 next_transmission_type_, &frame)) {
1147 // The creator is always flushed if there's not enough room for a new
1148 // stream frame before ConsumeData, so ConsumeData should always succeed.
1149 QUIC_BUG << "Failed to ConsumeData, stream:" << id;
1150 return QuicConsumedData(0, false);
1151 }
1152
1153 // A stream frame is created and added.
1154 size_t bytes_consumed = frame.stream_frame.data_length;
1155 total_bytes_consumed += bytes_consumed;
1156 fin_consumed = fin && total_bytes_consumed == write_length;
1157 if (fin_consumed && state == FIN_AND_PADDING) {
1158 AddRandomPadding();
1159 }
1160 DCHECK(total_bytes_consumed == write_length ||
1161 (bytes_consumed > 0 && HasPendingFrames()));
1162
1163 if (total_bytes_consumed == write_length) {
1164 // We're done writing the data. Exit the loop.
1165 // We don't make this a precondition because we could have 0 bytes of data
1166 // if we're simply writing a fin.
1167 break;
1168 }
1169 FlushCurrentPacket();
1170
1171 run_fast_path =
1172 !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
fayang2ab1e852019-11-04 11:24:36 -08001173 write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
1174 latched_hard_max_packet_length_ == 0;
fayang18be79a2019-09-16 15:17:12 -07001175 }
1176
1177 if (run_fast_path) {
1178 return ConsumeDataFastPath(id, write_length, offset, state != NO_FIN,
1179 total_bytes_consumed);
1180 }
1181
1182 // Don't allow the handshake to be bundled with other retransmittable frames.
1183 if (has_handshake) {
1184 FlushCurrentPacket();
1185 }
1186
1187 return QuicConsumedData(total_bytes_consumed, fin_consumed);
1188}
1189
1190QuicConsumedData QuicPacketCreator::ConsumeDataFastPath(
1191 QuicStreamId id,
1192 size_t write_length,
1193 QuicStreamOffset offset,
1194 bool fin,
1195 size_t total_bytes_consumed) {
fayang18be79a2019-09-16 15:17:12 -07001196 DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
1197
1198 while (total_bytes_consumed < write_length &&
1199 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
1200 NOT_HANDSHAKE)) {
1201 // Serialize and encrypt the packet.
1202 size_t bytes_consumed = 0;
1203 CreateAndSerializeStreamFrame(id, write_length, total_bytes_consumed,
1204 offset + total_bytes_consumed, fin,
1205 next_transmission_type_, &bytes_consumed);
fayangaf2cdfd2020-01-06 10:52:12 -08001206 if (bytes_consumed == 0) {
1207 const std::string error_details =
1208 "Failed in CreateAndSerializeStreamFrame.";
1209 QUIC_BUG << error_details;
1210 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
1211 error_details);
1212 break;
fayangd99c2c12019-11-08 13:22:51 -08001213 }
fayang18be79a2019-09-16 15:17:12 -07001214 total_bytes_consumed += bytes_consumed;
1215 }
1216
1217 return QuicConsumedData(total_bytes_consumed,
1218 fin && (total_bytes_consumed == write_length));
1219}
1220
1221size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
1222 size_t write_length,
1223 QuicStreamOffset offset) {
fayang18be79a2019-09-16 15:17:12 -07001224 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1225 "generator tries to write crypto data.";
1226 MaybeBundleAckOpportunistically();
1227 // To make reasoning about crypto frames easier, we don't combine them with
1228 // other retransmittable frames in a single packet.
1229 // TODO(nharper): Once we have separate packet number spaces, everything
1230 // should be driven by encryption level, and we should stop flushing in this
1231 // spot.
1232 if (HasPendingRetransmittableFrames()) {
1233 FlushCurrentPacket();
1234 }
1235
1236 size_t total_bytes_consumed = 0;
1237
1238 while (total_bytes_consumed < write_length) {
1239 QuicFrame frame;
1240 if (!ConsumeCryptoDataToFillCurrentPacket(
1241 level, write_length - total_bytes_consumed,
1242 offset + total_bytes_consumed, fully_pad_crypto_handshake_packets_,
1243 next_transmission_type_, &frame)) {
1244 // The only pending data in the packet is non-retransmittable frames. I'm
1245 // assuming here that they won't occupy so much of the packet that a
1246 // CRYPTO frame won't fit.
1247 QUIC_BUG << "Failed to ConsumeCryptoData at level " << level;
1248 return 0;
1249 }
1250 total_bytes_consumed += frame.crypto_frame->data_length;
1251 FlushCurrentPacket();
1252 }
1253
1254 // Don't allow the handshake to be bundled with other retransmittable frames.
1255 FlushCurrentPacket();
1256
1257 return total_bytes_consumed;
1258}
1259
1260void QuicPacketCreator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
fayang18be79a2019-09-16 15:17:12 -07001261 // MTU discovery frames must be sent by themselves.
1262 if (!CanSetMaxPacketLength()) {
1263 QUIC_BUG << "MTU discovery packets should only be sent when no other "
1264 << "frames needs to be sent.";
1265 return;
1266 }
1267 const QuicByteCount current_mtu = max_packet_length();
1268
1269 // The MTU discovery frame is allocated on the stack, since it is going to be
1270 // serialized within this function.
1271 QuicMtuDiscoveryFrame mtu_discovery_frame;
1272 QuicFrame frame(mtu_discovery_frame);
1273
1274 // Send the probe packet with the new length.
1275 SetMaxPacketLength(target_mtu);
1276 const bool success = AddPaddedSavedFrame(frame, next_transmission_type_);
1277 FlushCurrentPacket();
1278 // The only reason AddFrame can fail is that the packet is too full to fit in
1279 // a ping. This is not possible for any sane MTU.
ianswettbd78ea12019-09-26 06:32:37 -07001280 QUIC_BUG_IF(!success) << "Failed to send path MTU target_mtu:" << target_mtu
1281 << " transmission_type:" << next_transmission_type_;
fayang18be79a2019-09-16 15:17:12 -07001282
1283 // Reset the packet length back.
1284 SetMaxPacketLength(current_mtu);
1285}
1286
1287void QuicPacketCreator::MaybeBundleAckOpportunistically() {
fayang18be79a2019-09-16 15:17:12 -07001288 if (has_ack()) {
1289 // Ack already queued, nothing to do.
1290 return;
1291 }
1292 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
1293 NOT_HANDSHAKE)) {
1294 return;
1295 }
1296 const bool flushed =
1297 FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
ianswettbd78ea12019-09-26 06:32:37 -07001298 QUIC_BUG_IF(!flushed) << "Failed to flush ACK frame. encryption_level:"
1299 << packet_.encryption_level;
fayang18be79a2019-09-16 15:17:12 -07001300}
1301
1302bool QuicPacketCreator::FlushAckFrame(const QuicFrames& frames) {
fayang18be79a2019-09-16 15:17:12 -07001303 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1304 "generator tries to send ACK frame.";
1305 for (const auto& frame : frames) {
1306 DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME);
1307 if (HasPendingFrames()) {
renjietangb63005e2019-11-19 23:08:53 -08001308 if (AddFrame(frame, next_transmission_type_)) {
fayang18be79a2019-09-16 15:17:12 -07001309 // There is pending frames and current frame fits.
1310 continue;
1311 }
1312 }
1313 DCHECK(!HasPendingFrames());
1314 // There is no pending frames, consult the delegate whether a packet can be
1315 // generated.
1316 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
1317 NOT_HANDSHAKE)) {
1318 return false;
1319 }
renjietangb63005e2019-11-19 23:08:53 -08001320 const bool success = AddFrame(frame, next_transmission_type_);
fayang18be79a2019-09-16 15:17:12 -07001321 QUIC_BUG_IF(!success) << "Failed to flush " << frame;
1322 }
1323 return true;
1324}
1325
1326void QuicPacketCreator::AddRandomPadding() {
fayang18be79a2019-09-16 15:17:12 -07001327 AddPendingPadding(random_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
1328}
1329
1330void QuicPacketCreator::AttachPacketFlusher() {
fayang18be79a2019-09-16 15:17:12 -07001331 flusher_attached_ = true;
1332 if (!write_start_packet_number_.IsInitialized()) {
1333 write_start_packet_number_ = NextSendingPacketNumber();
1334 }
1335}
1336
1337void QuicPacketCreator::Flush() {
fayang18be79a2019-09-16 15:17:12 -07001338 FlushCurrentPacket();
1339 SendRemainingPendingPadding();
1340 flusher_attached_ = false;
1341 if (GetQuicFlag(FLAGS_quic_export_server_num_packets_per_write_histogram)) {
1342 if (!write_start_packet_number_.IsInitialized()) {
1343 QUIC_BUG << "write_start_packet_number is not initialized";
1344 return;
1345 }
1346 QUIC_SERVER_HISTOGRAM_COUNTS(
1347 "quic_server_num_written_packets_per_write",
1348 NextSendingPacketNumber() - write_start_packet_number_, 1, 200, 50,
1349 "Number of QUIC packets written per write operation");
1350 }
1351 write_start_packet_number_.Clear();
1352}
1353
1354void QuicPacketCreator::SendRemainingPendingPadding() {
fayang18be79a2019-09-16 15:17:12 -07001355 while (
1356 pending_padding_bytes() > 0 && !HasPendingFrames() &&
1357 delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) {
1358 FlushCurrentPacket();
1359 }
1360}
1361
1362void QuicPacketCreator::SetServerConnectionIdLength(uint32_t length) {
fayang18be79a2019-09-16 15:17:12 -07001363 if (length == 0) {
1364 SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
1365 } else {
1366 SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
1367 }
1368}
1369
1370void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
fayangcff885a2019-10-22 07:39:04 -07001371 next_transmission_type_ = type;
fayang18be79a2019-09-16 15:17:12 -07001372}
1373
1374MessageStatus QuicPacketCreator::AddMessageFrame(QuicMessageId message_id,
1375 QuicMemSliceSpan message) {
fayang18be79a2019-09-16 15:17:12 -07001376 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1377 "generator tries to add message frame.";
1378 MaybeBundleAckOpportunistically();
1379 const QuicByteCount message_length = message.total_length();
1380 if (message_length > GetCurrentLargestMessagePayload()) {
1381 return MESSAGE_STATUS_TOO_LARGE;
1382 }
1383 if (!HasRoomForMessageFrame(message_length)) {
1384 FlushCurrentPacket();
1385 }
1386 QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
renjietangb63005e2019-11-19 23:08:53 -08001387 const bool success = AddFrame(QuicFrame(frame), next_transmission_type_);
fayang18be79a2019-09-16 15:17:12 -07001388 if (!success) {
1389 QUIC_BUG << "Failed to send message " << message_id;
1390 delete frame;
1391 return MESSAGE_STATUS_INTERNAL_ERROR;
1392 }
1393 return MESSAGE_STATUS_SUCCESS;
1394}
1395
QUICHE teama6ef0a62019-03-07 20:34:33 -05001396QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
1397 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1398 HasIetfLongHeader()) {
1399 QuicLongHeaderType long_header_type =
1400 EncryptionlevelToLongHeaderType(packet_.encryption_level);
1401 if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
1402 long_header_type == HANDSHAKE) {
1403 return VARIABLE_LENGTH_INTEGER_LENGTH_2;
1404 }
1405 }
1406 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
1407}
1408
1409void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
QUICHE team2252b702019-05-14 23:55:14 -04001410 header->destination_connection_id = GetDestinationConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001411 header->destination_connection_id_included =
1412 GetDestinationConnectionIdIncluded();
QUICHE team2252b702019-05-14 23:55:14 -04001413 header->source_connection_id = GetSourceConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001414 header->source_connection_id_included = GetSourceConnectionIdIncluded();
1415 header->reset_flag = false;
1416 header->version_flag = IncludeVersionInHeader();
1417 if (IncludeNonceInPublicHeader()) {
1418 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
1419 header->nonce = &diversification_nonce_;
1420 } else {
1421 header->nonce = nullptr;
1422 }
fayang354c9422019-05-21 08:10:35 -07001423 packet_.packet_number = NextSendingPacketNumber();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001424 header->packet_number = packet_.packet_number;
1425 header->packet_number_length = GetPacketNumberLength();
1426 header->retry_token_length_length = GetRetryTokenLengthLength();
1427 header->retry_token = GetRetryToken();
1428 header->length_length = GetLengthLength();
1429 header->remaining_packet_length = 0;
1430 if (!HasIetfLongHeader()) {
1431 return;
1432 }
1433 header->long_packet_type =
1434 EncryptionlevelToLongHeaderType(packet_.encryption_level);
1435}
1436
1437bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001438 TransmissionType transmission_type) {
1439 QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
dschinazief79a5f2019-10-04 10:32:54 -07001440 << TransmissionTypeToString(transmission_type) << ": " << frame;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001441 if (frame.type == STREAM_FRAME &&
nharper46833c32019-05-15 21:33:05 -07001442 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
1443 frame.stream_frame.stream_id) &&
fayang49523232019-05-03 06:28:22 -07001444 (packet_.encryption_level == ENCRYPTION_INITIAL ||
1445 packet_.encryption_level == ENCRYPTION_HANDSHAKE)) {
dschinazief79a5f2019-10-04 10:32:54 -07001446 const std::string error_details =
dmcardlecf0bfcf2019-12-13 08:08:21 -08001447 quiche::QuicheStrCat("Cannot send stream data with level: ",
1448 EncryptionLevelToString(packet_.encryption_level));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001449 QUIC_BUG << error_details;
1450 delegate_->OnUnrecoverableError(
fkastenholz85f18902019-05-28 12:47:00 -07001451 QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001452 return false;
1453 }
renjietangdbe98342019-10-18 11:00:57 -07001454
renjietange426d622020-01-02 11:58:46 -08001455 if (frame.type == STREAM_FRAME) {
renjietang50ea92a2019-12-26 10:15:01 -08001456 if (MaybeCoalesceStreamFrame(frame.stream_frame)) {
1457 LogCoalesceStreamFrameStatus(true);
renjietang50ea92a2019-12-26 10:15:01 -08001458 return true;
1459 } else {
1460 LogCoalesceStreamFrameStatus(false);
1461 }
renjietangdbe98342019-10-18 11:00:57 -07001462 }
1463
QUICHE teama6ef0a62019-03-07 20:34:33 -05001464 size_t frame_len = framer_->GetSerializedFrameLength(
1465 frame, BytesFree(), queued_frames_.empty(),
1466 /* last_frame_in_packet= */ true, GetPacketNumberLength());
fayang2ab1e852019-11-04 11:24:36 -08001467 if (frame_len == 0 && RemoveSoftMaxPacketLength()) {
1468 // Remove soft max_packet_length and retry.
1469 frame_len = framer_->GetSerializedFrameLength(
1470 frame, BytesFree(), queued_frames_.empty(),
1471 /* last_frame_in_packet= */ true, GetPacketNumberLength());
1472 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001473 if (frame_len == 0) {
1474 // Current open packet is full.
fayang62b637b2019-09-16 08:40:49 -07001475 FlushCurrentPacket();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001476 return false;
1477 }
1478 DCHECK_LT(0u, packet_size_);
1479
1480 packet_size_ += ExpansionOnNewFrame() + frame_len;
1481
fayang347ab752019-10-22 11:17:43 -07001482 if (QuicUtils::IsRetransmittableFrame(frame.type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001483 packet_.retransmittable_frames.push_back(frame);
1484 queued_frames_.push_back(frame);
1485 if (QuicUtils::IsHandshakeFrame(frame, framer_->transport_version())) {
1486 packet_.has_crypto_handshake = IS_HANDSHAKE;
1487 }
1488 } else {
fayang02a28742019-12-04 07:09:38 -08001489 if (frame.type == PADDING_FRAME &&
1490 frame.padding_frame.num_padding_bytes == -1) {
1491 // Populate the actual length of full padding frame, such that one can
1492 // know how much padding is actually added.
1493 packet_.nonretransmittable_frames.push_back(
1494 QuicFrame(QuicPaddingFrame(frame_len)));
1495 } else {
1496 packet_.nonretransmittable_frames.push_back(frame);
fayang51152fd2019-10-21 06:48:09 -07001497 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001498 queued_frames_.push_back(frame);
1499 }
1500
1501 if (frame.type == ACK_FRAME) {
1502 packet_.has_ack = true;
1503 packet_.largest_acked = LargestAcked(*frame.ack_frame);
1504 }
1505 if (frame.type == STOP_WAITING_FRAME) {
1506 packet_.has_stop_waiting = true;
1507 }
1508 if (debug_delegate_ != nullptr) {
1509 debug_delegate_->OnFrameAddedToPacket(frame);
1510 }
1511
1512 // Packet transmission type is determined by the last added retransmittable
1513 // frame.
fayangcff885a2019-10-22 07:39:04 -07001514 if (QuicUtils::IsRetransmittableFrame(frame.type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001515 packet_.transmission_type = transmission_type;
1516 }
1517 return true;
1518}
1519
renjietangdbe98342019-10-18 11:00:57 -07001520bool QuicPacketCreator::MaybeCoalesceStreamFrame(const QuicStreamFrame& frame) {
1521 if (queued_frames_.empty() || queued_frames_.back().type != STREAM_FRAME) {
1522 return false;
1523 }
1524 QuicStreamFrame* candidate = &queued_frames_.back().stream_frame;
1525 if (candidate->stream_id != frame.stream_id ||
1526 candidate->offset + candidate->data_length != frame.offset ||
1527 frame.data_length > BytesFree()) {
1528 return false;
1529 }
1530 candidate->data_length += frame.data_length;
1531 candidate->fin = frame.fin;
1532
1533 // The back of retransmittable frames must be the same as the original
1534 // queued frames' back.
1535 DCHECK_EQ(packet_.retransmittable_frames.back().type, STREAM_FRAME);
1536 QuicStreamFrame* retransmittable =
1537 &packet_.retransmittable_frames.back().stream_frame;
1538 DCHECK_EQ(retransmittable->stream_id, frame.stream_id);
1539 DCHECK_EQ(retransmittable->offset + retransmittable->data_length,
1540 frame.offset);
1541 retransmittable->data_length = candidate->data_length;
1542 retransmittable->fin = candidate->fin;
1543 packet_size_ += frame.data_length;
1544 if (debug_delegate_ != nullptr) {
1545 debug_delegate_->OnStreamFrameCoalesced(*candidate);
1546 }
1547 return true;
1548}
1549
fayang2ab1e852019-11-04 11:24:36 -08001550bool QuicPacketCreator::RemoveSoftMaxPacketLength() {
1551 if (latched_hard_max_packet_length_ == 0) {
1552 return false;
1553 }
1554 if (!CanSetMaxPacketLength()) {
1555 return false;
1556 }
1557 QUIC_DVLOG(1) << "Restoring max packet length to: "
1558 << latched_hard_max_packet_length_;
1559 SetMaxPacketLength(latched_hard_max_packet_length_);
1560 // Reset latched_max_packet_length_.
1561 latched_hard_max_packet_length_ = 0;
1562 return true;
1563}
1564
QUICHE teama6ef0a62019-03-07 20:34:33 -05001565void QuicPacketCreator::MaybeAddPadding() {
1566 // The current packet should have no padding bytes because padding is only
1567 // added when this method is called just before the packet is serialized.
1568 DCHECK_EQ(0, packet_.num_padding_bytes);
1569 if (BytesFree() == 0) {
1570 // Don't pad full packets.
1571 return;
1572 }
1573
1574 if (packet_.transmission_type == PROBING_RETRANSMISSION) {
1575 needs_full_padding_ = true;
1576 }
1577
fayang58f71072019-11-05 08:47:02 -08001578 // Packet coalescer pads INITIAL packets, so the creator should not.
1579 if (framer_->version().CanSendCoalescedPackets() &&
1580 (packet_.encryption_level == ENCRYPTION_INITIAL ||
1581 packet_.encryption_level == ENCRYPTION_HANDSHAKE)) {
1582 // TODO(fayang): MTU discovery packets should not ever be sent as
1583 // ENCRYPTION_INITIAL or ENCRYPTION_HANDSHAKE.
1584 bool is_mtu_discovery = false;
1585 for (const auto& frame : packet_.nonretransmittable_frames) {
1586 if (frame.type == MTU_DISCOVERY_FRAME) {
1587 is_mtu_discovery = true;
1588 break;
1589 }
1590 }
1591 if (!is_mtu_discovery) {
1592 // Do not add full padding if connection tries to coalesce packet.
1593 needs_full_padding_ = false;
1594 }
1595 }
1596
nharper55fa6132019-05-07 19:37:21 -07001597 // Header protection requires a minimum plaintext packet size.
1598 size_t extra_padding_bytes = 0;
1599 if (framer_->version().HasHeaderProtection()) {
1600 size_t frame_bytes = PacketSize() - PacketHeaderSize();
1601
QUICHE team2252b702019-05-14 23:55:14 -04001602 if (frame_bytes + pending_padding_bytes_ <
1603 MinPlaintextPacketSize(framer_->version()) &&
nharper55fa6132019-05-07 19:37:21 -07001604 !needs_full_padding_) {
QUICHE team2252b702019-05-14 23:55:14 -04001605 extra_padding_bytes =
1606 MinPlaintextPacketSize(framer_->version()) - frame_bytes;
nharper55fa6132019-05-07 19:37:21 -07001607 }
1608 }
1609
1610 if (!needs_full_padding_ && pending_padding_bytes_ == 0 &&
1611 extra_padding_bytes == 0) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001612 // Do not need padding.
1613 return;
1614 }
1615
nharper55fa6132019-05-07 19:37:21 -07001616 int padding_bytes = -1;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001617 if (needs_full_padding_) {
1618 // Full padding does not consume pending padding bytes.
1619 packet_.num_padding_bytes = -1;
1620 } else {
1621 packet_.num_padding_bytes =
1622 std::min<int16_t>(pending_padding_bytes_, BytesFree());
1623 pending_padding_bytes_ -= packet_.num_padding_bytes;
nharper55fa6132019-05-07 19:37:21 -07001624 padding_bytes =
1625 std::max<int16_t>(packet_.num_padding_bytes, extra_padding_bytes);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001626 }
1627
fayang347ab752019-10-22 11:17:43 -07001628 bool success = AddFrame(QuicFrame(QuicPaddingFrame(padding_bytes)),
nharper55fa6132019-05-07 19:37:21 -07001629 packet_.transmission_type);
dschinazief79a5f2019-10-04 10:32:54 -07001630 QUIC_BUG_IF(!success) << "Failed to add padding_bytes: " << padding_bytes
1631 << " transmission_type: "
1632 << TransmissionTypeToString(packet_.transmission_type);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001633}
1634
1635bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
1636 return have_diversification_nonce_ &&
1637 packet_.encryption_level == ENCRYPTION_ZERO_RTT;
1638}
1639
1640bool QuicPacketCreator::IncludeVersionInHeader() const {
fayangd4291e42019-05-30 10:31:21 -07001641 if (VersionHasIetfInvariantHeader(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001642 return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1643 }
1644 return send_version_in_packet_;
1645}
1646
1647void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
1648 pending_padding_bytes_ += size;
1649}
1650
ianswette28f0222019-04-04 13:31:22 -07001651bool QuicPacketCreator::StreamFrameIsClientHello(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001652 const QuicStreamFrame& frame) const {
1653 if (framer_->perspective() == Perspective::IS_SERVER ||
nharper46833c32019-05-15 21:33:05 -07001654 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
1655 frame.stream_id)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001656 return false;
1657 }
ianswette28f0222019-04-04 13:31:22 -07001658 // The ClientHello is always sent with INITIAL encryption.
1659 return packet_.encryption_level == ENCRYPTION_INITIAL;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001660}
1661
dschinazi7b9278c2019-05-20 07:36:21 -07001662void QuicPacketCreator::SetServerConnectionIdIncluded(
1663 QuicConnectionIdIncluded server_connection_id_included) {
1664 DCHECK(server_connection_id_included == CONNECTION_ID_PRESENT ||
1665 server_connection_id_included == CONNECTION_ID_ABSENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001666 DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
dschinazi7b9278c2019-05-20 07:36:21 -07001667 server_connection_id_included != CONNECTION_ID_ABSENT);
1668 server_connection_id_included_ = server_connection_id_included;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001669}
1670
dschinazi7b9278c2019-05-20 07:36:21 -07001671void QuicPacketCreator::SetServerConnectionId(
1672 QuicConnectionId server_connection_id) {
1673 server_connection_id_ = server_connection_id;
QUICHE teamc65d1d12019-03-19 20:58:04 -07001674}
1675
dschinazi346b7ce2019-06-05 01:38:18 -07001676void QuicPacketCreator::SetClientConnectionId(
1677 QuicConnectionId client_connection_id) {
1678 DCHECK(client_connection_id.IsEmpty() ||
1679 framer_->version().SupportsClientConnectionIds());
dschinazi346b7ce2019-06-05 01:38:18 -07001680 client_connection_id_ = client_connection_id;
1681}
1682
ianswettb239f862019-04-05 09:15:06 -07001683QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001684 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001685 return 0;
1686 }
1687 const size_t packet_header_size = GetPacketHeaderSize(
1688 framer_->transport_version(), GetDestinationConnectionIdLength(),
1689 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
1690 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
ianswettb239f862019-04-05 09:15:06 -07001691 // No Retry token on packets containing application data.
1692 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001693 // This is the largest possible message payload when the length field is
1694 // omitted.
fayang2ab1e852019-11-04 11:24:36 -08001695 size_t max_plaintext_size =
1696 latched_hard_max_packet_length_ == 0
1697 ? max_plaintext_size_
1698 : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
1699 return max_plaintext_size -
1700 std::min(max_plaintext_size, packet_header_size + kQuicFrameTypeSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001701}
1702
ianswettb239f862019-04-05 09:15:06 -07001703QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001704 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
ianswettb239f862019-04-05 09:15:06 -07001705 return 0;
1706 }
1707 // QUIC Crypto server packets may include a diversification nonce.
1708 const bool may_include_nonce =
1709 framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
1710 framer_->perspective() == Perspective::IS_SERVER;
1711 // IETF QUIC long headers include a length on client 0RTT packets.
1712 QuicVariableLengthIntegerLength length_length =
nharperd43f1d62019-07-01 15:18:20 -07001713 VARIABLE_LENGTH_INTEGER_LENGTH_0;
1714 if (framer_->perspective() == Perspective::IS_CLIENT) {
1715 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
1716 }
nharper405f7192019-09-11 08:28:06 -07001717 if (!QuicVersionHasLongHeaderLengths(framer_->transport_version())) {
nharperd43f1d62019-07-01 15:18:20 -07001718 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
1719 }
ianswettb239f862019-04-05 09:15:06 -07001720 const size_t packet_header_size = GetPacketHeaderSize(
1721 framer_->transport_version(), GetDestinationConnectionIdLength(),
1722 // Assume CID lengths don't change, but version may be present.
1723 GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
1724 PACKET_4BYTE_PACKET_NUMBER,
1725 // No Retry token on packets containing application data.
1726 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
1727 // This is the largest possible message payload when the length field is
1728 // omitted.
fayang2ab1e852019-11-04 11:24:36 -08001729 size_t max_plaintext_size =
1730 latched_hard_max_packet_length_ == 0
1731 ? max_plaintext_size_
1732 : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
ianswettb239f862019-04-05 09:15:06 -07001733 const QuicPacketLength largest_payload =
fayang2ab1e852019-11-04 11:24:36 -08001734 max_plaintext_size -
1735 std::min(max_plaintext_size, packet_header_size + kQuicFrameTypeSize);
ianswettb239f862019-04-05 09:15:06 -07001736 // This must always be less than or equal to GetCurrentLargestMessagePayload.
1737 DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload());
1738 return largest_payload;
1739}
1740
QUICHE teama6ef0a62019-03-07 20:34:33 -05001741bool QuicPacketCreator::HasIetfLongHeader() const {
fayangd4291e42019-05-30 10:31:21 -07001742 return VersionHasIetfInvariantHeader(framer_->transport_version()) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05001743 packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1744}
1745
nharper6f8a7612019-07-08 12:31:20 -07001746// static
QUICHE team2252b702019-05-14 23:55:14 -04001747size_t QuicPacketCreator::MinPlaintextPacketSize(
1748 const ParsedQuicVersion& version) {
1749 if (!version.HasHeaderProtection()) {
nharper55fa6132019-05-07 19:37:21 -07001750 return 0;
1751 }
1752 // Header protection samples 16 bytes of ciphertext starting 4 bytes after the
1753 // packet number. In IETF QUIC, all AEAD algorithms have a 16-byte auth tag
1754 // (i.e. the ciphertext is 16 bytes larger than the plaintext). Since packet
1755 // numbers could be as small as 1 byte, but the sample starts 4 bytes after
1756 // the packet number, at least 3 bytes of plaintext are needed to make sure
1757 // that there is enough ciphertext to sample.
1758 //
1759 // Google QUIC crypto uses different AEAD algorithms - in particular the auth
1760 // tags are only 12 bytes instead of 16 bytes. Since the auth tag is 4 bytes
1761 // shorter, 4 more bytes of plaintext are needed to guarantee there is enough
1762 // ciphertext to sample.
1763 //
1764 // This method could check for PROTOCOL_TLS1_3 vs PROTOCOL_QUIC_CRYPTO and
1765 // return 3 when TLS 1.3 is in use (the use of IETF vs Google QUIC crypters is
1766 // determined based on the handshake protocol used). However, even when TLS
1767 // 1.3 is used, unittests still use NullEncrypter/NullDecrypter (and other
1768 // test crypters) which also only use 12 byte tags.
1769 //
1770 // TODO(nharper): Set this based on the handshake protocol in use.
1771 return 7;
1772}
1773
fayang354c9422019-05-21 08:10:35 -07001774QuicPacketNumber QuicPacketCreator::NextSendingPacketNumber() const {
1775 if (!packet_number().IsInitialized()) {
1776 return framer_->first_sending_packet_number();
1777 }
1778 return packet_number() + 1;
1779}
1780
fayang18be79a2019-09-16 15:17:12 -07001781bool QuicPacketCreator::PacketFlusherAttached() const {
fayang18be79a2019-09-16 15:17:12 -07001782 return flusher_attached_;
1783}
1784
QUICHE teama6ef0a62019-03-07 20:34:33 -05001785#undef ENDPOINT // undef for jumbo builds
1786} // namespace quic