use the receipt of a Retry packet to get a first RTT estimate

This commit is contained in:
Marten Seemann 2019-11-03 13:37:04 +07:00
parent 05514ab375
commit 6299ef3ab1
2 changed files with 48 additions and 0 deletions

View file

@ -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

View file

@ -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())
})
})
})