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

Unified Diff: net/quic/quic_packet_generator.cc

Issue 862133002: Update from https://crrev.com/312398 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 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
Index: net/quic/quic_packet_generator.cc
diff --git a/net/quic/quic_packet_generator.cc b/net/quic/quic_packet_generator.cc
index a7f0af08ade11a8577f4d79ce4ca5ddd1f1f281e..22bf530d1949058e1c0f536f7177b92ce7a9f711 100644
--- a/net/quic/quic_packet_generator.cc
+++ b/net/quic/quic_packet_generator.cc
@@ -18,15 +18,19 @@ namespace net {
namespace {
// 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.
+// 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 kMinFecTimeoutMs = 5u;
+
} // namespace
class QuicAckNotifier;
@@ -42,7 +46,6 @@ QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id,
fec_timeout_(QuicTime::Delta::Zero()),
should_fec_protect_(false),
should_send_ack_(false),
- should_send_feedback_(false),
should_send_stop_waiting_(false) {
}
@@ -59,9 +62,6 @@ QuicPacketGenerator::~QuicPacketGenerator() {
case ACK_FRAME:
delete it->ack_frame;
break;
- case CONGESTION_FEEDBACK_FRAME:
- delete it->congestion_feedback_frame;
- break;
case RST_STREAM_FRAME:
delete it->rst_stream_frame;
break;
@@ -100,27 +100,18 @@ void QuicPacketGenerator::OnRttChange(QuicTime::Delta rtt) {
fec_timeout_ = rtt.Multiply(kRttMultiplierForFecTimeout);
}
-void QuicPacketGenerator::SetShouldSendAck(bool also_send_feedback,
- bool also_send_stop_waiting) {
- if (FLAGS_quic_disallow_multiple_pending_ack_frames) {
- if (pending_ack_frame_ != nullptr) {
- // Ack already queued, nothing to do.
- return;
- }
-
- if (also_send_feedback && pending_feedback_frame_ != nullptr) {
- LOG(DFATAL) << "Should only ever be one pending feedback frame.";
- return;
- }
+void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) {
+ if (pending_ack_frame_ != nullptr) {
+ // Ack already queued, nothing to do.
+ return;
+ }
- if (also_send_stop_waiting && pending_stop_waiting_frame_ != nullptr) {
- LOG(DFATAL) << "Should only ever be one pending stop waiting frame.";
- return;
- }
+ if (also_send_stop_waiting && pending_stop_waiting_frame_ != nullptr) {
+ LOG(DFATAL) << "Should only ever be one pending stop waiting frame.";
+ return;
}
should_send_ack_ = true;
- should_send_feedback_ = also_send_feedback;
should_send_stop_waiting_ = also_send_stop_waiting;
SendQueuedFrames(false);
}
@@ -142,11 +133,11 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(
bool fin,
FecProtection fec_protection,
QuicAckNotifier::DelegateInterface* delegate) {
- IsHandshake handshake = id == kCryptoStreamId ? IS_HANDSHAKE : NOT_HANDSHAKE;
+ bool has_handshake = id == kCryptoStreamId;
// To make reasoning about crypto frames easier, we don't combine them with
// other retransmittable frames in a single packet.
- const bool flush = handshake == IS_HANDSHAKE &&
- packet_creator_.HasPendingRetransmittableFrames();
+ const bool flush =
+ has_handshake && packet_creator_.HasPendingRetransmittableFrames();
SendQueuedFrames(flush);
size_t total_bytes_consumed = 0;
@@ -169,14 +160,15 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(
IOVector data = data_to_write;
size_t data_size = data.TotalBufferSize();
- if (FLAGS_quic_empty_data_no_fin_early_return && !fin && (data_size == 0)) {
+ if (!fin && (data_size == 0)) {
LOG(DFATAL) << "Attempt to consume empty data without FIN.";
return QuicConsumedData(0, false);
}
int frames_created = 0;
- while (delegate_->ShouldGeneratePacket(NOT_RETRANSMISSION,
- HAS_RETRANSMITTABLE_DATA, handshake)) {
+ while (delegate_->ShouldGeneratePacket(
+ NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA,
+ has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) {
QuicFrame frame;
size_t bytes_consumed = packet_creator_.CreateStreamFrame(
id, data, offset + total_bytes_consumed, fin, &frame);
@@ -229,16 +221,13 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(
}
// Don't allow the handshake to be bundled with other retransmittable frames.
- if (handshake == IS_HANDSHAKE) {
+ if (has_handshake) {
SendQueuedFrames(true);
}
// Try to close FEC group since we've either run out of data to send or we're
// blocked. If not in batch mode, force close the group.
- // TODO(jri): This method should be called with flush=false here
- // once the timer-based FEC sending is done, to separate FEC sending from
- // the end of batch operations.
- MaybeSendFecPacketAndCloseGroup(!InBatchMode());
+ MaybeSendFecPacketAndCloseGroup(/*flush=*/false);
DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames());
return QuicConsumedData(total_bytes_consumed, fin_consumed);
@@ -247,8 +236,9 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(
bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
DCHECK(HasPendingFrames());
HasRetransmittableData retransmittable =
- (should_send_ack_ || should_send_feedback_ || should_send_stop_waiting_)
- ? NO_RETRANSMITTABLE_DATA : HAS_RETRANSMITTABLE_DATA;
+ (should_send_ack_ || should_send_stop_waiting_)
+ ? NO_RETRANSMITTABLE_DATA
+ : HAS_RETRANSMITTABLE_DATA;
if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
DCHECK(!queued_control_frames_.empty()); // These are retransmittable.
}
@@ -265,15 +255,10 @@ void QuicPacketGenerator::SendQueuedFrames(bool flush) {
SerializeAndSendPacket();
}
}
-
- if (!InBatchMode() || flush) {
- if (packet_creator_.HasPendingFrames()) {
- SerializeAndSendPacket();
- }
- // Ensure the FEC group is closed at the end of this method unless other
- // writes are pending.
- MaybeSendFecPacketAndCloseGroup(true);
+ if (packet_creator_.HasPendingFrames() && (flush || !InBatchMode())) {
+ SerializeAndSendPacket();
}
+ MaybeSendFecPacketAndCloseGroup(flush);
}
void QuicPacketGenerator::MaybeStartFecProtection() {
@@ -299,9 +284,7 @@ void QuicPacketGenerator::MaybeStartFecProtection() {
}
void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force) {
- if (!packet_creator_.IsFecProtected() ||
- packet_creator_.HasPendingFrames() ||
- !packet_creator_.ShouldSendFec(force)) {
+ if (!ShouldSendFecPacket(force)) {
return;
}
// TODO(jri): SerializeFec can return a NULL packet, and this should
@@ -319,6 +302,36 @@ void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force) {
}
}
+bool QuicPacketGenerator::ShouldSendFecPacket(bool force) {
+ return packet_creator_.IsFecProtected() &&
+ !packet_creator_.HasPendingFrames() &&
+ packet_creator_.ShouldSendFec(force);
+}
+
+void QuicPacketGenerator::OnFecTimeout() {
+ DCHECK(!InBatchMode());
+ if (!ShouldSendFecPacket(true)) {
+ LOG(DFATAL) << "No FEC packet to send on FEC timeout.";
+ return;
+ }
+ // Flush out any pending frames in the generator and the creator, and then
+ // send out FEC packet.
+ SendQueuedFrames(true);
+ MaybeSendFecPacketAndCloseGroup(/*flush=*/true);
+}
+
+QuicTime::Delta QuicPacketGenerator::GetFecTimeout(
+ QuicPacketSequenceNumber sequence_number) {
+ // Do not set up FEC alarm for |sequence_number| it is not the first packet in
+ // the current group.
+ if (packet_creator_.IsFecGroupOpen() &&
+ (sequence_number == packet_creator_.fec_group_number())) {
+ return QuicTime::Delta::Max(
+ fec_timeout_, QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs));
+ }
+ return QuicTime::Delta::Infinite();
+}
+
bool QuicPacketGenerator::InBatchMode() {
return batch_mode_;
}
@@ -341,8 +354,8 @@ bool QuicPacketGenerator::HasQueuedFrames() const {
}
bool QuicPacketGenerator::HasPendingFrames() const {
- return should_send_ack_ || should_send_feedback_ ||
- should_send_stop_waiting_ || !queued_control_frames_.empty();
+ return should_send_ack_ || should_send_stop_waiting_ ||
+ !queued_control_frames_.empty();
}
bool QuicPacketGenerator::AddNextPendingFrame() {
@@ -355,15 +368,6 @@ bool QuicPacketGenerator::AddNextPendingFrame() {
return !should_send_ack_;
}
- if (should_send_feedback_) {
- pending_feedback_frame_.reset(delegate_->CreateFeedbackFrame());
- // If we can't this add the frame now, then we still need to do so later.
- should_send_feedback_ = !AddFrame(QuicFrame(pending_feedback_frame_.get()));
- // Return success if we have cleared out this flag (i.e., added the frame).
- // If we still need to send, then the frame is full, and we have failed.
- return !should_send_feedback_;
- }
-
if (should_send_stop_waiting_) {
pending_stop_waiting_frame_.reset(delegate_->CreateStopWaitingFrame());
// If we can't this add the frame now, then we still need to do so later.
@@ -403,14 +407,11 @@ void QuicPacketGenerator::SerializeAndSendPacket() {
}
delegate_->OnSerializedPacket(serialized_packet);
- MaybeSendFecPacketAndCloseGroup(false);
+ MaybeSendFecPacketAndCloseGroup(/*flush=*/false);
// The packet has now been serialized, safe to delete pending frames.
- if (FLAGS_quic_disallow_multiple_pending_ack_frames) {
- pending_ack_frame_.reset();
- pending_feedback_frame_.reset();
- pending_stop_waiting_frame_.reset();
- }
+ pending_ack_frame_.reset();
+ pending_stop_waiting_frame_.reset();
}
void QuicPacketGenerator::StopSendingVersion() {

Powered by Google App Engine
This is Rietveld 408576698