Delete unused downloads page asset.
[chromium-blink-merge.git] / net / quic / quic_packet_creator.cc
blob3dcfe6e06b98f9bdb435b298b4136c6fb9cdec03
1 // 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.
5 #include "net/quic/quic_packet_creator.h"
7 #include <algorithm>
9 #include "base/basictypes.h"
10 #include "base/logging.h"
11 #include "net/quic/crypto/quic_random.h"
12 #include "net/quic/quic_ack_notifier.h"
13 #include "net/quic/quic_data_writer.h"
14 #include "net/quic/quic_fec_group.h"
15 #include "net/quic/quic_utils.h"
17 using base::StringPiece;
18 using std::make_pair;
19 using std::max;
20 using std::min;
21 using std::pair;
22 using std::vector;
24 namespace net {
26 namespace {
28 // Default max packets in an FEC group.
29 static const size_t kDefaultMaxPacketsPerFecGroup = 10;
30 // Lowest max packets in an FEC group.
31 static const size_t kLowestMaxPacketsPerFecGroup = 2;
33 } // namespace
35 // A QuicRandom wrapper that gets a bucket of entropy and distributes it
36 // bit-by-bit. Replenishes the bucket as needed. Not thread-safe. Expose this
37 // class if single bit randomness is needed elsewhere.
38 class QuicRandomBoolSource {
39 public:
40 // random: Source of entropy. Not owned.
41 explicit QuicRandomBoolSource(QuicRandom* random)
42 : random_(random),
43 bit_bucket_(0),
44 bit_mask_(0) {}
46 ~QuicRandomBoolSource() {}
48 // Returns the next random bit from the bucket.
49 bool RandBool() {
50 if (bit_mask_ == 0) {
51 bit_bucket_ = random_->RandUint64();
52 bit_mask_ = 1;
54 bool result = ((bit_bucket_ & bit_mask_) != 0);
55 bit_mask_ <<= 1;
56 return result;
59 private:
60 // Source of entropy.
61 QuicRandom* random_;
62 // Stored random bits.
63 uint64 bit_bucket_;
64 // The next available bit has "1" in the mask. Zero means empty bucket.
65 uint64 bit_mask_;
67 DISALLOW_COPY_AND_ASSIGN(QuicRandomBoolSource);
70 QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id,
71 QuicFramer* framer,
72 QuicRandom* random_generator)
73 : connection_id_(connection_id),
74 encryption_level_(ENCRYPTION_NONE),
75 framer_(framer),
76 random_bool_source_(new QuicRandomBoolSource(random_generator)),
77 packet_number_(0),
78 should_fec_protect_(false),
79 fec_group_number_(0),
80 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
81 max_packet_length_(0),
82 max_packets_per_fec_group_(kDefaultMaxPacketsPerFecGroup),
83 connection_id_length_(PACKET_8BYTE_CONNECTION_ID),
84 next_packet_number_length_(PACKET_1BYTE_PACKET_NUMBER),
85 packet_number_length_(next_packet_number_length_),
86 packet_size_(0),
87 needs_padding_(false) {
88 SetMaxPacketLength(kDefaultMaxPacketSize);
91 QuicPacketCreator::~QuicPacketCreator() {
94 void QuicPacketCreator::OnBuiltFecProtectedPayload(
95 const QuicPacketHeader& header, StringPiece payload) {
96 if (fec_group_.get()) {
97 DCHECK_NE(0u, header.fec_group);
98 fec_group_->Update(encryption_level_, header, payload);
102 void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
103 QuicEncrypter* encrypter) {
104 framer_->SetEncrypter(level, encrypter);
105 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
108 bool QuicPacketCreator::CanSetMaxPacketLength() const {
109 // |max_packet_length_| should not be changed mid-packet or mid-FEC group.
110 return fec_group_.get() == nullptr && queued_frames_.empty();
113 void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
114 DCHECK(CanSetMaxPacketLength());
116 // Avoid recomputing |max_plaintext_size_| if the length does not actually
117 // change.
118 if (length == max_packet_length_) {
119 return;
122 max_packet_length_ = length;
123 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
126 void QuicPacketCreator::set_max_packets_per_fec_group(
127 size_t max_packets_per_fec_group) {
128 max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup,
129 max_packets_per_fec_group);
130 DCHECK_LT(0u, max_packets_per_fec_group_);
133 bool QuicPacketCreator::ShouldSendFec(bool force_close) const {
134 DCHECK(!HasPendingFrames());
135 return fec_group_.get() != nullptr && fec_group_->NumReceivedPackets() > 0 &&
136 (force_close ||
137 fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_);
140 void QuicPacketCreator::ResetFecGroup() {
141 if (HasPendingFrames()) {
142 LOG_IF(DFATAL, packet_size_ != 0)
143 << "Cannot reset FEC group with pending frames.";
144 return;
146 fec_group_.reset(nullptr);
149 bool QuicPacketCreator::IsFecGroupOpen() const {
150 return fec_group_.get() != nullptr;
153 void QuicPacketCreator::StartFecProtectingPackets() {
154 if (!IsFecEnabled()) {
155 LOG(DFATAL) << "Cannot start FEC protection when FEC is not enabled.";
156 return;
158 // TODO(jri): This currently requires that the generator flush out any
159 // pending frames when FEC protection is turned on. If current packet can be
160 // converted to an FEC protected packet, do it. This will require the
161 // generator to check if the resulting expansion still allows the incoming
162 // frame to be added to the packet.
163 if (HasPendingFrames()) {
164 LOG(DFATAL) << "Cannot start FEC protection with pending frames.";
165 return;
167 DCHECK(!should_fec_protect_);
168 should_fec_protect_ = true;
171 void QuicPacketCreator::StopFecProtectingPackets() {
172 if (fec_group_.get() != nullptr) {
173 LOG(DFATAL) << "Cannot stop FEC protection with open FEC group.";
174 return;
176 DCHECK(should_fec_protect_);
177 should_fec_protect_ = false;
178 fec_group_number_ = 0;
181 bool QuicPacketCreator::IsFecProtected() const {
182 return should_fec_protect_;
185 bool QuicPacketCreator::IsFecEnabled() const {
186 return max_packets_per_fec_group_ > 0;
189 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() {
190 if (fec_group_.get() != nullptr) {
191 // Don't update any lengths when an FEC group is open, to ensure same
192 // packet header size in all packets within a group.
193 return IN_FEC_GROUP;
195 if (!queued_frames_.empty()) {
196 // Don't change creator state if there are frames queued.
197 return NOT_IN_FEC_GROUP;
200 // Update packet number length only on packet and FEC group boundaries.
201 packet_number_length_ = next_packet_number_length_;
203 if (!should_fec_protect_) {
204 return NOT_IN_FEC_GROUP;
206 // Start a new FEC group since protection is on. Set the fec group number to
207 // the packet number of the next packet.
208 fec_group_number_ = packet_number() + 1;
209 fec_group_.reset(new QuicFecGroup());
210 return IN_FEC_GROUP;
213 // Stops serializing version of the protocol in packets sent after this call.
214 // A packet that is already open might send kQuicVersionSize bytes less than the
215 // maximum packet size if we stop sending version before it is serialized.
216 void QuicPacketCreator::StopSendingVersion() {
217 DCHECK(send_version_in_packet_);
218 send_version_in_packet_ = false;
219 if (packet_size_ > 0) {
220 DCHECK_LT(kQuicVersionSize, packet_size_);
221 packet_size_ -= kQuicVersionSize;
225 void QuicPacketCreator::UpdatePacketNumberLength(
226 QuicPacketNumber least_packet_awaited_by_peer,
227 QuicPacketCount max_packets_in_flight) {
228 DCHECK_LE(least_packet_awaited_by_peer, packet_number_ + 1);
229 // Since the packet creator will not change packet number length mid FEC
230 // group, include the size of an FEC group to be safe.
231 const QuicPacketNumber current_delta = max_packets_per_fec_group_ +
232 packet_number_ + 1 -
233 least_packet_awaited_by_peer;
234 const uint64 delta = max(current_delta, max_packets_in_flight);
235 next_packet_number_length_ =
236 QuicFramer::GetMinSequenceNumberLength(delta * 4);
239 bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
240 QuicStreamOffset offset) const {
241 // TODO(jri): This is a simple safe decision for now, but make
242 // is_in_fec_group a parameter. Same as with all public methods in
243 // QuicPacketCreator.
244 return BytesFree() >
245 QuicFramer::GetMinStreamFrameSize(id, offset, true,
246 should_fec_protect_ ? IN_FEC_GROUP :
247 NOT_IN_FEC_GROUP);
250 // static
251 size_t QuicPacketCreator::StreamFramePacketOverhead(
252 QuicConnectionIdLength connection_id_length,
253 bool include_version,
254 QuicPacketNumberLength packet_number_length,
255 QuicStreamOffset offset,
256 InFecGroup is_in_fec_group) {
257 return GetPacketHeaderSize(connection_id_length, include_version,
258 packet_number_length, is_in_fec_group) +
259 // Assumes this is a stream with a single lone packet.
260 QuicFramer::GetMinStreamFrameSize(1u, offset, true, is_in_fec_group);
263 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
264 const QuicIOVector& iov,
265 size_t iov_offset,
266 QuicStreamOffset offset,
267 bool fin,
268 QuicFrame* frame,
269 scoped_ptr<char[]>* buffer) {
270 DCHECK_GT(max_packet_length_,
271 StreamFramePacketOverhead(connection_id_length_, kIncludeVersion,
272 PACKET_6BYTE_PACKET_NUMBER, offset,
273 IN_FEC_GROUP));
274 DCHECK(buffer);
276 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
278 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset))
279 << "No room for Stream frame, BytesFree: " << BytesFree()
280 << " MinStreamFrameSize: "
281 << QuicFramer::GetMinStreamFrameSize(id, offset, true, is_in_fec_group);
283 if (iov_offset == iov.total_length) {
284 LOG_IF(DFATAL, !fin)
285 << "Creating a stream frame with no data or fin.";
286 // Create a new packet for the fin, if necessary.
287 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, StringPiece()));
288 return 0;
291 const size_t data_size = iov.total_length - iov_offset;
292 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
293 id, offset, /* last_frame_in_packet= */ true, is_in_fec_group);
294 size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size);
296 bool set_fin = fin && bytes_consumed == data_size; // Last frame.
297 buffer->reset(new char[bytes_consumed]);
298 CopyToBuffer(iov, iov_offset, bytes_consumed, buffer->get());
299 *frame = QuicFrame(new QuicStreamFrame(
300 id, set_fin, offset, StringPiece(buffer->get(), bytes_consumed)));
301 return bytes_consumed;
304 // static
305 void QuicPacketCreator::CopyToBuffer(const QuicIOVector& iov,
306 size_t iov_offset,
307 size_t length,
308 char* buffer) {
309 int iovnum = 0;
310 while (iovnum < iov.iov_count && iov_offset >= iov.iov[iovnum].iov_len) {
311 iov_offset -= iov.iov[iovnum].iov_len;
312 ++iovnum;
314 while (iovnum < iov.iov_count && length > 0) {
315 const size_t copy_len = min(length, iov.iov[iovnum].iov_len - iov_offset);
316 memcpy(buffer, static_cast<char*>(iov.iov[iovnum].iov_base) + iov_offset,
317 copy_len);
318 iov_offset = 0;
319 length -= copy_len;
320 buffer += copy_len;
321 ++iovnum;
323 LOG_IF(DFATAL, length > 0) << "Failed to copy entire length to buffer.";
326 SerializedPacket QuicPacketCreator::ReserializeAllFrames(
327 const RetransmittableFrames& frames,
328 QuicPacketNumberLength original_length,
329 char* buffer,
330 size_t buffer_len) {
331 DCHECK(fec_group_.get() == nullptr);
332 const QuicPacketNumberLength saved_length = packet_number_length_;
333 const QuicPacketNumberLength saved_next_length = next_packet_number_length_;
334 const bool saved_should_fec_protect = should_fec_protect_;
335 const bool needs_padding = needs_padding_;
336 const EncryptionLevel default_encryption_level = encryption_level_;
338 // Temporarily set the packet number length, stop FEC protection,
339 // and change the encryption level.
340 packet_number_length_ = original_length;
341 next_packet_number_length_ = original_length;
342 should_fec_protect_ = false;
343 encryption_level_ = frames.encryption_level();
344 needs_padding_ = frames.needs_padding();
346 // Serialize the packet and restore the FEC and packet number length state.
347 SerializedPacket serialized_packet =
348 SerializeAllFrames(frames.frames(), buffer, buffer_len);
349 packet_number_length_ = saved_length;
350 next_packet_number_length_ = saved_next_length;
351 should_fec_protect_ = saved_should_fec_protect;
352 needs_padding_ = needs_padding;
353 encryption_level_ = default_encryption_level;
355 return serialized_packet;
358 SerializedPacket QuicPacketCreator::SerializeAllFrames(const QuicFrames& frames,
359 char* buffer,
360 size_t buffer_len) {
361 LOG_IF(DFATAL, !queued_frames_.empty()) << "Frames already queued.";
362 LOG_IF(DFATAL, frames.empty())
363 << "Attempt to serialize empty packet";
364 for (const QuicFrame& frame : frames) {
365 bool success = AddFrame(frame, false, false, nullptr);
366 DCHECK(success);
368 SerializedPacket packet = SerializePacket(buffer, buffer_len);
369 DCHECK(packet.retransmittable_frames == nullptr);
370 return packet;
373 bool QuicPacketCreator::HasPendingFrames() const {
374 return !queued_frames_.empty();
377 bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
378 return queued_retransmittable_frames_.get() != nullptr &&
379 !queued_retransmittable_frames_->frames().empty();
382 size_t QuicPacketCreator::ExpansionOnNewFrame() const {
383 // If packet is FEC protected, there's no expansion.
384 if (should_fec_protect_) {
385 return 0;
387 // If the last frame in the packet is a stream frame, then it will expand to
388 // include the stream_length field when a new frame is added.
389 bool has_trailing_stream_frame =
390 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME;
391 return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0;
394 size_t QuicPacketCreator::BytesFree() const {
395 DCHECK_GE(max_plaintext_size_, PacketSize());
396 return max_plaintext_size_ - min(max_plaintext_size_, PacketSize()
397 + ExpansionOnNewFrame());
400 size_t QuicPacketCreator::PacketSize() const {
401 if (!queued_frames_.empty()) {
402 return packet_size_;
404 if (fec_group_.get() == nullptr) {
405 // Update packet number length on packet and FEC boundary.
406 packet_number_length_ = next_packet_number_length_;
408 packet_size_ = GetPacketHeaderSize(
409 connection_id_length_, send_version_in_packet_, packet_number_length_,
410 should_fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP);
411 return packet_size_;
414 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) {
415 return AddFrame(frame,
416 /*save_retransmittable_frames=*/true,
417 /*needs_padding=*/false, nullptr);
420 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame, char* buffer) {
421 return AddFrame(frame,
422 /*save_retransmittable_frames=*/true,
423 /*needs_padding=*/false, buffer);
426 bool QuicPacketCreator::AddPaddedSavedFrame(const QuicFrame& frame,
427 char* buffer) {
428 return AddFrame(frame,
429 /*save_retransmittable_frames=*/true,
430 /*needs_padding=*/true, buffer);
433 SerializedPacket QuicPacketCreator::SerializePacket(
434 char* encrypted_buffer,
435 size_t encrypted_buffer_len) {
436 DCHECK_LT(0u, encrypted_buffer_len);
437 LOG_IF(DFATAL, queued_frames_.empty())
438 << "Attempt to serialize empty packet";
439 DCHECK_GE(packet_number_ + 1, fec_group_number_);
440 QuicPacketHeader header;
441 FillPacketHeader(should_fec_protect_ ? fec_group_number_ : 0, false, &header);
443 MaybeAddPadding();
445 DCHECK_GE(max_plaintext_size_, packet_size_);
446 // ACK Frames will be truncated due to length only if they're the only frame
447 // in the packet, and if packet_size_ was set to max_plaintext_size_. If
448 // truncation due to length occurred, then GetSerializedFrameLength will have
449 // returned all bytes free.
450 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
451 queued_frames_.size() == 1 &&
452 queued_frames_.back().type == ACK_FRAME;
453 char buffer[kMaxPacketSize];
454 scoped_ptr<QuicPacket> packet;
455 // Use the packet_size_ instead of the buffer size to ensure smaller
456 // packet sizes are properly used.
457 scoped_ptr<char[]> large_buffer;
458 if (packet_size_ <= kMaxPacketSize) {
459 packet.reset(
460 framer_->BuildDataPacket(header, queued_frames_, buffer, packet_size_));
461 } else {
462 large_buffer.reset(new char[packet_size_]);
463 packet.reset(framer_->BuildDataPacket(header, queued_frames_,
464 large_buffer.get(), packet_size_));
466 if (packet == nullptr) {
467 LOG(DFATAL) << "Failed to serialize " << queued_frames_.size()
468 << " frames.";
469 return NoPacket();
472 OnBuiltFecProtectedPayload(header, packet->FecProtectedData());
474 // Because of possible truncation, we can't be confident that our
475 // packet size calculation worked correctly.
476 if (!possibly_truncated_by_length) {
477 DCHECK_EQ(packet_size_, packet->length());
479 // Immediately encrypt the packet, to ensure we don't encrypt the same packet
480 // packet number multiple times.
481 QuicEncryptedPacket* encrypted =
482 framer_->EncryptPayload(encryption_level_, packet_number_, *packet,
483 encrypted_buffer, encrypted_buffer_len);
484 if (encrypted == nullptr) {
485 LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_;
486 return NoPacket();
489 // Update |needs_padding_| flag of |queued_retransmittable_frames_| here, and
490 // not in AddFrame, because when the first padded frame is added to the queue,
491 // it might not be retransmittable, and hence the flag would end up being not
492 // set.
493 if (queued_retransmittable_frames_.get() != nullptr) {
494 queued_retransmittable_frames_->set_needs_padding(needs_padding_);
497 bool has_ack = false;
498 bool has_stop_waiting = false;
499 for (const QuicFrame& frame : queued_frames_) {
500 has_ack |= frame.type == ACK_FRAME;
501 has_stop_waiting |= frame.type == STOP_WAITING_FRAME;
504 packet_size_ = 0;
505 queued_frames_.clear();
506 needs_padding_ = false;
507 return SerializedPacket(
508 header.packet_packet_number, header.public_header.packet_number_length,
509 encrypted, QuicFramer::GetPacketEntropyHash(header),
510 queued_retransmittable_frames_.release(), has_ack, has_stop_waiting);
513 SerializedPacket QuicPacketCreator::SerializeFec(char* buffer,
514 size_t buffer_len) {
515 DCHECK_LT(0u, buffer_len);
516 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) {
517 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group.";
518 // TODO(jri): Make this a public method of framer?
519 return NoPacket();
521 DCHECK_EQ(0u, queued_frames_.size());
522 QuicPacketHeader header;
523 FillPacketHeader(fec_group_number_, true, &header);
524 QuicFecData fec_data;
525 fec_data.fec_group = fec_group_->min_protected_packet();
526 fec_data.redundancy = fec_group_->payload_parity();
527 scoped_ptr<QuicPacket> packet(framer_->BuildFecPacket(header, fec_data));
528 fec_group_.reset(nullptr);
529 packet_size_ = 0;
530 LOG_IF(DFATAL, packet == nullptr)
531 << "Failed to serialize fec packet for group:" << fec_data.fec_group;
532 DCHECK_GE(max_packet_length_, packet->length());
533 // Immediately encrypt the packet, to ensure we don't encrypt the same packet
534 // packet number multiple times.
535 QuicEncryptedPacket* encrypted = framer_->EncryptPayload(
536 encryption_level_, packet_number_, *packet, buffer, buffer_len);
537 if (encrypted == nullptr) {
538 LOG(DFATAL) << "Failed to encrypt packet number " << packet_number_;
539 return NoPacket();
541 SerializedPacket serialized(
542 header.packet_packet_number, header.public_header.packet_number_length,
543 encrypted, QuicFramer::GetPacketEntropyHash(header), nullptr, false,
544 false);
545 serialized.is_fec_packet = true;
546 return serialized;
549 QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket(
550 const QuicVersionVector& supported_versions) {
551 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
552 QuicPacketPublicHeader header;
553 header.connection_id = connection_id_;
554 header.reset_flag = false;
555 header.version_flag = true;
556 header.versions = supported_versions;
557 QuicEncryptedPacket* encrypted =
558 framer_->BuildVersionNegotiationPacket(header, supported_versions);
559 DCHECK(encrypted);
560 DCHECK_GE(max_packet_length_, encrypted->length());
561 return encrypted;
564 SerializedPacket QuicPacketCreator::NoPacket() {
565 return SerializedPacket(0, PACKET_1BYTE_PACKET_NUMBER, nullptr, 0, nullptr,
566 false, false);
569 void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
570 bool fec_flag,
571 QuicPacketHeader* header) {
572 header->public_header.connection_id = connection_id_;
573 header->public_header.connection_id_length = connection_id_length_;
574 header->public_header.reset_flag = false;
575 header->public_header.version_flag = send_version_in_packet_;
576 header->fec_flag = fec_flag;
577 header->packet_packet_number = ++packet_number_;
578 header->public_header.packet_number_length = packet_number_length_;
579 header->entropy_flag = random_bool_source_->RandBool();
580 header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
581 header->fec_group = fec_group;
584 bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
585 switch (frame.type) {
586 case ACK_FRAME:
587 case PADDING_FRAME:
588 case STOP_WAITING_FRAME:
589 case MTU_DISCOVERY_FRAME:
590 return false;
591 default:
592 return true;
596 bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
597 bool save_retransmittable_frames,
598 bool needs_padding,
599 char* buffer) {
600 DVLOG(1) << "Adding frame: " << frame;
601 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
603 size_t frame_len = framer_->GetSerializedFrameLength(
604 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group,
605 packet_number_length_);
606 if (frame_len == 0) {
607 return false;
609 DCHECK_LT(0u, packet_size_);
610 packet_size_ += ExpansionOnNewFrame() + frame_len;
612 if (save_retransmittable_frames && ShouldRetransmit(frame)) {
613 if (queued_retransmittable_frames_.get() == nullptr) {
614 queued_retransmittable_frames_.reset(
615 new RetransmittableFrames(encryption_level_));
617 queued_frames_.push_back(
618 queued_retransmittable_frames_->AddFrame(frame, buffer));
619 } else {
620 queued_frames_.push_back(frame);
623 if (needs_padding) {
624 needs_padding_ = true;
627 return true;
630 void QuicPacketCreator::MaybeAddPadding() {
631 if (!needs_padding_) {
632 return;
635 if (BytesFree() == 0) {
636 // Don't pad full packets.
637 return;
640 QuicPaddingFrame padding;
641 bool success = AddFrame(QuicFrame(&padding), false, false, nullptr);
642 DCHECK(success);
645 } // namespace net