Fix ChromePublic icon and app name.
[chromium-blink-merge.git] / net / quic / quic_packet_creator.cc
blob7474b0b17b75bd1f3ebc8cea4b7f683583989e93
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 sequence_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_sequence_number_length_(PACKET_1BYTE_SEQUENCE_NUMBER),
85 sequence_number_length_(next_sequence_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 sequence number length only on packet and FEC group boundaries.
201 sequence_number_length_ = next_sequence_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 sequence number of the next packet.
208 fec_group_number_ = sequence_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::UpdateSequenceNumberLength(
226 QuicPacketSequenceNumber least_packet_awaited_by_peer,
227 QuicPacketCount max_packets_in_flight) {
228 DCHECK_LE(least_packet_awaited_by_peer, sequence_number_ + 1);
229 // Since the packet creator will not change sequence number length mid FEC
230 // group, include the size of an FEC group to be safe.
231 const QuicPacketSequenceNumber current_delta =
232 max_packets_per_fec_group_ + sequence_number_ + 1
233 - least_packet_awaited_by_peer;
234 const uint64 delta = max(current_delta, max_packets_in_flight);
235 next_sequence_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 QuicSequenceNumberLength sequence_number_length,
255 QuicStreamOffset offset,
256 InFecGroup is_in_fec_group) {
257 return GetPacketHeaderSize(connection_id_length, include_version,
258 sequence_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_, StreamFramePacketOverhead(
271 connection_id_length_, kIncludeVersion,
272 PACKET_6BYTE_SEQUENCE_NUMBER, offset, IN_FEC_GROUP));
273 DCHECK(buffer);
275 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
277 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset))
278 << "No room for Stream frame, BytesFree: " << BytesFree()
279 << " MinStreamFrameSize: "
280 << QuicFramer::GetMinStreamFrameSize(id, offset, true, is_in_fec_group);
282 if (iov_offset == iov.total_length) {
283 LOG_IF(DFATAL, !fin)
284 << "Creating a stream frame with no data or fin.";
285 // Create a new packet for the fin, if necessary.
286 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, StringPiece()));
287 return 0;
290 const size_t data_size = iov.total_length - iov_offset;
291 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
292 id, offset, /* last_frame_in_packet= */ true, is_in_fec_group);
293 size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size);
295 bool set_fin = fin && bytes_consumed == data_size; // Last frame.
296 buffer->reset(new char[bytes_consumed]);
297 CopyToBuffer(iov, iov_offset, bytes_consumed, buffer->get());
298 *frame = QuicFrame(new QuicStreamFrame(
299 id, set_fin, offset, StringPiece(buffer->get(), bytes_consumed)));
300 return bytes_consumed;
303 // static
304 void QuicPacketCreator::CopyToBuffer(const QuicIOVector& iov,
305 size_t iov_offset,
306 size_t length,
307 char* buffer) {
308 int iovnum = 0;
309 while (iovnum < iov.iov_count && iov_offset >= iov.iov[iovnum].iov_len) {
310 iov_offset -= iov.iov[iovnum].iov_len;
311 ++iovnum;
313 while (iovnum < iov.iov_count && length > 0) {
314 const size_t copy_len = min(length, iov.iov[iovnum].iov_len - iov_offset);
315 memcpy(buffer, static_cast<char*>(iov.iov[iovnum].iov_base) + iov_offset,
316 copy_len);
317 iov_offset = 0;
318 length -= copy_len;
319 buffer += copy_len;
320 ++iovnum;
322 LOG_IF(DFATAL, length > 0) << "Failed to copy entire length to buffer.";
325 SerializedPacket QuicPacketCreator::ReserializeAllFrames(
326 const RetransmittableFrames& frames,
327 QuicSequenceNumberLength original_length,
328 char* buffer,
329 size_t buffer_len) {
330 DCHECK(fec_group_.get() == nullptr);
331 const QuicSequenceNumberLength saved_length = sequence_number_length_;
332 const QuicSequenceNumberLength saved_next_length =
333 next_sequence_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 sequence number length, stop FEC protection,
339 // and change the encryption level.
340 sequence_number_length_ = original_length;
341 next_sequence_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 sequence number length state.
347 SerializedPacket serialized_packet =
348 SerializeAllFrames(frames.frames(), buffer, buffer_len);
349 sequence_number_length_ = saved_length;
350 next_sequence_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 sequence number length on packet and FEC boundary.
406 sequence_number_length_ = next_sequence_number_length_;
408 packet_size_ = GetPacketHeaderSize(
409 connection_id_length_, send_version_in_packet_, sequence_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(sequence_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 // sequence number multiple times.
481 QuicEncryptedPacket* encrypted =
482 framer_->EncryptPayload(encryption_level_, sequence_number_, *packet,
483 encrypted_buffer, encrypted_buffer_len);
484 if (encrypted == nullptr) {
485 LOG(DFATAL) << "Failed to encrypt packet number " << sequence_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 packet_size_ = 0;
498 queued_frames_.clear();
499 needs_padding_ = false;
500 return SerializedPacket(header.packet_sequence_number,
501 header.public_header.sequence_number_length,
502 encrypted, QuicFramer::GetPacketEntropyHash(header),
503 queued_retransmittable_frames_.release());
506 SerializedPacket QuicPacketCreator::SerializeFec(char* buffer,
507 size_t buffer_len) {
508 DCHECK_LT(0u, buffer_len);
509 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) {
510 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group.";
511 // TODO(jri): Make this a public method of framer?
512 return NoPacket();
514 DCHECK_EQ(0u, queued_frames_.size());
515 QuicPacketHeader header;
516 FillPacketHeader(fec_group_number_, true, &header);
517 QuicFecData fec_data;
518 fec_data.fec_group = fec_group_->min_protected_packet();
519 fec_data.redundancy = fec_group_->payload_parity();
520 scoped_ptr<QuicPacket> packet(framer_->BuildFecPacket(header, fec_data));
521 fec_group_.reset(nullptr);
522 packet_size_ = 0;
523 LOG_IF(DFATAL, packet == nullptr)
524 << "Failed to serialize fec packet for group:" << fec_data.fec_group;
525 DCHECK_GE(max_packet_length_, packet->length());
526 // Immediately encrypt the packet, to ensure we don't encrypt the same packet
527 // sequence number multiple times.
528 QuicEncryptedPacket* encrypted = framer_->EncryptPayload(
529 encryption_level_, sequence_number_, *packet, buffer, buffer_len);
530 if (encrypted == nullptr) {
531 LOG(DFATAL) << "Failed to encrypt packet number " << sequence_number_;
532 return NoPacket();
534 SerializedPacket serialized(
535 header.packet_sequence_number,
536 header.public_header.sequence_number_length, encrypted,
537 QuicFramer::GetPacketEntropyHash(header), nullptr);
538 serialized.is_fec_packet = true;
539 return serialized;
542 QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket(
543 const QuicVersionVector& supported_versions) {
544 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
545 QuicPacketPublicHeader header;
546 header.connection_id = connection_id_;
547 header.reset_flag = false;
548 header.version_flag = true;
549 header.versions = supported_versions;
550 QuicEncryptedPacket* encrypted =
551 framer_->BuildVersionNegotiationPacket(header, supported_versions);
552 DCHECK(encrypted);
553 DCHECK_GE(max_packet_length_, encrypted->length());
554 return encrypted;
557 SerializedPacket QuicPacketCreator::NoPacket() {
558 return SerializedPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, nullptr);
561 void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
562 bool fec_flag,
563 QuicPacketHeader* header) {
564 header->public_header.connection_id = connection_id_;
565 header->public_header.connection_id_length = connection_id_length_;
566 header->public_header.reset_flag = false;
567 header->public_header.version_flag = send_version_in_packet_;
568 header->fec_flag = fec_flag;
569 header->packet_sequence_number = ++sequence_number_;
570 header->public_header.sequence_number_length = sequence_number_length_;
571 header->entropy_flag = random_bool_source_->RandBool();
572 header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
573 header->fec_group = fec_group;
576 bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
577 switch (frame.type) {
578 case ACK_FRAME:
579 case PADDING_FRAME:
580 case STOP_WAITING_FRAME:
581 case MTU_DISCOVERY_FRAME:
582 return false;
583 default:
584 return true;
588 bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
589 bool save_retransmittable_frames,
590 bool needs_padding,
591 char* buffer) {
592 DVLOG(1) << "Adding frame: " << frame;
593 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
595 size_t frame_len = framer_->GetSerializedFrameLength(
596 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group,
597 sequence_number_length_);
598 if (frame_len == 0) {
599 return false;
601 DCHECK_LT(0u, packet_size_);
602 packet_size_ += ExpansionOnNewFrame() + frame_len;
604 if (save_retransmittable_frames && ShouldRetransmit(frame)) {
605 if (queued_retransmittable_frames_.get() == nullptr) {
606 queued_retransmittable_frames_.reset(
607 new RetransmittableFrames(encryption_level_));
609 queued_frames_.push_back(
610 queued_retransmittable_frames_->AddFrame(frame, buffer));
611 } else {
612 queued_frames_.push_back(frame);
615 if (needs_padding) {
616 needs_padding_ = true;
619 return true;
622 void QuicPacketCreator::MaybeAddPadding() {
623 if (!needs_padding_) {
624 return;
627 if (BytesFree() == 0) {
628 // Don't pad full packets.
629 return;
632 QuicPaddingFrame padding;
633 bool success = AddFrame(QuicFrame(&padding), false, false, nullptr);
634 DCHECK(success);
637 } // namespace net