| Index: net/quic/quic_packet_creator.cc
|
| diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc
|
| index 4c57b4bb904e4c1ec411f1889e06a83adaa45229..e567a054629d35865b078c6638ee94c60f4d650b 100644
|
| --- a/net/quic/quic_packet_creator.cc
|
| +++ b/net/quic/quic_packet_creator.cc
|
| @@ -64,6 +64,7 @@ QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id,
|
| framer_(framer),
|
| random_bool_source_(new QuicRandomBoolSource(random_generator)),
|
| sequence_number_(0),
|
| + should_fec_protect_(false),
|
| fec_group_number_(0),
|
| is_server_(is_server),
|
| send_version_in_packet_(!is_server),
|
| @@ -85,12 +86,59 @@ void QuicPacketCreator::OnBuiltFecProtectedPayload(
|
|
|
| bool QuicPacketCreator::ShouldSendFec(bool force_close) const {
|
| return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 &&
|
| - (force_close ||
|
| - fec_group_->NumReceivedPackets() >= options_.max_packets_per_fec_group);
|
| + (force_close || fec_group_->NumReceivedPackets() >=
|
| + options_.max_packets_per_fec_group);
|
| }
|
|
|
| -InFecGroup QuicPacketCreator::MaybeStartFEC() {
|
| - if (IsFecEnabled() && fec_group_.get() == NULL) {
|
| +void QuicPacketCreator::StartFecProtectingPackets() {
|
| + if (!IsFecEnabled()) {
|
| + LOG(DFATAL) << "Cannot start FEC protection when FEC is not enabled.";
|
| + return;
|
| + }
|
| + // TODO(jri): This currently requires that the generator flush out any
|
| + // pending frames when FEC protection is turned on. If current packet can be
|
| + // converted to an FEC protected packet, do it. This will require the
|
| + // generator to check if the resulting expansion still allows the incoming
|
| + // frame to be added to the packet.
|
| + if (HasPendingFrames()) {
|
| + LOG(DFATAL) << "Cannot start FEC protection with pending frames.";
|
| + return;
|
| + }
|
| + DCHECK(!should_fec_protect_);
|
| + should_fec_protect_ = true;
|
| +}
|
| +
|
| +void QuicPacketCreator::StopFecProtectingPackets() {
|
| + if (fec_group_.get() != NULL) {
|
| + LOG(DFATAL) << "Cannot stop FEC protection with open FEC group.";
|
| + return;
|
| + }
|
| + DCHECK(should_fec_protect_);
|
| + should_fec_protect_ = false;
|
| + fec_group_number_ = 0;
|
| +}
|
| +
|
| +bool QuicPacketCreator::IsFecProtected() const {
|
| + return should_fec_protect_;
|
| +}
|
| +
|
| +bool QuicPacketCreator::IsFecEnabled() const {
|
| + return options_.max_packets_per_fec_group > 0;
|
| +}
|
| +
|
| +size_t QuicPacketCreator::max_packets_per_fec_group() const {
|
| + return options_.max_packets_per_fec_group;
|
| +}
|
| +
|
| +void QuicPacketCreator::set_max_packets_per_fec_group(
|
| + size_t max_packets_per_fec_group) {
|
| + // To turn off FEC protection, use StopFecProtectingPackets().
|
| + DCHECK_NE(0u, 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;
|
| @@ -134,7 +182,8 @@ bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
|
| // QuicPacketCreator.
|
| return BytesFree() >
|
| QuicFramer::GetMinStreamFrameSize(framer_->version(), id, offset, true,
|
| - IsFecEnabled());
|
| + should_fec_protect_ ? IN_FEC_GROUP :
|
| + NOT_IN_FEC_GROUP);
|
| }
|
|
|
| // static
|
| @@ -159,7 +208,8 @@ size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
|
| StreamFramePacketOverhead(
|
| 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 = MaybeStartFec();
|
|
|
| LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset))
|
| << "No room for Stream frame, BytesFree: " << BytesFree()
|
| @@ -210,25 +260,22 @@ size_t QuicPacketCreator::CreateStreamFrameWithNotifier(
|
| SerializedPacket QuicPacketCreator::ReserializeAllFrames(
|
| const QuicFrames& frames,
|
| QuicSequenceNumberLength original_length) {
|
| - const QuicSequenceNumberLength start_length = sequence_number_length_;
|
| - const QuicSequenceNumberLength start_options_length =
|
| + DCHECK(fec_group_.get() == NULL);
|
| + const QuicSequenceNumberLength saved_length = sequence_number_length_;
|
| + const QuicSequenceNumberLength saved_options_length =
|
| options_.send_sequence_number_length;
|
| - const QuicFecGroupNumber start_fec_group = fec_group_number_;
|
| - const size_t start_max_packets_per_fec_group =
|
| - options_.max_packets_per_fec_group;
|
| + const bool saved_should_fec_protect = should_fec_protect_;
|
|
|
| - // Temporarily set the sequence number length and disable FEC.
|
| + // Temporarily set the sequence number length and stop FEC protection.
|
| sequence_number_length_ = original_length;
|
| options_.send_sequence_number_length = original_length;
|
| - fec_group_number_ = 0;
|
| - options_.max_packets_per_fec_group = 0;
|
| + should_fec_protect_ = false;
|
|
|
| - // Serialize the packet and restore the fec and sequence number length state.
|
| + // Serialize the packet and restore the FEC and sequence number length state.
|
| SerializedPacket serialized_packet = SerializeAllFrames(frames);
|
| - sequence_number_length_ = start_length;
|
| - options_.send_sequence_number_length = start_options_length;
|
| - fec_group_number_ = start_fec_group;
|
| - options_.max_packets_per_fec_group = start_max_packets_per_fec_group;
|
| + sequence_number_length_ = saved_length;
|
| + options_.send_sequence_number_length = saved_options_length;
|
| + should_fec_protect_ = saved_should_fec_protect;
|
|
|
| return serialized_packet;
|
| }
|
| @@ -256,7 +303,7 @@ bool QuicPacketCreator::HasPendingFrames() {
|
|
|
| size_t QuicPacketCreator::ExpansionOnNewFrame() const {
|
| // If packet is FEC protected, there's no expansion.
|
| - if (fec_group_.get() != NULL) {
|
| + if (should_fec_protect_) {
|
| return 0;
|
| }
|
| // If the last frame in the packet is a stream frame, then it will expand to
|
| @@ -274,11 +321,6 @@ size_t QuicPacketCreator::BytesFree() const {
|
| + ExpansionOnNewFrame());
|
| }
|
|
|
| -InFecGroup QuicPacketCreator::IsFecEnabled() const {
|
| - return (options_.max_packets_per_fec_group == 0) ?
|
| - NOT_IN_FEC_GROUP : IN_FEC_GROUP;
|
| -}
|
| -
|
| size_t QuicPacketCreator::PacketSize() const {
|
| if (queued_frames_.empty()) {
|
| // Only adjust the sequence number length when the FEC group is not open,
|
| @@ -290,7 +332,8 @@ size_t QuicPacketCreator::PacketSize() const {
|
| packet_size_ = GetPacketHeaderSize(options_.send_connection_id_length,
|
| send_version_in_packet_,
|
| sequence_number_length_,
|
| - IsFecEnabled());
|
| + should_fec_protect_ ? IN_FEC_GROUP :
|
| + NOT_IN_FEC_GROUP);
|
| }
|
| return packet_size_;
|
| }
|
| @@ -302,8 +345,9 @@ bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) {
|
| SerializedPacket QuicPacketCreator::SerializePacket() {
|
| LOG_IF(DFATAL, queued_frames_.empty())
|
| << "Attempt to serialize empty packet";
|
| + DCHECK_GE(sequence_number_ + 1, fec_group_number_);
|
| QuicPacketHeader header;
|
| - FillPacketHeader(fec_group_number_, false, &header);
|
| + FillPacketHeader(should_fec_protect_ ? fec_group_number_ : 0, false, &header);
|
|
|
| MaybeAddPadding();
|
|
|
| @@ -348,7 +392,6 @@ SerializedPacket QuicPacketCreator::SerializeFec() {
|
| fec_data.redundancy = fec_group_->payload_parity();
|
| SerializedPacket serialized = framer_->BuildFecPacket(header, fec_data);
|
| fec_group_.reset(NULL);
|
| - fec_group_number_ = 0;
|
| packet_size_ = 0;
|
| LOG_IF(DFATAL, !serialized.packet)
|
| << "Failed to serialize fec packet for group:" << fec_data.fec_group;
|
| @@ -407,7 +450,7 @@ 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 = MaybeStartFec();
|
| size_t frame_len = framer_->GetSerializedFrameLength(
|
| frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group,
|
| options()->send_sequence_number_length);
|
|
|