ackhandler: use the receive time of the Retry packet for RTT estimation (#4070)

This commit is contained in:
Marten Seemann
2023-09-09 20:12:19 +07:00
committed by GitHub
parent dc0369cad4
commit 54b76ceb3e
6 changed files with 32 additions and 26 deletions

View File

@@ -13,10 +13,10 @@ type SentPacketHandler interface {
SentPacket(t time.Time, pn, largestAcked protocol.PacketNumber, streamFrames []StreamFrame, frames []Frame, encLevel protocol.EncryptionLevel, size protocol.ByteCount, isPathMTUProbePacket bool)
// ReceivedAck processes an ACK frame.
// It does not store a copy of the frame.
ReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, recvTime time.Time) (bool /* 1-RTT packet acked */, error)
ReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool /* 1-RTT packet acked */, error)
ReceivedBytes(protocol.ByteCount)
DropPackets(protocol.EncryptionLevel)
ResetForRetry() error
ResetForRetry(rcvTime time.Time) error
SetHandshakeConfirmed()
// The SendMode determines if and what kind of packets can be sent.

View File

@@ -824,7 +824,7 @@ func (h *sentPacketHandler) queueFramesForRetransmission(p *packet) {
p.Frames = nil
}
func (h *sentPacketHandler) ResetForRetry() error {
func (h *sentPacketHandler) ResetForRetry(now time.Time) error {
h.bytesInFlight = 0
var firstPacketSendTime time.Time
h.initialPackets.history.Iterate(func(p *packet) (bool, error) {
@@ -850,7 +850,6 @@ func (h *sentPacketHandler) ResetForRetry() error {
// Otherwise, we don't know which Initial the Retry was sent in response to.
if h.ptoCount == 0 {
// Don't set the RTT to a value lower than 5ms here.
now := time.Now()
h.rttStats.UpdateRTT(utils.Max(minRTTAfterRetry, now.Sub(firstPacketSendTime)), 0, now)
if h.logger.Debug() {
h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation())

View File

@@ -1334,7 +1334,7 @@ var _ = Describe("SentPacketHandler", func() {
Expect(handler.bytesInFlight).ToNot(BeZero())
Expect(handler.SendMode(time.Now())).To(Equal(SendAny))
// now receive a Retry
Expect(handler.ResetForRetry()).To(Succeed())
Expect(handler.ResetForRetry(time.Now())).To(Succeed())
Expect(lostPackets).To(Equal([]protocol.PacketNumber{42}))
Expect(handler.bytesInFlight).To(BeZero())
Expect(handler.GetLossDetectionTimeout()).To(BeZero())
@@ -1369,7 +1369,7 @@ var _ = Describe("SentPacketHandler", func() {
})
Expect(handler.bytesInFlight).ToNot(BeZero())
// now receive a Retry
Expect(handler.ResetForRetry()).To(Succeed())
Expect(handler.ResetForRetry(time.Now())).To(Succeed())
Expect(handler.bytesInFlight).To(BeZero())
Expect(lostInitial).To(BeTrue())
Expect(lost0RTT).To(BeTrue())
@@ -1379,49 +1379,53 @@ var _ = Describe("SentPacketHandler", func() {
})
It("uses a Retry for an RTT estimate, if it was not retransmitted", func() {
now := time.Now()
sentPacket(ackElicitingPacket(&packet{
PacketNumber: 42,
EncryptionLevel: protocol.EncryptionInitial,
SendTime: time.Now().Add(-500 * time.Millisecond),
SendTime: now,
}))
sentPacket(ackElicitingPacket(&packet{
PacketNumber: 43,
EncryptionLevel: protocol.EncryptionInitial,
SendTime: time.Now().Add(-10 * time.Millisecond),
SendTime: now.Add(500 * time.Millisecond),
}))
Expect(handler.ResetForRetry()).To(Succeed())
Expect(handler.rttStats.SmoothedRTT()).To(BeNumerically("~", 500*time.Millisecond, 100*time.Millisecond))
Expect(handler.ResetForRetry(now.Add(time.Second))).To(Succeed())
Expect(handler.rttStats.SmoothedRTT()).To(Equal(time.Second))
})
It("uses a Retry for an RTT estimate, but doesn't set the RTT to a value lower than 5ms", func() {
now := time.Now()
sentPacket(ackElicitingPacket(&packet{
PacketNumber: 42,
EncryptionLevel: protocol.EncryptionInitial,
SendTime: time.Now().Add(-500 * time.Microsecond),
SendTime: now,
}))
sentPacket(ackElicitingPacket(&packet{
PacketNumber: 43,
EncryptionLevel: protocol.EncryptionInitial,
SendTime: time.Now().Add(-10 * time.Microsecond),
SendTime: now.Add(2 * time.Millisecond),
}))
Expect(handler.ResetForRetry()).To(Succeed())
Expect(handler.ResetForRetry(now.Add(4 * time.Millisecond))).To(Succeed())
Expect(minRTTAfterRetry).To(BeNumerically(">", 4*time.Millisecond))
Expect(handler.rttStats.SmoothedRTT()).To(Equal(minRTTAfterRetry))
})
It("doesn't use a Retry for an RTT estimate, if it was not retransmitted", func() {
now := time.Now()
sentPacket(ackElicitingPacket(&packet{
PacketNumber: 42,
EncryptionLevel: protocol.EncryptionInitial,
SendTime: time.Now().Add(-800 * time.Millisecond),
SendTime: now,
}))
Expect(handler.OnLossDetectionTimeout()).To(Succeed())
Expect(handler.SendMode(time.Now())).To(Equal(SendPTOInitial))
sentPacket(ackElicitingPacket(&packet{
PacketNumber: 43,
EncryptionLevel: protocol.EncryptionInitial,
SendTime: time.Now().Add(-100 * time.Millisecond),
SendTime: now.Add(500 * time.Millisecond),
}))
Expect(handler.ResetForRetry()).To(Succeed())
Expect(handler.ResetForRetry(now.Add(time.Second))).To(Succeed())
Expect(handler.rttStats.SmoothedRTT()).To(BeZero())
})
})