Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(208)

Unified Diff: net/quic/quic_packet_creator.cc

Issue 1784903003: Remove FEC from send path. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@114770052
Patch Set: Restore accidentally removed OnRttChanged call Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/quic/quic_packet_creator.h ('k') | net/quic/quic_packet_creator_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 =
« no previous file with comments | « net/quic/quic_packet_creator.h ('k') | net/quic/quic_packet_creator_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698