blob: 96b5bc6e0895f141a31d03aa3da0a6976454e536 [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>
8#include <cstdint>
vasilvv872e7a32019-03-12 16:42:44 -07009#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050010
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
12#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
ianswettb239f862019-04-05 09:15:06 -070013#include "net/third_party/quiche/src/quic/core/quic_constants.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
15#include "net/third_party/quiche/src/quic/core/quic_types.h"
16#include "net/third_party/quiche/src/quic/core/quic_utils.h"
ianswettb239f862019-04-05 09:15:06 -070017#include "net/third_party/quiche/src/quic/core/quic_versions.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050018#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h"
19#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
20#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
21#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
22#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
23#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
24#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050025#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
26#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
27
28namespace quic {
29namespace {
30
31QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
32 switch (level) {
QUICHE team6987b4a2019-03-15 16:23:04 -070033 case ENCRYPTION_INITIAL:
QUICHE teama6ef0a62019-03-07 20:34:33 -050034 return INITIAL;
QUICHE team88ea0082019-03-15 10:05:26 -070035 case ENCRYPTION_HANDSHAKE:
36 return HANDSHAKE;
QUICHE teama6ef0a62019-03-07 20:34:33 -050037 case ENCRYPTION_ZERO_RTT:
38 return ZERO_RTT_PROTECTED;
39 case ENCRYPTION_FORWARD_SECURE:
40 QUIC_BUG
41 << "Try to derive long header type for packet with encryption level: "
42 << QuicUtils::EncryptionLevelToString(level);
43 return INVALID_PACKET_TYPE;
44 default:
45 QUIC_BUG << QuicUtils::EncryptionLevelToString(level);
46 return INVALID_PACKET_TYPE;
47 }
48}
49
50} // namespace
51
52#define ENDPOINT \
53 (framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
54
55QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id,
56 QuicFramer* framer,
57 DelegateInterface* delegate)
58 : QuicPacketCreator(connection_id,
59 framer,
60 QuicRandom::GetInstance(),
61 delegate) {}
62
63QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id,
64 QuicFramer* framer,
65 QuicRandom* random,
66 DelegateInterface* delegate)
67 : delegate_(delegate),
68 debug_delegate_(nullptr),
69 framer_(framer),
70 random_(random),
71 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
72 have_diversification_nonce_(false),
73 max_packet_length_(0),
74 connection_id_included_(CONNECTION_ID_PRESENT),
75 packet_size_(0),
76 connection_id_(connection_id),
77 packet_(QuicPacketNumber(),
78 PACKET_1BYTE_PACKET_NUMBER,
79 nullptr,
80 0,
81 false,
82 false),
83 pending_padding_bytes_(0),
84 needs_full_padding_(false),
85 can_set_transmission_type_(false),
86 set_transmission_type_for_next_frame_(
87 GetQuicReloadableFlag(quic_set_transmission_type_for_next_frame)) {
88 SetMaxPacketLength(kDefaultMaxPacketSize);
89}
90
91QuicPacketCreator::~QuicPacketCreator() {
92 DeleteFrames(&packet_.retransmittable_frames);
93}
94
95void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
96 std::unique_ptr<QuicEncrypter> encrypter) {
97 framer_->SetEncrypter(level, std::move(encrypter));
98 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
99}
100
101bool QuicPacketCreator::CanSetMaxPacketLength() const {
102 // |max_packet_length_| should not be changed mid-packet.
103 return queued_frames_.empty();
104}
105
106void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
107 DCHECK(CanSetMaxPacketLength());
108
109 // Avoid recomputing |max_plaintext_size_| if the length does not actually
110 // change.
111 if (length == max_packet_length_) {
112 return;
113 }
114
115 max_packet_length_ = length;
116 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
117}
118
119// Stops serializing version of the protocol in packets sent after this call.
120// A packet that is already open might send kQuicVersionSize bytes less than the
121// maximum packet size if we stop sending version before it is serialized.
122void QuicPacketCreator::StopSendingVersion() {
123 DCHECK(send_version_in_packet_);
124 DCHECK_LE(framer_->transport_version(), QUIC_VERSION_43);
125 send_version_in_packet_ = false;
126 if (packet_size_ > 0) {
127 DCHECK_LT(kQuicVersionSize, packet_size_);
128 packet_size_ -= kQuicVersionSize;
129 }
130}
131
132void QuicPacketCreator::SetDiversificationNonce(
133 const DiversificationNonce& nonce) {
134 DCHECK(!have_diversification_nonce_);
135 have_diversification_nonce_ = true;
136 diversification_nonce_ = nonce;
137}
138
139void QuicPacketCreator::UpdatePacketNumberLength(
140 QuicPacketNumber least_packet_awaited_by_peer,
141 QuicPacketCount max_packets_in_flight) {
142 if (!queued_frames_.empty()) {
143 // Don't change creator state if there are frames queued.
144 QUIC_BUG << "Called UpdatePacketNumberLength with " << queued_frames_.size()
145 << " queued_frames. First frame type:"
146 << queued_frames_.front().type
147 << " last frame type:" << queued_frames_.back().type;
148 return;
149 }
150
151 DCHECK_LE(least_packet_awaited_by_peer, packet_.packet_number + 1);
152 const uint64_t current_delta =
153 packet_.packet_number + 1 - least_packet_awaited_by_peer;
154 const uint64_t delta = std::max(current_delta, max_packets_in_flight);
155 packet_.packet_number_length = QuicFramer::GetMinPacketNumberLength(
156 framer_->transport_version(), QuicPacketNumber(delta * 4));
157}
158
159bool QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
160 size_t write_length,
161 QuicStreamOffset offset,
162 TransmissionType transmission_type,
163 QuicFrame* frame) {
164 if (!CreateCryptoFrame(level, write_length, offset, frame)) {
165 return false;
166 }
167 // When crypto data was sent in stream frames, ConsumeData is called with
168 // |needs_full_padding = true|. Keep the same behavior here when sending
169 // crypto frames.
170 //
171 // TODO(nharper): Check what the IETF drafts say about padding out initial
172 // messages and change this as appropriate.
173 needs_full_padding_ = true;
174 return AddFrame(*frame, /*save_retransmittable_frames*/ true,
175 transmission_type);
176}
177
178bool QuicPacketCreator::ConsumeData(QuicStreamId id,
ianswette28f0222019-04-04 13:31:22 -0700179 size_t data_size,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500180 QuicStreamOffset offset,
181 bool fin,
182 bool needs_full_padding,
183 TransmissionType transmission_type,
184 QuicFrame* frame) {
QUICHE teamf08778a2019-03-14 08:10:26 -0700185 if (!HasRoomForStreamFrame(id, offset, data_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500186 return false;
187 }
QUICHE teamf08778a2019-03-14 08:10:26 -0700188 CreateStreamFrame(id, data_size, offset, fin, frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500189 // Explicitly disallow multi-packet CHLOs.
190 if (FLAGS_quic_enforce_single_packet_chlo &&
ianswette28f0222019-04-04 13:31:22 -0700191 StreamFrameIsClientHello(frame->stream_frame) &&
192 frame->stream_frame.data_length < data_size) {
vasilvvc48c8712019-03-11 13:38:16 -0700193 const std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500194 "Client hello won't fit in a single packet.";
195 QUIC_BUG << error_details << " Constructed stream frame length: "
196 << frame->stream_frame.data_length
ianswette28f0222019-04-04 13:31:22 -0700197 << " CHLO length: " << data_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500198 delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details,
199 ConnectionCloseSource::FROM_SELF);
200 return false;
201 }
202 if (!AddFrame(*frame, /*save_retransmittable_frames=*/true,
203 transmission_type)) {
204 // Fails if we try to write unencrypted stream data.
205 return false;
206 }
207 if (needs_full_padding) {
208 needs_full_padding_ = true;
209 }
210
211 return true;
212}
213
214bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
215 QuicStreamOffset offset,
216 size_t data_size) {
217 return BytesFree() >
218 QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
219 offset, true, data_size);
220}
221
222bool QuicPacketCreator::HasRoomForMessageFrame(QuicByteCount length) {
223 return BytesFree() >= QuicFramer::GetMessageFrameSize(
224 framer_->transport_version(), true, length);
225}
226
227// TODO(fkastenholz): this method should not use constant values for
228// the last-frame-in-packet and data-length parameters to
229// GetMinStreamFrameSize. Proper values should be plumbed in from
230// higher up. This was left this way for now for a few reasons. First,
231// higher up calls to StreamFramePacketOverhead() do not always know
232// this information, leading to a cascade of changes and B) the
233// higher-up software does not always loop, calling
234// StreamFramePacketOverhead() once for every packet -- eg there is
235// a test in quic_connection_test that calls it once and assumes that
236// the value is the same for all packets.
237
238// static
239size_t QuicPacketCreator::StreamFramePacketOverhead(
240 QuicTransportVersion version,
241 QuicConnectionIdLength destination_connection_id_length,
242 QuicConnectionIdLength source_connection_id_length,
243 bool include_version,
244 bool include_diversification_nonce,
245 QuicPacketNumberLength packet_number_length,
246 QuicVariableLengthIntegerLength retry_token_length_length,
247 QuicVariableLengthIntegerLength length_length,
248 QuicStreamOffset offset) {
249 return GetPacketHeaderSize(version, destination_connection_id_length,
250 source_connection_id_length, include_version,
251 include_diversification_nonce,
252 packet_number_length, retry_token_length_length, 0,
253 length_length) +
254
255 // Assumes this is a packet with a single stream frame in it. Since
256 // last_frame_in_packet is set true, the size of the length field is
257 // not included in the calculation. This is OK because in other places
258 // in the code, the logic adds back 2 (the size of the Google QUIC
259 // length) when a frame is not the last frame of the packet. This is
260 // also acceptable for IETF Quic; even though the length field could be
261 // 8 bytes long, in practice it will not be longer than 2 bytes (enough
262 // to encode 16K). A length that would be encoded in 2 bytes (0xfff)
263 // is passed just for cleanliness.
264 //
265 // TODO(fkastenholz): This is very hacky and feels brittle. Ideally we
266 // would calculate the correct lengths at the correct time, based on
267 // the state at that time/place.
268 QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true,
dschinazi66dea072019-04-09 11:41:06 -0700269 kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500270}
271
272void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
QUICHE teamf08778a2019-03-14 08:10:26 -0700273 size_t data_size,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500274 QuicStreamOffset offset,
275 bool fin,
276 QuicFrame* frame) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500277 DCHECK_GT(
278 max_packet_length_,
279 StreamFramePacketOverhead(
280 framer_->transport_version(), GetDestinationConnectionIdLength(),
281 GetSourceConnectionIdLength(), kIncludeVersion,
282 IncludeNonceInPublicHeader(), PACKET_6BYTE_PACKET_NUMBER,
283 GetRetryTokenLengthLength(), GetLengthLength(), offset));
284
285 QUIC_BUG_IF(!HasRoomForStreamFrame(id, offset, data_size))
286 << "No room for Stream frame, BytesFree: " << BytesFree()
287 << " MinStreamFrameSize: "
288 << QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
289 offset, true, data_size);
290
QUICHE teamf08778a2019-03-14 08:10:26 -0700291 QUIC_BUG_IF(data_size == 0 && !fin)
292 << "Creating a stream frame for stream ID:" << id
293 << " with no data or fin.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500294 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
295 framer_->transport_version(), id, offset,
296 /* last_frame_in_packet= */ true, data_size);
297 size_t bytes_consumed =
298 std::min<size_t>(BytesFree() - min_frame_size, data_size);
299
300 bool set_fin = fin && bytes_consumed == data_size; // Last frame.
301 *frame = QuicFrame(QuicStreamFrame(id, set_fin, offset, bytes_consumed));
302}
303
304bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
305 size_t write_length,
306 QuicStreamOffset offset,
307 QuicFrame* frame) {
308 size_t min_frame_size =
309 QuicFramer::GetMinCryptoFrameSize(write_length, offset);
310 if (BytesFree() <= min_frame_size) {
311 return false;
312 }
313 size_t max_write_length = BytesFree() - min_frame_size;
314 size_t bytes_consumed = std::min<size_t>(max_write_length, write_length);
315 *frame = QuicFrame(new QuicCryptoFrame(level, offset, bytes_consumed));
316 return true;
317}
318
319void QuicPacketCreator::ReserializeAllFrames(
320 const QuicPendingRetransmission& retransmission,
321 char* buffer,
322 size_t buffer_len) {
323 DCHECK(queued_frames_.empty());
324 DCHECK_EQ(0, packet_.num_padding_bytes);
325 QUIC_BUG_IF(retransmission.retransmittable_frames.empty())
326 << "Attempt to serialize empty packet";
327 const EncryptionLevel default_encryption_level = packet_.encryption_level;
328
329 // Temporarily set the packet number length and change the encryption level.
330 packet_.packet_number_length = retransmission.packet_number_length;
331 if (retransmission.num_padding_bytes == -1) {
332 // Only retransmit padding when original packet needs full padding. Padding
333 // from pending_padding_bytes_ are not retransmitted.
334 needs_full_padding_ = true;
335 }
336 // Only preserve the original encryption level if it's a handshake packet or
337 // if we haven't gone forward secure.
338 if (retransmission.has_crypto_handshake ||
339 packet_.encryption_level != ENCRYPTION_FORWARD_SECURE) {
340 packet_.encryption_level = retransmission.encryption_level;
341 }
342
343 // Serialize the packet and restore packet number length state.
344 for (const QuicFrame& frame : retransmission.retransmittable_frames) {
345 bool success = AddFrame(frame, false, retransmission.transmission_type);
346 QUIC_BUG_IF(!success) << " Failed to add frame of type:" << frame.type
347 << " num_frames:"
348 << retransmission.retransmittable_frames.size()
349 << " retransmission.packet_number_length:"
350 << retransmission.packet_number_length
351 << " packet_.packet_number_length:"
352 << packet_.packet_number_length;
353 }
354 packet_.transmission_type = retransmission.transmission_type;
355 SerializePacket(buffer, buffer_len);
356 packet_.original_packet_number = retransmission.packet_number;
357 OnSerializedPacket();
358 // Restore old values.
359 packet_.encryption_level = default_encryption_level;
360}
361
362void QuicPacketCreator::Flush() {
363 if (!HasPendingFrames() && pending_padding_bytes_ == 0) {
364 return;
365 }
366
dschinazi66dea072019-04-09 11:41:06 -0700367 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500368 char* serialized_packet_buffer = delegate_->GetPacketBuffer();
369 if (serialized_packet_buffer == nullptr) {
370 serialized_packet_buffer = stack_buffer;
371 }
372
dschinazi66dea072019-04-09 11:41:06 -0700373 SerializePacket(serialized_packet_buffer, kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500374 OnSerializedPacket();
375}
376
377void QuicPacketCreator::OnSerializedPacket() {
378 if (packet_.encrypted_buffer == nullptr) {
vasilvvc48c8712019-03-11 13:38:16 -0700379 const std::string error_details = "Failed to SerializePacket.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500380 QUIC_BUG << error_details;
381 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
382 error_details,
383 ConnectionCloseSource::FROM_SELF);
384 return;
385 }
386
387 SerializedPacket packet(std::move(packet_));
388 ClearPacket();
389 delegate_->OnSerializedPacket(&packet);
390}
391
392void QuicPacketCreator::ClearPacket() {
393 packet_.has_ack = false;
394 packet_.has_stop_waiting = false;
395 packet_.has_crypto_handshake = NOT_HANDSHAKE;
396 packet_.num_padding_bytes = 0;
397 packet_.original_packet_number.Clear();
398 if (!can_set_transmission_type_ || ShouldSetTransmissionTypeForNextFrame()) {
399 packet_.transmission_type = NOT_RETRANSMISSION;
400 }
401 packet_.encrypted_buffer = nullptr;
402 packet_.encrypted_length = 0;
403 DCHECK(packet_.retransmittable_frames.empty());
404 packet_.largest_acked.Clear();
405 needs_full_padding_ = false;
406}
407
408void QuicPacketCreator::CreateAndSerializeStreamFrame(
409 QuicStreamId id,
410 size_t write_length,
411 QuicStreamOffset iov_offset,
412 QuicStreamOffset stream_offset,
413 bool fin,
414 TransmissionType transmission_type,
415 size_t* num_bytes_consumed) {
416 DCHECK(queued_frames_.empty());
417 // Write out the packet header
418 QuicPacketHeader header;
419 FillPacketHeader(&header);
420
dschinazi66dea072019-04-09 11:41:06 -0700421 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500422 char* encrypted_buffer = delegate_->GetPacketBuffer();
423 if (encrypted_buffer == nullptr) {
424 encrypted_buffer = stack_buffer;
425 }
426
dschinazi66dea072019-04-09 11:41:06 -0700427 QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500428 size_t length_field_offset = 0;
429 if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
430 QUIC_BUG << "AppendPacketHeader failed";
431 return;
432 }
433
434 // Create a Stream frame with the remaining space.
435 QUIC_BUG_IF(iov_offset == write_length && !fin)
436 << "Creating a stream frame with no data or fin.";
437 const size_t remaining_data_size = write_length - iov_offset;
438 const size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
439 framer_->transport_version(), id, stream_offset,
440 /* last_frame_in_packet= */ true, remaining_data_size);
441 const size_t available_size =
442 max_plaintext_size_ - writer.length() - min_frame_size;
443 const size_t bytes_consumed =
444 std::min<size_t>(available_size, remaining_data_size);
445
446 const bool set_fin = fin && (bytes_consumed == remaining_data_size);
447 QuicStreamFrame frame(id, set_fin, stream_offset, bytes_consumed);
rchc76cd742019-03-26 16:00:03 -0700448 if (debug_delegate_ != nullptr) {
449 debug_delegate_->OnFrameAddedToPacket(QuicFrame(frame));
450 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500451 QUIC_DVLOG(1) << ENDPOINT << "Adding frame: " << frame;
452
453 // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized
454 // into one method that takes a QuicStreamFrame, if warranted.
455 if (!framer_->AppendTypeByte(QuicFrame(frame),
456 /* no stream frame length */ true, &writer)) {
457 QUIC_BUG << "AppendTypeByte failed";
458 return;
459 }
460 if (!framer_->AppendStreamFrame(frame, /* no stream frame length */ true,
461 &writer)) {
462 QUIC_BUG << "AppendStreamFrame failed";
463 return;
464 }
465
466 if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset,
467 packet_.encryption_level)) {
468 return;
469 }
470
471 if (ShouldSetTransmissionTypeForNextFrame()) {
472 QUIC_RELOADABLE_FLAG_COUNT_N(quic_set_transmission_type_for_next_frame, 1,
473 2);
474 packet_.transmission_type = transmission_type;
475 }
476
477 size_t encrypted_length = framer_->EncryptInPlace(
478 packet_.encryption_level, packet_.packet_number,
479 GetStartOfEncryptedData(framer_->transport_version(), header),
dschinazi66dea072019-04-09 11:41:06 -0700480 writer.length(), kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500481 if (encrypted_length == 0) {
482 QUIC_BUG << "Failed to encrypt packet number " << header.packet_number;
483 return;
484 }
485 // TODO(ianswett): Optimize the storage so RetransmitableFrames can be
486 // unioned with a QuicStreamFrame and a UniqueStreamBuffer.
487 *num_bytes_consumed = bytes_consumed;
488 packet_size_ = 0;
489 packet_.encrypted_buffer = encrypted_buffer;
490 packet_.encrypted_length = encrypted_length;
491 packet_.retransmittable_frames.push_back(QuicFrame(frame));
492 OnSerializedPacket();
493}
494
495bool QuicPacketCreator::HasPendingFrames() const {
496 return !queued_frames_.empty();
497}
498
499bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
500 return !packet_.retransmittable_frames.empty();
501}
502
503bool QuicPacketCreator::HasPendingStreamFramesOfStream(QuicStreamId id) const {
504 for (const auto& frame : packet_.retransmittable_frames) {
505 if (frame.type == STREAM_FRAME && frame.stream_frame.stream_id == id) {
506 return true;
507 }
508 }
509 return false;
510}
511
512size_t QuicPacketCreator::ExpansionOnNewFrame() const {
513 // If the last frame in the packet is a message frame, then it will expand to
514 // include the varint message length when a new frame is added.
515 const bool has_trailing_message_frame =
516 !queued_frames_.empty() && queued_frames_.back().type == MESSAGE_FRAME;
517 if (has_trailing_message_frame) {
518 return QuicDataWriter::GetVarInt62Len(
519 queued_frames_.back().message_frame->message_length);
520 }
521 // If the last frame in the packet is a stream frame, then it will expand to
522 // include the stream_length field when a new frame is added.
523 const bool has_trailing_stream_frame =
524 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME;
525 if (!has_trailing_stream_frame) {
526 return 0;
527 }
528 if (framer_->transport_version() == QUIC_VERSION_99) {
529 return QuicDataWriter::GetVarInt62Len(
530 queued_frames_.back().stream_frame.data_length);
531 }
532 return kQuicStreamPayloadLengthSize;
533}
534
535size_t QuicPacketCreator::BytesFree() {
536 DCHECK_GE(max_plaintext_size_, PacketSize());
537 return max_plaintext_size_ -
538 std::min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
539}
540
541size_t QuicPacketCreator::PacketSize() {
542 if (!queued_frames_.empty()) {
543 return packet_size_;
544 }
545 packet_size_ = GetPacketHeaderSize(
546 framer_->transport_version(), GetDestinationConnectionIdLength(),
547 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
548 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
549 GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
550 return packet_size_;
551}
552
553bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame,
554 TransmissionType transmission_type) {
555 return AddFrame(frame, /*save_retransmittable_frames=*/true,
556 transmission_type);
557}
558
559bool QuicPacketCreator::AddPaddedSavedFrame(
560 const QuicFrame& frame,
561 TransmissionType transmission_type) {
562 if (AddFrame(frame, /*save_retransmittable_frames=*/true,
563 transmission_type)) {
564 needs_full_padding_ = true;
565 return true;
566 }
567 return false;
568}
569
570void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
571 size_t encrypted_buffer_len) {
572 DCHECK_LT(0u, encrypted_buffer_len);
573 QUIC_BUG_IF(queued_frames_.empty() && pending_padding_bytes_ == 0)
574 << "Attempt to serialize empty packet";
575 QuicPacketHeader header;
576 // FillPacketHeader increments packet_number_.
577 FillPacketHeader(&header);
578
579 MaybeAddPadding();
580
581 DCHECK_GE(max_plaintext_size_, packet_size_);
582 // Use the packet_size_ instead of the buffer size to ensure smaller
583 // packet sizes are properly used.
584 size_t length =
585 framer_->BuildDataPacket(header, queued_frames_, encrypted_buffer,
586 packet_size_, packet_.encryption_level);
587 if (length == 0) {
588 QUIC_BUG << "Failed to serialize " << queued_frames_.size() << " frames.";
589 return;
590 }
591
592 // ACK Frames will be truncated due to length only if they're the only frame
593 // in the packet, and if packet_size_ was set to max_plaintext_size_. If
594 // truncation due to length occurred, then GetSerializedFrameLength will have
595 // returned all bytes free.
596 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
597 queued_frames_.size() == 1 &&
598 queued_frames_.back().type == ACK_FRAME;
599 // Because of possible truncation, we can't be confident that our
600 // packet size calculation worked correctly.
601 if (!possibly_truncated_by_length) {
602 DCHECK_EQ(packet_size_, length);
603 }
604 const size_t encrypted_length = framer_->EncryptInPlace(
605 packet_.encryption_level, packet_.packet_number,
606 GetStartOfEncryptedData(framer_->transport_version(), header), length,
607 encrypted_buffer_len, encrypted_buffer);
608 if (encrypted_length == 0) {
609 QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number;
610 return;
611 }
612
613 packet_size_ = 0;
614 queued_frames_.clear();
615 packet_.encrypted_buffer = encrypted_buffer;
616 packet_.encrypted_length = encrypted_length;
617}
618
619std::unique_ptr<QuicEncryptedPacket>
620QuicPacketCreator::SerializeVersionNegotiationPacket(
621 bool ietf_quic,
622 const ParsedQuicVersionVector& supported_versions) {
623 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
624 std::unique_ptr<QuicEncryptedPacket> encrypted =
625 QuicFramer::BuildVersionNegotiationPacket(connection_id_, ietf_quic,
626 supported_versions);
627 DCHECK(encrypted);
628 DCHECK_GE(max_packet_length_, encrypted->length());
629 return encrypted;
630}
631
632OwningSerializedPacketPointer
633QuicPacketCreator::SerializeConnectivityProbingPacket() {
634 QUIC_BUG_IF(framer_->transport_version() == QUIC_VERSION_99)
635 << "Must not be version 99 to serialize padded ping connectivity probe";
636 QuicPacketHeader header;
637 // FillPacketHeader increments packet_number_.
638 FillPacketHeader(&header);
639
dschinazi66dea072019-04-09 11:41:06 -0700640 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500641 size_t length = framer_->BuildConnectivityProbingPacket(
642 header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
643 DCHECK(length);
644
645 const size_t encrypted_length = framer_->EncryptInPlace(
646 packet_.encryption_level, packet_.packet_number,
647 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700648 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500649 DCHECK(encrypted_length);
650
651 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
652 header.packet_number, header.packet_number_length, buffer.release(),
653 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
654
655 serialize_packet->encryption_level = packet_.encryption_level;
656 serialize_packet->transmission_type = NOT_RETRANSMISSION;
657
658 return serialize_packet;
659}
660
661OwningSerializedPacketPointer
662QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
663 QuicPathFrameBuffer* payload) {
664 QUIC_BUG_IF(framer_->transport_version() != QUIC_VERSION_99)
665 << "Must be version 99 to serialize path challenge connectivity probe, "
666 "is version "
667 << framer_->transport_version();
668 QuicPacketHeader header;
669 // FillPacketHeader increments packet_number_.
670 FillPacketHeader(&header);
671
dschinazi66dea072019-04-09 11:41:06 -0700672 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500673 size_t length = framer_->BuildPaddedPathChallengePacket(
674 header, buffer.get(), max_plaintext_size_, payload, random_,
675 packet_.encryption_level);
676 DCHECK(length);
677
678 const size_t encrypted_length = framer_->EncryptInPlace(
679 packet_.encryption_level, packet_.packet_number,
680 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700681 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500682 DCHECK(encrypted_length);
683
684 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
685 header.packet_number, header.packet_number_length, buffer.release(),
686 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
687
688 serialize_packet->encryption_level = packet_.encryption_level;
689 serialize_packet->transmission_type = NOT_RETRANSMISSION;
690
691 return serialize_packet;
692}
693
694OwningSerializedPacketPointer
695QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
696 const QuicDeque<QuicPathFrameBuffer>& payloads,
697 const bool is_padded) {
698 QUIC_BUG_IF(framer_->transport_version() != QUIC_VERSION_99)
699 << "Must be version 99 to serialize path response connectivity probe, is "
700 "version "
701 << framer_->transport_version();
702 QuicPacketHeader header;
703 // FillPacketHeader increments packet_number_.
704 FillPacketHeader(&header);
705
dschinazi66dea072019-04-09 11:41:06 -0700706 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500707 size_t length = framer_->BuildPathResponsePacket(
708 header, buffer.get(), max_plaintext_size_, payloads, is_padded,
709 packet_.encryption_level);
710 DCHECK(length);
711
712 const size_t encrypted_length = framer_->EncryptInPlace(
713 packet_.encryption_level, packet_.packet_number,
714 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700715 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500716 DCHECK(encrypted_length);
717
718 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
719 header.packet_number, header.packet_number_length, buffer.release(),
720 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
721
722 serialize_packet->encryption_level = packet_.encryption_level;
723 serialize_packet->transmission_type = NOT_RETRANSMISSION;
724
725 return serialize_packet;
726}
727
728// TODO(b/74062209): Make this a public method of framer?
729SerializedPacket QuicPacketCreator::NoPacket() {
730 return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
731 nullptr, 0, false, false);
732}
733
734QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
735 const {
736 if (framer_->transport_version() > QUIC_VERSION_43) {
737 // Packets sent by client always include destination connection ID, and
738 // those sent by the server do not include destination connection ID.
739 return framer_->perspective() == Perspective::IS_CLIENT
740 ? CONNECTION_ID_PRESENT
741 : CONNECTION_ID_ABSENT;
742 }
743 return connection_id_included_;
744}
745
746QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
747 const {
748 // Long header packets sent by server include source connection ID.
749 if (HasIetfLongHeader() && framer_->perspective() == Perspective::IS_SERVER) {
750 return CONNECTION_ID_PRESENT;
751 }
752 return CONNECTION_ID_ABSENT;
753}
754
755QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
756 const {
757 DCHECK(QuicUtils::IsConnectionIdValidForVersion(connection_id_,
758 transport_version()));
759 return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
760 ? static_cast<QuicConnectionIdLength>(connection_id_.length())
761 : PACKET_0BYTE_CONNECTION_ID;
762}
763
764QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
765 DCHECK(QuicUtils::IsConnectionIdValidForVersion(connection_id_,
766 transport_version()));
767 return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
768 ? static_cast<QuicConnectionIdLength>(connection_id_.length())
769 : PACKET_0BYTE_CONNECTION_ID;
770}
771
772QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
773 if (HasIetfLongHeader() && framer_->transport_version() != QUIC_VERSION_99) {
774 return PACKET_4BYTE_PACKET_NUMBER;
775 }
776 return packet_.packet_number_length;
777}
778
779QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
780 const {
781 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
782 HasIetfLongHeader() &&
783 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
784 return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
785 }
786 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
787}
788
789QuicStringPiece QuicPacketCreator::GetRetryToken() const {
790 return retry_token_;
791}
792
793void QuicPacketCreator::SetRetryToken(QuicStringPiece retry_token) {
vasilvvc48c8712019-03-11 13:38:16 -0700794 retry_token_ = std::string(retry_token);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500795}
796
797QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
798 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
799 HasIetfLongHeader()) {
800 QuicLongHeaderType long_header_type =
801 EncryptionlevelToLongHeaderType(packet_.encryption_level);
802 if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
803 long_header_type == HANDSHAKE) {
804 return VARIABLE_LENGTH_INTEGER_LENGTH_2;
805 }
806 }
807 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
808}
809
810void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
811 header->destination_connection_id = connection_id_;
812 header->destination_connection_id_included =
813 GetDestinationConnectionIdIncluded();
814 header->source_connection_id = connection_id_;
815 header->source_connection_id_included = GetSourceConnectionIdIncluded();
816 header->reset_flag = false;
817 header->version_flag = IncludeVersionInHeader();
818 if (IncludeNonceInPublicHeader()) {
819 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
820 header->nonce = &diversification_nonce_;
821 } else {
822 header->nonce = nullptr;
823 }
824 if (!packet_.packet_number.IsInitialized()) {
825 packet_.packet_number = framer_->first_sending_packet_number();
826 } else {
827 ++packet_.packet_number;
828 }
829 header->packet_number = packet_.packet_number;
830 header->packet_number_length = GetPacketNumberLength();
831 header->retry_token_length_length = GetRetryTokenLengthLength();
832 header->retry_token = GetRetryToken();
833 header->length_length = GetLengthLength();
834 header->remaining_packet_length = 0;
835 if (!HasIetfLongHeader()) {
836 return;
837 }
838 header->long_packet_type =
839 EncryptionlevelToLongHeaderType(packet_.encryption_level);
840}
841
842bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
843 bool save_retransmittable_frames,
844 TransmissionType transmission_type) {
845 QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
846 << transmission_type << ": " << frame;
847 if (frame.type == STREAM_FRAME &&
848 frame.stream_frame.stream_id !=
849 QuicUtils::GetCryptoStreamId(framer_->transport_version()) &&
QUICHE team6987b4a2019-03-15 16:23:04 -0700850 packet_.encryption_level == ENCRYPTION_INITIAL) {
vasilvvc48c8712019-03-11 13:38:16 -0700851 const std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500852 "Cannot send stream data without encryption.";
853 QUIC_BUG << error_details;
854 delegate_->OnUnrecoverableError(
855 QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA, error_details,
856 ConnectionCloseSource::FROM_SELF);
857 return false;
858 }
859 size_t frame_len = framer_->GetSerializedFrameLength(
860 frame, BytesFree(), queued_frames_.empty(),
861 /* last_frame_in_packet= */ true, GetPacketNumberLength());
862 if (frame_len == 0) {
863 // Current open packet is full.
864 Flush();
865 return false;
866 }
867 DCHECK_LT(0u, packet_size_);
868
869 packet_size_ += ExpansionOnNewFrame() + frame_len;
870
871 if (save_retransmittable_frames &&
872 QuicUtils::IsRetransmittableFrame(frame.type)) {
873 packet_.retransmittable_frames.push_back(frame);
874 queued_frames_.push_back(frame);
875 if (QuicUtils::IsHandshakeFrame(frame, framer_->transport_version())) {
876 packet_.has_crypto_handshake = IS_HANDSHAKE;
877 }
878 } else {
879 queued_frames_.push_back(frame);
880 }
881
882 if (frame.type == ACK_FRAME) {
883 packet_.has_ack = true;
884 packet_.largest_acked = LargestAcked(*frame.ack_frame);
885 }
886 if (frame.type == STOP_WAITING_FRAME) {
887 packet_.has_stop_waiting = true;
888 }
889 if (debug_delegate_ != nullptr) {
890 debug_delegate_->OnFrameAddedToPacket(frame);
891 }
892
893 // Packet transmission type is determined by the last added retransmittable
894 // frame.
895 if (ShouldSetTransmissionTypeForNextFrame() &&
896 QuicUtils::IsRetransmittableFrame(frame.type)) {
897 QUIC_RELOADABLE_FLAG_COUNT_N(quic_set_transmission_type_for_next_frame, 2,
898 2);
899 packet_.transmission_type = transmission_type;
900 }
901 return true;
902}
903
904void QuicPacketCreator::MaybeAddPadding() {
905 // The current packet should have no padding bytes because padding is only
906 // added when this method is called just before the packet is serialized.
907 DCHECK_EQ(0, packet_.num_padding_bytes);
908 if (BytesFree() == 0) {
909 // Don't pad full packets.
910 return;
911 }
912
913 if (packet_.transmission_type == PROBING_RETRANSMISSION) {
914 needs_full_padding_ = true;
915 }
916
917 if (!needs_full_padding_ && pending_padding_bytes_ == 0) {
918 // Do not need padding.
919 return;
920 }
921
922 if (needs_full_padding_) {
923 // Full padding does not consume pending padding bytes.
924 packet_.num_padding_bytes = -1;
925 } else {
926 packet_.num_padding_bytes =
927 std::min<int16_t>(pending_padding_bytes_, BytesFree());
928 pending_padding_bytes_ -= packet_.num_padding_bytes;
929 }
930
931 bool success =
932 AddFrame(QuicFrame(QuicPaddingFrame(packet_.num_padding_bytes)), false,
933 packet_.transmission_type);
934 DCHECK(success);
935}
936
937bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
938 return have_diversification_nonce_ &&
939 packet_.encryption_level == ENCRYPTION_ZERO_RTT;
940}
941
942bool QuicPacketCreator::IncludeVersionInHeader() const {
943 if (framer_->transport_version() > QUIC_VERSION_43) {
944 return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
945 }
946 return send_version_in_packet_;
947}
948
949void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
950 pending_padding_bytes_ += size;
951}
952
ianswette28f0222019-04-04 13:31:22 -0700953bool QuicPacketCreator::StreamFrameIsClientHello(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500954 const QuicStreamFrame& frame) const {
955 if (framer_->perspective() == Perspective::IS_SERVER ||
956 frame.stream_id !=
ianswette28f0222019-04-04 13:31:22 -0700957 QuicUtils::GetCryptoStreamId(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500958 return false;
959 }
ianswette28f0222019-04-04 13:31:22 -0700960 // The ClientHello is always sent with INITIAL encryption.
961 return packet_.encryption_level == ENCRYPTION_INITIAL;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500962}
963
964void QuicPacketCreator::SetConnectionIdIncluded(
965 QuicConnectionIdIncluded connection_id_included) {
966 DCHECK(connection_id_included == CONNECTION_ID_PRESENT ||
967 connection_id_included == CONNECTION_ID_ABSENT);
968 DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
969 connection_id_included != CONNECTION_ID_ABSENT);
970 connection_id_included_ = connection_id_included;
971}
972
QUICHE teamc65d1d12019-03-19 20:58:04 -0700973void QuicPacketCreator::SetConnectionId(QuicConnectionId connection_id) {
974 connection_id_ = connection_id;
975}
976
QUICHE teama6ef0a62019-03-07 20:34:33 -0500977void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
978 DCHECK(can_set_transmission_type_);
979
980 if (!ShouldSetTransmissionTypeForNextFrame()) {
981 QUIC_DVLOG_IF(1, type != packet_.transmission_type)
982 << ENDPOINT << "Setting Transmission type to "
983 << QuicUtils::TransmissionTypeToString(type);
984
985 packet_.transmission_type = type;
986 }
987}
988
ianswettb239f862019-04-05 09:15:06 -0700989QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500990 if (framer_->transport_version() <= QUIC_VERSION_44) {
991 return 0;
992 }
993 const size_t packet_header_size = GetPacketHeaderSize(
994 framer_->transport_version(), GetDestinationConnectionIdLength(),
995 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
996 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
ianswettb239f862019-04-05 09:15:06 -0700997 // No Retry token on packets containing application data.
998 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500999 // This is the largest possible message payload when the length field is
1000 // omitted.
1001 return max_plaintext_size_ -
1002 std::min(max_plaintext_size_, packet_header_size + kQuicFrameTypeSize);
1003}
1004
ianswettb239f862019-04-05 09:15:06 -07001005QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
1006 if (framer_->transport_version() <= QUIC_VERSION_44) {
1007 return 0;
1008 }
1009 // QUIC Crypto server packets may include a diversification nonce.
1010 const bool may_include_nonce =
1011 framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
1012 framer_->perspective() == Perspective::IS_SERVER;
1013 // IETF QUIC long headers include a length on client 0RTT packets.
1014 QuicVariableLengthIntegerLength length_length =
1015 framer_->perspective() == Perspective::IS_CLIENT
1016 ? VARIABLE_LENGTH_INTEGER_LENGTH_2
1017 : VARIABLE_LENGTH_INTEGER_LENGTH_0;
1018 const size_t packet_header_size = GetPacketHeaderSize(
1019 framer_->transport_version(), GetDestinationConnectionIdLength(),
1020 // Assume CID lengths don't change, but version may be present.
1021 GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
1022 PACKET_4BYTE_PACKET_NUMBER,
1023 // No Retry token on packets containing application data.
1024 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
1025 // This is the largest possible message payload when the length field is
1026 // omitted.
1027 const QuicPacketLength largest_payload =
1028 max_plaintext_size_ -
1029 std::min(max_plaintext_size_, packet_header_size + kQuicFrameTypeSize);
1030 // This must always be less than or equal to GetCurrentLargestMessagePayload.
1031 DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload());
1032 return largest_payload;
1033}
1034
QUICHE teama6ef0a62019-03-07 20:34:33 -05001035bool QuicPacketCreator::HasIetfLongHeader() const {
1036 return framer_->transport_version() > QUIC_VERSION_43 &&
1037 packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1038}
1039
1040#undef ENDPOINT // undef for jumbo builds
1041} // namespace quic