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"
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
;
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;
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
{
40 // random: Source of entropy. Not owned.
41 explicit QuicRandomBoolSource(QuicRandom
* random
)
46 ~QuicRandomBoolSource() {}
48 // Returns the next random bit from the bucket.
51 bit_bucket_
= random_
->RandUint64();
54 bool result
= ((bit_bucket_
& bit_mask_
) != 0);
62 // Stored random bits.
64 // The next available bit has "1" in the mask. Zero means empty bucket.
67 DISALLOW_COPY_AND_ASSIGN(QuicRandomBoolSource
);
70 QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id
,
72 QuicRandom
* random_generator
)
73 : connection_id_(connection_id
),
74 encryption_level_(ENCRYPTION_NONE
),
76 random_bool_source_(new QuicRandomBoolSource(random_generator
)),
78 should_fec_protect_(false),
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_
),
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
118 if (length
== max_packet_length_
) {
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 &&
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.";
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.";
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.";
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.";
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.
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());
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_
+
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.
245 QuicFramer::GetMinStreamFrameSize(id
, offset
, true,
246 should_fec_protect_
? IN_FEC_GROUP
:
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
,
266 QuicStreamOffset offset
,
269 scoped_ptr
<char[]>* buffer
) {
270 DCHECK_GT(max_packet_length_
,
271 StreamFramePacketOverhead(connection_id_length_
, kIncludeVersion
,
272 PACKET_6BYTE_PACKET_NUMBER
, offset
,
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
) {
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()));
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
;
305 void QuicPacketCreator::CopyToBuffer(const QuicIOVector
& iov
,
310 while (iovnum
< iov
.iov_count
&& iov_offset
>= iov
.iov
[iovnum
].iov_len
) {
311 iov_offset
-= iov
.iov
[iovnum
].iov_len
;
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
,
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
,
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
,
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);
368 SerializedPacket packet
= SerializePacket(buffer
, buffer_len
);
369 DCHECK(packet
.retransmittable_frames
== nullptr);
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_
) {
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()) {
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
);
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
,
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
);
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
) {
460 framer_
->BuildDataPacket(header
, queued_frames_
, buffer
, packet_size_
));
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()
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_
;
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
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
;
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
,
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?
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);
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_
;
541 SerializedPacket
serialized(
542 header
.packet_packet_number
, header
.public_header
.packet_number_length
,
543 encrypted
, QuicFramer::GetPacketEntropyHash(header
), nullptr, false,
545 serialized
.is_fec_packet
= true;
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
);
560 DCHECK_GE(max_packet_length_
, encrypted
->length());
564 SerializedPacket
QuicPacketCreator::NoPacket() {
565 return SerializedPacket(0, PACKET_1BYTE_PACKET_NUMBER
, nullptr, 0, nullptr,
569 void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group
,
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
) {
588 case STOP_WAITING_FRAME
:
589 case MTU_DISCOVERY_FRAME
:
596 bool QuicPacketCreator::AddFrame(const QuicFrame
& frame
,
597 bool save_retransmittable_frames
,
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) {
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
));
620 queued_frames_
.push_back(frame
);
624 needs_padding_
= true;
630 void QuicPacketCreator::MaybeAddPadding() {
631 if (!needs_padding_
) {
635 if (BytesFree() == 0) {
636 // Don't pad full packets.
640 QuicPaddingFrame padding
;
641 bool success
= AddFrame(QuicFrame(&padding
), false, false, nullptr);