Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / net / quic / quic_packet_creator.cc
blob969ba5cd386634b6873fb7c16a0a7535e74a310d
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_packets_per_fec_group_(kDefaultMaxPacketsPerFecGroup),
82 connection_id_length_(PACKET_8BYTE_CONNECTION_ID),
83 next_sequence_number_length_(PACKET_1BYTE_SEQUENCE_NUMBER),
84 sequence_number_length_(next_sequence_number_length_),
85 packet_size_(0) {
86 SetMaxPacketLength(kDefaultMaxPacketSize);
89 QuicPacketCreator::~QuicPacketCreator() {
92 void QuicPacketCreator::OnBuiltFecProtectedPayload(
93 const QuicPacketHeader& header, StringPiece payload) {
94 if (fec_group_.get()) {
95 DCHECK_NE(0u, header.fec_group);
96 fec_group_->Update(encryption_level_, header, payload);
100 void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
101 QuicEncrypter* encrypter) {
102 framer_->SetEncrypter(level, encrypter);
103 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
106 void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
107 // |max_packet_length_| should not be changed mid-packet or mid-FEC group.
108 DCHECK(fec_group_.get() == nullptr && queued_frames_.empty());
109 max_packet_length_ = length;
110 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
113 void QuicPacketCreator::set_max_packets_per_fec_group(
114 size_t max_packets_per_fec_group) {
115 max_packets_per_fec_group_ = max(kLowestMaxPacketsPerFecGroup,
116 max_packets_per_fec_group);
117 DCHECK_LT(0u, max_packets_per_fec_group_);
120 bool QuicPacketCreator::ShouldSendFec(bool force_close) const {
121 DCHECK(!HasPendingFrames());
122 return fec_group_.get() != nullptr && fec_group_->NumReceivedPackets() > 0 &&
123 (force_close ||
124 fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_);
127 void QuicPacketCreator::ResetFecGroup() {
128 if (HasPendingFrames()) {
129 LOG_IF(DFATAL, packet_size_ != 0)
130 << "Cannot reset FEC group with pending frames.";
131 return;
133 fec_group_.reset(nullptr);
136 bool QuicPacketCreator::IsFecGroupOpen() const {
137 return fec_group_.get() != nullptr;
140 void QuicPacketCreator::StartFecProtectingPackets() {
141 if (!IsFecEnabled()) {
142 LOG(DFATAL) << "Cannot start FEC protection when FEC is not enabled.";
143 return;
145 // TODO(jri): This currently requires that the generator flush out any
146 // pending frames when FEC protection is turned on. If current packet can be
147 // converted to an FEC protected packet, do it. This will require the
148 // generator to check if the resulting expansion still allows the incoming
149 // frame to be added to the packet.
150 if (HasPendingFrames()) {
151 LOG(DFATAL) << "Cannot start FEC protection with pending frames.";
152 return;
154 DCHECK(!should_fec_protect_);
155 should_fec_protect_ = true;
158 void QuicPacketCreator::StopFecProtectingPackets() {
159 if (fec_group_.get() != nullptr) {
160 LOG(DFATAL) << "Cannot stop FEC protection with open FEC group.";
161 return;
163 DCHECK(should_fec_protect_);
164 should_fec_protect_ = false;
165 fec_group_number_ = 0;
168 bool QuicPacketCreator::IsFecProtected() const {
169 return should_fec_protect_;
172 bool QuicPacketCreator::IsFecEnabled() const {
173 return max_packets_per_fec_group_ > 0;
176 InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() {
177 if (fec_group_.get() != nullptr) {
178 // Don't update any lengths when an FEC group is open, to ensure same
179 // packet header size in all packets within a group.
180 return IN_FEC_GROUP;
182 if (!queued_frames_.empty()) {
183 // Don't change creator state if there are frames queued.
184 return fec_group_.get() == nullptr ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
187 // Update sequence number length only on packet and FEC group boundaries.
188 sequence_number_length_ = next_sequence_number_length_;
190 if (!should_fec_protect_) {
191 return NOT_IN_FEC_GROUP;
193 // Start a new FEC group since protection is on. Set the fec group number to
194 // the sequence number of the next packet.
195 fec_group_number_ = sequence_number() + 1;
196 fec_group_.reset(new QuicFecGroup());
197 return IN_FEC_GROUP;
200 // Stops serializing version of the protocol in packets sent after this call.
201 // A packet that is already open might send kQuicVersionSize bytes less than the
202 // maximum packet size if we stop sending version before it is serialized.
203 void QuicPacketCreator::StopSendingVersion() {
204 DCHECK(send_version_in_packet_);
205 send_version_in_packet_ = false;
206 if (packet_size_ > 0) {
207 DCHECK_LT(kQuicVersionSize, packet_size_);
208 packet_size_ -= kQuicVersionSize;
212 void QuicPacketCreator::UpdateSequenceNumberLength(
213 QuicPacketSequenceNumber least_packet_awaited_by_peer,
214 QuicPacketCount max_packets_in_flight) {
215 DCHECK_LE(least_packet_awaited_by_peer, sequence_number_ + 1);
216 // Since the packet creator will not change sequence number length mid FEC
217 // group, include the size of an FEC group to be safe.
218 const QuicPacketSequenceNumber current_delta =
219 max_packets_per_fec_group_ + sequence_number_ + 1
220 - least_packet_awaited_by_peer;
221 const uint64 delta = max(current_delta, max_packets_in_flight);
222 next_sequence_number_length_ =
223 QuicFramer::GetMinSequenceNumberLength(delta * 4);
226 bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
227 QuicStreamOffset offset) const {
228 // TODO(jri): This is a simple safe decision for now, but make
229 // is_in_fec_group a parameter. Same as with all public methods in
230 // QuicPacketCreator.
231 return BytesFree() >
232 QuicFramer::GetMinStreamFrameSize(id, offset, true,
233 should_fec_protect_ ? IN_FEC_GROUP :
234 NOT_IN_FEC_GROUP);
237 // static
238 size_t QuicPacketCreator::StreamFramePacketOverhead(
239 QuicConnectionIdLength connection_id_length,
240 bool include_version,
241 QuicSequenceNumberLength sequence_number_length,
242 QuicStreamOffset offset,
243 InFecGroup is_in_fec_group) {
244 return GetPacketHeaderSize(connection_id_length, include_version,
245 sequence_number_length, is_in_fec_group) +
246 // Assumes this is a stream with a single lone packet.
247 QuicFramer::GetMinStreamFrameSize(1u, offset, true, is_in_fec_group);
250 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
251 const IOVector& data,
252 QuicStreamOffset offset,
253 bool fin,
254 QuicFrame* frame) {
255 DCHECK_GT(max_packet_length_, StreamFramePacketOverhead(
256 connection_id_length_, kIncludeVersion,
257 PACKET_6BYTE_SEQUENCE_NUMBER, offset, IN_FEC_GROUP));
259 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
261 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset))
262 << "No room for Stream frame, BytesFree: " << BytesFree()
263 << " MinStreamFrameSize: "
264 << QuicFramer::GetMinStreamFrameSize(id, offset, true, is_in_fec_group);
266 if (data.Empty()) {
267 LOG_IF(DFATAL, !fin)
268 << "Creating a stream frame with no data or fin.";
269 // Create a new packet for the fin, if necessary.
270 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, data));
271 return 0;
274 const size_t data_size = data.TotalBufferSize();
275 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
276 id, offset, /* last_frame_in_packet= */ true, is_in_fec_group);
277 size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size);
279 bool set_fin = fin && bytes_consumed == data_size; // Last frame.
280 IOVector frame_data;
281 frame_data.AppendIovecAtMostBytes(data.iovec(), data.Size(),
282 bytes_consumed);
283 DCHECK_EQ(frame_data.TotalBufferSize(), bytes_consumed);
284 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, frame_data));
285 return bytes_consumed;
288 SerializedPacket QuicPacketCreator::ReserializeAllFrames(
289 const RetransmittableFrames& frames,
290 QuicSequenceNumberLength original_length,
291 char* buffer,
292 size_t buffer_len) {
293 DCHECK(fec_group_.get() == nullptr);
294 const QuicSequenceNumberLength saved_length = sequence_number_length_;
295 const QuicSequenceNumberLength saved_next_length =
296 next_sequence_number_length_;
297 const bool saved_should_fec_protect = should_fec_protect_;
298 const EncryptionLevel default_encryption_level = encryption_level_;
300 // Temporarily set the sequence number length, stop FEC protection,
301 // and change the encryption level.
302 sequence_number_length_ = original_length;
303 next_sequence_number_length_ = original_length;
304 should_fec_protect_ = false;
305 encryption_level_ = frames.encryption_level();
307 // Serialize the packet and restore the FEC and sequence number length state.
308 SerializedPacket serialized_packet =
309 SerializeAllFrames(frames.frames(), buffer, buffer_len);
310 sequence_number_length_ = saved_length;
311 next_sequence_number_length_ = saved_next_length;
312 should_fec_protect_ = saved_should_fec_protect;
313 encryption_level_ = default_encryption_level;
315 return serialized_packet;
318 SerializedPacket QuicPacketCreator::SerializeAllFrames(const QuicFrames& frames,
319 char* buffer,
320 size_t buffer_len) {
321 LOG_IF(DFATAL, !queued_frames_.empty()) << "Frames already queued.";
322 LOG_IF(DFATAL, frames.empty())
323 << "Attempt to serialize empty packet";
324 for (const QuicFrame& frame : frames) {
325 bool success = AddFrame(frame, false);
326 DCHECK(success);
328 SerializedPacket packet = SerializePacket(buffer, buffer_len);
329 DCHECK(packet.retransmittable_frames == nullptr);
330 return packet;
333 bool QuicPacketCreator::HasPendingFrames() const {
334 return !queued_frames_.empty();
337 bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
338 return queued_retransmittable_frames_.get() != nullptr &&
339 !queued_retransmittable_frames_->frames().empty();
342 size_t QuicPacketCreator::ExpansionOnNewFrame() const {
343 // If packet is FEC protected, there's no expansion.
344 if (should_fec_protect_) {
345 return 0;
347 // If the last frame in the packet is a stream frame, then it will expand to
348 // include the stream_length field when a new frame is added.
349 bool has_trailing_stream_frame =
350 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME;
351 return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0;
354 size_t QuicPacketCreator::BytesFree() const {
355 DCHECK_GE(max_plaintext_size_, PacketSize());
356 return max_plaintext_size_ - min(max_plaintext_size_, PacketSize()
357 + ExpansionOnNewFrame());
360 size_t QuicPacketCreator::PacketSize() const {
361 if (!queued_frames_.empty()) {
362 return packet_size_;
364 if (fec_group_.get() == nullptr) {
365 // Update sequence number length on packet and FEC boundary.
366 sequence_number_length_ = next_sequence_number_length_;
368 packet_size_ = GetPacketHeaderSize(
369 connection_id_length_, send_version_in_packet_, sequence_number_length_,
370 should_fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP);
371 return packet_size_;
374 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) {
375 return AddFrame(frame, true);
378 SerializedPacket QuicPacketCreator::SerializePacket(
379 char* encrypted_buffer,
380 size_t encrypted_buffer_len) {
381 DCHECK_LT(0u, encrypted_buffer_len);
382 LOG_IF(DFATAL, queued_frames_.empty())
383 << "Attempt to serialize empty packet";
384 DCHECK_GE(sequence_number_ + 1, fec_group_number_);
385 QuicPacketHeader header;
386 FillPacketHeader(should_fec_protect_ ? fec_group_number_ : 0, false, &header);
388 MaybeAddPadding();
390 DCHECK_GE(max_plaintext_size_, packet_size_);
391 // ACK Frames will be truncated due to length only if they're the only frame
392 // in the packet, and if packet_size_ was set to max_plaintext_size_. If
393 // truncation due to length occurred, then GetSerializedFrameLength will have
394 // returned all bytes free.
395 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
396 queued_frames_.size() == 1 &&
397 queued_frames_.back().type == ACK_FRAME;
398 char buffer[kMaxPacketSize];
399 scoped_ptr<QuicPacket> packet;
400 // Use the packet_size_ instead of the buffer size to ensure smaller
401 // packet sizes are properly used.
402 scoped_ptr<char[]> large_buffer;
403 if (packet_size_ <= kMaxPacketSize) {
404 packet.reset(
405 framer_->BuildDataPacket(header, queued_frames_, buffer, packet_size_));
406 } else {
407 large_buffer.reset(new char[packet_size_]);
408 packet.reset(framer_->BuildDataPacket(header, queued_frames_,
409 large_buffer.get(), packet_size_));
411 OnBuiltFecProtectedPayload(header, packet->FecProtectedData());
413 LOG_IF(DFATAL, packet == nullptr) << "Failed to serialize "
414 << queued_frames_.size() << " frames.";
415 // Because of possible truncation, we can't be confident that our
416 // packet size calculation worked correctly.
417 if (!possibly_truncated_by_length) {
418 DCHECK_EQ(packet_size_, packet->length());
420 // Immediately encrypt the packet, to ensure we don't encrypt the same packet
421 // sequence number multiple times.
422 QuicEncryptedPacket* encrypted =
423 framer_->EncryptPacket(encryption_level_, sequence_number_, *packet,
424 encrypted_buffer, encrypted_buffer_len);
425 if (encrypted == nullptr) {
426 LOG(DFATAL) << "Failed to encrypt packet number " << sequence_number_;
427 return NoPacket();
430 packet_size_ = 0;
431 queued_frames_.clear();
432 return SerializedPacket(header.packet_sequence_number,
433 header.public_header.sequence_number_length,
434 encrypted, QuicFramer::GetPacketEntropyHash(header),
435 queued_retransmittable_frames_.release());
438 SerializedPacket QuicPacketCreator::SerializeFec(char* buffer,
439 size_t buffer_len) {
440 DCHECK_LT(0u, buffer_len);
441 if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) {
442 LOG(DFATAL) << "SerializeFEC called but no group or zero packets in group.";
443 // TODO(jri): Make this a public method of framer?
444 return NoPacket();
446 DCHECK_EQ(0u, queued_frames_.size());
447 QuicPacketHeader header;
448 FillPacketHeader(fec_group_number_, true, &header);
449 QuicFecData fec_data;
450 fec_data.fec_group = fec_group_->min_protected_packet();
451 fec_data.redundancy = fec_group_->payload_parity();
452 scoped_ptr<QuicPacket> packet(framer_->BuildFecPacket(header, fec_data));
453 fec_group_.reset(nullptr);
454 packet_size_ = 0;
455 LOG_IF(DFATAL, packet == nullptr)
456 << "Failed to serialize fec packet for group:" << fec_data.fec_group;
457 DCHECK_GE(max_packet_length_, packet->length());
458 // Immediately encrypt the packet, to ensure we don't encrypt the same packet
459 // sequence number multiple times.
460 QuicEncryptedPacket* encrypted = framer_->EncryptPacket(
461 encryption_level_, sequence_number_, *packet, buffer, buffer_len);
462 if (encrypted == nullptr) {
463 LOG(DFATAL) << "Failed to encrypt packet number " << sequence_number_;
464 return NoPacket();
466 SerializedPacket serialized(
467 header.packet_sequence_number,
468 header.public_header.sequence_number_length, encrypted,
469 QuicFramer::GetPacketEntropyHash(header), nullptr);
470 serialized.is_fec_packet = true;
471 return serialized;
474 QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket(
475 const QuicVersionVector& supported_versions) {
476 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
477 QuicPacketPublicHeader header;
478 header.connection_id = connection_id_;
479 header.reset_flag = false;
480 header.version_flag = true;
481 header.versions = supported_versions;
482 QuicEncryptedPacket* encrypted =
483 framer_->BuildVersionNegotiationPacket(header, supported_versions);
484 DCHECK(encrypted);
485 DCHECK_GE(max_packet_length_, encrypted->length());
486 return encrypted;
489 SerializedPacket QuicPacketCreator::NoPacket() {
490 return SerializedPacket(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, nullptr);
493 void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
494 bool fec_flag,
495 QuicPacketHeader* header) {
496 header->public_header.connection_id = connection_id_;
497 header->public_header.connection_id_length = connection_id_length_;
498 header->public_header.reset_flag = false;
499 header->public_header.version_flag = send_version_in_packet_;
500 header->fec_flag = fec_flag;
501 header->packet_sequence_number = ++sequence_number_;
502 header->public_header.sequence_number_length = sequence_number_length_;
503 header->entropy_flag = random_bool_source_->RandBool();
504 header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
505 header->fec_group = fec_group;
508 bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
509 switch (frame.type) {
510 case ACK_FRAME:
511 case PADDING_FRAME:
512 case STOP_WAITING_FRAME:
513 return false;
514 default:
515 return true;
519 bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
520 bool save_retransmittable_frames) {
521 DVLOG(1) << "Adding frame: " << frame;
522 InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
524 size_t frame_len = framer_->GetSerializedFrameLength(
525 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group,
526 sequence_number_length_);
527 if (frame_len == 0) {
528 return false;
530 DCHECK_LT(0u, packet_size_);
531 packet_size_ += ExpansionOnNewFrame() + frame_len;
533 if (save_retransmittable_frames && ShouldRetransmit(frame)) {
534 if (queued_retransmittable_frames_.get() == nullptr) {
535 queued_retransmittable_frames_.reset(
536 new RetransmittableFrames(encryption_level_));
538 if (frame.type == STREAM_FRAME) {
539 queued_frames_.push_back(
540 queued_retransmittable_frames_->AddStreamFrame(frame.stream_frame));
541 } else {
542 queued_frames_.push_back(
543 queued_retransmittable_frames_->AddNonStreamFrame(frame));
545 } else {
546 queued_frames_.push_back(frame);
548 return true;
551 void QuicPacketCreator::MaybeAddPadding() {
552 if (BytesFree() == 0) {
553 // Don't pad full packets.
554 return;
557 // Since ReserializeAllFrames does not populate queued_retransmittable_frames_
558 // it's not sufficient to simply call
559 // queued_retransmittable_frames_->HasCryptoHandshake().
560 // TODO(rch): we should really make ReserializeAllFrames not be a special
561 // case!
563 // If any of the frames in the current packet are on the crypto stream
564 // then they contain handshake messagses, and we should pad them.
565 bool is_handshake = false;
566 for (const QuicFrame& frame : queued_frames_) {
567 if (frame.type == STREAM_FRAME &&
568 frame.stream_frame->stream_id == kCryptoStreamId) {
569 is_handshake = true;
570 break;
573 if (!is_handshake) {
574 return;
577 QuicPaddingFrame padding;
578 bool success = AddFrame(QuicFrame(&padding), false);
579 DCHECK(success);
582 } // namespace net