From 77d48248ff5c12caba3200b3fd042e09cd702beb Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 20 Dec 2018 16:10:20 +0630 Subject: [PATCH] unify TLP and RTO This doesn't yet implement the persistent congestion detection, since the specification of that still is in flux. --- internal/ackhandler/send_mode.go | 12 +- internal/ackhandler/send_mode_test.go | 3 +- internal/ackhandler/sent_packet_handler.go | 118 +++-------- .../ackhandler/sent_packet_handler_test.go | 190 ++++-------------- session.go | 2 +- session_test.go | 2 +- 6 files changed, 82 insertions(+), 245 deletions(-) diff --git a/internal/ackhandler/send_mode.go b/internal/ackhandler/send_mode.go index 76c833c4b..8cdaa7e6b 100644 --- a/internal/ackhandler/send_mode.go +++ b/internal/ackhandler/send_mode.go @@ -12,10 +12,8 @@ const ( SendAck // SendRetransmission means that retransmissions should be sent SendRetransmission - // SendRTO means that an RTO probe packet should be sent - SendRTO - // SendTLP means that a TLP probe packet should be sent - SendTLP + // SendPTO means that a probe packet should be sent + SendPTO // SendAny means that any packet should be sent SendAny ) @@ -28,10 +26,8 @@ func (s SendMode) String() string { return "ack" case SendRetransmission: return "retransmission" - case SendRTO: - return "rto" - case SendTLP: - return "tlp" + case SendPTO: + return "pto" case SendAny: return "any" default: diff --git a/internal/ackhandler/send_mode_test.go b/internal/ackhandler/send_mode_test.go index c267d38c1..251daffc9 100644 --- a/internal/ackhandler/send_mode_test.go +++ b/internal/ackhandler/send_mode_test.go @@ -10,8 +10,7 @@ var _ = Describe("Send Mode", func() { Expect(SendNone.String()).To(Equal("none")) Expect(SendAny.String()).To(Equal("any")) Expect(SendAck.String()).To(Equal("ack")) - Expect(SendRTO.String()).To(Equal("rto")) - Expect(SendTLP.String()).To(Equal("tlp")) + Expect(SendPTO.String()).To(Equal("pto")) Expect(SendRetransmission.String()).To(Equal("retransmission")) Expect(SendMode(123).String()).To(Equal("invalid send mode: 123")) }) diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index 776f87a89..0c67b0da4 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -17,16 +17,8 @@ const ( // Maximum reordering in time space before time based loss detection considers a packet lost. // In fraction of an RTT. timeReorderingFraction = 1.0 / 8 - // defaultRTOTimeout is the RTO time on new connections - defaultRTOTimeout = 500 * time.Millisecond - // Minimum time in the future a tail loss probe alarm may be set for. - minTPLTimeout = 10 * time.Millisecond - // Maximum number of tail loss probes before an RTO fires. - maxTLPs = 2 - // Minimum time in the future an RTO alarm may be set for. - minRTOTimeout = 200 * time.Millisecond - // maxRTOTimeout is the maximum RTO time - maxRTOTimeout = 60 * time.Second + // Timer granularity. The timer will not be set to a value smaller than granularity. + granularity = time.Millisecond ) type sentPacketHandler struct { @@ -44,7 +36,6 @@ type sentPacketHandler struct { // example: we send an ACK for packets 90-100 with packet number 20 // once we receive an ACK from the peer for packet 20, the lowestPacketNotConfirmedAcked is 101 lowestPacketNotConfirmedAcked protocol.PacketNumber - largestSentBeforeRTO protocol.PacketNumber packetHistory *sentPacketHistory @@ -56,17 +47,13 @@ type sentPacketHandler struct { rttStats *congestion.RTTStats handshakeComplete bool + // The number of times the crypto packets have been retransmitted without receiving an ack. cryptoCount uint32 - - // The number of times a TLP has been sent without receiving an ack. - tlpCount uint32 - allowTLP bool - - // The number of times an RTO has been sent without receiving an ack. - rtoCount uint32 - // The number of RTO probe packets that should be sent. - numRTOs int + // The number of times a PTO has been sent without receiving an ack. + ptoCount uint32 + // The number of PTO probe packets that should be sent. + 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 @@ -173,10 +160,9 @@ func (h *sentPacketHandler) sentPacketImpl(packet *Packet) bool /* isRetransmitt packet.includedInBytesInFlight = true h.bytesInFlight += packet.Length packet.canBeRetransmitted = true - if h.numRTOs > 0 { - h.numRTOs-- + if h.numProbesToSend > 0 { + h.numProbesToSend-- } - h.allowTLP = false } h.congestion.OnPacketSent(packet.SendTime, h.bytesInFlight, packet.PacketNumber, packet.Length, isRetransmittable) @@ -210,6 +196,9 @@ func (h *sentPacketHandler) ReceivedAck(ackFrame *wire.AckFrame, withPacketNumbe if err != nil { return err } + if len(ackedPackets) == 0 { + return nil + } priorInFlight := h.bytesInFlight for _, p := range ackedPackets { @@ -235,6 +224,10 @@ func (h *sentPacketHandler) ReceivedAck(ackFrame *wire.AckFrame, withPacketNumbe if err := h.detectLostPackets(rcvTime, priorInFlight); err != nil { return err } + + h.ptoCount = 0 + h.cryptoCount = 0 + h.updateLossDetectionAlarm() return nil } @@ -310,15 +303,8 @@ func (h *sentPacketHandler) updateLossDetectionAlarm() { } else if !h.lossTime.IsZero() { // Early retransmit timer or time loss detection. h.alarm = h.lossTime - } else { - // RTO or TLP alarm - alarmDuration := h.computeRTOTimeout() - if h.tlpCount < maxTLPs { - tlpAlarm := h.computeTLPTimeout() - // if the RTO duration is shorter than the TLP duration, use the RTO duration - alarmDuration = utils.MinDuration(alarmDuration, tlpAlarm) - } - h.alarm = h.lastSentRetransmittablePacketTime.Add(alarmDuration) + } else { // PTO alarm + h.alarm = h.lastSentRetransmittablePacketTime.Add(h.computePTOTimeout()) } } @@ -346,6 +332,7 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, priorInFlight proto } return true, nil }) + if h.logger.Debug() && len(lostPackets) > 0 { pns := make([]protocol.PacketNumber, len(lostPackets)) for i, p := range lostPackets { @@ -399,21 +386,12 @@ func (h *sentPacketHandler) onVerifiedAlarm() error { } // Early retransmit or time loss detection err = h.detectLostPackets(time.Now(), h.bytesInFlight) - } else if h.tlpCount < maxTLPs { // TLP + } else { // PTO if h.logger.Debug() { - h.logger.Debugf("Loss detection alarm fired in TLP mode. TLP count: %d", h.tlpCount) + h.logger.Debugf("Loss detection alarm fired in PTO mode. PTO count: %d", h.ptoCount) } - h.allowTLP = true - h.tlpCount++ - } else { // RTO - if h.logger.Debug() { - h.logger.Debugf("Loss detection alarm fired in RTO mode. RTO count: %d", h.rtoCount) - } - if h.rtoCount == 0 { - h.largestSentBeforeRTO = h.lastSentPacketNumber - } - h.rtoCount++ - h.numRTOs += 2 + h.ptoCount++ + h.numProbesToSend += 2 } return err } @@ -454,15 +432,9 @@ func (h *sentPacketHandler) onPacketAcked(p *Packet, rcvTime time.Time) error { if p.includedInBytesInFlight { h.bytesInFlight -= p.Length } - if h.rtoCount > 0 { - h.verifyRTO(p.PacketNumber) - } if err := h.stopRetransmissionsFor(p); err != nil { return err } - h.rtoCount = 0 - h.tlpCount = 0 - h.cryptoCount = 0 return h.packetHistory.Remove(p.PacketNumber) } @@ -480,18 +452,6 @@ func (h *sentPacketHandler) stopRetransmissionsFor(p *Packet) error { return nil } -func (h *sentPacketHandler) verifyRTO(pn protocol.PacketNumber) { - if pn <= h.largestSentBeforeRTO { - h.logger.Debugf("Spurious RTO detected. Received an ACK for %#x (largest sent before RTO: %#x)", pn, h.largestSentBeforeRTO) - // Replace SRTT with latest_rtt and increase the variance to prevent - // a spurious RTO from happening again. - h.rttStats.ExpireSmoothedMetrics() - return - } - h.logger.Debugf("RTO verified. Received an ACK for %#x (largest sent before RTO: %#x", pn, h.largestSentBeforeRTO) - h.congestion.OnRetransmissionTimeout(true) -} - func (h *sentPacketHandler) DequeuePacketForRetransmission() *Packet { if len(h.retransmissionQueue) == 0 { return nil @@ -539,11 +499,8 @@ func (h *sentPacketHandler) SendMode() SendMode { } return SendNone } - if h.allowTLP { - return SendTLP - } - if h.numRTOs > 0 { - return SendRTO + if h.numProbesToSend > 0 { + return SendPTO } // Only send ACKs if we're congestion limited. if cwnd := h.congestion.GetCongestionWindow(); h.bytesInFlight > cwnd { @@ -570,9 +527,9 @@ func (h *sentPacketHandler) TimeUntilSend() time.Time { } func (h *sentPacketHandler) ShouldSendNumPackets() int { - if h.numRTOs > 0 { + if h.numProbesToSend > 0 { // RTO probes should not be paced, but must be sent immediately. - return h.numRTOs + return h.numProbesToSend } delay := h.congestion.TimeUntilSend(h.bytesInFlight) if delay == 0 || delay > protocol.MinPacingDelay { @@ -610,27 +567,14 @@ func (h *sentPacketHandler) queuePacketForRetransmission(p *Packet) error { } func (h *sentPacketHandler) computeCryptoTimeout() time.Duration { - duration := utils.MaxDuration(2*h.rttStats.SmoothedOrInitialRTT(), minTPLTimeout) + duration := utils.MaxDuration(2*h.rttStats.SmoothedOrInitialRTT(), granularity) // exponential backoff // There's an implicit limit to this set by the crypto timeout. return duration << h.cryptoCount } -func (h *sentPacketHandler) computeTLPTimeout() time.Duration { +func (h *sentPacketHandler) computePTOTimeout() time.Duration { // TODO(#1236): include the max_ack_delay - return utils.MaxDuration(h.rttStats.SmoothedOrInitialRTT()*3/2, minTPLTimeout) -} - -func (h *sentPacketHandler) computeRTOTimeout() time.Duration { - var rto time.Duration - rtt := h.rttStats.SmoothedRTT() - if rtt == 0 { - rto = defaultRTOTimeout - } else { - rto = rtt + 4*h.rttStats.MeanDeviation() - } - rto = utils.MaxDuration(rto, minRTOTimeout) - // Exponential backoff - rto <<= h.rtoCount - return utils.MinDuration(rto, maxRTOTimeout) + duration := utils.MaxDuration(h.rttStats.SmoothedOrInitialRTT()+4*h.rttStats.MeanDeviation(), granularity) + return duration << h.ptoCount } diff --git a/internal/ackhandler/sent_packet_handler_test.go b/internal/ackhandler/sent_packet_handler_test.go index 2094bc68c..87f52443f 100644 --- a/internal/ackhandler/sent_packet_handler_test.go +++ b/internal/ackhandler/sent_packet_handler_test.go @@ -468,67 +468,6 @@ var _ = Describe("SentPacketHandler", func() { Expect(err).NotTo(HaveOccurred()) }) - It("doesn't call OnPacketLost and OnRetransmissionTimeout when queuing RTOs", func() { - for i := protocol.PacketNumber(1); i < 3; i++ { - cong.EXPECT().OnPacketSent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()) - cong.EXPECT().TimeUntilSend(gomock.Any()) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: i})) - } - handler.OnAlarm() // TLP - handler.OnAlarm() // TLP - handler.OnAlarm() // RTO - }) - - It("declares all lower packets lost and call OnRetransmissionTimeout when verifying an RTO", func() { - cong.EXPECT().OnPacketSent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(5) - cong.EXPECT().TimeUntilSend(gomock.Any()).Times(5) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)})) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 2, SendTime: time.Now().Add(-time.Hour)})) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 3, SendTime: time.Now().Add(-time.Hour)})) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 4, SendTime: time.Now().Add(-time.Hour)})) - handler.OnAlarm() // TLP - handler.OnAlarm() // TLP - handler.OnAlarm() // RTO - // send one probe packet and receive an ACK for it - rcvTime := time.Now() - gomock.InOrder( - cong.EXPECT().MaybeExitSlowStart(), - cong.EXPECT().OnRetransmissionTimeout(true), - cong.EXPECT().OnPacketAcked(protocol.PacketNumber(5), protocol.ByteCount(1), protocol.ByteCount(5), rcvTime), - cong.EXPECT().OnPacketLost(protocol.PacketNumber(1), protocol.ByteCount(1), protocol.ByteCount(5)), - cong.EXPECT().OnPacketLost(protocol.PacketNumber(2), protocol.ByteCount(1), protocol.ByteCount(5)), - cong.EXPECT().OnPacketLost(protocol.PacketNumber(3), protocol.ByteCount(1), protocol.ByteCount(5)), - cong.EXPECT().OnPacketLost(protocol.PacketNumber(4), protocol.ByteCount(1), protocol.ByteCount(5)), - ) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 5})) - ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 5, Largest: 5}}} - err := handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, rcvTime) - Expect(err).ToNot(HaveOccurred()) - }) - - It("doesn't call OnRetransmissionTimeout when a spurious RTO occurs", func() { - cong.EXPECT().OnPacketSent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3) - cong.EXPECT().TimeUntilSend(gomock.Any()).Times(3) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)})) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 2, SendTime: time.Now()})) - handler.OnAlarm() // TLP - handler.OnAlarm() // TLP - handler.OnAlarm() // RTO - - // send one probe packet - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 3})) - // receive an ACK for a packet send *before* the probe packet - // don't EXPECT any call to OnRetransmissionTimeout - gomock.InOrder( - cong.EXPECT().MaybeExitSlowStart(), - cong.EXPECT().OnPacketAcked(protocol.PacketNumber(2), protocol.ByteCount(1), protocol.ByteCount(3), gomock.Any()), - cong.EXPECT().OnPacketLost(protocol.PacketNumber(1), protocol.ByteCount(1), protocol.ByteCount(3)), - ) - ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 2}}} - err := handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, time.Now()) - Expect(err).ToNot(HaveOccurred()) - }) - It("doesn't call OnPacketAcked when a retransmitted packet is acked", func() { cong.EXPECT().OnPacketSent(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2) cong.EXPECT().TimeUntilSend(gomock.Any()).Times(2) @@ -621,9 +560,9 @@ var _ = Describe("SentPacketHandler", func() { It("allows RTOs, even when congestion limited", func() { // note that we don't EXPECT a call to GetCongestionWindow // that means retransmissions are sent without considering the congestion window - handler.numRTOs = 1 + handler.numProbesToSend = 1 handler.retransmissionQueue = []*Packet{{PacketNumber: 3}} - Expect(handler.SendMode()).To(Equal(SendRTO)) + Expect(handler.SendMode()).To(Equal(SendPTO)) }) It("gets the pacing delay", func() { @@ -636,7 +575,7 @@ var _ = Describe("SentPacketHandler", func() { }) It("allows sending of all RTO probe packets", func() { - handler.numRTOs = 5 + handler.numProbesToSend = 5 Expect(handler.ShouldSendNumPackets()).To(Equal(5)) }) @@ -672,81 +611,55 @@ var _ = Describe("SentPacketHandler", func() { Expect(handler.SendMode()).To(Equal(SendAny)) }) - Context("TLPs", func() { + Context("probe packets", func() { It("uses the RTT from RTT stats", func() { rtt := 2 * time.Second updateRTT(rtt) - Expect(handler.computeTLPTimeout()).To(Equal(rtt * 3 / 2)) + Expect(handler.rttStats.SmoothedOrInitialRTT()).To(Equal(2 * time.Second)) + Expect(handler.rttStats.MeanDeviation()).To(Equal(time.Second)) + Expect(handler.computePTOTimeout()).To(Equal(time.Duration(2+4) * time.Second)) }) - It("uses the minTLPTimeout for short RTTs", func() { - rtt := 2 * time.Microsecond + It("uses the granularity for short RTTs", func() { + rtt := time.Microsecond updateRTT(rtt) - Expect(handler.computeTLPTimeout()).To(Equal(minTPLTimeout)) - }) - - It("sets the TLP send mode until one retransmittable packet is sent", func() { - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)})) - handler.OnAlarm() - Expect(handler.SendMode()).To(Equal(SendTLP)) - // Send a non-retransmittable packet. - // It doesn't count as a probe packet. - handler.SentPacket(nonRetransmittablePacket(&Packet{PacketNumber: 2})) - Expect(handler.SendMode()).To(Equal(SendTLP)) - // Send a retransmittable packet. - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 3})) - Expect(handler.SendMode()).ToNot(Equal(SendTLP)) - }) - - It("sends two TLPs, then RTOs", func() { - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)})) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 2, SendTime: time.Now().Add(-time.Hour)})) - // first TLP - handler.OnAlarm() - Expect(handler.SendMode()).To(Equal(SendTLP)) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 3})) - // second TLP - handler.OnAlarm() - Expect(handler.SendMode()).To(Equal(SendTLP)) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 4})) - // fire alarm a third time - handler.OnAlarm() - Expect(handler.SendMode()).To(Equal(SendRTO)) - }) - }) - - Context("RTOs", func() { - It("uses default RTO", func() { - Expect(handler.computeRTOTimeout()).To(Equal(defaultRTOTimeout)) - }) - - It("uses RTO from rttStats", func() { - rtt := time.Second - handler.rttStats.UpdateRTT(rtt, 0, time.Now()) - Expect(handler.rttStats.SmoothedRTT()).To(Equal(rtt)) - Expect(handler.rttStats.MeanDeviation()).To(Equal(rtt / 2)) - expected := rtt + rtt/2*4 - Expect(handler.computeRTOTimeout()).To(Equal(expected)) - }) - - It("limits RTO min", func() { - rtt := 3 * time.Millisecond - updateRTT(rtt) - Expect(handler.computeRTOTimeout()).To(Equal(minRTOTimeout)) - }) - - It("limits RTO max", func() { - updateRTT(time.Hour) - Expect(handler.computeRTOTimeout()).To(Equal(maxRTOTimeout)) + Expect(handler.computePTOTimeout()).To(Equal(granularity)) }) It("implements exponential backoff", func() { - handler.rtoCount = 0 - Expect(handler.computeRTOTimeout()).To(Equal(defaultRTOTimeout)) - handler.rtoCount = 1 - Expect(handler.computeRTOTimeout()).To(Equal(2 * defaultRTOTimeout)) - handler.rtoCount = 2 - Expect(handler.computeRTOTimeout()).To(Equal(4 * defaultRTOTimeout)) + handler.ptoCount = 0 + timeout := handler.computePTOTimeout() + Expect(timeout).ToNot(BeZero()) + handler.ptoCount = 1 + Expect(handler.computePTOTimeout()).To(Equal(2 * timeout)) + handler.ptoCount = 2 + Expect(handler.computePTOTimeout()).To(Equal(4 * timeout)) + }) + + It("sets the TPO send mode until two packets is sent", func() { + handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)})) + handler.OnAlarm() + Expect(handler.SendMode()).To(Equal(SendPTO)) + Expect(handler.ShouldSendNumPackets()).To(Equal(2)) + handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 2})) + Expect(handler.SendMode()).To(Equal(SendPTO)) + handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 3})) + Expect(handler.SendMode()).ToNot(Equal(SendPTO)) + }) + + It("only counts retransmittable packets as probe packets", func() { + handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)})) + handler.OnAlarm() + Expect(handler.SendMode()).To(Equal(SendPTO)) + Expect(handler.ShouldSendNumPackets()).To(Equal(2)) + handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 2})) + Expect(handler.SendMode()).To(Equal(SendPTO)) + for p := protocol.PacketNumber(3); p < 30; p++ { + handler.SentPacket(nonRetransmittablePacket(&Packet{PacketNumber: p})) + Expect(handler.SendMode()).To(Equal(SendPTO)) + } + handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 30})) + Expect(handler.SendMode()).ToNot(Equal(SendPTO)) }) It("gets two probe packets if RTO expires", func() { @@ -755,7 +668,6 @@ var _ = Describe("SentPacketHandler", func() { updateRTT(time.Hour) Expect(handler.lossTime.IsZero()).To(BeTrue()) - Expect(time.Until(handler.GetAlarmTimeout())).To(BeNumerically("~", handler.computeRTOTimeout(), time.Minute)) handler.OnAlarm() // TLP handler.OnAlarm() // TLP @@ -770,7 +682,7 @@ var _ = Describe("SentPacketHandler", func() { Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(2))) Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(2))) - Expect(handler.rtoCount).To(BeEquivalentTo(1)) + Expect(handler.ptoCount).To(BeEquivalentTo(3)) }) It("doesn't delete packets transmitted as RTO from the history", func() { @@ -797,20 +709,6 @@ var _ = Describe("SentPacketHandler", func() { Expect(handler.retransmissionQueue).To(BeEmpty()) // 1 and 2 were already sent as probe packets }) - It("allows sending of two probe packets", func() { - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)})) - handler.OnAlarm() // TLP - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 2})) // send the first TLP - handler.OnAlarm() // TLP - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 3})) // send the second TLP - handler.OnAlarm() // RTO - Expect(handler.SendMode()).To(Equal(SendRTO)) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 4})) - Expect(handler.SendMode()).To(Equal(SendRTO)) - handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 5})) - Expect(handler.SendMode()).ToNot(Equal(SendRTO)) - }) - It("gets packets sent before the probe packet for retransmission", func() { handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 1, SendTime: time.Now().Add(-time.Hour)})) handler.SentPacket(retransmittablePacket(&Packet{PacketNumber: 2, SendTime: time.Now().Add(-time.Hour)})) diff --git a/session.go b/session.go index 2cdd6d8c0..b5fa84b9d 100644 --- a/session.go +++ b/session.go @@ -821,7 +821,7 @@ sendLoop: // There will only be a new ACK after receiving new packets. // SendAck is only returned when we're congestion limited, so we don't need to set the pacingt timer. return s.maybeSendAckOnlyPacket() - case ackhandler.SendTLP, ackhandler.SendRTO: + case ackhandler.SendPTO: if err := s.sendProbePacket(); err != nil { return err } diff --git a/session_test.go b/session_test.go index 02fb35792..27f09146e 100644 --- a/session_test.go +++ b/session_test.go @@ -697,7 +697,7 @@ var _ = Describe("Session", func() { retransmittedPacket := getPacket(123) sph := mockackhandler.NewMockSentPacketHandler(mockCtrl) sph.EXPECT().TimeUntilSend() - sph.EXPECT().SendMode().Return(ackhandler.SendTLP) + sph.EXPECT().SendMode().Return(ackhandler.SendPTO) sph.EXPECT().ShouldSendNumPackets().Return(1) sph.EXPECT().DequeueProbePacket().Return(packetToRetransmit, nil) packer.EXPECT().PackRetransmission(packetToRetransmit).Return([]*packedPacket{retransmittedPacket}, nil)