forked from quic-go/quic-go
Merge pull request #2021 from lucas-clemente/early-retransmit-for-crypto-packets
use early retransmit for crypto packets
This commit is contained in:
@@ -37,8 +37,8 @@ type SentPacketHandler interface {
|
||||
PeekPacketNumber(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen)
|
||||
PopPacketNumber(protocol.EncryptionLevel) protocol.PacketNumber
|
||||
|
||||
GetAlarmTimeout() time.Time
|
||||
OnAlarm() error
|
||||
GetLossDetectionTimeout() time.Time
|
||||
OnLossDetectionTimeout() error
|
||||
|
||||
// report some congestion statistics. For tracing only.
|
||||
GetStats() *quictrace.TransportState
|
||||
|
||||
@@ -24,6 +24,7 @@ type packetNumberSpace struct {
|
||||
history *sentPacketHistory
|
||||
pns *packetNumberGenerator
|
||||
|
||||
lossTime time.Time
|
||||
largestAcked protocol.PacketNumber
|
||||
largestSent protocol.PacketNumber
|
||||
}
|
||||
@@ -68,9 +69,6 @@ type sentPacketHandler struct {
|
||||
// Only applies to the application-data packet number space.
|
||||
numProbesToSend int
|
||||
|
||||
// The time at which the next packet will be considered lost based on early transmit or exceeding the reordering window in time.
|
||||
lossTime time.Time
|
||||
|
||||
// The alarm timeout
|
||||
alarm time.Time
|
||||
|
||||
@@ -136,7 +134,7 @@ func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel) {
|
||||
func (h *sentPacketHandler) SentPacket(packet *Packet) {
|
||||
if isAckEliciting := h.sentPacketImpl(packet); isAckEliciting {
|
||||
h.getPacketNumberSpace(packet.EncryptionLevel).history.SentPacket(packet)
|
||||
h.updateLossDetectionAlarm()
|
||||
h.setLossDetectionTimer()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +146,7 @@ func (h *sentPacketHandler) SentPacketsAsRetransmission(packets []*Packet, retra
|
||||
}
|
||||
}
|
||||
h.getPacketNumberSpace(p[0].EncryptionLevel).history.SentPacketsAsRetransmission(p, retransmissionOf)
|
||||
h.updateLossDetectionAlarm()
|
||||
h.setLossDetectionTimer()
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) getPacketNumberSpace(encLevel protocol.EncryptionLevel) *packetNumberSpace {
|
||||
@@ -258,7 +256,7 @@ func (h *sentPacketHandler) ReceivedAck(ackFrame *wire.AckFrame, withPacketNumbe
|
||||
h.cryptoCount = 0
|
||||
h.numProbesToSend = 0
|
||||
|
||||
h.updateLossDetectionAlarm()
|
||||
h.setLossDetectionTimer()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -314,6 +312,25 @@ func (h *sentPacketHandler) determineNewlyAckedPackets(
|
||||
return ackedPackets, err
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) getEarliestLossTime() (time.Time, protocol.EncryptionLevel) {
|
||||
var encLevel protocol.EncryptionLevel
|
||||
var lossTime time.Time
|
||||
|
||||
if h.initialPackets != nil {
|
||||
lossTime = h.initialPackets.lossTime
|
||||
encLevel = protocol.EncryptionInitial
|
||||
}
|
||||
if h.handshakePackets != nil && (lossTime.IsZero() || h.handshakePackets.lossTime.Before(lossTime)) {
|
||||
lossTime = h.handshakePackets.lossTime
|
||||
encLevel = protocol.EncryptionHandshake
|
||||
}
|
||||
if lossTime.IsZero() || h.oneRTTPackets.lossTime.Before(lossTime) {
|
||||
lossTime = h.oneRTTPackets.lossTime
|
||||
encLevel = protocol.Encryption1RTT
|
||||
}
|
||||
return lossTime, encLevel
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) hasOutstandingCryptoPackets() bool {
|
||||
var hasInitial, hasHandshake bool
|
||||
if h.initialPackets != nil {
|
||||
@@ -329,18 +346,20 @@ func (h *sentPacketHandler) hasOutstandingPackets() bool {
|
||||
return h.oneRTTPackets.history.HasOutstandingPackets() || h.hasOutstandingCryptoPackets()
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) updateLossDetectionAlarm() {
|
||||
func (h *sentPacketHandler) setLossDetectionTimer() {
|
||||
// Cancel the alarm if no packets are outstanding
|
||||
if !h.hasOutstandingPackets() {
|
||||
h.alarm = time.Time{}
|
||||
return
|
||||
}
|
||||
|
||||
lossTime, _ := h.getEarliestLossTime()
|
||||
|
||||
if h.hasOutstandingCryptoPackets() {
|
||||
h.alarm = h.lastSentCryptoPacketTime.Add(h.computeCryptoTimeout())
|
||||
} else if !h.lossTime.IsZero() {
|
||||
} else if !lossTime.IsZero() {
|
||||
// Early retransmit timer or time loss detection.
|
||||
h.alarm = h.lossTime
|
||||
h.alarm = lossTime
|
||||
} else { // PTO alarm
|
||||
h.alarm = h.lastSentAckElicitingPacketTime.Add(h.rttStats.PTO() << h.ptoCount)
|
||||
}
|
||||
@@ -351,10 +370,8 @@ func (h *sentPacketHandler) detectLostPackets(
|
||||
encLevel protocol.EncryptionLevel,
|
||||
priorInFlight protocol.ByteCount,
|
||||
) error {
|
||||
if encLevel == protocol.Encryption1RTT {
|
||||
h.lossTime = time.Time{}
|
||||
}
|
||||
pnSpace := h.getPacketNumberSpace(encLevel)
|
||||
pnSpace.lossTime = time.Time{}
|
||||
|
||||
maxRTT := float64(utils.MaxDuration(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT()))
|
||||
lossDelay := time.Duration(timeThreshold * maxRTT)
|
||||
@@ -371,12 +388,12 @@ func (h *sentPacketHandler) detectLostPackets(
|
||||
timeSinceSent := now.Sub(packet.SendTime)
|
||||
if timeSinceSent > lossDelay {
|
||||
lostPackets = append(lostPackets, packet)
|
||||
} else if h.lossTime.IsZero() && encLevel == protocol.Encryption1RTT {
|
||||
} else if pnSpace.lossTime.IsZero() && encLevel == protocol.Encryption1RTT {
|
||||
if h.logger.Debug() {
|
||||
h.logger.Debugf("\tsetting loss timer for packet %#x to %s (in %s)", packet.PacketNumber, lossDelay, lossDelay-timeSinceSent)
|
||||
}
|
||||
// Note: This conditional is only entered once per call
|
||||
h.lossTime = now.Add(lossDelay - timeSinceSent)
|
||||
pnSpace.lossTime = now.Add(lossDelay - timeSinceSent)
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
@@ -417,34 +434,35 @@ func (h *sentPacketHandler) detectLostPackets(
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) OnAlarm() error {
|
||||
func (h *sentPacketHandler) OnLossDetectionTimeout() error {
|
||||
// When all outstanding are acknowledged, the alarm is canceled in
|
||||
// updateLossDetectionAlarm. This doesn't reset the timer in the session though.
|
||||
// When OnAlarm is called, we therefore need to make sure that there are
|
||||
// actually packets outstanding.
|
||||
if h.hasOutstandingPackets() {
|
||||
if err := h.onVerifiedAlarm(); err != nil {
|
||||
if err := h.onVerifiedLossDetectionTimeout(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
h.updateLossDetectionAlarm()
|
||||
h.setLossDetectionTimer()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) onVerifiedAlarm() error {
|
||||
func (h *sentPacketHandler) onVerifiedLossDetectionTimeout() error {
|
||||
var err error
|
||||
if h.hasOutstandingCryptoPackets() {
|
||||
lossTime, encLevel := h.getEarliestLossTime()
|
||||
if !lossTime.IsZero() {
|
||||
if h.logger.Debug() {
|
||||
h.logger.Debugf("Loss detection alarm fired in loss timer mode. Loss time: %s", lossTime)
|
||||
}
|
||||
// Early retransmit or time loss detection
|
||||
err = h.detectLostPackets(time.Now(), encLevel, h.bytesInFlight)
|
||||
} else if h.hasOutstandingCryptoPackets() {
|
||||
if h.logger.Debug() {
|
||||
h.logger.Debugf("Loss detection alarm fired in crypto mode. Crypto count: %d", h.cryptoCount)
|
||||
}
|
||||
h.cryptoCount++
|
||||
err = h.queueCryptoPacketsForRetransmission()
|
||||
} else if !h.lossTime.IsZero() {
|
||||
if h.logger.Debug() {
|
||||
h.logger.Debugf("Loss detection alarm fired in loss timer mode. Loss time: %s", h.lossTime)
|
||||
}
|
||||
// Early retransmit or time loss detection
|
||||
err = h.detectLostPackets(time.Now(), protocol.Encryption1RTT, h.bytesInFlight)
|
||||
} else { // PTO
|
||||
if h.logger.Debug() {
|
||||
h.logger.Debugf("Loss detection alarm fired in PTO mode. PTO count: %d", h.ptoCount)
|
||||
@@ -455,7 +473,7 @@ func (h *sentPacketHandler) onVerifiedAlarm() error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) GetAlarmTimeout() time.Time {
|
||||
func (h *sentPacketHandler) GetLossDetectionTimeout() time.Time {
|
||||
return h.alarm
|
||||
}
|
||||
|
||||
@@ -672,7 +690,7 @@ func (h *sentPacketHandler) ResetForRetry() error {
|
||||
h.retransmissionQueue = append(h.retransmissionQueue, p)
|
||||
}
|
||||
h.initialPackets = newPacketNumberSpace(h.initialPackets.pns.Pop())
|
||||
h.updateLossDetectionAlarm()
|
||||
h.setLossDetectionTimer()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -602,11 +602,11 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 10, Largest: 11}}}
|
||||
err := handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, time.Now())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(handler.GetAlarmTimeout()).To(BeZero())
|
||||
Expect(handler.GetLossDetectionTimeout()).To(BeZero())
|
||||
})
|
||||
|
||||
It("does nothing on OnAlarm if there are no outstanding packets", func() {
|
||||
Expect(handler.OnAlarm()).To(Succeed())
|
||||
Expect(handler.OnLossDetectionTimeout()).To(Succeed())
|
||||
Expect(handler.SendMode()).To(Equal(SendAny))
|
||||
})
|
||||
|
||||
@@ -614,19 +614,19 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
It("implements exponential backoff", func() {
|
||||
sendTime := time.Now().Add(-time.Hour)
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 1, SendTime: sendTime}))
|
||||
timeout := handler.GetAlarmTimeout().Sub(sendTime)
|
||||
Expect(handler.GetAlarmTimeout().Sub(sendTime)).To(Equal(timeout))
|
||||
timeout := handler.GetLossDetectionTimeout().Sub(sendTime)
|
||||
Expect(handler.GetLossDetectionTimeout().Sub(sendTime)).To(Equal(timeout))
|
||||
handler.ptoCount = 1
|
||||
handler.updateLossDetectionAlarm()
|
||||
Expect(handler.GetAlarmTimeout().Sub(sendTime)).To(Equal(2 * timeout))
|
||||
handler.setLossDetectionTimer()
|
||||
Expect(handler.GetLossDetectionTimeout().Sub(sendTime)).To(Equal(2 * timeout))
|
||||
handler.ptoCount = 2
|
||||
handler.updateLossDetectionAlarm()
|
||||
Expect(handler.GetAlarmTimeout().Sub(sendTime)).To(Equal(4 * timeout))
|
||||
handler.setLossDetectionTimer()
|
||||
Expect(handler.GetLossDetectionTimeout().Sub(sendTime)).To(Equal(4 * timeout))
|
||||
})
|
||||
|
||||
It("sets the TPO send mode until two packets is sent", func() {
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)}))
|
||||
handler.OnAlarm()
|
||||
handler.OnLossDetectionTimeout()
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
Expect(handler.ShouldSendNumPackets()).To(Equal(2))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 2}))
|
||||
@@ -637,7 +637,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
|
||||
It("only counts ack-eliciting packets as probe packets", func() {
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)}))
|
||||
handler.OnAlarm()
|
||||
handler.OnLossDetectionTimeout()
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
Expect(handler.ShouldSendNumPackets()).To(Equal(2))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 2}))
|
||||
@@ -655,11 +655,11 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 2}))
|
||||
|
||||
updateRTT(time.Hour)
|
||||
Expect(handler.lossTime.IsZero()).To(BeTrue())
|
||||
Expect(handler.oneRTTPackets.lossTime.IsZero()).To(BeTrue())
|
||||
|
||||
handler.OnAlarm() // TLP
|
||||
handler.OnAlarm() // TLP
|
||||
handler.OnAlarm() // RTO
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // RTO
|
||||
p, err := handler.DequeueProbePacket()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(p).ToNot(BeNil())
|
||||
@@ -677,9 +677,9 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)}))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 2, SendTime: time.Now().Add(-time.Hour)}))
|
||||
handler.rttStats.UpdateRTT(time.Second, 0, time.Now())
|
||||
handler.OnAlarm() // TLP
|
||||
handler.OnAlarm() // TLP
|
||||
handler.OnAlarm() // RTO
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // RTO
|
||||
_, err := handler.DequeueProbePacket()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = handler.DequeueProbePacket()
|
||||
@@ -700,7 +700,7 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
It("resets the send mode when it receives an acknowledgement after queueing probe packets", func() {
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)}))
|
||||
handler.rttStats.UpdateRTT(time.Second, 0, time.Now())
|
||||
handler.OnAlarm()
|
||||
handler.OnLossDetectionTimeout()
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}}
|
||||
Expect(handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, time.Now())).To(Succeed())
|
||||
@@ -713,9 +713,9 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 3, SendTime: time.Now().Add(-time.Hour)}))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 4, SendTime: time.Now().Add(-time.Hour)}))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 5, SendTime: time.Now().Add(-time.Hour)}))
|
||||
handler.OnAlarm() // TLP
|
||||
handler.OnAlarm() // TLP
|
||||
handler.OnAlarm() // RTO
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // RTO
|
||||
_, err := handler.DequeueProbePacket()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = handler.DequeueProbePacket()
|
||||
@@ -735,23 +735,23 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
It("handles ACKs for the original packet", func() {
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 5, SendTime: time.Now().Add(-time.Hour)}))
|
||||
handler.rttStats.UpdateRTT(time.Second, 0, time.Now())
|
||||
handler.OnAlarm() // TLP
|
||||
handler.OnAlarm() // TLP
|
||||
handler.OnAlarm() // RTO
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // RTO
|
||||
handler.SentPacketsAsRetransmission([]*Packet{ackElicitingPacket(&Packet{PacketNumber: 6})}, 5)
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 5, Largest: 5}}}
|
||||
err := handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, time.Now())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
err = handler.OnAlarm()
|
||||
err = handler.OnLossDetectionTimeout()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("handles ACKs for the original packet", func() {
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 5, SendTime: time.Now().Add(-time.Hour)}))
|
||||
handler.rttStats.UpdateRTT(time.Second, 0, time.Now())
|
||||
err := handler.OnAlarm()
|
||||
err := handler.OnLossDetectionTimeout()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
err = handler.OnAlarm()
|
||||
err = handler.OnLossDetectionTimeout()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
})
|
||||
@@ -761,15 +761,29 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
now := time.Now()
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 1, SendTime: now.Add(-time.Hour)}))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 2, SendTime: now.Add(-time.Second)}))
|
||||
Expect(handler.lossTime.IsZero()).To(BeTrue())
|
||||
Expect(handler.oneRTTPackets.lossTime.IsZero()).To(BeTrue())
|
||||
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 2}}}
|
||||
err := handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, now)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, now)).To(Succeed())
|
||||
Expect(handler.DequeuePacketForRetransmission()).ToNot(BeNil())
|
||||
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
|
||||
// no need to set an alarm, since packet 1 was already declared lost
|
||||
Expect(handler.lossTime.IsZero()).To(BeTrue())
|
||||
Expect(handler.oneRTTPackets.lossTime.IsZero()).To(BeTrue())
|
||||
Expect(handler.bytesInFlight).To(BeZero())
|
||||
})
|
||||
|
||||
It("uses early retransmit for crypto packets", func() {
|
||||
now := time.Now()
|
||||
handler.SentPacket(cryptoPacket(&Packet{PacketNumber: 1, SendTime: now.Add(-time.Hour)}))
|
||||
handler.SentPacket(cryptoPacket(&Packet{PacketNumber: 2, SendTime: now.Add(-time.Second)}))
|
||||
Expect(handler.oneRTTPackets.lossTime.IsZero()).To(BeTrue())
|
||||
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 2}}}
|
||||
Expect(handler.ReceivedAck(ack, 1, protocol.EncryptionInitial, now)).To(Succeed())
|
||||
Expect(handler.DequeuePacketForRetransmission()).ToNot(BeNil())
|
||||
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
|
||||
// no need to set an alarm, since packet 1 was already declared lost
|
||||
Expect(handler.initialPackets.lossTime.IsZero()).To(BeTrue())
|
||||
Expect(handler.bytesInFlight).To(BeZero())
|
||||
})
|
||||
|
||||
@@ -778,17 +792,17 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 1, SendTime: now.Add(-2 * time.Second), EncryptionLevel: protocol.Encryption1RTT}))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 2, SendTime: now.Add(-2 * time.Second), EncryptionLevel: protocol.Encryption1RTT}))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 3, SendTime: now.Add(-time.Second), EncryptionLevel: protocol.Encryption1RTT}))
|
||||
Expect(handler.lossTime.IsZero()).To(BeTrue())
|
||||
Expect(handler.oneRTTPackets.lossTime.IsZero()).To(BeTrue())
|
||||
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 2}}}
|
||||
Expect(handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, now.Add(-time.Second))).To(Succeed())
|
||||
Expect(handler.rttStats.SmoothedRTT()).To(Equal(time.Second))
|
||||
|
||||
// Packet 1 should be considered lost (1+1/8) RTTs after it was sent.
|
||||
Expect(handler.lossTime.IsZero()).To(BeFalse())
|
||||
Expect(handler.lossTime.Sub(getPacket(1, protocol.Encryption1RTT).SendTime)).To(Equal(time.Second * 9 / 8))
|
||||
Expect(handler.oneRTTPackets.lossTime.IsZero()).To(BeFalse())
|
||||
Expect(handler.oneRTTPackets.lossTime.Sub(getPacket(1, protocol.Encryption1RTT).SendTime)).To(Equal(time.Second * 9 / 8))
|
||||
|
||||
Expect(handler.OnAlarm()).To(Succeed())
|
||||
Expect(handler.OnLossDetectionTimeout()).To(Succeed())
|
||||
Expect(handler.DequeuePacketForRetransmission()).NotTo(BeNil())
|
||||
// make sure this is not an RTO: only packet 1 is retransmissted
|
||||
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
|
||||
@@ -810,17 +824,17 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
Expect(handler.ReceivedAck(ack, 1, protocol.EncryptionInitial, now)).To(Succeed())
|
||||
// RTT is now 1 minute
|
||||
Expect(handler.rttStats.SmoothedRTT()).To(Equal(time.Minute))
|
||||
Expect(handler.lossTime.IsZero()).To(BeTrue())
|
||||
Expect(handler.GetAlarmTimeout().Sub(sendTime)).To(Equal(2 * time.Minute))
|
||||
Expect(handler.oneRTTPackets.lossTime.IsZero()).To(BeTrue())
|
||||
Expect(handler.GetLossDetectionTimeout().Sub(sendTime)).To(Equal(2 * time.Minute))
|
||||
|
||||
Expect(handler.OnAlarm()).To(Succeed())
|
||||
Expect(handler.OnLossDetectionTimeout()).To(Succeed())
|
||||
p := handler.DequeuePacketForRetransmission()
|
||||
Expect(p).ToNot(BeNil())
|
||||
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(3)))
|
||||
Expect(handler.cryptoCount).To(BeEquivalentTo(1))
|
||||
handler.SentPacket(cryptoPacket(&Packet{PacketNumber: 4, SendTime: lastCryptoPacketSendTime}))
|
||||
// make sure the exponential backoff is used
|
||||
Expect(handler.GetAlarmTimeout().Sub(lastCryptoPacketSendTime)).To(Equal(4 * time.Minute))
|
||||
Expect(handler.GetLossDetectionTimeout().Sub(lastCryptoPacketSendTime)).To(Equal(4 * time.Minute))
|
||||
})
|
||||
|
||||
It("rejects an ACK that acks packets with a higher encryption level", func() {
|
||||
@@ -908,14 +922,14 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
Length: 100,
|
||||
}
|
||||
handler.SentPacket(packet)
|
||||
Expect(handler.GetAlarmTimeout()).ToNot(BeZero())
|
||||
Expect(handler.GetLossDetectionTimeout()).ToNot(BeZero())
|
||||
Expect(handler.bytesInFlight).ToNot(BeZero())
|
||||
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
|
||||
Expect(handler.SendMode()).To(Equal(SendAny))
|
||||
// now receive a Retry
|
||||
Expect(handler.ResetForRetry()).To(Succeed())
|
||||
Expect(handler.bytesInFlight).To(BeZero())
|
||||
Expect(handler.GetAlarmTimeout()).To(BeZero())
|
||||
Expect(handler.GetLossDetectionTimeout()).To(BeZero())
|
||||
Expect(handler.SendMode()).To(Equal(SendRetransmission))
|
||||
p := handler.DequeuePacketForRetransmission()
|
||||
Expect(p.PacketNumber).To(Equal(packet.PacketNumber))
|
||||
|
||||
@@ -79,18 +79,18 @@ func (mr *MockSentPacketHandlerMockRecorder) DropPackets(arg0 interface{}) *gomo
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropPackets", reflect.TypeOf((*MockSentPacketHandler)(nil).DropPackets), arg0)
|
||||
}
|
||||
|
||||
// GetAlarmTimeout mocks base method
|
||||
func (m *MockSentPacketHandler) GetAlarmTimeout() time.Time {
|
||||
// GetLossDetectionTimeout mocks base method
|
||||
func (m *MockSentPacketHandler) GetLossDetectionTimeout() time.Time {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAlarmTimeout")
|
||||
ret := m.ctrl.Call(m, "GetLossDetectionTimeout")
|
||||
ret0, _ := ret[0].(time.Time)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetAlarmTimeout indicates an expected call of GetAlarmTimeout
|
||||
func (mr *MockSentPacketHandlerMockRecorder) GetAlarmTimeout() *gomock.Call {
|
||||
// GetLossDetectionTimeout indicates an expected call of GetLossDetectionTimeout
|
||||
func (mr *MockSentPacketHandlerMockRecorder) GetLossDetectionTimeout() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlarmTimeout", reflect.TypeOf((*MockSentPacketHandler)(nil).GetAlarmTimeout))
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLossDetectionTimeout", reflect.TypeOf((*MockSentPacketHandler)(nil).GetLossDetectionTimeout))
|
||||
}
|
||||
|
||||
// GetLowestPacketNotConfirmedAcked mocks base method
|
||||
@@ -121,18 +121,18 @@ func (mr *MockSentPacketHandlerMockRecorder) GetStats() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStats", reflect.TypeOf((*MockSentPacketHandler)(nil).GetStats))
|
||||
}
|
||||
|
||||
// OnAlarm mocks base method
|
||||
func (m *MockSentPacketHandler) OnAlarm() error {
|
||||
// OnLossDetectionTimeout mocks base method
|
||||
func (m *MockSentPacketHandler) OnLossDetectionTimeout() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "OnAlarm")
|
||||
ret := m.ctrl.Call(m, "OnLossDetectionTimeout")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// OnAlarm indicates an expected call of OnAlarm
|
||||
func (mr *MockSentPacketHandlerMockRecorder) OnAlarm() *gomock.Call {
|
||||
// OnLossDetectionTimeout indicates an expected call of OnLossDetectionTimeout
|
||||
func (mr *MockSentPacketHandlerMockRecorder) OnLossDetectionTimeout() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnAlarm", reflect.TypeOf((*MockSentPacketHandler)(nil).OnAlarm))
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnLossDetectionTimeout", reflect.TypeOf((*MockSentPacketHandler)(nil).OnLossDetectionTimeout))
|
||||
}
|
||||
|
||||
// PeekPacketNumber mocks base method
|
||||
|
||||
@@ -419,10 +419,10 @@ runLoop:
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
if timeout := s.sentPacketHandler.GetAlarmTimeout(); !timeout.IsZero() && timeout.Before(now) {
|
||||
if timeout := s.sentPacketHandler.GetLossDetectionTimeout(); !timeout.IsZero() && timeout.Before(now) {
|
||||
// This could cause packets to be retransmitted.
|
||||
// Check it before trying to send packets.
|
||||
if err := s.sentPacketHandler.OnAlarm(); err != nil {
|
||||
if err := s.sentPacketHandler.OnLossDetectionTimeout(); err != nil {
|
||||
s.closeLocal(err)
|
||||
}
|
||||
}
|
||||
@@ -484,7 +484,7 @@ func (s *session) maybeResetTimer() {
|
||||
if ackAlarm := s.receivedPacketHandler.GetAlarmTimeout(); !ackAlarm.IsZero() {
|
||||
deadline = utils.MinTime(deadline, ackAlarm)
|
||||
}
|
||||
if lossTime := s.sentPacketHandler.GetAlarmTimeout(); !lossTime.IsZero() {
|
||||
if lossTime := s.sentPacketHandler.GetLossDetectionTimeout(); !lossTime.IsZero() {
|
||||
deadline = utils.MinTime(deadline, lossTime)
|
||||
}
|
||||
if !s.handshakeComplete {
|
||||
|
||||
@@ -845,7 +845,7 @@ var _ = Describe("Session", func() {
|
||||
|
||||
It("sends ACK only packets", func() {
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().GetAlarmTimeout().AnyTimes()
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().SendMode().Return(ackhandler.SendAck)
|
||||
sph.EXPECT().ShouldSendNumPackets().Return(1000)
|
||||
packer.EXPECT().MaybePackAckPacket()
|
||||
@@ -952,7 +952,7 @@ var _ = Describe("Session", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
sph = mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().GetAlarmTimeout().AnyTimes()
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().DequeuePacketForRetransmission().AnyTimes()
|
||||
sess.sentPacketHandler = sph
|
||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||
@@ -1092,7 +1092,7 @@ var _ = Describe("Session", func() {
|
||||
Context("scheduling sending", func() {
|
||||
It("sends when scheduleSending is called", func() {
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().GetAlarmTimeout().AnyTimes()
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().TimeUntilSend().AnyTimes()
|
||||
sph.EXPECT().SendMode().Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().ShouldSendNumPackets().AnyTimes().Return(1)
|
||||
@@ -1122,7 +1122,7 @@ var _ = Describe("Session", func() {
|
||||
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
|
||||
sph.EXPECT().TimeUntilSend().Return(time.Now())
|
||||
sph.EXPECT().TimeUntilSend().Return(time.Now().Add(time.Hour))
|
||||
sph.EXPECT().GetAlarmTimeout().AnyTimes()
|
||||
sph.EXPECT().GetLossDetectionTimeout().AnyTimes()
|
||||
sph.EXPECT().SendMode().Return(ackhandler.SendAny).AnyTimes()
|
||||
sph.EXPECT().ShouldSendNumPackets().Return(1)
|
||||
sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
|
||||
|
||||
Reference in New Issue
Block a user