blob: f95fe638adabd9249787362a37328825798f1019 [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"
24#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
25#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
26#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"
bnc2c2444e2019-05-03 08:18:23 -070030#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050031#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
32#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
33
34namespace quic {
35namespace {
36
37QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
38 switch (level) {
QUICHE team6987b4a2019-03-15 16:23:04 -070039 case ENCRYPTION_INITIAL:
QUICHE teama6ef0a62019-03-07 20:34:33 -050040 return INITIAL;
QUICHE team88ea0082019-03-15 10:05:26 -070041 case ENCRYPTION_HANDSHAKE:
42 return HANDSHAKE;
QUICHE teama6ef0a62019-03-07 20:34:33 -050043 case ENCRYPTION_ZERO_RTT:
44 return ZERO_RTT_PROTECTED;
45 case ENCRYPTION_FORWARD_SECURE:
46 QUIC_BUG
47 << "Try to derive long header type for packet with encryption level: "
dschinazief79a5f2019-10-04 10:32:54 -070048 << EncryptionLevelToString(level);
QUICHE teama6ef0a62019-03-07 20:34:33 -050049 return INVALID_PACKET_TYPE;
50 default:
dschinazief79a5f2019-10-04 10:32:54 -070051 QUIC_BUG << EncryptionLevelToString(level);
QUICHE teama6ef0a62019-03-07 20:34:33 -050052 return INVALID_PACKET_TYPE;
53 }
54}
55
fayang08750832019-10-24 11:25:34 -070056// ScopedPacketContextSwitcher saves |packet|'s states and change states
57// during its construction. When the switcher goes out of scope, it restores
58// saved states.
59class ScopedPacketContextSwitcher {
60 public:
61 ScopedPacketContextSwitcher(QuicPacketNumber packet_number,
62 QuicPacketNumberLength packet_number_length,
63 EncryptionLevel encryption_level,
64 SerializedPacket* packet)
65
66 : saved_packet_number_(packet->packet_number),
67 saved_packet_number_length_(packet->packet_number_length),
68 saved_encryption_level_(packet->encryption_level),
69 packet_(packet) {
70 packet_->packet_number = packet_number,
71 packet_->packet_number_length = packet_number_length;
72 packet_->encryption_level = encryption_level;
73 }
74
75 ~ScopedPacketContextSwitcher() {
76 packet_->packet_number = saved_packet_number_;
77 packet_->packet_number_length = saved_packet_number_length_;
78 packet_->encryption_level = saved_encryption_level_;
79 }
80
81 private:
82 const QuicPacketNumber saved_packet_number_;
83 const QuicPacketNumberLength saved_packet_number_length_;
84 const EncryptionLevel saved_encryption_level_;
85 SerializedPacket* packet_;
86};
87
QUICHE teama6ef0a62019-03-07 20:34:33 -050088} // namespace
89
90#define ENDPOINT \
91 (framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
92
dschinazi7b9278c2019-05-20 07:36:21 -070093QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050094 QuicFramer* framer,
95 DelegateInterface* delegate)
dschinazi7b9278c2019-05-20 07:36:21 -070096 : QuicPacketCreator(server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050097 framer,
98 QuicRandom::GetInstance(),
99 delegate) {}
100
dschinazi7b9278c2019-05-20 07:36:21 -0700101QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500102 QuicFramer* framer,
103 QuicRandom* random,
104 DelegateInterface* delegate)
105 : delegate_(delegate),
106 debug_delegate_(nullptr),
107 framer_(framer),
108 random_(random),
109 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
110 have_diversification_nonce_(false),
111 max_packet_length_(0),
dschinazi7b9278c2019-05-20 07:36:21 -0700112 server_connection_id_included_(CONNECTION_ID_PRESENT),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500113 packet_size_(0),
dschinazi7b9278c2019-05-20 07:36:21 -0700114 server_connection_id_(server_connection_id),
dschinazi346b7ce2019-06-05 01:38:18 -0700115 client_connection_id_(EmptyQuicConnectionId()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500116 packet_(QuicPacketNumber(),
117 PACKET_1BYTE_PACKET_NUMBER,
118 nullptr,
119 0,
120 false,
121 false),
122 pending_padding_bytes_(0),
123 needs_full_padding_(false),
fayang18be79a2019-09-16 15:17:12 -0700124 next_transmission_type_(NOT_RETRANSMISSION),
125 flusher_attached_(false),
126 fully_pad_crypto_handshake_packets_(true),
fayang02a28742019-12-04 07:09:38 -0800127 latched_hard_max_packet_length_(0) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500128 SetMaxPacketLength(kDefaultMaxPacketSize);
129}
130
131QuicPacketCreator::~QuicPacketCreator() {
132 DeleteFrames(&packet_.retransmittable_frames);
133}
134
135void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
136 std::unique_ptr<QuicEncrypter> encrypter) {
137 framer_->SetEncrypter(level, std::move(encrypter));
138 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
139}
140
141bool QuicPacketCreator::CanSetMaxPacketLength() const {
142 // |max_packet_length_| should not be changed mid-packet.
143 return queued_frames_.empty();
144}
145
146void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
147 DCHECK(CanSetMaxPacketLength());
148
149 // Avoid recomputing |max_plaintext_size_| if the length does not actually
150 // change.
151 if (length == max_packet_length_) {
152 return;
153 }
154
155 max_packet_length_ = length;
156 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
nharper55fa6132019-05-07 19:37:21 -0700157 QUIC_BUG_IF(max_plaintext_size_ - PacketHeaderSize() <
QUICHE team2252b702019-05-14 23:55:14 -0400158 MinPlaintextPacketSize(framer_->version()))
nharper55fa6132019-05-07 19:37:21 -0700159 << "Attempted to set max packet length too small";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500160}
161
fayang2ab1e852019-11-04 11:24:36 -0800162void QuicPacketCreator::SetSoftMaxPacketLength(QuicByteCount length) {
163 DCHECK(CanSetMaxPacketLength());
164 if (length > max_packet_length_) {
165 QUIC_BUG << ENDPOINT
166 << "Try to increase max_packet_length_ in "
167 "SetSoftMaxPacketLength, use SetMaxPacketLength instead.";
168 return;
169 }
170 if (framer_->GetMaxPlaintextSize(length) <
171 PacketHeaderSize() + MinPlaintextPacketSize(framer_->version())) {
172 QUIC_DLOG(INFO) << length << " is too small to fit packet header";
173 return;
174 }
175 QUIC_DVLOG(1) << "Setting soft max packet length to: " << length;
176 latched_hard_max_packet_length_ = max_packet_length_;
177 max_packet_length_ = length;
178 max_plaintext_size_ = framer_->GetMaxPlaintextSize(length);
179}
180
QUICHE teama6ef0a62019-03-07 20:34:33 -0500181// Stops serializing version of the protocol in packets sent after this call.
182// A packet that is already open might send kQuicVersionSize bytes less than the
183// maximum packet size if we stop sending version before it is serialized.
184void QuicPacketCreator::StopSendingVersion() {
185 DCHECK(send_version_in_packet_);
fayangd4291e42019-05-30 10:31:21 -0700186 DCHECK(!VersionHasIetfInvariantHeader(framer_->transport_version()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500187 send_version_in_packet_ = false;
188 if (packet_size_ > 0) {
189 DCHECK_LT(kQuicVersionSize, packet_size_);
190 packet_size_ -= kQuicVersionSize;
191 }
192}
193
194void QuicPacketCreator::SetDiversificationNonce(
195 const DiversificationNonce& nonce) {
196 DCHECK(!have_diversification_nonce_);
197 have_diversification_nonce_ = true;
198 diversification_nonce_ = nonce;
199}
200
201void QuicPacketCreator::UpdatePacketNumberLength(
202 QuicPacketNumber least_packet_awaited_by_peer,
203 QuicPacketCount max_packets_in_flight) {
204 if (!queued_frames_.empty()) {
205 // Don't change creator state if there are frames queued.
206 QUIC_BUG << "Called UpdatePacketNumberLength with " << queued_frames_.size()
207 << " queued_frames. First frame type:"
208 << queued_frames_.front().type
209 << " last frame type:" << queued_frames_.back().type;
210 return;
211 }
212
213 DCHECK_LE(least_packet_awaited_by_peer, packet_.packet_number + 1);
214 const uint64_t current_delta =
215 packet_.packet_number + 1 - least_packet_awaited_by_peer;
216 const uint64_t delta = std::max(current_delta, max_packets_in_flight);
217 packet_.packet_number_length = QuicFramer::GetMinPacketNumberLength(
218 framer_->transport_version(), QuicPacketNumber(delta * 4));
219}
220
fayang4c1c2362019-09-13 07:20:01 -0700221void QuicPacketCreator::SkipNPacketNumbers(
222 QuicPacketCount count,
223 QuicPacketNumber least_packet_awaited_by_peer,
224 QuicPacketCount max_packets_in_flight) {
225 if (!queued_frames_.empty()) {
226 // Don't change creator state if there are frames queued.
227 QUIC_BUG << "Called SkipNPacketNumbers with " << queued_frames_.size()
228 << " queued_frames. First frame type:"
229 << queued_frames_.front().type
230 << " last frame type:" << queued_frames_.back().type;
231 return;
232 }
233 if (packet_.packet_number > packet_.packet_number + count) {
234 // Skipping count packet numbers causes packet number wrapping around,
235 // reject it.
236 QUIC_LOG(WARNING) << "Skipping " << count
237 << " packet numbers causes packet number wrapping "
238 "around, least_packet_awaited_by_peer: "
239 << least_packet_awaited_by_peer
240 << " packet_number:" << packet_.packet_number;
241 return;
242 }
243 packet_.packet_number += count;
244 // Packet number changes, update packet number length if necessary.
245 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight);
246}
247
fayang62b637b2019-09-16 08:40:49 -0700248bool QuicPacketCreator::ConsumeCryptoDataToFillCurrentPacket(
249 EncryptionLevel level,
250 size_t write_length,
251 QuicStreamOffset offset,
252 bool needs_full_padding,
253 TransmissionType transmission_type,
254 QuicFrame* frame) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500255 if (!CreateCryptoFrame(level, write_length, offset, frame)) {
256 return false;
257 }
258 // When crypto data was sent in stream frames, ConsumeData is called with
259 // |needs_full_padding = true|. Keep the same behavior here when sending
260 // crypto frames.
261 //
262 // TODO(nharper): Check what the IETF drafts say about padding out initial
263 // messages and change this as appropriate.
nharper51961cf2019-05-13 13:23:24 -0700264 if (needs_full_padding) {
265 needs_full_padding_ = true;
266 }
fayang347ab752019-10-22 11:17:43 -0700267 return AddFrame(*frame, transmission_type);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500268}
269
fayang62b637b2019-09-16 08:40:49 -0700270bool QuicPacketCreator::ConsumeDataToFillCurrentPacket(
271 QuicStreamId id,
272 size_t data_size,
273 QuicStreamOffset offset,
274 bool fin,
275 bool needs_full_padding,
276 TransmissionType transmission_type,
277 QuicFrame* frame) {
QUICHE teamf08778a2019-03-14 08:10:26 -0700278 if (!HasRoomForStreamFrame(id, offset, data_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500279 return false;
280 }
QUICHE teamf08778a2019-03-14 08:10:26 -0700281 CreateStreamFrame(id, data_size, offset, fin, frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500282 // Explicitly disallow multi-packet CHLOs.
danzh88e3e052019-06-13 11:47:18 -0700283 if (GetQuicFlag(FLAGS_quic_enforce_single_packet_chlo) &&
ianswette28f0222019-04-04 13:31:22 -0700284 StreamFrameIsClientHello(frame->stream_frame) &&
285 frame->stream_frame.data_length < data_size) {
vasilvvc48c8712019-03-11 13:38:16 -0700286 const std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500287 "Client hello won't fit in a single packet.";
288 QUIC_BUG << error_details << " Constructed stream frame length: "
289 << frame->stream_frame.data_length
ianswette28f0222019-04-04 13:31:22 -0700290 << " CHLO length: " << data_size;
fkastenholz85f18902019-05-28 12:47:00 -0700291 delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500292 return false;
293 }
fayang347ab752019-10-22 11:17:43 -0700294 if (!AddFrame(*frame, transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500295 // Fails if we try to write unencrypted stream data.
296 return false;
297 }
298 if (needs_full_padding) {
299 needs_full_padding_ = true;
300 }
301
302 return true;
303}
304
305bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
306 QuicStreamOffset offset,
307 size_t data_size) {
fayang2ab1e852019-11-04 11:24:36 -0800308 const size_t min_stream_frame_size = QuicFramer::GetMinStreamFrameSize(
309 framer_->transport_version(), id, offset, /*last_frame_in_packet=*/true,
310 data_size);
311 if (BytesFree() > min_stream_frame_size) {
312 return true;
313 }
314 if (!RemoveSoftMaxPacketLength()) {
315 return false;
316 }
317 return BytesFree() > min_stream_frame_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500318}
319
320bool QuicPacketCreator::HasRoomForMessageFrame(QuicByteCount length) {
fayang2ab1e852019-11-04 11:24:36 -0800321 const size_t message_frame_size = QuicFramer::GetMessageFrameSize(
322 framer_->transport_version(), /*last_frame_in_packet=*/true, length);
323 if (BytesFree() >= message_frame_size) {
324 return true;
325 }
326 if (!RemoveSoftMaxPacketLength()) {
327 return false;
328 }
329 return BytesFree() >= message_frame_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500330}
331
332// TODO(fkastenholz): this method should not use constant values for
333// the last-frame-in-packet and data-length parameters to
334// GetMinStreamFrameSize. Proper values should be plumbed in from
335// higher up. This was left this way for now for a few reasons. First,
336// higher up calls to StreamFramePacketOverhead() do not always know
337// this information, leading to a cascade of changes and B) the
338// higher-up software does not always loop, calling
339// StreamFramePacketOverhead() once for every packet -- eg there is
340// a test in quic_connection_test that calls it once and assumes that
341// the value is the same for all packets.
342
343// static
344size_t QuicPacketCreator::StreamFramePacketOverhead(
345 QuicTransportVersion version,
346 QuicConnectionIdLength destination_connection_id_length,
347 QuicConnectionIdLength source_connection_id_length,
348 bool include_version,
349 bool include_diversification_nonce,
350 QuicPacketNumberLength packet_number_length,
351 QuicVariableLengthIntegerLength retry_token_length_length,
352 QuicVariableLengthIntegerLength length_length,
353 QuicStreamOffset offset) {
354 return GetPacketHeaderSize(version, destination_connection_id_length,
355 source_connection_id_length, include_version,
356 include_diversification_nonce,
357 packet_number_length, retry_token_length_length, 0,
358 length_length) +
359
360 // Assumes this is a packet with a single stream frame in it. Since
361 // last_frame_in_packet is set true, the size of the length field is
362 // not included in the calculation. This is OK because in other places
363 // in the code, the logic adds back 2 (the size of the Google QUIC
364 // length) when a frame is not the last frame of the packet. This is
365 // also acceptable for IETF Quic; even though the length field could be
366 // 8 bytes long, in practice it will not be longer than 2 bytes (enough
367 // to encode 16K). A length that would be encoded in 2 bytes (0xfff)
368 // is passed just for cleanliness.
369 //
370 // TODO(fkastenholz): This is very hacky and feels brittle. Ideally we
371 // would calculate the correct lengths at the correct time, based on
372 // the state at that time/place.
373 QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true,
dschinazi66dea072019-04-09 11:41:06 -0700374 kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500375}
376
377void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
QUICHE teamf08778a2019-03-14 08:10:26 -0700378 size_t data_size,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500379 QuicStreamOffset offset,
380 bool fin,
381 QuicFrame* frame) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500382 DCHECK_GT(
383 max_packet_length_,
384 StreamFramePacketOverhead(
385 framer_->transport_version(), GetDestinationConnectionIdLength(),
386 GetSourceConnectionIdLength(), kIncludeVersion,
387 IncludeNonceInPublicHeader(), PACKET_6BYTE_PACKET_NUMBER,
388 GetRetryTokenLengthLength(), GetLengthLength(), offset));
389
390 QUIC_BUG_IF(!HasRoomForStreamFrame(id, offset, data_size))
391 << "No room for Stream frame, BytesFree: " << BytesFree()
392 << " MinStreamFrameSize: "
393 << QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
394 offset, true, data_size);
395
QUICHE teamf08778a2019-03-14 08:10:26 -0700396 QUIC_BUG_IF(data_size == 0 && !fin)
397 << "Creating a stream frame for stream ID:" << id
398 << " with no data or fin.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500399 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
400 framer_->transport_version(), id, offset,
401 /* last_frame_in_packet= */ true, data_size);
402 size_t bytes_consumed =
403 std::min<size_t>(BytesFree() - min_frame_size, data_size);
404
405 bool set_fin = fin && bytes_consumed == data_size; // Last frame.
406 *frame = QuicFrame(QuicStreamFrame(id, set_fin, offset, bytes_consumed));
407}
408
409bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
410 size_t write_length,
411 QuicStreamOffset offset,
412 QuicFrame* frame) {
413 size_t min_frame_size =
414 QuicFramer::GetMinCryptoFrameSize(write_length, offset);
fayang2ab1e852019-11-04 11:24:36 -0800415 if (BytesFree() <= min_frame_size &&
416 (!RemoveSoftMaxPacketLength() || BytesFree() <= min_frame_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500417 return false;
418 }
419 size_t max_write_length = BytesFree() - min_frame_size;
420 size_t bytes_consumed = std::min<size_t>(max_write_length, write_length);
421 *frame = QuicFrame(new QuicCryptoFrame(level, offset, bytes_consumed));
422 return true;
423}
424
fayang62b637b2019-09-16 08:40:49 -0700425void QuicPacketCreator::FlushCurrentPacket() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500426 if (!HasPendingFrames() && pending_padding_bytes_ == 0) {
427 return;
428 }
429
dschinazi66dea072019-04-09 11:41:06 -0700430 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500431 char* serialized_packet_buffer = delegate_->GetPacketBuffer();
432 if (serialized_packet_buffer == nullptr) {
433 serialized_packet_buffer = stack_buffer;
434 }
435
dschinazi66dea072019-04-09 11:41:06 -0700436 SerializePacket(serialized_packet_buffer, kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500437 OnSerializedPacket();
438}
439
440void QuicPacketCreator::OnSerializedPacket() {
441 if (packet_.encrypted_buffer == nullptr) {
vasilvvc48c8712019-03-11 13:38:16 -0700442 const std::string error_details = "Failed to SerializePacket.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500443 QUIC_BUG << error_details;
444 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
fkastenholz85f18902019-05-28 12:47:00 -0700445 error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500446 return;
447 }
448
449 SerializedPacket packet(std::move(packet_));
450 ClearPacket();
fayang2ab1e852019-11-04 11:24:36 -0800451 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500452 delegate_->OnSerializedPacket(&packet);
453}
454
455void QuicPacketCreator::ClearPacket() {
456 packet_.has_ack = false;
457 packet_.has_stop_waiting = false;
458 packet_.has_crypto_handshake = NOT_HANDSHAKE;
459 packet_.num_padding_bytes = 0;
wub98669f52019-04-18 10:49:18 -0700460 packet_.transmission_type = NOT_RETRANSMISSION;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500461 packet_.encrypted_buffer = nullptr;
462 packet_.encrypted_length = 0;
463 DCHECK(packet_.retransmittable_frames.empty());
fayang51152fd2019-10-21 06:48:09 -0700464 DCHECK(packet_.nonretransmittable_frames.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500465 packet_.largest_acked.Clear();
466 needs_full_padding_ = false;
467}
468
fayang08750832019-10-24 11:25:34 -0700469size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
470 const SerializedPacket& packet,
471 size_t padding_size,
472 char* buffer,
473 size_t buffer_len) {
474 QUIC_BUG_IF(packet.encryption_level != ENCRYPTION_INITIAL);
475 QUIC_BUG_IF(packet.nonretransmittable_frames.empty() &&
476 packet.retransmittable_frames.empty())
477 << "Attempt to serialize empty ENCRYPTION_INITIAL packet in coalesced "
478 "packet";
479 ScopedPacketContextSwitcher switcher(
480 packet.packet_number -
481 1, // -1 because serialize packet increase packet number.
482 packet.packet_number_length, packet.encryption_level, &packet_);
483 for (const QuicFrame& frame : packet.nonretransmittable_frames) {
484 if (!AddFrame(frame, packet.transmission_type)) {
485 QUIC_BUG << "Failed to serialize frame: " << frame;
486 return 0;
487 }
488 }
489 for (const QuicFrame& frame : packet.retransmittable_frames) {
490 if (!AddFrame(frame, packet.transmission_type)) {
491 QUIC_BUG << "Failed to serialize frame: " << frame;
492 return 0;
493 }
494 }
495 // Add necessary padding.
496 if (padding_size > 0) {
497 QUIC_DVLOG(2) << ENDPOINT << "Add padding of size: " << padding_size;
498 if (!AddFrame(QuicFrame(QuicPaddingFrame(padding_size)),
499 packet.transmission_type)) {
500 QUIC_BUG << "Failed to add padding of size " << padding_size
501 << " when serializing ENCRYPTION_INITIAL "
502 "packet in coalesced packet";
503 return 0;
504 }
505 }
506 SerializePacket(buffer, buffer_len);
507 const size_t encrypted_length = packet_.encrypted_length;
508 // Clear frames in packet_. No need to DeleteFrames since frames are owned by
509 // initial_packet.
510 packet_.retransmittable_frames.clear();
511 packet_.nonretransmittable_frames.clear();
512 ClearPacket();
513 return encrypted_length;
514}
515
QUICHE teama6ef0a62019-03-07 20:34:33 -0500516void QuicPacketCreator::CreateAndSerializeStreamFrame(
517 QuicStreamId id,
518 size_t write_length,
519 QuicStreamOffset iov_offset,
520 QuicStreamOffset stream_offset,
521 bool fin,
522 TransmissionType transmission_type,
523 size_t* num_bytes_consumed) {
524 DCHECK(queued_frames_.empty());
525 // Write out the packet header
526 QuicPacketHeader header;
527 FillPacketHeader(&header);
528
dschinazi66dea072019-04-09 11:41:06 -0700529 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500530 char* encrypted_buffer = delegate_->GetPacketBuffer();
531 if (encrypted_buffer == nullptr) {
532 encrypted_buffer = stack_buffer;
533 }
534
dschinazi66dea072019-04-09 11:41:06 -0700535 QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500536 size_t length_field_offset = 0;
537 if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
538 QUIC_BUG << "AppendPacketHeader failed";
539 return;
540 }
541
542 // Create a Stream frame with the remaining space.
543 QUIC_BUG_IF(iov_offset == write_length && !fin)
544 << "Creating a stream frame with no data or fin.";
545 const size_t remaining_data_size = write_length - iov_offset;
nharperebabffd2019-06-03 17:34:45 -0700546 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500547 framer_->transport_version(), id, stream_offset,
548 /* last_frame_in_packet= */ true, remaining_data_size);
nharperebabffd2019-06-03 17:34:45 -0700549 size_t available_size =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500550 max_plaintext_size_ - writer.length() - min_frame_size;
nharperebabffd2019-06-03 17:34:45 -0700551 size_t bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
552 size_t plaintext_bytes_written = min_frame_size + bytes_consumed;
553 bool needs_padding = false;
554 if (plaintext_bytes_written < MinPlaintextPacketSize(framer_->version())) {
555 needs_padding = true;
556 // Recalculate sizes with the stream frame not being marked as the last
557 // frame in the packet.
558 min_frame_size = QuicFramer::GetMinStreamFrameSize(
559 framer_->transport_version(), id, stream_offset,
560 /* last_frame_in_packet= */ false, remaining_data_size);
561 available_size = max_plaintext_size_ - writer.length() - min_frame_size;
562 bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
563 plaintext_bytes_written = min_frame_size + bytes_consumed;
564 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500565
566 const bool set_fin = fin && (bytes_consumed == remaining_data_size);
567 QuicStreamFrame frame(id, set_fin, stream_offset, bytes_consumed);
rchc76cd742019-03-26 16:00:03 -0700568 if (debug_delegate_ != nullptr) {
569 debug_delegate_->OnFrameAddedToPacket(QuicFrame(frame));
570 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500571 QUIC_DVLOG(1) << ENDPOINT << "Adding frame: " << frame;
572
dschinazi118934b2019-06-13 18:09:08 -0700573 QUIC_DVLOG(2) << ENDPOINT << "Serializing stream packet " << header << frame;
574
QUICHE teama6ef0a62019-03-07 20:34:33 -0500575 // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized
576 // into one method that takes a QuicStreamFrame, if warranted.
nharperebabffd2019-06-03 17:34:45 -0700577 bool omit_frame_length = !needs_padding;
578 if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500579 QUIC_BUG << "AppendTypeByte failed";
580 return;
581 }
nharperebabffd2019-06-03 17:34:45 -0700582 if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500583 QUIC_BUG << "AppendStreamFrame failed";
584 return;
585 }
nharperebabffd2019-06-03 17:34:45 -0700586 if (needs_padding &&
587 plaintext_bytes_written < MinPlaintextPacketSize(framer_->version()) &&
QUICHE team2252b702019-05-14 23:55:14 -0400588 !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) -
nharper55fa6132019-05-07 19:37:21 -0700589 plaintext_bytes_written)) {
590 QUIC_BUG << "Unable to add padding bytes";
591 return;
592 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500593
594 if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset,
595 packet_.encryption_level)) {
596 return;
597 }
598
fayangcff885a2019-10-22 07:39:04 -0700599 packet_.transmission_type = transmission_type;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500600
601 size_t encrypted_length = framer_->EncryptInPlace(
602 packet_.encryption_level, packet_.packet_number,
603 GetStartOfEncryptedData(framer_->transport_version(), header),
dschinazi66dea072019-04-09 11:41:06 -0700604 writer.length(), kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500605 if (encrypted_length == 0) {
606 QUIC_BUG << "Failed to encrypt packet number " << header.packet_number;
607 return;
608 }
609 // TODO(ianswett): Optimize the storage so RetransmitableFrames can be
610 // unioned with a QuicStreamFrame and a UniqueStreamBuffer.
611 *num_bytes_consumed = bytes_consumed;
612 packet_size_ = 0;
613 packet_.encrypted_buffer = encrypted_buffer;
614 packet_.encrypted_length = encrypted_length;
615 packet_.retransmittable_frames.push_back(QuicFrame(frame));
616 OnSerializedPacket();
617}
618
619bool QuicPacketCreator::HasPendingFrames() const {
620 return !queued_frames_.empty();
621}
622
623bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
624 return !packet_.retransmittable_frames.empty();
625}
626
627bool QuicPacketCreator::HasPendingStreamFramesOfStream(QuicStreamId id) const {
628 for (const auto& frame : packet_.retransmittable_frames) {
629 if (frame.type == STREAM_FRAME && frame.stream_frame.stream_id == id) {
630 return true;
631 }
632 }
633 return false;
634}
635
636size_t QuicPacketCreator::ExpansionOnNewFrame() const {
637 // If the last frame in the packet is a message frame, then it will expand to
638 // include the varint message length when a new frame is added.
639 const bool has_trailing_message_frame =
640 !queued_frames_.empty() && queued_frames_.back().type == MESSAGE_FRAME;
641 if (has_trailing_message_frame) {
642 return QuicDataWriter::GetVarInt62Len(
643 queued_frames_.back().message_frame->message_length);
644 }
645 // If the last frame in the packet is a stream frame, then it will expand to
646 // include the stream_length field when a new frame is added.
647 const bool has_trailing_stream_frame =
648 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME;
649 if (!has_trailing_stream_frame) {
650 return 0;
651 }
fkastenholz305e1732019-06-18 05:01:22 -0700652 if (VersionHasIetfQuicFrames(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500653 return QuicDataWriter::GetVarInt62Len(
654 queued_frames_.back().stream_frame.data_length);
655 }
656 return kQuicStreamPayloadLengthSize;
657}
658
659size_t QuicPacketCreator::BytesFree() {
660 DCHECK_GE(max_plaintext_size_, PacketSize());
661 return max_plaintext_size_ -
662 std::min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
663}
664
665size_t QuicPacketCreator::PacketSize() {
666 if (!queued_frames_.empty()) {
667 return packet_size_;
668 }
nharper55fa6132019-05-07 19:37:21 -0700669 packet_size_ = PacketHeaderSize();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500670 return packet_size_;
671}
672
QUICHE teama6ef0a62019-03-07 20:34:33 -0500673bool QuicPacketCreator::AddPaddedSavedFrame(
674 const QuicFrame& frame,
675 TransmissionType transmission_type) {
fayang347ab752019-10-22 11:17:43 -0700676 if (AddFrame(frame, transmission_type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500677 needs_full_padding_ = true;
678 return true;
679 }
680 return false;
681}
682
683void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
684 size_t encrypted_buffer_len) {
685 DCHECK_LT(0u, encrypted_buffer_len);
686 QUIC_BUG_IF(queued_frames_.empty() && pending_padding_bytes_ == 0)
687 << "Attempt to serialize empty packet";
688 QuicPacketHeader header;
689 // FillPacketHeader increments packet_number_.
690 FillPacketHeader(&header);
691
692 MaybeAddPadding();
693
dschinazi118934b2019-06-13 18:09:08 -0700694 QUIC_DVLOG(2) << ENDPOINT << "Serializing packet " << header
wub031d47c2019-11-21 08:04:07 -0800695 << QuicFramesToString(queued_frames_) << " at encryption_level "
696 << EncryptionLevelToString(packet_.encryption_level);
dschinazi118934b2019-06-13 18:09:08 -0700697
QUICHE teama6ef0a62019-03-07 20:34:33 -0500698 DCHECK_GE(max_plaintext_size_, packet_size_);
699 // Use the packet_size_ instead of the buffer size to ensure smaller
700 // packet sizes are properly used.
701 size_t length =
702 framer_->BuildDataPacket(header, queued_frames_, encrypted_buffer,
703 packet_size_, packet_.encryption_level);
704 if (length == 0) {
705 QUIC_BUG << "Failed to serialize " << queued_frames_.size() << " frames.";
706 return;
707 }
708
709 // ACK Frames will be truncated due to length only if they're the only frame
710 // in the packet, and if packet_size_ was set to max_plaintext_size_. If
711 // truncation due to length occurred, then GetSerializedFrameLength will have
712 // returned all bytes free.
713 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
714 queued_frames_.size() == 1 &&
715 queued_frames_.back().type == ACK_FRAME;
716 // Because of possible truncation, we can't be confident that our
717 // packet size calculation worked correctly.
718 if (!possibly_truncated_by_length) {
719 DCHECK_EQ(packet_size_, length);
720 }
721 const size_t encrypted_length = framer_->EncryptInPlace(
722 packet_.encryption_level, packet_.packet_number,
723 GetStartOfEncryptedData(framer_->transport_version(), header), length,
724 encrypted_buffer_len, encrypted_buffer);
725 if (encrypted_length == 0) {
726 QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number;
727 return;
728 }
729
730 packet_size_ = 0;
731 queued_frames_.clear();
732 packet_.encrypted_buffer = encrypted_buffer;
733 packet_.encrypted_length = encrypted_length;
734}
735
736std::unique_ptr<QuicEncryptedPacket>
737QuicPacketCreator::SerializeVersionNegotiationPacket(
738 bool ietf_quic,
dschinazi48ac9192019-07-31 00:07:26 -0700739 bool use_length_prefix,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500740 const ParsedQuicVersionVector& supported_versions) {
741 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
742 std::unique_ptr<QuicEncryptedPacket> encrypted =
dschinazi48ac9192019-07-31 00:07:26 -0700743 QuicFramer::BuildVersionNegotiationPacket(
744 server_connection_id_, client_connection_id_, ietf_quic,
745 use_length_prefix, supported_versions);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500746 DCHECK(encrypted);
747 DCHECK_GE(max_packet_length_, encrypted->length());
748 return encrypted;
749}
750
751OwningSerializedPacketPointer
752QuicPacketCreator::SerializeConnectivityProbingPacket() {
fkastenholz305e1732019-06-18 05:01:22 -0700753 QUIC_BUG_IF(VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500754 << "Must not be version 99 to serialize padded ping connectivity probe";
fayang2ab1e852019-11-04 11:24:36 -0800755 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500756 QuicPacketHeader header;
757 // FillPacketHeader increments packet_number_.
758 FillPacketHeader(&header);
759
dschinazi118934b2019-06-13 18:09:08 -0700760 QUIC_DVLOG(2) << ENDPOINT << "Serializing connectivity probing packet "
761 << header;
762
dschinazi66dea072019-04-09 11:41:06 -0700763 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700764 size_t length = BuildConnectivityProbingPacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500765 header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
766 DCHECK(length);
767
768 const size_t encrypted_length = framer_->EncryptInPlace(
769 packet_.encryption_level, packet_.packet_number,
770 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700771 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500772 DCHECK(encrypted_length);
773
774 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
775 header.packet_number, header.packet_number_length, buffer.release(),
776 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
777
778 serialize_packet->encryption_level = packet_.encryption_level;
779 serialize_packet->transmission_type = NOT_RETRANSMISSION;
780
781 return serialize_packet;
782}
783
784OwningSerializedPacketPointer
785QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
786 QuicPathFrameBuffer* payload) {
fkastenholz305e1732019-06-18 05:01:22 -0700787 QUIC_BUG_IF(!VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500788 << "Must be version 99 to serialize path challenge connectivity probe, "
789 "is version "
790 << framer_->transport_version();
fayang2ab1e852019-11-04 11:24:36 -0800791 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500792 QuicPacketHeader header;
793 // FillPacketHeader increments packet_number_.
794 FillPacketHeader(&header);
795
dschinazi118934b2019-06-13 18:09:08 -0700796 QUIC_DVLOG(2) << ENDPOINT << "Serializing path challenge packet " << header;
797
dschinazi66dea072019-04-09 11:41:06 -0700798 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700799 size_t length = BuildPaddedPathChallengePacket(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500800 header, buffer.get(), max_plaintext_size_, payload, random_,
801 packet_.encryption_level);
802 DCHECK(length);
803
804 const size_t encrypted_length = framer_->EncryptInPlace(
805 packet_.encryption_level, packet_.packet_number,
806 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700807 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500808 DCHECK(encrypted_length);
809
810 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
811 header.packet_number, header.packet_number_length, buffer.release(),
812 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
813
814 serialize_packet->encryption_level = packet_.encryption_level;
815 serialize_packet->transmission_type = NOT_RETRANSMISSION;
816
817 return serialize_packet;
818}
819
820OwningSerializedPacketPointer
821QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
822 const QuicDeque<QuicPathFrameBuffer>& payloads,
823 const bool is_padded) {
fkastenholz305e1732019-06-18 05:01:22 -0700824 QUIC_BUG_IF(!VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500825 << "Must be version 99 to serialize path response connectivity probe, is "
826 "version "
827 << framer_->transport_version();
fayang2ab1e852019-11-04 11:24:36 -0800828 RemoveSoftMaxPacketLength();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500829 QuicPacketHeader header;
830 // FillPacketHeader increments packet_number_.
831 FillPacketHeader(&header);
832
dschinazi118934b2019-06-13 18:09:08 -0700833 QUIC_DVLOG(2) << ENDPOINT << "Serializing path response packet " << header;
834
dschinazi66dea072019-04-09 11:41:06 -0700835 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
renjietang4c704c82019-10-07 16:39:11 -0700836 size_t length =
837 BuildPathResponsePacket(header, buffer.get(), max_plaintext_size_,
838 payloads, is_padded, packet_.encryption_level);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500839 DCHECK(length);
840
841 const size_t encrypted_length = framer_->EncryptInPlace(
842 packet_.encryption_level, packet_.packet_number,
843 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700844 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500845 DCHECK(encrypted_length);
846
847 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
848 header.packet_number, header.packet_number_length, buffer.release(),
849 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
850
851 serialize_packet->encryption_level = packet_.encryption_level;
852 serialize_packet->transmission_type = NOT_RETRANSMISSION;
853
854 return serialize_packet;
855}
856
renjietang4c704c82019-10-07 16:39:11 -0700857size_t QuicPacketCreator::BuildPaddedPathChallengePacket(
858 const QuicPacketHeader& header,
859 char* buffer,
860 size_t packet_length,
861 QuicPathFrameBuffer* payload,
862 QuicRandom* randomizer,
863 EncryptionLevel level) {
864 DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()));
865 QuicFrames frames;
866
867 // Write a PATH_CHALLENGE frame, which has a random 8-byte payload
868 randomizer->RandBytes(payload->data(), payload->size());
869 QuicPathChallengeFrame path_challenge_frame(0, *payload);
870 frames.push_back(QuicFrame(&path_challenge_frame));
871
872 if (debug_delegate_ != nullptr) {
873 debug_delegate_->OnFrameAddedToPacket(QuicFrame(&path_challenge_frame));
874 }
875
876 // Add padding to the rest of the packet in order to assess Path MTU
877 // characteristics.
878 QuicPaddingFrame padding_frame;
879 frames.push_back(QuicFrame(padding_frame));
880
881 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
882}
883
884size_t QuicPacketCreator::BuildPathResponsePacket(
885 const QuicPacketHeader& header,
886 char* buffer,
887 size_t packet_length,
888 const QuicDeque<QuicPathFrameBuffer>& payloads,
889 const bool is_padded,
890 EncryptionLevel level) {
891 if (payloads.empty()) {
892 QUIC_BUG
893 << "Attempt to generate connectivity response with no request payloads";
894 return 0;
895 }
896 DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()));
897
898 std::vector<std::unique_ptr<QuicPathResponseFrame>> path_response_frames;
899 for (const QuicPathFrameBuffer& payload : payloads) {
900 // Note that the control frame ID can be 0 since this is not retransmitted.
901 path_response_frames.push_back(
902 std::make_unique<QuicPathResponseFrame>(0, payload));
903 }
904
905 QuicFrames frames;
906 for (const std::unique_ptr<QuicPathResponseFrame>& path_response_frame :
907 path_response_frames) {
908 frames.push_back(QuicFrame(path_response_frame.get()));
909 if (debug_delegate_ != nullptr) {
910 debug_delegate_->OnFrameAddedToPacket(
911 QuicFrame(path_response_frame.get()));
912 }
913 }
914
915 if (is_padded) {
916 // Add padding to the rest of the packet in order to assess Path MTU
917 // characteristics.
918 QuicPaddingFrame padding_frame;
919 frames.push_back(QuicFrame(padding_frame));
920 }
921
922 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
923}
924
925size_t QuicPacketCreator::BuildConnectivityProbingPacket(
926 const QuicPacketHeader& header,
927 char* buffer,
928 size_t packet_length,
929 EncryptionLevel level) {
930 QuicFrames frames;
931
932 // Write a PING frame, which has no data payload.
933 QuicPingFrame ping_frame;
934 frames.push_back(QuicFrame(ping_frame));
935
936 // Add padding to the rest of the packet.
937 QuicPaddingFrame padding_frame;
938 frames.push_back(QuicFrame(padding_frame));
939
940 return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
941}
942
fayang08750832019-10-24 11:25:34 -0700943size_t QuicPacketCreator::SerializeCoalescedPacket(
944 const QuicCoalescedPacket& coalesced,
945 char* buffer,
946 size_t buffer_len) {
947 QUIC_BUG_IF(packet_.num_padding_bytes != 0);
948 if (HasPendingFrames()) {
949 QUIC_BUG << "Try to serialize coalesced packet with pending frames";
950 return 0;
951 }
fayang58f71072019-11-05 08:47:02 -0800952 RemoveSoftMaxPacketLength();
fayang08750832019-10-24 11:25:34 -0700953 QUIC_BUG_IF(coalesced.length() == 0)
954 << "Attempt to serialize empty coalesced packet";
955 size_t packet_length = 0;
956 if (coalesced.initial_packet() != nullptr) {
957 size_t initial_length = ReserializeInitialPacketInCoalescedPacket(
958 *coalesced.initial_packet(),
959 /*padding_size=*/coalesced.max_packet_length() - coalesced.length(),
960 buffer, buffer_len);
961 if (initial_length == 0) {
962 QUIC_BUG << "Failed to reserialize ENCRYPTION_INITIAL packet in "
963 "coalesced packet";
964 return 0;
965 }
966 buffer += initial_length;
967 buffer_len -= initial_length;
968 packet_length += initial_length;
969 }
970 size_t length_copied = 0;
971 if (!coalesced.CopyEncryptedBuffers(buffer, buffer_len, &length_copied)) {
972 return 0;
973 }
974 packet_length += length_copied;
975 QUIC_DVLOG(1) << ENDPOINT
976 << "Successfully serialized coalesced packet of length: "
977 << packet_length;
978 return packet_length;
979}
980
QUICHE teama6ef0a62019-03-07 20:34:33 -0500981// TODO(b/74062209): Make this a public method of framer?
982SerializedPacket QuicPacketCreator::NoPacket() {
983 return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
984 nullptr, 0, false, false);
985}
986
QUICHE team2252b702019-05-14 23:55:14 -0400987QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -0400988 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi346b7ce2019-06-05 01:38:18 -0700989 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400990 }
dschinazi7b9278c2019-05-20 07:36:21 -0700991 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400992}
993
994QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -0400995 if (framer_->perspective() == Perspective::IS_CLIENT) {
dschinazi346b7ce2019-06-05 01:38:18 -0700996 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400997 }
dschinazi7b9278c2019-05-20 07:36:21 -0700998 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400999}
1000
QUICHE teama6ef0a62019-03-07 20:34:33 -05001001QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
1002 const {
dschinazi5e1a7b22019-07-31 12:23:21 -07001003 // In versions that do not support client connection IDs, the destination
1004 // connection ID is only sent from client to server.
1005 return (framer_->perspective() == Perspective::IS_CLIENT ||
1006 framer_->version().SupportsClientConnectionIds())
1007 ? CONNECTION_ID_PRESENT
1008 : CONNECTION_ID_ABSENT;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001009}
1010
1011QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
1012 const {
1013 // Long header packets sent by server include source connection ID.
dschinazi346b7ce2019-06-05 01:38:18 -07001014 // Ones sent by the client only include source connection ID if the version
1015 // supports client connection IDs.
1016 if (HasIetfLongHeader() &&
1017 (framer_->perspective() == Perspective::IS_SERVER ||
1018 framer_->version().SupportsClientConnectionIds())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001019 return CONNECTION_ID_PRESENT;
1020 }
dschinazi5e1a7b22019-07-31 12:23:21 -07001021 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi7b9278c2019-05-20 07:36:21 -07001022 return server_connection_id_included_;
QUICHE team2252b702019-05-14 23:55:14 -04001023 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001024 return CONNECTION_ID_ABSENT;
1025}
1026
1027QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
1028 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 GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -04001032 ? static_cast<QuicConnectionIdLength>(
1033 GetDestinationConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001034 : PACKET_0BYTE_CONNECTION_ID;
1035}
1036
1037QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
dschinazi7b9278c2019-05-20 07:36:21 -07001038 DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001039 transport_version()));
1040 return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -04001041 ? static_cast<QuicConnectionIdLength>(
1042 GetSourceConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -05001043 : PACKET_0BYTE_CONNECTION_ID;
1044}
1045
1046QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
fayang3ac15c12019-06-14 14:04:51 -07001047 if (HasIetfLongHeader() &&
1048 !framer_->version().SendsVariableLengthPacketNumberInLongHeader()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001049 return PACKET_4BYTE_PACKET_NUMBER;
1050 }
1051 return packet_.packet_number_length;
1052}
1053
nharper55fa6132019-05-07 19:37:21 -07001054size_t QuicPacketCreator::PacketHeaderSize() const {
1055 return GetPacketHeaderSize(
1056 framer_->transport_version(), GetDestinationConnectionIdLength(),
1057 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
1058 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
1059 GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
1060}
1061
QUICHE teama6ef0a62019-03-07 20:34:33 -05001062QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
1063 const {
1064 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1065 HasIetfLongHeader() &&
1066 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
1067 return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
1068 }
1069 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
1070}
1071
1072QuicStringPiece QuicPacketCreator::GetRetryToken() const {
dschinazi0db87092019-05-20 07:59:15 -07001073 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1074 HasIetfLongHeader() &&
1075 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
1076 return retry_token_;
1077 }
1078 return QuicStringPiece();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001079}
1080
1081void QuicPacketCreator::SetRetryToken(QuicStringPiece retry_token) {
vasilvvc48c8712019-03-11 13:38:16 -07001082 retry_token_ = std::string(retry_token);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001083}
1084
fayang18be79a2019-09-16 15:17:12 -07001085bool QuicPacketCreator::ConsumeRetransmittableControlFrame(
1086 const QuicFrame& frame) {
fayang18be79a2019-09-16 15:17:12 -07001087 QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame))
1088 << "Adding a control frame with no control frame id: " << frame;
1089 DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame;
1090 MaybeBundleAckOpportunistically();
1091 if (HasPendingFrames()) {
renjietangb63005e2019-11-19 23:08:53 -08001092 if (AddFrame(frame, next_transmission_type_)) {
fayang18be79a2019-09-16 15:17:12 -07001093 // There is pending frames and current frame fits.
1094 return true;
1095 }
1096 }
1097 DCHECK(!HasPendingFrames());
1098 if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME &&
1099 !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
1100 NOT_HANDSHAKE)) {
1101 // Do not check congestion window for ping or connection close frames.
1102 return false;
1103 }
renjietangb63005e2019-11-19 23:08:53 -08001104 const bool success = AddFrame(frame, next_transmission_type_);
ianswettbd78ea12019-09-26 06:32:37 -07001105 QUIC_BUG_IF(!success) << "Failed to add frame:" << frame
1106 << " transmission_type:" << next_transmission_type_;
fayang18be79a2019-09-16 15:17:12 -07001107 return success;
1108}
1109
1110QuicConsumedData QuicPacketCreator::ConsumeData(QuicStreamId id,
1111 size_t write_length,
1112 QuicStreamOffset offset,
1113 StreamSendingState state) {
fayang18be79a2019-09-16 15:17:12 -07001114 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1115 "generator tries to write stream data.";
1116 bool has_handshake = QuicUtils::IsCryptoStreamId(transport_version(), id);
1117 MaybeBundleAckOpportunistically();
1118 bool fin = state != NO_FIN;
1119 QUIC_BUG_IF(has_handshake && fin)
1120 << "Handshake packets should never send a fin";
1121 // To make reasoning about crypto frames easier, we don't combine them with
1122 // other retransmittable frames in a single packet.
1123 if (has_handshake && HasPendingRetransmittableFrames()) {
1124 FlushCurrentPacket();
1125 }
1126
1127 size_t total_bytes_consumed = 0;
1128 bool fin_consumed = false;
1129
1130 if (!HasRoomForStreamFrame(id, offset, write_length)) {
1131 FlushCurrentPacket();
1132 }
1133
1134 if (!fin && (write_length == 0)) {
1135 QUIC_BUG << "Attempt to consume empty data without FIN.";
1136 return QuicConsumedData(0, false);
1137 }
1138 // We determine if we can enter the fast path before executing
1139 // the slow path loop.
1140 bool run_fast_path =
1141 !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
fayang2ab1e852019-11-04 11:24:36 -08001142 write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
1143 latched_hard_max_packet_length_ == 0;
fayang18be79a2019-09-16 15:17:12 -07001144
1145 while (!run_fast_path && delegate_->ShouldGeneratePacket(
1146 HAS_RETRANSMITTABLE_DATA,
1147 has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) {
1148 QuicFrame frame;
1149 bool needs_full_padding =
1150 has_handshake && fully_pad_crypto_handshake_packets_;
1151
1152 if (!ConsumeDataToFillCurrentPacket(id, write_length - total_bytes_consumed,
1153 offset + total_bytes_consumed, fin,
1154 needs_full_padding,
1155 next_transmission_type_, &frame)) {
1156 // The creator is always flushed if there's not enough room for a new
1157 // stream frame before ConsumeData, so ConsumeData should always succeed.
1158 QUIC_BUG << "Failed to ConsumeData, stream:" << id;
1159 return QuicConsumedData(0, false);
1160 }
1161
1162 // A stream frame is created and added.
1163 size_t bytes_consumed = frame.stream_frame.data_length;
1164 total_bytes_consumed += bytes_consumed;
1165 fin_consumed = fin && total_bytes_consumed == write_length;
1166 if (fin_consumed && state == FIN_AND_PADDING) {
1167 AddRandomPadding();
1168 }
1169 DCHECK(total_bytes_consumed == write_length ||
1170 (bytes_consumed > 0 && HasPendingFrames()));
1171
1172 if (total_bytes_consumed == write_length) {
1173 // We're done writing the data. Exit the loop.
1174 // We don't make this a precondition because we could have 0 bytes of data
1175 // if we're simply writing a fin.
1176 break;
1177 }
1178 FlushCurrentPacket();
1179
1180 run_fast_path =
1181 !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
fayang2ab1e852019-11-04 11:24:36 -08001182 write_length - total_bytes_consumed > kMaxOutgoingPacketSize &&
1183 latched_hard_max_packet_length_ == 0;
fayang18be79a2019-09-16 15:17:12 -07001184 }
1185
1186 if (run_fast_path) {
1187 return ConsumeDataFastPath(id, write_length, offset, state != NO_FIN,
1188 total_bytes_consumed);
1189 }
1190
1191 // Don't allow the handshake to be bundled with other retransmittable frames.
1192 if (has_handshake) {
1193 FlushCurrentPacket();
1194 }
1195
1196 return QuicConsumedData(total_bytes_consumed, fin_consumed);
1197}
1198
1199QuicConsumedData QuicPacketCreator::ConsumeDataFastPath(
1200 QuicStreamId id,
1201 size_t write_length,
1202 QuicStreamOffset offset,
1203 bool fin,
1204 size_t total_bytes_consumed) {
fayang18be79a2019-09-16 15:17:12 -07001205 DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
1206
1207 while (total_bytes_consumed < write_length &&
1208 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
1209 NOT_HANDSHAKE)) {
1210 // Serialize and encrypt the packet.
1211 size_t bytes_consumed = 0;
1212 CreateAndSerializeStreamFrame(id, write_length, total_bytes_consumed,
1213 offset + total_bytes_consumed, fin,
1214 next_transmission_type_, &bytes_consumed);
fayangd99c2c12019-11-08 13:22:51 -08001215 if (GetQuicReloadableFlag(
1216 quic_close_connection_on_failed_consume_data_fast_path)) {
1217 QUIC_RELOADABLE_FLAG_COUNT(
1218 quic_close_connection_on_failed_consume_data_fast_path);
1219 if (bytes_consumed == 0) {
1220 const std::string error_details =
1221 "Failed in CreateAndSerializeStreamFrame.";
1222 QUIC_BUG << error_details;
1223 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
1224 error_details);
1225 break;
1226 }
1227 }
fayang18be79a2019-09-16 15:17:12 -07001228 total_bytes_consumed += bytes_consumed;
1229 }
1230
1231 return QuicConsumedData(total_bytes_consumed,
1232 fin && (total_bytes_consumed == write_length));
1233}
1234
1235size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
1236 size_t write_length,
1237 QuicStreamOffset offset) {
fayang18be79a2019-09-16 15:17:12 -07001238 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1239 "generator tries to write crypto data.";
1240 MaybeBundleAckOpportunistically();
1241 // To make reasoning about crypto frames easier, we don't combine them with
1242 // other retransmittable frames in a single packet.
1243 // TODO(nharper): Once we have separate packet number spaces, everything
1244 // should be driven by encryption level, and we should stop flushing in this
1245 // spot.
1246 if (HasPendingRetransmittableFrames()) {
1247 FlushCurrentPacket();
1248 }
1249
1250 size_t total_bytes_consumed = 0;
1251
1252 while (total_bytes_consumed < write_length) {
1253 QuicFrame frame;
1254 if (!ConsumeCryptoDataToFillCurrentPacket(
1255 level, write_length - total_bytes_consumed,
1256 offset + total_bytes_consumed, fully_pad_crypto_handshake_packets_,
1257 next_transmission_type_, &frame)) {
1258 // The only pending data in the packet is non-retransmittable frames. I'm
1259 // assuming here that they won't occupy so much of the packet that a
1260 // CRYPTO frame won't fit.
1261 QUIC_BUG << "Failed to ConsumeCryptoData at level " << level;
1262 return 0;
1263 }
1264 total_bytes_consumed += frame.crypto_frame->data_length;
1265 FlushCurrentPacket();
1266 }
1267
1268 // Don't allow the handshake to be bundled with other retransmittable frames.
1269 FlushCurrentPacket();
1270
1271 return total_bytes_consumed;
1272}
1273
1274void QuicPacketCreator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
fayang18be79a2019-09-16 15:17:12 -07001275 // MTU discovery frames must be sent by themselves.
1276 if (!CanSetMaxPacketLength()) {
1277 QUIC_BUG << "MTU discovery packets should only be sent when no other "
1278 << "frames needs to be sent.";
1279 return;
1280 }
1281 const QuicByteCount current_mtu = max_packet_length();
1282
1283 // The MTU discovery frame is allocated on the stack, since it is going to be
1284 // serialized within this function.
1285 QuicMtuDiscoveryFrame mtu_discovery_frame;
1286 QuicFrame frame(mtu_discovery_frame);
1287
1288 // Send the probe packet with the new length.
1289 SetMaxPacketLength(target_mtu);
1290 const bool success = AddPaddedSavedFrame(frame, next_transmission_type_);
1291 FlushCurrentPacket();
1292 // The only reason AddFrame can fail is that the packet is too full to fit in
1293 // a ping. This is not possible for any sane MTU.
ianswettbd78ea12019-09-26 06:32:37 -07001294 QUIC_BUG_IF(!success) << "Failed to send path MTU target_mtu:" << target_mtu
1295 << " transmission_type:" << next_transmission_type_;
fayang18be79a2019-09-16 15:17:12 -07001296
1297 // Reset the packet length back.
1298 SetMaxPacketLength(current_mtu);
1299}
1300
1301void QuicPacketCreator::MaybeBundleAckOpportunistically() {
fayang18be79a2019-09-16 15:17:12 -07001302 if (has_ack()) {
1303 // Ack already queued, nothing to do.
1304 return;
1305 }
1306 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
1307 NOT_HANDSHAKE)) {
1308 return;
1309 }
1310 const bool flushed =
1311 FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
ianswettbd78ea12019-09-26 06:32:37 -07001312 QUIC_BUG_IF(!flushed) << "Failed to flush ACK frame. encryption_level:"
1313 << packet_.encryption_level;
fayang18be79a2019-09-16 15:17:12 -07001314}
1315
1316bool QuicPacketCreator::FlushAckFrame(const QuicFrames& frames) {
fayang18be79a2019-09-16 15:17:12 -07001317 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1318 "generator tries to send ACK frame.";
1319 for (const auto& frame : frames) {
1320 DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME);
1321 if (HasPendingFrames()) {
renjietangb63005e2019-11-19 23:08:53 -08001322 if (AddFrame(frame, next_transmission_type_)) {
fayang18be79a2019-09-16 15:17:12 -07001323 // There is pending frames and current frame fits.
1324 continue;
1325 }
1326 }
1327 DCHECK(!HasPendingFrames());
1328 // There is no pending frames, consult the delegate whether a packet can be
1329 // generated.
1330 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
1331 NOT_HANDSHAKE)) {
1332 return false;
1333 }
renjietangb63005e2019-11-19 23:08:53 -08001334 const bool success = AddFrame(frame, next_transmission_type_);
fayang18be79a2019-09-16 15:17:12 -07001335 QUIC_BUG_IF(!success) << "Failed to flush " << frame;
1336 }
1337 return true;
1338}
1339
1340void QuicPacketCreator::AddRandomPadding() {
fayang18be79a2019-09-16 15:17:12 -07001341 AddPendingPadding(random_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
1342}
1343
1344void QuicPacketCreator::AttachPacketFlusher() {
fayang18be79a2019-09-16 15:17:12 -07001345 flusher_attached_ = true;
1346 if (!write_start_packet_number_.IsInitialized()) {
1347 write_start_packet_number_ = NextSendingPacketNumber();
1348 }
1349}
1350
1351void QuicPacketCreator::Flush() {
fayang18be79a2019-09-16 15:17:12 -07001352 FlushCurrentPacket();
1353 SendRemainingPendingPadding();
1354 flusher_attached_ = false;
1355 if (GetQuicFlag(FLAGS_quic_export_server_num_packets_per_write_histogram)) {
1356 if (!write_start_packet_number_.IsInitialized()) {
1357 QUIC_BUG << "write_start_packet_number is not initialized";
1358 return;
1359 }
1360 QUIC_SERVER_HISTOGRAM_COUNTS(
1361 "quic_server_num_written_packets_per_write",
1362 NextSendingPacketNumber() - write_start_packet_number_, 1, 200, 50,
1363 "Number of QUIC packets written per write operation");
1364 }
1365 write_start_packet_number_.Clear();
1366}
1367
1368void QuicPacketCreator::SendRemainingPendingPadding() {
fayang18be79a2019-09-16 15:17:12 -07001369 while (
1370 pending_padding_bytes() > 0 && !HasPendingFrames() &&
1371 delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) {
1372 FlushCurrentPacket();
1373 }
1374}
1375
1376void QuicPacketCreator::SetServerConnectionIdLength(uint32_t length) {
fayang18be79a2019-09-16 15:17:12 -07001377 if (length == 0) {
1378 SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
1379 } else {
1380 SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
1381 }
1382}
1383
1384void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
fayangcff885a2019-10-22 07:39:04 -07001385 next_transmission_type_ = type;
fayang18be79a2019-09-16 15:17:12 -07001386}
1387
1388MessageStatus QuicPacketCreator::AddMessageFrame(QuicMessageId message_id,
1389 QuicMemSliceSpan message) {
fayang18be79a2019-09-16 15:17:12 -07001390 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
1391 "generator tries to add message frame.";
1392 MaybeBundleAckOpportunistically();
1393 const QuicByteCount message_length = message.total_length();
1394 if (message_length > GetCurrentLargestMessagePayload()) {
1395 return MESSAGE_STATUS_TOO_LARGE;
1396 }
1397 if (!HasRoomForMessageFrame(message_length)) {
1398 FlushCurrentPacket();
1399 }
1400 QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
renjietangb63005e2019-11-19 23:08:53 -08001401 const bool success = AddFrame(QuicFrame(frame), next_transmission_type_);
fayang18be79a2019-09-16 15:17:12 -07001402 if (!success) {
1403 QUIC_BUG << "Failed to send message " << message_id;
1404 delete frame;
1405 return MESSAGE_STATUS_INTERNAL_ERROR;
1406 }
1407 return MESSAGE_STATUS_SUCCESS;
1408}
1409
QUICHE teama6ef0a62019-03-07 20:34:33 -05001410QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
1411 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1412 HasIetfLongHeader()) {
1413 QuicLongHeaderType long_header_type =
1414 EncryptionlevelToLongHeaderType(packet_.encryption_level);
1415 if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
1416 long_header_type == HANDSHAKE) {
1417 return VARIABLE_LENGTH_INTEGER_LENGTH_2;
1418 }
1419 }
1420 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
1421}
1422
1423void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
QUICHE team2252b702019-05-14 23:55:14 -04001424 header->destination_connection_id = GetDestinationConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001425 header->destination_connection_id_included =
1426 GetDestinationConnectionIdIncluded();
QUICHE team2252b702019-05-14 23:55:14 -04001427 header->source_connection_id = GetSourceConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001428 header->source_connection_id_included = GetSourceConnectionIdIncluded();
1429 header->reset_flag = false;
1430 header->version_flag = IncludeVersionInHeader();
1431 if (IncludeNonceInPublicHeader()) {
1432 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
1433 header->nonce = &diversification_nonce_;
1434 } else {
1435 header->nonce = nullptr;
1436 }
fayang354c9422019-05-21 08:10:35 -07001437 packet_.packet_number = NextSendingPacketNumber();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001438 header->packet_number = packet_.packet_number;
1439 header->packet_number_length = GetPacketNumberLength();
1440 header->retry_token_length_length = GetRetryTokenLengthLength();
1441 header->retry_token = GetRetryToken();
1442 header->length_length = GetLengthLength();
1443 header->remaining_packet_length = 0;
1444 if (!HasIetfLongHeader()) {
1445 return;
1446 }
1447 header->long_packet_type =
1448 EncryptionlevelToLongHeaderType(packet_.encryption_level);
1449}
1450
1451bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
QUICHE teama6ef0a62019-03-07 20:34:33 -05001452 TransmissionType transmission_type) {
1453 QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
dschinazief79a5f2019-10-04 10:32:54 -07001454 << TransmissionTypeToString(transmission_type) << ": " << frame;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001455 if (frame.type == STREAM_FRAME &&
nharper46833c32019-05-15 21:33:05 -07001456 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
1457 frame.stream_frame.stream_id) &&
fayang49523232019-05-03 06:28:22 -07001458 (packet_.encryption_level == ENCRYPTION_INITIAL ||
1459 packet_.encryption_level == ENCRYPTION_HANDSHAKE)) {
dschinazief79a5f2019-10-04 10:32:54 -07001460 const std::string error_details =
1461 QuicStrCat("Cannot send stream data with level: ",
1462 EncryptionLevelToString(packet_.encryption_level));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001463 QUIC_BUG << error_details;
1464 delegate_->OnUnrecoverableError(
fkastenholz85f18902019-05-28 12:47:00 -07001465 QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001466 return false;
1467 }
renjietangdbe98342019-10-18 11:00:57 -07001468
renjietanga66e4152019-11-11 13:23:33 -08001469 if (GetQuicRestartFlag(quic_coalesce_stream_frames_2) &&
renjietangdbe98342019-10-18 11:00:57 -07001470 frame.type == STREAM_FRAME &&
1471 MaybeCoalesceStreamFrame(frame.stream_frame)) {
renjietanga66e4152019-11-11 13:23:33 -08001472 QUIC_RESTART_FLAG_COUNT_N(quic_coalesce_stream_frames_2, 1, 3);
renjietangdbe98342019-10-18 11:00:57 -07001473 return true;
1474 }
1475
QUICHE teama6ef0a62019-03-07 20:34:33 -05001476 size_t frame_len = framer_->GetSerializedFrameLength(
1477 frame, BytesFree(), queued_frames_.empty(),
1478 /* last_frame_in_packet= */ true, GetPacketNumberLength());
fayang2ab1e852019-11-04 11:24:36 -08001479 if (frame_len == 0 && RemoveSoftMaxPacketLength()) {
1480 // Remove soft max_packet_length and retry.
1481 frame_len = framer_->GetSerializedFrameLength(
1482 frame, BytesFree(), queued_frames_.empty(),
1483 /* last_frame_in_packet= */ true, GetPacketNumberLength());
1484 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001485 if (frame_len == 0) {
1486 // Current open packet is full.
fayang62b637b2019-09-16 08:40:49 -07001487 FlushCurrentPacket();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001488 return false;
1489 }
1490 DCHECK_LT(0u, packet_size_);
1491
1492 packet_size_ += ExpansionOnNewFrame() + frame_len;
1493
fayang347ab752019-10-22 11:17:43 -07001494 if (QuicUtils::IsRetransmittableFrame(frame.type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001495 packet_.retransmittable_frames.push_back(frame);
1496 queued_frames_.push_back(frame);
1497 if (QuicUtils::IsHandshakeFrame(frame, framer_->transport_version())) {
1498 packet_.has_crypto_handshake = IS_HANDSHAKE;
1499 }
1500 } else {
fayang02a28742019-12-04 07:09:38 -08001501 if (frame.type == PADDING_FRAME &&
1502 frame.padding_frame.num_padding_bytes == -1) {
1503 // Populate the actual length of full padding frame, such that one can
1504 // know how much padding is actually added.
1505 packet_.nonretransmittable_frames.push_back(
1506 QuicFrame(QuicPaddingFrame(frame_len)));
1507 } else {
1508 packet_.nonretransmittable_frames.push_back(frame);
fayang51152fd2019-10-21 06:48:09 -07001509 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001510 queued_frames_.push_back(frame);
1511 }
1512
1513 if (frame.type == ACK_FRAME) {
1514 packet_.has_ack = true;
1515 packet_.largest_acked = LargestAcked(*frame.ack_frame);
1516 }
1517 if (frame.type == STOP_WAITING_FRAME) {
1518 packet_.has_stop_waiting = true;
1519 }
1520 if (debug_delegate_ != nullptr) {
1521 debug_delegate_->OnFrameAddedToPacket(frame);
1522 }
1523
1524 // Packet transmission type is determined by the last added retransmittable
1525 // frame.
fayangcff885a2019-10-22 07:39:04 -07001526 if (QuicUtils::IsRetransmittableFrame(frame.type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001527 packet_.transmission_type = transmission_type;
1528 }
1529 return true;
1530}
1531
renjietangdbe98342019-10-18 11:00:57 -07001532bool QuicPacketCreator::MaybeCoalesceStreamFrame(const QuicStreamFrame& frame) {
1533 if (queued_frames_.empty() || queued_frames_.back().type != STREAM_FRAME) {
1534 return false;
1535 }
1536 QuicStreamFrame* candidate = &queued_frames_.back().stream_frame;
1537 if (candidate->stream_id != frame.stream_id ||
1538 candidate->offset + candidate->data_length != frame.offset ||
1539 frame.data_length > BytesFree()) {
1540 return false;
1541 }
1542 candidate->data_length += frame.data_length;
1543 candidate->fin = frame.fin;
1544
1545 // The back of retransmittable frames must be the same as the original
1546 // queued frames' back.
1547 DCHECK_EQ(packet_.retransmittable_frames.back().type, STREAM_FRAME);
1548 QuicStreamFrame* retransmittable =
1549 &packet_.retransmittable_frames.back().stream_frame;
1550 DCHECK_EQ(retransmittable->stream_id, frame.stream_id);
1551 DCHECK_EQ(retransmittable->offset + retransmittable->data_length,
1552 frame.offset);
1553 retransmittable->data_length = candidate->data_length;
1554 retransmittable->fin = candidate->fin;
1555 packet_size_ += frame.data_length;
1556 if (debug_delegate_ != nullptr) {
1557 debug_delegate_->OnStreamFrameCoalesced(*candidate);
1558 }
1559 return true;
1560}
1561
fayang2ab1e852019-11-04 11:24:36 -08001562bool QuicPacketCreator::RemoveSoftMaxPacketLength() {
1563 if (latched_hard_max_packet_length_ == 0) {
1564 return false;
1565 }
1566 if (!CanSetMaxPacketLength()) {
1567 return false;
1568 }
1569 QUIC_DVLOG(1) << "Restoring max packet length to: "
1570 << latched_hard_max_packet_length_;
1571 SetMaxPacketLength(latched_hard_max_packet_length_);
1572 // Reset latched_max_packet_length_.
1573 latched_hard_max_packet_length_ = 0;
1574 return true;
1575}
1576
QUICHE teama6ef0a62019-03-07 20:34:33 -05001577void QuicPacketCreator::MaybeAddPadding() {
1578 // The current packet should have no padding bytes because padding is only
1579 // added when this method is called just before the packet is serialized.
1580 DCHECK_EQ(0, packet_.num_padding_bytes);
1581 if (BytesFree() == 0) {
1582 // Don't pad full packets.
1583 return;
1584 }
1585
1586 if (packet_.transmission_type == PROBING_RETRANSMISSION) {
1587 needs_full_padding_ = true;
1588 }
1589
fayang58f71072019-11-05 08:47:02 -08001590 // Packet coalescer pads INITIAL packets, so the creator should not.
1591 if (framer_->version().CanSendCoalescedPackets() &&
1592 (packet_.encryption_level == ENCRYPTION_INITIAL ||
1593 packet_.encryption_level == ENCRYPTION_HANDSHAKE)) {
1594 // TODO(fayang): MTU discovery packets should not ever be sent as
1595 // ENCRYPTION_INITIAL or ENCRYPTION_HANDSHAKE.
1596 bool is_mtu_discovery = false;
1597 for (const auto& frame : packet_.nonretransmittable_frames) {
1598 if (frame.type == MTU_DISCOVERY_FRAME) {
1599 is_mtu_discovery = true;
1600 break;
1601 }
1602 }
1603 if (!is_mtu_discovery) {
1604 // Do not add full padding if connection tries to coalesce packet.
1605 needs_full_padding_ = false;
1606 }
1607 }
1608
nharper55fa6132019-05-07 19:37:21 -07001609 // Header protection requires a minimum plaintext packet size.
1610 size_t extra_padding_bytes = 0;
1611 if (framer_->version().HasHeaderProtection()) {
1612 size_t frame_bytes = PacketSize() - PacketHeaderSize();
1613
QUICHE team2252b702019-05-14 23:55:14 -04001614 if (frame_bytes + pending_padding_bytes_ <
1615 MinPlaintextPacketSize(framer_->version()) &&
nharper55fa6132019-05-07 19:37:21 -07001616 !needs_full_padding_) {
QUICHE team2252b702019-05-14 23:55:14 -04001617 extra_padding_bytes =
1618 MinPlaintextPacketSize(framer_->version()) - frame_bytes;
nharper55fa6132019-05-07 19:37:21 -07001619 }
1620 }
1621
1622 if (!needs_full_padding_ && pending_padding_bytes_ == 0 &&
1623 extra_padding_bytes == 0) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001624 // Do not need padding.
1625 return;
1626 }
1627
nharper55fa6132019-05-07 19:37:21 -07001628 int padding_bytes = -1;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001629 if (needs_full_padding_) {
1630 // Full padding does not consume pending padding bytes.
1631 packet_.num_padding_bytes = -1;
1632 } else {
1633 packet_.num_padding_bytes =
1634 std::min<int16_t>(pending_padding_bytes_, BytesFree());
1635 pending_padding_bytes_ -= packet_.num_padding_bytes;
nharper55fa6132019-05-07 19:37:21 -07001636 padding_bytes =
1637 std::max<int16_t>(packet_.num_padding_bytes, extra_padding_bytes);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001638 }
1639
fayang347ab752019-10-22 11:17:43 -07001640 bool success = AddFrame(QuicFrame(QuicPaddingFrame(padding_bytes)),
nharper55fa6132019-05-07 19:37:21 -07001641 packet_.transmission_type);
dschinazief79a5f2019-10-04 10:32:54 -07001642 QUIC_BUG_IF(!success) << "Failed to add padding_bytes: " << padding_bytes
1643 << " transmission_type: "
1644 << TransmissionTypeToString(packet_.transmission_type);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001645}
1646
1647bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
1648 return have_diversification_nonce_ &&
1649 packet_.encryption_level == ENCRYPTION_ZERO_RTT;
1650}
1651
1652bool QuicPacketCreator::IncludeVersionInHeader() const {
fayangd4291e42019-05-30 10:31:21 -07001653 if (VersionHasIetfInvariantHeader(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001654 return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1655 }
1656 return send_version_in_packet_;
1657}
1658
1659void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
1660 pending_padding_bytes_ += size;
1661}
1662
ianswette28f0222019-04-04 13:31:22 -07001663bool QuicPacketCreator::StreamFrameIsClientHello(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001664 const QuicStreamFrame& frame) const {
1665 if (framer_->perspective() == Perspective::IS_SERVER ||
nharper46833c32019-05-15 21:33:05 -07001666 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
1667 frame.stream_id)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001668 return false;
1669 }
ianswette28f0222019-04-04 13:31:22 -07001670 // The ClientHello is always sent with INITIAL encryption.
1671 return packet_.encryption_level == ENCRYPTION_INITIAL;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001672}
1673
dschinazi7b9278c2019-05-20 07:36:21 -07001674void QuicPacketCreator::SetServerConnectionIdIncluded(
1675 QuicConnectionIdIncluded server_connection_id_included) {
1676 DCHECK(server_connection_id_included == CONNECTION_ID_PRESENT ||
1677 server_connection_id_included == CONNECTION_ID_ABSENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001678 DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
dschinazi7b9278c2019-05-20 07:36:21 -07001679 server_connection_id_included != CONNECTION_ID_ABSENT);
1680 server_connection_id_included_ = server_connection_id_included;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001681}
1682
dschinazi7b9278c2019-05-20 07:36:21 -07001683void QuicPacketCreator::SetServerConnectionId(
1684 QuicConnectionId server_connection_id) {
1685 server_connection_id_ = server_connection_id;
QUICHE teamc65d1d12019-03-19 20:58:04 -07001686}
1687
dschinazi346b7ce2019-06-05 01:38:18 -07001688void QuicPacketCreator::SetClientConnectionId(
1689 QuicConnectionId client_connection_id) {
1690 DCHECK(client_connection_id.IsEmpty() ||
1691 framer_->version().SupportsClientConnectionIds());
dschinazi346b7ce2019-06-05 01:38:18 -07001692 client_connection_id_ = client_connection_id;
1693}
1694
ianswettb239f862019-04-05 09:15:06 -07001695QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001696 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001697 return 0;
1698 }
1699 const size_t packet_header_size = GetPacketHeaderSize(
1700 framer_->transport_version(), GetDestinationConnectionIdLength(),
1701 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
1702 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
ianswettb239f862019-04-05 09:15:06 -07001703 // No Retry token on packets containing application data.
1704 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001705 // This is the largest possible message payload when the length field is
1706 // omitted.
fayang2ab1e852019-11-04 11:24:36 -08001707 size_t max_plaintext_size =
1708 latched_hard_max_packet_length_ == 0
1709 ? max_plaintext_size_
1710 : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
1711 return max_plaintext_size -
1712 std::min(max_plaintext_size, packet_header_size + kQuicFrameTypeSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001713}
1714
ianswettb239f862019-04-05 09:15:06 -07001715QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001716 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
ianswettb239f862019-04-05 09:15:06 -07001717 return 0;
1718 }
1719 // QUIC Crypto server packets may include a diversification nonce.
1720 const bool may_include_nonce =
1721 framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
1722 framer_->perspective() == Perspective::IS_SERVER;
1723 // IETF QUIC long headers include a length on client 0RTT packets.
1724 QuicVariableLengthIntegerLength length_length =
nharperd43f1d62019-07-01 15:18:20 -07001725 VARIABLE_LENGTH_INTEGER_LENGTH_0;
1726 if (framer_->perspective() == Perspective::IS_CLIENT) {
1727 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
1728 }
nharper405f7192019-09-11 08:28:06 -07001729 if (!QuicVersionHasLongHeaderLengths(framer_->transport_version())) {
nharperd43f1d62019-07-01 15:18:20 -07001730 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
1731 }
ianswettb239f862019-04-05 09:15:06 -07001732 const size_t packet_header_size = GetPacketHeaderSize(
1733 framer_->transport_version(), GetDestinationConnectionIdLength(),
1734 // Assume CID lengths don't change, but version may be present.
1735 GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
1736 PACKET_4BYTE_PACKET_NUMBER,
1737 // No Retry token on packets containing application data.
1738 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
1739 // This is the largest possible message payload when the length field is
1740 // omitted.
fayang2ab1e852019-11-04 11:24:36 -08001741 size_t max_plaintext_size =
1742 latched_hard_max_packet_length_ == 0
1743 ? max_plaintext_size_
1744 : framer_->GetMaxPlaintextSize(latched_hard_max_packet_length_);
ianswettb239f862019-04-05 09:15:06 -07001745 const QuicPacketLength largest_payload =
fayang2ab1e852019-11-04 11:24:36 -08001746 max_plaintext_size -
1747 std::min(max_plaintext_size, packet_header_size + kQuicFrameTypeSize);
ianswettb239f862019-04-05 09:15:06 -07001748 // This must always be less than or equal to GetCurrentLargestMessagePayload.
1749 DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload());
1750 return largest_payload;
1751}
1752
QUICHE teama6ef0a62019-03-07 20:34:33 -05001753bool QuicPacketCreator::HasIetfLongHeader() const {
fayangd4291e42019-05-30 10:31:21 -07001754 return VersionHasIetfInvariantHeader(framer_->transport_version()) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05001755 packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1756}
1757
nharper6f8a7612019-07-08 12:31:20 -07001758// static
QUICHE team2252b702019-05-14 23:55:14 -04001759size_t QuicPacketCreator::MinPlaintextPacketSize(
1760 const ParsedQuicVersion& version) {
1761 if (!version.HasHeaderProtection()) {
nharper55fa6132019-05-07 19:37:21 -07001762 return 0;
1763 }
1764 // Header protection samples 16 bytes of ciphertext starting 4 bytes after the
1765 // packet number. In IETF QUIC, all AEAD algorithms have a 16-byte auth tag
1766 // (i.e. the ciphertext is 16 bytes larger than the plaintext). Since packet
1767 // numbers could be as small as 1 byte, but the sample starts 4 bytes after
1768 // the packet number, at least 3 bytes of plaintext are needed to make sure
1769 // that there is enough ciphertext to sample.
1770 //
1771 // Google QUIC crypto uses different AEAD algorithms - in particular the auth
1772 // tags are only 12 bytes instead of 16 bytes. Since the auth tag is 4 bytes
1773 // shorter, 4 more bytes of plaintext are needed to guarantee there is enough
1774 // ciphertext to sample.
1775 //
1776 // This method could check for PROTOCOL_TLS1_3 vs PROTOCOL_QUIC_CRYPTO and
1777 // return 3 when TLS 1.3 is in use (the use of IETF vs Google QUIC crypters is
1778 // determined based on the handshake protocol used). However, even when TLS
1779 // 1.3 is used, unittests still use NullEncrypter/NullDecrypter (and other
1780 // test crypters) which also only use 12 byte tags.
1781 //
1782 // TODO(nharper): Set this based on the handshake protocol in use.
1783 return 7;
1784}
1785
fayang354c9422019-05-21 08:10:35 -07001786QuicPacketNumber QuicPacketCreator::NextSendingPacketNumber() const {
1787 if (!packet_number().IsInitialized()) {
1788 return framer_->first_sending_packet_number();
1789 }
1790 return packet_number() + 1;
1791}
1792
fayang18be79a2019-09-16 15:17:12 -07001793bool QuicPacketCreator::PacketFlusherAttached() const {
fayang18be79a2019-09-16 15:17:12 -07001794 return flusher_attached_;
1795}
1796
QUICHE teama6ef0a62019-03-07 20:34:33 -05001797#undef ENDPOINT // undef for jumbo builds
1798} // namespace quic