| Index: net/quic/quic_packet_creator.cc
|
| diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc
|
| index e567a054629d35865b078c6638ee94c60f4d650b..eadc09ca81b69e19840c247dda667c208a5a51ad 100644
|
| --- a/net/quic/quic_packet_creator.cc
|
| +++ b/net/quic/quic_packet_creator.cc
|
| @@ -137,14 +137,27 @@ void QuicPacketCreator::set_max_packets_per_fec_group(
|
| options_.max_packets_per_fec_group = max_packets_per_fec_group;
|
| }
|
|
|
| -InFecGroup QuicPacketCreator::MaybeStartFec() {
|
| - if (should_fec_protect_ && fec_group_.get() == NULL) {
|
| - DCHECK(queued_frames_.empty());
|
| - // Set the fec group number to the sequence number of the next packet.
|
| - fec_group_number_ = sequence_number() + 1;
|
| - fec_group_.reset(new QuicFecGroup());
|
| +InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() {
|
| + if (fec_group_.get() != NULL) {
|
| + // Don't update any lengths when an FEC group is open, to ensure same
|
| + // packet header size in all packets within a group.
|
| + return IN_FEC_GROUP;
|
| + }
|
| + if (!queued_frames_.empty()) {
|
| + // Don't change creator state if there are frames queued.
|
| + return fec_group_.get() == NULL ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
|
| + }
|
| + // TODO(jri): Add max_packet_length and send_connection_id_length here too.
|
| + sequence_number_length_ = options_.send_sequence_number_length;
|
| +
|
| + if (!should_fec_protect_) {
|
| + return NOT_IN_FEC_GROUP;
|
| }
|
| - return fec_group_.get() == NULL ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
|
| + // Start a new FEC group since protection is on. Set the fec group number to
|
| + // the sequence number of the next packet.
|
| + fec_group_number_ = sequence_number() + 1;
|
| + fec_group_.reset(new QuicFecGroup());
|
| + return IN_FEC_GROUP;
|
| }
|
|
|
| // Stops serializing version of the protocol in packets sent after this call.
|
| @@ -209,7 +222,7 @@ size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
|
| framer_->version(), PACKET_8BYTE_CONNECTION_ID, kIncludeVersion,
|
| PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP));
|
|
|
| - InFecGroup is_in_fec_group = MaybeStartFec();
|
| + InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
|
|
|
| LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset))
|
| << "No room for Stream frame, BytesFree: " << BytesFree()
|
| @@ -354,22 +367,21 @@ SerializedPacket QuicPacketCreator::SerializePacket() {
|
| size_t max_plaintext_size =
|
| framer_->GetMaxPlaintextSize(options_.max_packet_length);
|
| DCHECK_GE(max_plaintext_size, packet_size_);
|
| - // ACK and CONNECTION_CLOSE Frames will be truncated only if they're
|
| - // the first frame in the packet. If truncation is to occur, then
|
| - // GetSerializedFrameLength will have returned all bytes free.
|
| - bool possibly_truncated =
|
| - packet_size_ != max_plaintext_size ||
|
| - queued_frames_.size() != 1 ||
|
| - (queued_frames_.back().type == ACK_FRAME ||
|
| - queued_frames_.back().type == CONNECTION_CLOSE_FRAME);
|
| + // ACK Frames will be truncated only if they're the only frame in the packet,
|
| + // and if packet_size_ was set to max_plaintext_size. If truncation occurred,
|
| + // then GetSerializedFrameLength will have returned all bytes free.
|
| + bool possibly_truncated = packet_size_ == max_plaintext_size &&
|
| + queued_frames_.size() == 1 &&
|
| + queued_frames_.back().type == ACK_FRAME;
|
| SerializedPacket serialized =
|
| framer_->BuildDataPacket(header, queued_frames_, packet_size_);
|
| LOG_IF(DFATAL, !serialized.packet)
|
| << "Failed to serialize " << queued_frames_.size() << " frames.";
|
| // Because of possible truncation, we can't be confident that our
|
| // packet size calculation worked correctly.
|
| - if (!possibly_truncated)
|
| + if (!possibly_truncated) {
|
| DCHECK_EQ(packet_size_, serialized.packet->length());
|
| + }
|
|
|
| packet_size_ = 0;
|
| queued_frames_.clear();
|
| @@ -450,10 +462,11 @@ bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) {
|
| bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
|
| bool save_retransmittable_frames) {
|
| DVLOG(1) << "Adding frame: " << frame;
|
| - InFecGroup is_in_fec_group = MaybeStartFec();
|
| + InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec();
|
| +
|
| size_t frame_len = framer_->GetSerializedFrameLength(
|
| frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group,
|
| - options()->send_sequence_number_length);
|
| + sequence_number_length_);
|
| if (frame_len == 0) {
|
| return false;
|
| }
|
|
|