| Index: net/quic/quic_packet_creator.cc
|
| diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc
|
| index 2cdfd69f67fb2bd0125fe1cb1d847f66654859a0..c8d132fe8329d4c2d542bc659cbf847ac789d84b 100644
|
| --- a/net/quic/quic_packet_creator.cc
|
| +++ b/net/quic/quic_packet_creator.cc
|
| @@ -28,7 +28,9 @@ QuicPacketCreator::QuicPacketCreator(QuicGuid guid,
|
| fec_group_number_(0),
|
| is_server_(is_server),
|
| send_version_in_packet_(!is_server),
|
| - packet_size_(GetPacketHeaderSize(send_version_in_packet_)) {
|
| + packet_size_(GetPacketHeaderSize(options_.send_guid_length,
|
| + send_version_in_packet_,
|
| + NOT_IN_FEC_GROUP)) {
|
| framer_->set_fec_builder(this);
|
| }
|
|
|
| @@ -43,16 +45,21 @@ void QuicPacketCreator::OnBuiltFecProtectedPayload(
|
| }
|
|
|
| bool QuicPacketCreator::ShouldSendFec(bool force_close) const {
|
| - return fec_group_.get() != NULL &&
|
| + return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 &&
|
| (force_close ||
|
| fec_group_->NumReceivedPackets() >= options_.max_packets_per_fec_group);
|
| }
|
|
|
| void QuicPacketCreator::MaybeStartFEC() {
|
| if (options_.max_packets_per_fec_group > 0 && 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());
|
| + packet_size_ = GetPacketHeaderSize(options_.send_guid_length,
|
| + send_version_in_packet_,
|
| + IN_FEC_GROUP);
|
| + DCHECK_LE(packet_size_, options_.max_packet_length);
|
| }
|
| }
|
|
|
| @@ -73,9 +80,12 @@ bool QuicPacketCreator::HasRoomForStreamFrame() const {
|
| }
|
|
|
| // static
|
| -size_t QuicPacketCreator::StreamFramePacketOverhead(int num_frames,
|
| - bool include_version) {
|
| - return GetPacketHeaderSize(include_version) +
|
| +size_t QuicPacketCreator::StreamFramePacketOverhead(
|
| + int num_frames,
|
| + QuicGuidLength guid_length,
|
| + bool include_version,
|
| + InFecGroup is_in_fec_group) {
|
| + return GetPacketHeaderSize(guid_length, include_version, is_in_fec_group) +
|
| QuicFramer::GetMinStreamFrameSize() * num_frames;
|
| }
|
|
|
| @@ -85,7 +95,8 @@ size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
|
| bool fin,
|
| QuicFrame* frame) {
|
| DCHECK_GT(options_.max_packet_length,
|
| - StreamFramePacketOverhead(1, kIncludeVersion));
|
| + StreamFramePacketOverhead(
|
| + 1, PACKET_8BYTE_GUID, kIncludeVersion, IN_FEC_GROUP));
|
| DCHECK(HasRoomForStreamFrame());
|
|
|
| const size_t free_bytes = BytesFree();
|
| @@ -147,7 +158,10 @@ SerializedPacket QuicPacketCreator::SerializePacket() {
|
| SerializedPacket serialized = framer_->ConstructFrameDataPacket(
|
| header, queued_frames_, packet_size_);
|
| queued_frames_.clear();
|
| - packet_size_ = GetPacketHeaderSize(send_version_in_packet_);
|
| + packet_size_ = GetPacketHeaderSize(options_.send_guid_length,
|
| + send_version_in_packet_,
|
| + fec_group_.get() != NULL ?
|
| + IN_FEC_GROUP : NOT_IN_FEC_GROUP);
|
| serialized.retransmittable_frames = queued_retransmittable_frames_.release();
|
| return serialized;
|
| }
|
| @@ -164,6 +178,10 @@ SerializedPacket QuicPacketCreator::SerializeFec() {
|
| SerializedPacket serialized = framer_->ConstructFecPacket(header, fec_data);
|
| fec_group_.reset(NULL);
|
| fec_group_number_ = 0;
|
| + // Reset packet_size_, since the next packet may not have an FEC group.
|
| + packet_size_ = GetPacketHeaderSize(options_.send_guid_length,
|
| + send_version_in_packet_,
|
| + NOT_IN_FEC_GROUP);
|
| DCHECK(serialized.packet);
|
| DCHECK_GE(options_.max_packet_length, serialized.packet->length());
|
| return serialized;
|
| @@ -199,15 +217,23 @@ void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group,
|
| header->public_header.reset_flag = false;
|
| header->public_header.version_flag = send_version_in_packet_;
|
| header->fec_flag = fec_flag;
|
| - header->fec_entropy_flag = fec_entropy_flag;
|
| header->packet_sequence_number = ++sequence_number_;
|
| +
|
| + bool entropy_flag;
|
| if (header->packet_sequence_number == 1) {
|
| + DCHECK(!fec_flag);
|
| // TODO(satyamshekhar): No entropy in the first message.
|
| // For crypto tests to pass. Fix this by using deterministic QuicRandom.
|
| - header->entropy_flag = 0;
|
| + entropy_flag = 0;
|
| + } else if (fec_flag) {
|
| + // FEC packets don't have an entropy of their own. Entropy flag for FEC
|
| + // packets is the XOR of entropy of previous packets.
|
| + entropy_flag = fec_entropy_flag;
|
| } else {
|
| - header->entropy_flag = random_generator_->RandBool();
|
| + entropy_flag = random_generator_->RandBool();
|
| }
|
| + header->entropy_flag = entropy_flag;
|
| + header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
|
| header->fec_group = fec_group;
|
| }
|
|
|
|
|