Index: net/quic/quic_packet_creator.cc |
diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc |
index f4e0cf743df56f313c648375be7e7a074e819914..56e88bfdedbb56eec6f8866ed907201b84bf26ff 100644 |
--- a/net/quic/quic_packet_creator.cc |
+++ b/net/quic/quic_packet_creator.cc |
@@ -11,7 +11,6 @@ |
#include "net/quic/crypto/quic_random.h" |
#include "net/quic/quic_bug_tracker.h" |
#include "net/quic/quic_data_writer.h" |
-#include "net/quic/quic_fec_group.h" |
#include "net/quic/quic_flags.h" |
#include "net/quic/quic_utils.h" |
@@ -24,29 +23,6 @@ using std::vector; |
namespace net { |
-namespace { |
- |
-// Default max packets in an FEC group. |
-static const size_t kDefaultMaxPacketsPerFecGroup = 10; |
-// Lowest max packets in an FEC group. |
-static const size_t kLowestMaxPacketsPerFecGroup = 2; |
- |
-// We want to put some space between a protected packet and the FEC packet to |
-// avoid losing them both within the same loss episode. On the other hand, we |
-// expect to be able to recover from any loss in about an RTT. We resolve this |
-// tradeoff by sending an FEC packet atmost half an RTT, or equivalently, half |
-// the max number of in-flight packets, the first protected packet. Since we |
-// don't want to delay an FEC packet past half an RTT, we set the max FEC group |
-// size to be half the current congestion window. |
-const float kMaxPacketsInFlightMultiplierForFecGroupSize = 0.5; |
-const float kRttMultiplierForFecTimeout = 0.5; |
- |
-// Minimum timeout for FEC alarm, set to half the minimum Tail Loss Probe |
-// timeout of 10ms. |
-const int64_t kMinFecTimeoutMs = 5u; |
- |
-} // namespace |
- |
// A QuicRandom wrapper that gets a bucket of entropy and distributes it |
// bit-by-bit. Replenishes the bucket as needed. Not thread-safe. Expose this |
// class if single bit randomness is needed elsewhere. |
@@ -104,13 +80,7 @@ QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id, |
0, |
0, |
false, |
- false), |
- should_fec_protect_next_packet_(false), |
- fec_protect_(false), |
- max_packets_per_fec_group_(kDefaultMaxPacketsPerFecGroup), |
- fec_send_policy_(FEC_ANY_TRIGGER), |
- fec_timeout_(QuicTime::Delta::Zero()), |
- rtt_multiplier_for_fec_timeout_(kRttMultiplierForFecTimeout) { |
+ false) { |
SetMaxPacketLength(kDefaultMaxPacketSize); |
} |
@@ -118,15 +88,6 @@ QuicPacketCreator::~QuicPacketCreator() { |
QuicUtils::DeleteFrames(&packet_.retransmittable_frames); |
} |
-void QuicPacketCreator::OnBuiltFecProtectedPayload( |
- const QuicPacketHeader& header, |
- StringPiece payload) { |
- if (fec_group_.get() != nullptr) { |
- DCHECK_NE(0u, header.fec_group); |
- fec_group_->Update(packet_.encryption_level, header, payload); |
- } |
-} |
- |
void QuicPacketCreator::SetEncrypter(EncryptionLevel level, |
QuicEncrypter* encrypter) { |
framer_->SetEncrypter(level, encrypter); |
@@ -134,8 +95,8 @@ void QuicPacketCreator::SetEncrypter(EncryptionLevel level, |
} |
bool QuicPacketCreator::CanSetMaxPacketLength() const { |
- // |max_packet_length_| should not be changed mid-packet or mid-FEC group. |
- return fec_group_.get() == nullptr && queued_frames_.empty(); |
+ // |max_packet_length_| should not be changed mid-packet. |
+ return queued_frames_.empty(); |
} |
void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) { |
@@ -151,81 +112,14 @@ void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) { |
max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_); |
} |
-void QuicPacketCreator::set_max_packets_per_fec_group( |
- size_t max_packets_per_fec_group) { |
- max_packets_per_fec_group_ = |
- max(kLowestMaxPacketsPerFecGroup, max_packets_per_fec_group); |
- DCHECK_LT(0u, max_packets_per_fec_group_); |
-} |
- |
-bool QuicPacketCreator::ShouldSendFec(bool force_close) const { |
- return !HasPendingFrames() && fec_group_.get() != nullptr && |
- fec_group_->NumReceivedPackets() > 0 && |
- (force_close || |
- fec_group_->NumReceivedPackets() >= max_packets_per_fec_group_); |
-} |
- |
-void QuicPacketCreator::ResetFecGroup() { |
- if (HasPendingFrames()) { |
- QUIC_BUG_IF(packet_size_ != 0) |
- << "Cannot reset FEC group with pending frames."; |
- return; |
- } |
- fec_group_.reset(nullptr); |
-} |
- |
-bool QuicPacketCreator::IsFecGroupOpen() const { |
- return fec_group_.get() != nullptr; |
-} |
- |
-void QuicPacketCreator::StartFecProtectingPackets() { |
- if (max_packets_per_fec_group_ == 0) { |
- QUIC_BUG << "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()) { |
- QUIC_BUG << "Cannot start FEC protection with pending frames."; |
- return; |
- } |
- DCHECK(!fec_protect_); |
- fec_protect_ = true; |
-} |
- |
-void QuicPacketCreator::StopFecProtectingPackets() { |
- if (fec_group_.get() != nullptr) { |
- QUIC_BUG << "Cannot stop FEC protection with open FEC group."; |
- return; |
- } |
- DCHECK(fec_protect_); |
- fec_protect_ = false; |
-} |
- |
-InFecGroup QuicPacketCreator::MaybeUpdateLengthsAndStartFec() { |
- if (fec_group_.get() != nullptr) { |
- // 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; |
- } |
+void QuicPacketCreator::MaybeUpdatePacketNumberLength() { |
if (!queued_frames_.empty()) { |
// Don't change creator state if there are frames queued. |
- return NOT_IN_FEC_GROUP; |
+ return; |
} |
- // Update packet number length only on packet and FEC group boundaries. |
+ // Update packet number length only on packet boundary. |
packet_.packet_number_length = next_packet_number_length_; |
- |
- if (!fec_protect_) { |
- return NOT_IN_FEC_GROUP; |
- } |
- // Start a new FEC group since protection is on. Set the fec group number to |
- // the packet number of the next packet. |
- fec_group_.reset(new QuicFecGroup(packet_.packet_number + 1)); |
- return IN_FEC_GROUP; |
} |
// Stops serializing version of the protocol in packets sent after this call. |
@@ -244,11 +138,8 @@ void QuicPacketCreator::UpdatePacketNumberLength( |
QuicPacketNumber least_packet_awaited_by_peer, |
QuicPacketCount max_packets_in_flight) { |
DCHECK_LE(least_packet_awaited_by_peer, packet_.packet_number + 1); |
- // Since the packet creator will not change packet number length mid FEC |
- // group, include the size of an FEC group to be safe. |
- const QuicPacketNumber current_delta = max_packets_per_fec_group_ + |
- packet_.packet_number + 1 - |
- least_packet_awaited_by_peer; |
+ const QuicPacketNumber current_delta = |
+ packet_.packet_number + 1 - least_packet_awaited_by_peer; |
const uint64_t delta = max(current_delta, max_packets_in_flight); |
next_packet_number_length_ = |
QuicFramer::GetMinSequenceNumberLength(delta * 4); |
@@ -260,15 +151,10 @@ bool QuicPacketCreator::ConsumeData(QuicStreamId id, |
QuicStreamOffset offset, |
bool fin, |
bool needs_padding, |
- QuicFrame* frame, |
- FecProtection fec_protection) { |
+ QuicFrame* frame) { |
if (!HasRoomForStreamFrame(id, offset)) { |
return false; |
} |
- if (fec_protection == MUST_FEC_PROTECT) { |
- should_fec_protect_next_packet_ = true; |
- MaybeStartFecProtection(); |
- } |
CreateStreamFrame(id, iov, iov_offset, offset, fin, frame); |
if (!AddFrame(*frame, /*save_retransmittable_frames=*/true)) { |
// Fails if we try to write unencrypted stream data. |
@@ -278,23 +164,13 @@ bool QuicPacketCreator::ConsumeData(QuicStreamId id, |
if (needs_padding) { |
packet_.needs_padding = true; |
} |
- if (fec_protection == MUST_FEC_PROTECT && |
- iov_offset + frame->stream_frame->frame_length == iov.total_length) { |
- // Turn off FEC protection when we're done writing protected data. |
- DVLOG(1) << "Turning FEC protection OFF"; |
- should_fec_protect_next_packet_ = false; |
- } |
return true; |
} |
bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id, |
QuicStreamOffset offset) { |
- // TODO(jri): This is a simple safe decision for now, but make |
- // is_in_fec_group a parameter. Same as with all public methods in |
- // QuicPacketCreator. |
return BytesFree() > |
- QuicFramer::GetMinStreamFrameSize( |
- id, offset, true, fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); |
+ QuicFramer::GetMinStreamFrameSize(id, offset, true, NOT_IN_FEC_GROUP); |
} |
// static |
@@ -323,12 +199,12 @@ size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, |
connection_id_length_, kIncludeVersion, kIncludePathId, |
PACKET_6BYTE_PACKET_NUMBER, offset, IN_FEC_GROUP)); |
- InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); |
+ MaybeUpdatePacketNumberLength(); |
LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset)) |
<< "No room for Stream frame, BytesFree: " << BytesFree() |
<< " MinStreamFrameSize: " |
- << QuicFramer::GetMinStreamFrameSize(id, offset, true, is_in_fec_group); |
+ << QuicFramer::GetMinStreamFrameSize(id, offset, true, NOT_IN_FEC_GROUP); |
if (iov_offset == iov.total_length) { |
QUIC_BUG_IF(!fin) << "Creating a stream frame with no data or fin."; |
@@ -339,7 +215,7 @@ size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, |
const size_t data_size = iov.total_length - iov_offset; |
size_t min_frame_size = QuicFramer::GetMinStreamFrameSize( |
- id, offset, /* last_frame_in_packet= */ true, is_in_fec_group); |
+ id, offset, /* last_frame_in_packet= */ true, NOT_IN_FEC_GROUP); |
size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size); |
bool set_fin = fin && bytes_consumed == data_size; // Last frame. |
@@ -409,20 +285,17 @@ void QuicPacketCreator::ReserializeAllFrames( |
char* buffer, |
size_t buffer_len) { |
DCHECK(queued_frames_.empty()); |
- DCHECK(fec_group_.get() == nullptr); |
DCHECK(!packet_.needs_padding); |
QUIC_BUG_IF(retransmission.retransmittable_frames.empty()) |
<< "Attempt to serialize empty packet"; |
const QuicPacketNumberLength saved_length = packet_.packet_number_length; |
const QuicPacketNumberLength saved_next_length = next_packet_number_length_; |
- const bool saved_should_fec_protect = fec_protect_; |
const EncryptionLevel default_encryption_level = packet_.encryption_level; |
// Temporarily set the packet number length, stop FEC protection, |
// and change the encryption level. |
packet_.packet_number_length = retransmission.packet_number_length; |
next_packet_number_length_ = retransmission.packet_number_length; |
- fec_protect_ = false; |
packet_.needs_padding = retransmission.needs_padding; |
// Only preserve the original encryption level if it's a handshake packet or |
// if we haven't gone forward secure. |
@@ -443,7 +316,6 @@ void QuicPacketCreator::ReserializeAllFrames( |
// Restore old values. |
packet_.packet_number_length = saved_length; |
next_packet_number_length_ = saved_next_length; |
- fec_protect_ = saved_should_fec_protect; |
packet_.encryption_level = default_encryption_level; |
} |
@@ -461,8 +333,7 @@ void QuicPacketCreator::Flush() { |
void QuicPacketCreator::OnSerializedPacket() { |
if (packet_.encrypted_buffer == nullptr) { |
- QUIC_BUG << "Failed to SerializePacket. fec_policy:" << fec_send_policy() |
- << " should_fec_protect_:" << should_fec_protect_next_packet_; |
+ QUIC_BUG << "Failed to SerializePacket."; |
delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET, |
ConnectionCloseSource::FROM_SELF); |
return; |
@@ -470,8 +341,6 @@ void QuicPacketCreator::OnSerializedPacket() { |
delegate_->OnSerializedPacket(&packet_); |
ClearPacket(); |
- MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/false, |
- /*is_fec_timeout=*/false); |
// Maximum packet size may be only enacted while no packet is currently being |
// constructed, so here we have a good opportunity to actually change it. |
if (CanSetMaxPacketLength()) { |
@@ -502,10 +371,6 @@ bool QuicPacketCreator::HasPendingRetransmittableFrames() const { |
} |
size_t QuicPacketCreator::ExpansionOnNewFrame() const { |
- // If packet is FEC protected, there's no expansion. |
- if (fec_protect_) { |
- return 0; |
- } |
// If the last frame in the packet is a stream frame, then it will expand to |
// include the stream_length field when a new frame is added. |
bool has_trailing_stream_frame = |
@@ -523,14 +388,11 @@ size_t QuicPacketCreator::PacketSize() { |
if (!queued_frames_.empty()) { |
return packet_size_; |
} |
- if (fec_group_.get() == nullptr) { |
- // Update packet number length on packet and FEC boundary. |
- packet_.packet_number_length = next_packet_number_length_; |
- } |
- packet_size_ = |
- GetPacketHeaderSize(connection_id_length_, send_version_in_packet_, |
- send_path_id_in_packet_, packet_.packet_number_length, |
- fec_protect_ ? IN_FEC_GROUP : NOT_IN_FEC_GROUP); |
+ // Update packet number length on packet boundary. |
+ packet_.packet_number_length = next_packet_number_length_; |
+ packet_size_ = GetPacketHeaderSize( |
+ connection_id_length_, send_version_in_packet_, send_path_id_in_packet_, |
+ packet_.packet_number_length, NOT_IN_FEC_GROUP); |
return packet_size_; |
} |
@@ -556,13 +418,9 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer, |
size_t encrypted_buffer_len) { |
DCHECK_LT(0u, encrypted_buffer_len); |
QUIC_BUG_IF(queued_frames_.empty()) << "Attempt to serialize empty packet"; |
- if (fec_group_.get() != nullptr) { |
- DCHECK_GE(packet_.packet_number + 1, fec_group_->FecGroupNumber()); |
- } |
QuicPacketHeader header; |
// FillPacketHeader increments packet_number_. |
- FillPacketHeader(fec_group_ != nullptr ? fec_group_->FecGroupNumber() : 0, |
- false, &header); |
+ FillPacketHeader(&header); |
MaybeAddPadding(); |
@@ -590,7 +448,6 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer, |
/* owns_buffer */ false, header.public_header.connection_id_length, |
header.public_header.version_flag, header.public_header.multipath_flag, |
header.public_header.packet_number_length); |
- OnBuiltFecProtectedPayload(header, packet.FecProtectedData()); |
// Because of possible truncation, we can't be confident that our |
// packet size calculation worked correctly. |
@@ -614,44 +471,6 @@ void QuicPacketCreator::SerializePacket(char* encrypted_buffer, |
packet_.encrypted_length = encrypted_length; |
} |
-void QuicPacketCreator::SerializeFec(char* buffer, size_t buffer_len) { |
- DCHECK_LT(0u, buffer_len); |
- if (fec_group_.get() == nullptr || fec_group_->NumReceivedPackets() <= 0) { |
- QUIC_BUG << "SerializeFEC called but no group or zero packets in group."; |
- return; |
- } |
- if (FLAGS_quic_no_unencrypted_fec && |
- packet_.encryption_level == ENCRYPTION_NONE) { |
- QUIC_BUG << "SerializeFEC must be called with encryption."; |
- delegate_->OnUnrecoverableError(QUIC_UNENCRYPTED_FEC_DATA, |
- ConnectionCloseSource::FROM_SELF); |
- return; |
- } |
- DCHECK_EQ(0u, queued_frames_.size()); |
- QuicPacketHeader header; |
- FillPacketHeader(fec_group_->FecGroupNumber(), true, &header); |
- scoped_ptr<QuicPacket> packet( |
- framer_->BuildFecPacket(header, fec_group_->PayloadParity())); |
- fec_group_.reset(nullptr); |
- packet_size_ = 0; |
- QUIC_BUG_IF(packet == nullptr) << "Failed to serialize fec packet for group:" |
- << fec_group_->FecGroupNumber(); |
- DCHECK_GE(max_packet_length_, packet->length()); |
- // Immediately encrypt the packet, to ensure we don't encrypt the same packet |
- // packet number multiple times. |
- size_t encrypted_length = framer_->EncryptPayload( |
- packet_.encryption_level, packet_.path_id, packet_.packet_number, *packet, |
- buffer, buffer_len); |
- if (encrypted_length == 0) { |
- QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number; |
- return; |
- } |
- packet_.entropy_hash = QuicFramer::GetPacketEntropyHash(header); |
- packet_.encrypted_buffer = buffer; |
- packet_.encrypted_length = encrypted_length; |
- packet_.is_fec_packet = true; |
-} |
- |
QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket( |
const QuicVersionVector& supported_versions) { |
DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective()); |
@@ -668,21 +487,19 @@ SerializedPacket QuicPacketCreator::NoPacket() { |
nullptr, 0, 0, false, false); |
} |
-void QuicPacketCreator::FillPacketHeader(QuicFecGroupNumber fec_group, |
- bool fec_flag, |
- QuicPacketHeader* header) { |
+void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) { |
header->public_header.connection_id = connection_id_; |
header->public_header.connection_id_length = connection_id_length_; |
header->public_header.multipath_flag = send_path_id_in_packet_; |
header->public_header.reset_flag = false; |
header->public_header.version_flag = send_version_in_packet_; |
- header->fec_flag = fec_flag; |
+ header->fec_flag = false; |
header->path_id = packet_.path_id; |
header->packet_number = ++packet_.packet_number; |
header->public_header.packet_number_length = packet_.packet_number_length; |
header->entropy_flag = random_bool_source_->RandBool(); |
- header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; |
- header->fec_group = fec_group; |
+ header->is_in_fec_group = NOT_IN_FEC_GROUP; |
+ header->fec_group = 0; |
} |
bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) { |
@@ -708,10 +525,10 @@ bool QuicPacketCreator::AddFrame(const QuicFrame& frame, |
ConnectionCloseSource::FROM_SELF); |
return false; |
} |
- InFecGroup is_in_fec_group = MaybeUpdateLengthsAndStartFec(); |
+ MaybeUpdatePacketNumberLength(); |
size_t frame_len = framer_->GetSerializedFrameLength( |
- frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, |
+ frame, BytesFree(), queued_frames_.empty(), true, NOT_IN_FEC_GROUP, |
packet_.packet_number_length); |
if (frame_len == 0) { |
// Current open packet is full. |
@@ -762,64 +579,6 @@ void QuicPacketCreator::MaybeAddPadding() { |
DCHECK(success); |
} |
-void QuicPacketCreator::MaybeStartFecProtection() { |
- if (max_packets_per_fec_group_ == 0 || fec_protect_) { |
- // Do not start FEC protection when FEC protection is not enabled or FEC |
- // protection is already on. |
- return; |
- } |
- DVLOG(1) << "Turning FEC protection ON"; |
- // Flush current open packet. |
- Flush(); |
- |
- StartFecProtectingPackets(); |
- DCHECK(fec_protect_); |
-} |
- |
-void QuicPacketCreator::MaybeSendFecPacketAndCloseGroup(bool force_send_fec, |
- bool is_fec_timeout) { |
- if (ShouldSendFec(force_send_fec)) { |
- if ((FLAGS_quic_no_unencrypted_fec && |
- packet_.encryption_level == ENCRYPTION_NONE) || |
- (fec_send_policy_ == FEC_ALARM_TRIGGER && !is_fec_timeout)) { |
- ResetFecGroup(); |
- delegate_->OnResetFecGroup(); |
- } else { |
- // TODO(zhongyi): Change the default 64 alignas value (used the default |
- // value from CACHELINE_SIZE). |
- ALIGNAS(64) char seralized_fec_buffer[kMaxPacketSize]; |
- SerializeFec(seralized_fec_buffer, kMaxPacketSize); |
- OnSerializedPacket(); |
- } |
- } |
- |
- if (!should_fec_protect_next_packet_ && fec_protect_ && !IsFecGroupOpen()) { |
- StopFecProtectingPackets(); |
- } |
-} |
- |
-QuicTime::Delta QuicPacketCreator::GetFecTimeout( |
- QuicPacketNumber packet_number) { |
- // Do not set up FEC alarm for |packet_number| it is not the first packet in |
- // the current group. |
- if (fec_group_.get() != nullptr && |
- (packet_number == fec_group_->FecGroupNumber())) { |
- return QuicTime::Delta::Max( |
- fec_timeout_, QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs)); |
- } |
- return QuicTime::Delta::Infinite(); |
-} |
- |
-void QuicPacketCreator::OnCongestionWindowChange( |
- QuicPacketCount max_packets_in_flight) { |
- set_max_packets_per_fec_group(static_cast<size_t>( |
- kMaxPacketsInFlightMultiplierForFecGroupSize * max_packets_in_flight)); |
-} |
- |
-void QuicPacketCreator::OnRttChange(QuicTime::Delta rtt) { |
- fec_timeout_ = rtt.Multiply(rtt_multiplier_for_fec_timeout_); |
-} |
- |
void QuicPacketCreator::SetCurrentPath( |
QuicPathId path_id, |
QuicPacketNumber least_packet_awaited_by_peer, |
@@ -832,10 +591,6 @@ void QuicPacketCreator::SetCurrentPath( |
QUIC_BUG << "Unable to change paths when a packet is under construction."; |
return; |
} |
- |
- // Send FEC packet and close FEC group. |
- MaybeSendFecPacketAndCloseGroup(/*force_send_fec=*/true, |
- /*is_fec_timeout=*/false); |
// Save current packet number and load switching path's packet number. |
multipath_packet_number_[packet_.path_id] = packet_.packet_number; |
std::unordered_map<QuicPathId, QuicPacketNumber>::iterator it = |