From 7f1e85a97756b42a28d700c3bc5ae73c2d087641 Mon Sep 17 00:00:00 2001 From: Lucas Clemente Date: Thu, 28 Apr 2016 14:32:48 +0200 Subject: [PATCH] implement CubicSender.RetransmissionDelay --- congestion/cubic_sender.go | 8 ++++++++ congestion/cubic_sender_test.go | 27 +++++++++++++++++++++++++++ congestion/interface.go | 1 + 3 files changed, 36 insertions(+) diff --git a/congestion/cubic_sender.go b/congestion/cubic_sender.go index ecf4b2e8..79a5686e 100644 --- a/congestion/cubic_sender.go +++ b/congestion/cubic_sender.go @@ -300,3 +300,11 @@ func (c *cubicSender) OnConnectionMigration() { func (c *cubicSender) SetSlowStartLargeReduction(enabled bool) { c.slowStartLargeReduction = enabled } + +// RetransmissionDelay gives the time to retransmission +func (c *cubicSender) RetransmissionDelay() time.Duration { + if c.rttStats.SmoothedRTT() == 0 { + return 0 + } + return c.rttStats.SmoothedRTT() + c.rttStats.MeanDeviation()*4 +} diff --git a/congestion/cubic_sender_test.go b/congestion/cubic_sender_test.go index 85b51c76..31e3a4f6 100644 --- a/congestion/cubic_sender_test.go +++ b/congestion/cubic_sender_test.go @@ -390,6 +390,33 @@ var _ = Describe("Cubic Sender", func() { Expect(sender.GetCongestionWindow()).To(Equal(defaultWindowTCP)) }) + It("retransmission delay", func() { + const kRttMs = 10 * time.Millisecond + const kDeviationMs = 3 * time.Millisecond + Expect(sender.RetransmissionDelay()).To(BeZero()) + + rttStats.UpdateRTT(kRttMs, 0, clock.Now()) + + // Initial value is to set the median deviation to half of the initial + // rtt, the median in then multiplied by a factor of 4 and finally the + // smoothed rtt is added which is the initial rtt. + expected_delay := kRttMs + kRttMs/2*4 + Expect(sender.RetransmissionDelay()).To(Equal(expected_delay)) + + for i := 0; i < 100; i++ { + // Run to make sure that we converge. + rttStats.UpdateRTT(kRttMs+kDeviationMs, 0, clock.Now()) + rttStats.UpdateRTT(kRttMs-kDeviationMs, 0, clock.Now()) + } + expected_delay = kRttMs + kDeviationMs*4 + + Expect(rttStats.SmoothedRTT()).To(BeNumerically("~", kRttMs, time.Millisecond)) + Expect(sender.RetransmissionDelay()).To(BeNumerically("~", expected_delay, time.Millisecond)) + Expect(sender.BandwidthEstimate() / congestion.BytesPerSecond).To(Equal(congestion.Bandwidth( + sender.GetCongestionWindow() * uint64(time.Second) / uint64(rttStats.SmoothedRTT()), + ))) + }) + It("slow start max send window", func() { const kMaxCongestionWindowTCP = 50 const kNumberOfAcks = 100 diff --git a/congestion/interface.go b/congestion/interface.go index 24cd7d77..8860a9de 100644 --- a/congestion/interface.go +++ b/congestion/interface.go @@ -16,6 +16,7 @@ type SendAlgorithm interface { OnRetransmissionTimeout(packetsRetransmitted bool) InRecovery() bool OnConnectionMigration() + RetransmissionDelay() time.Duration // Experiments SetSlowStartLargeReduction(enabled bool)