From 6299ef3ab1670327bca37617982feeb5e4000cb2 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 3 Nov 2019 13:37:04 +0700 Subject: [PATCH] use the receipt of a Retry packet to get a first RTT estimate --- internal/ackhandler/sent_packet_handler.go | 16 ++++++++++ .../ackhandler/sent_packet_handler_test.go | 32 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index 5dc57bdd1..e9bba293c 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -772,7 +772,11 @@ func (h *sentPacketHandler) queueFramesForRetransmission(p *Packet) { func (h *sentPacketHandler) ResetForRetry() error { h.bytesInFlight = 0 + var firstPacketSendTime time.Time h.initialPackets.history.Iterate(func(p *Packet) (bool, error) { + if firstPacketSendTime.IsZero() { + firstPacketSendTime = p.SendTime + } h.queueFramesForRetransmission(p) return true, nil }) @@ -783,6 +787,18 @@ func (h *sentPacketHandler) ResetForRetry() error { return true, nil }) + // Only use the Retry to estimate the RTT if we didn't send any retransmission for the Initial. + // Otherwise, we don't know which Initial the Retry was sent in response to. + if h.ptoCount == 0 { + now := time.Now() + h.rttStats.UpdateRTT(now.Sub(firstPacketSendTime), 0, now) + if h.logger.Debug() { + h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation()) + } + if h.qlogger != nil { + h.qlogger.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight()) + } + } h.initialPackets = newPacketNumberSpace(h.initialPackets.pns.Pop()) h.appDataPackets = newPacketNumberSpace(h.appDataPackets.pns.Pop()) oldAlarm := h.alarm diff --git a/internal/ackhandler/sent_packet_handler_test.go b/internal/ackhandler/sent_packet_handler_test.go index 38ec87dd2..1d9d5ce63 100644 --- a/internal/ackhandler/sent_packet_handler_test.go +++ b/internal/ackhandler/sent_packet_handler_test.go @@ -1149,5 +1149,37 @@ var _ = Describe("SentPacketHandler", func() { // make sure we keep increasing the packet number for 0-RTT packets Expect(handler.PopPacketNumber(protocol.Encryption0RTT)).To(BeNumerically(">", pn)) }) + + It("uses a Retry for an RTT estimate, if it was not retransmitted", func() { + handler.SentPacket(ackElicitingPacket(&Packet{ + PacketNumber: 42, + EncryptionLevel: protocol.EncryptionInitial, + SendTime: time.Now().Add(-500 * time.Millisecond), + })) + handler.SentPacket(ackElicitingPacket(&Packet{ + PacketNumber: 43, + EncryptionLevel: protocol.EncryptionInitial, + SendTime: time.Now().Add(-10 * time.Millisecond), + })) + Expect(handler.ResetForRetry()).To(Succeed()) + Expect(handler.rttStats.SmoothedRTT()).To(BeNumerically("~", 500*time.Millisecond, 100*time.Millisecond)) + }) + + It("doesn't use a Retry for an RTT estimate, if it was not retransmitted", func() { + handler.SentPacket(ackElicitingPacket(&Packet{ + PacketNumber: 42, + EncryptionLevel: protocol.EncryptionInitial, + SendTime: time.Now().Add(-800 * time.Millisecond), + })) + Expect(handler.OnLossDetectionTimeout()).To(Succeed()) + Expect(handler.SendMode()).To(Equal(SendPTOInitial)) + handler.SentPacket(ackElicitingPacket(&Packet{ + PacketNumber: 43, + EncryptionLevel: protocol.EncryptionInitial, + SendTime: time.Now().Add(-100 * time.Millisecond), + })) + Expect(handler.ResetForRetry()).To(Succeed()) + Expect(handler.rttStats.SmoothedRTT()).To(BeZero()) + }) }) })