Skip to content

Commit

Permalink
Land Recent QUIC Changes.
Browse files Browse the repository at this point in the history
QUIC - fixing lint errors found while sync'ing with server.

Merge internal change: 56944792

Fix a QUIC bug where the congestion manager was telling the send
algorithm of a loss once one nack was received, but only retransmitted
when 3 were received.

Merge internal change: 56922588

Enables pacing of QUIC packets, via a new flag.  If set, the client
will always use pacing, however, the server will only pace if the
client negotiates pacing.  This allows us to use finch to control the
behavior so we can analyze the performance impact.

Adds a new FLAGS_use_quic_pacing to enable pacing of QUIC packets.
It defaults to false.

Merge internal change: 56869575

Move QUIC's rto count from the connection to the congestion manager.

Merge internal change: 56787945

Use the packet size of CHLO packets to set the QUIC max_packet_size for
the server.

Merge internal change: 56758103

Move QUIC's nack counter into QuicCongestionManager from
QuicSentPacketManager.

Merge internal change: 56746459

Only retransmit the minimum number of packets in QUIC(in TCP's case, 2)
when the RTO fires, instead of retransmitting the entire window.

Based on conversations with Jana, it appears we should be reducing our
congestion window, and the most important mitigation may be implementing
a tail loss probe.

Merge internal change: 56693737

QUIC - minor cleanup of code (lint errors), found while merging.

R=rch@chromium.org

Review URL: https://codereview.chromium.org/77613002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@236311 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
rtenneti@chromium.org committed Nov 20, 2013
1 parent 1cefd4b commit 622f947
Show file tree
Hide file tree
Showing 35 changed files with 767 additions and 434 deletions.
9 changes: 7 additions & 2 deletions net/quic/congestion_control/fix_rate_sender.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ FixRateSender::~FixRateSender() {
}

void FixRateSender::SetFromConfig(const QuicConfig& config, bool is_server) {
max_segment_size_ = config.server_max_packet_size();
}

void FixRateSender::SetMaxPacketSize(QuicByteCount max_packet_size) {
max_segment_size_ = max_packet_size;
paced_sender_.set_max_segment_size(max_segment_size_);
}

Expand Down Expand Up @@ -65,7 +68,7 @@ void FixRateSender::OnIncomingAck(
latest_rtt_ = rtt;
}

void FixRateSender::OnIncomingLoss(QuicPacketSequenceNumber /*largest_loss*/,
void FixRateSender::OnIncomingLoss(QuicPacketSequenceNumber /*sequence_number*/,
QuicTime /*ack_receive_time*/) {
// Ignore losses for fix rate sender.
}
Expand All @@ -84,6 +87,8 @@ bool FixRateSender::OnPacketSent(
return true;
}

void FixRateSender::OnRetransmissionTimeout() { }

void FixRateSender::OnPacketAbandoned(
QuicPacketSequenceNumber /*sequence_number*/,
QuicByteCount /*abandoned_bytes*/) {
Expand Down
9 changes: 5 additions & 4 deletions net/quic/congestion_control/fix_rate_sender.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,25 @@ class NET_EXPORT_PRIVATE FixRateSender : public SendAlgorithmInterface {
explicit FixRateSender(const QuicClock* clock);
virtual ~FixRateSender();

virtual void SetFromConfig(const QuicConfig& config, bool is_server) OVERRIDE;

// Start implementation of SendAlgorithmInterface.
virtual void SetFromConfig(const QuicConfig& config, bool is_server) OVERRIDE;
virtual void SetMaxPacketSize(QuicByteCount max_packet_size) OVERRIDE;
virtual void OnIncomingQuicCongestionFeedbackFrame(
const QuicCongestionFeedbackFrame& feedback,
QuicTime feedback_receive_time,
const SentPacketsMap& sent_packets) OVERRIDE;
virtual void OnIncomingAck(QuicPacketSequenceNumber acked_sequence_number,
QuicByteCount acked_bytes,
QuicTime::Delta rtt) OVERRIDE;
virtual void OnIncomingLoss(QuicPacketSequenceNumber largest_loss,
virtual void OnIncomingLoss(QuicPacketSequenceNumber sequence_number,
QuicTime ack_receive_time) OVERRIDE;
virtual bool OnPacketSent(
QuicTime sent_time,
QuicPacketSequenceNumber equence_number,
QuicPacketSequenceNumber sequence_number,
QuicByteCount bytes,
TransmissionType transmission_type,
HasRetransmittableData has_retransmittable_data) OVERRIDE;
virtual void OnRetransmissionTimeout() OVERRIDE;
virtual void OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
QuicByteCount abandoned_bytes) OVERRIDE;
virtual QuicTime::Delta TimeUntilSend(
Expand Down
21 changes: 14 additions & 7 deletions net/quic/congestion_control/inter_arrival_sender.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ InterArrivalSender::~InterArrivalSender() {

void InterArrivalSender::SetFromConfig(const QuicConfig& config,
bool is_server) {
max_segment_size_ = config.server_max_packet_size();
}

void InterArrivalSender::SetMaxPacketSize(QuicByteCount max_packet_size) {
max_segment_size_ = max_packet_size;
paced_sender_->set_max_segment_size(max_segment_size_);
probe_->set_max_segment_size(max_segment_size_);
}
Expand All @@ -70,11 +73,11 @@ QuicBandwidth InterArrivalSender::CalculateSentBandwidth(
QuicTime::Delta max_diff = QuicTime::Delta::Zero();
for (; history_rit != sent_packets_map.rend(); ++history_rit) {
QuicTime::Delta diff =
feedback_receive_time.Subtract(history_rit->second->SendTimestamp());
feedback_receive_time.Subtract(history_rit->second->send_timestamp());
if (diff > kBitrateSmoothingPeriod) {
break;
}
sum_bytes_sent += history_rit->second->BytesSent();
sum_bytes_sent += history_rit->second->bytes_sent();
max_diff = diff;
}
if (max_diff < kMinBitrateSmoothingPeriod) {
Expand Down Expand Up @@ -111,8 +114,8 @@ void InterArrivalSender::OnIncomingQuicCongestionFeedbackFrame(
continue;
}
QuicTime time_received = received_it->second;
QuicTime time_sent = sent_it->second->SendTimestamp();
QuicByteCount bytes_sent = sent_it->second->BytesSent();
QuicTime time_sent = sent_it->second->send_timestamp();
QuicByteCount bytes_sent = sent_it->second->bytes_sent();

channel_estimator_->OnAcknowledgedPacket(
sequence_number, bytes_sent, time_sent, time_received);
Expand All @@ -126,7 +129,7 @@ void InterArrivalSender::OnIncomingQuicCongestionFeedbackFrame(
// No more sent packets; hence this must be the last.
last_of_send_time = true;
} else {
if (time_sent != next_sent_it->second->SendTimestamp()) {
if (time_sent != next_sent_it->second->send_timestamp()) {
// Next sent packet have a different send time.
last_of_send_time = true;
}
Expand Down Expand Up @@ -232,7 +235,7 @@ void InterArrivalSender::OnIncomingAck(
}

void InterArrivalSender::OnIncomingLoss(
QuicPacketSequenceNumber /*largest_loss*/,
QuicPacketSequenceNumber /*sequence_number*/,
QuicTime ack_receive_time) {
// Packet loss was reported.
if (!probing_) {
Expand All @@ -258,6 +261,10 @@ bool InterArrivalSender::OnPacketSent(
return true;
}

void InterArrivalSender::OnRetransmissionTimeout() {
// TODO(ianswett): Decrease the available bandwidth.
}

void InterArrivalSender::OnPacketAbandoned(
QuicPacketSequenceNumber /*sequence_number*/,
QuicByteCount abandoned_bytes) {
Expand Down
13 changes: 4 additions & 9 deletions net/quic/congestion_control/inter_arrival_sender.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,41 +27,36 @@ class NET_EXPORT_PRIVATE InterArrivalSender : public SendAlgorithmInterface {
explicit InterArrivalSender(const QuicClock* clock);
virtual ~InterArrivalSender();

virtual void SetFromConfig(const QuicConfig& config, bool is_server) OVERRIDE;

static QuicBandwidth CalculateSentBandwidth(
const SendAlgorithmInterface::SentPacketsMap& sent_packets_map,
QuicTime feedback_receive_time);

// Start implementation of SendAlgorithmInterface.
virtual void SetFromConfig(const QuicConfig& config, bool is_server) OVERRIDE;
virtual void SetMaxPacketSize(QuicByteCount max_packet_size) OVERRIDE;
virtual void OnIncomingQuicCongestionFeedbackFrame(
const QuicCongestionFeedbackFrame& feedback,
QuicTime feedback_receive_time,
const SentPacketsMap& sent_packets) OVERRIDE;

virtual void OnIncomingAck(QuicPacketSequenceNumber acked_sequence_number,
QuicByteCount acked_bytes,
QuicTime::Delta rtt) OVERRIDE;

virtual void OnIncomingLoss(QuicPacketSequenceNumber largest_loss,
virtual void OnIncomingLoss(QuicPacketSequenceNumber sequence_number,
QuicTime ack_receive_time) OVERRIDE;

virtual bool OnPacketSent(
QuicTime sent_time,
QuicPacketSequenceNumber sequence_number,
QuicByteCount bytes,
TransmissionType transmission_type,
HasRetransmittableData has_retransmittable_data) OVERRIDE;

virtual void OnRetransmissionTimeout() OVERRIDE;
virtual void OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
QuicByteCount abandoned_bytes) OVERRIDE;

virtual QuicTime::Delta TimeUntilSend(
QuicTime now,
TransmissionType transmission_type,
HasRetransmittableData has_retransmittable_data,
IsHandshake handshake) OVERRIDE;

virtual QuicBandwidth BandwidthEstimate() const OVERRIDE;
virtual QuicTime::Delta SmoothedRtt() const OVERRIDE;
virtual QuicTime::Delta RetransmissionDelay() const OVERRIDE;
Expand Down
2 changes: 1 addition & 1 deletion net/quic/congestion_control/inter_arrival_sender_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class InterArrivalSenderTest : public ::testing::Test {
QuicByteCount bytes_in_packet = kDefaultMaxPacketSize;
sent_packets_[sequence_number_] =
new class SendAlgorithmInterface::SentPacket(
bytes_in_packet, send_clock_.Now());
bytes_in_packet, send_clock_.Now(), HAS_RETRANSMITTABLE_DATA);

sender_.OnPacketSent(send_clock_.Now(), sequence_number_, bytes_in_packet,
NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
Expand Down
51 changes: 38 additions & 13 deletions net/quic/congestion_control/pacing_sender.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ PacingSender::PacingSender(SendAlgorithmInterface* sender,

PacingSender::~PacingSender() {}

void PacingSender::SetMaxPacketSize(QuicByteCount max_packet_size) {
max_segment_size_ = max_packet_size;
sender_->SetMaxPacketSize(max_packet_size);
}

void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) {
max_segment_size_ = config.server_max_packet_size();
sender_->SetFromConfig(config, is_server);
}

Expand All @@ -37,22 +41,34 @@ void PacingSender::OnIncomingAck(
sender_->OnIncomingAck(acked_sequence_number, acked_bytes, rtt);
}

void PacingSender::OnIncomingLoss(QuicPacketSequenceNumber largest_loss,
void PacingSender::OnIncomingLoss(QuicPacketSequenceNumber sequence_number,
QuicTime ack_receive_time) {
sender_->OnIncomingLoss(largest_loss, ack_receive_time);
sender_->OnIncomingLoss(sequence_number, ack_receive_time);
}

bool PacingSender::OnPacketSent(QuicTime sent_time,
QuicPacketSequenceNumber sequence_number,
QuicByteCount bytes,
TransmissionType transmission_type,
HasRetransmittableData is_retransmittable) {
// The next packet should be sent as soon as the current packets has
// been transferred.
next_packet_send_time_ =
next_packet_send_time_.Add(BandwidthEstimate().TransferTime(bytes));
bool PacingSender::OnPacketSent(
QuicTime sent_time,
QuicPacketSequenceNumber sequence_number,
QuicByteCount bytes,
TransmissionType transmission_type,
HasRetransmittableData has_retransmittable_data) {
// Only pace data packets.
if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA) {
// The next packet should be sent as soon as the current packets has
// been transferred. We pace at twice the rate of the underlying
// sender's bandwidth estimate to help ensure that pacing doesn't become
// a bottleneck.
const float kPacingAggression = 2;
QuicTime::Delta delay =
BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes);
next_packet_send_time_ = next_packet_send_time_.Add(delay);
}
return sender_->OnPacketSent(sent_time, sequence_number, bytes,
transmission_type, is_retransmittable);
transmission_type, has_retransmittable_data);
}

void PacingSender::OnRetransmissionTimeout() {
sender_->OnRetransmissionTimeout();
}

void PacingSender::OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
Expand All @@ -74,6 +90,12 @@ QuicTime::Delta PacingSender::TimeUntilSend(
return time_until_send;
}

if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
// Don't pace ACK packets, since they do not count against CWND and do not
// cause CWND to grow.
return QuicTime::Delta::Zero();
}

if (!was_last_send_delayed_ &&
(!next_packet_send_time_.IsInitialized() ||
now > next_packet_send_time_.Add(alarm_granularity_))) {
Expand All @@ -86,11 +108,14 @@ QuicTime::Delta PacingSender::TimeUntilSend(
// If the end of the epoch is far enough in the future, delay the send.
if (next_packet_send_time_ > now.Add(alarm_granularity_)) {
was_last_send_delayed_ = true;
DVLOG(1) << "Delaying packet: "
<< next_packet_send_time_.Subtract(now).ToMicroseconds();
return next_packet_send_time_.Subtract(now);
}

// Sent it immediately. The epoch end will be adjusted in OnPacketSent.
was_last_send_delayed_ = false;
DVLOG(1) << "Sending packet now";
return QuicTime::Delta::Zero();
}

Expand Down
4 changes: 3 additions & 1 deletion net/quic/congestion_control/pacing_sender.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,22 @@ class NET_EXPORT_PRIVATE PacingSender : public SendAlgorithmInterface {

// SendAlgorithmInterface methods.
virtual void SetFromConfig(const QuicConfig& config, bool is_server) OVERRIDE;
virtual void SetMaxPacketSize(QuicByteCount max_packet_size) OVERRIDE;
virtual void OnIncomingQuicCongestionFeedbackFrame(
const QuicCongestionFeedbackFrame& feedback,
QuicTime feedback_receive_time,
const SendAlgorithmInterface::SentPacketsMap& sent_packets) OVERRIDE;
virtual void OnIncomingAck(QuicPacketSequenceNumber acked_sequence_number,
QuicByteCount acked_bytes,
QuicTime::Delta rtt) OVERRIDE;
virtual void OnIncomingLoss(QuicPacketSequenceNumber largest_loss,
virtual void OnIncomingLoss(QuicPacketSequenceNumber sequence_number,
QuicTime ack_receive_time) OVERRIDE;
virtual bool OnPacketSent(QuicTime sent_time,
QuicPacketSequenceNumber sequence_number,
QuicByteCount bytes,
TransmissionType transmission_type,
HasRetransmittableData is_retransmittable) OVERRIDE;
virtual void OnRetransmissionTimeout() OVERRIDE;
virtual void OnPacketAbandoned(QuicPacketSequenceNumber sequence_number,
QuicByteCount abandoned_bytes) OVERRIDE;
virtual QuicTime::Delta TimeUntilSend(
Expand Down
29 changes: 27 additions & 2 deletions net/quic/congestion_control/pacing_sender_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,29 @@ class PacingSenderTest : public ::testing::Test {
HAS_RETRANSMITTABLE_DATA);
}

void CheckAckIsSentImmediately() {
// In order for the ack to be sendable, the underlying sender must
// permit it to be sent immediately.
EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(),
NOT_RETRANSMISSION,
NO_RETRANSMITTABLE_DATA,
NOT_HANDSHAKE))
.WillOnce(Return(zero_time_));
// Verify that the ACK can be sent immediately.
EXPECT_EQ(zero_time_,
pacing_sender_->TimeUntilSend(clock_.Now(), NOT_RETRANSMISSION,
NO_RETRANSMITTABLE_DATA,
NOT_HANDSHAKE));

// Actually send the packet.
EXPECT_CALL(*mock_sender_,
OnPacketSent(clock_.Now(), sequence_number_, kMaxPacketSize,
NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA));
pacing_sender_->OnPacketSent(clock_.Now(), sequence_number_++,
kMaxPacketSize, NOT_RETRANSMISSION,
NO_RETRANSMITTABLE_DATA);
}

void CheckPacketIsDelayed(QuicTime::Delta delay) {
// In order for the packet to be sendable, the underlying sender must
// permit it to be sent immediately.
Expand Down Expand Up @@ -103,10 +126,11 @@ TEST_F(PacingSenderTest, SendNow) {
}

TEST_F(PacingSenderTest, VariousSending) {
// Configure bandwith of 1 packet per 1 ms.
// Configure bandwith of 1 packet per 2 ms, for which the pacing rate
// will be 1 packet per 1 ms.
EXPECT_CALL(*mock_sender_, BandwidthEstimate())
.WillRepeatedly(Return(QuicBandwidth::FromBytesAndTimeDelta(
kMaxPacketSize, QuicTime::Delta::FromMilliseconds(1))));
kMaxPacketSize, QuicTime::Delta::FromMilliseconds(2))));

CheckPacketIsSentImmediately();
CheckPacketIsSentImmediately();
Expand All @@ -121,6 +145,7 @@ TEST_F(PacingSenderTest, VariousSending) {
CheckPacketIsSentImmediately();
CheckPacketIsSentImmediately();
CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2));
CheckAckIsSentImmediately();

// Wake up late.
clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(4));
Expand Down
Loading

0 comments on commit 622f947

Please sign in to comment.