mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 12:47:36 +03:00
retransmit frames instead of packets
This commit is contained in:
parent
515c21dd1d
commit
1d392b4276
16 changed files with 705 additions and 962 deletions
|
@ -14,40 +14,15 @@ import (
|
|||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func ackElicitingPacket(p *Packet) *Packet {
|
||||
if p.EncryptionLevel == protocol.EncryptionUnspecified {
|
||||
p.EncryptionLevel = protocol.Encryption1RTT
|
||||
}
|
||||
if p.Length == 0 {
|
||||
p.Length = 1
|
||||
}
|
||||
if p.SendTime.IsZero() {
|
||||
p.SendTime = time.Now()
|
||||
}
|
||||
p.Frames = []wire.Frame{&wire.PingFrame{}}
|
||||
return p
|
||||
}
|
||||
|
||||
func nonAckElicitingPacket(p *Packet) *Packet {
|
||||
p = ackElicitingPacket(p)
|
||||
p.Frames = nil
|
||||
p.LargestAcked = 1
|
||||
return p
|
||||
}
|
||||
|
||||
func cryptoPacket(p *Packet) *Packet {
|
||||
p = ackElicitingPacket(p)
|
||||
p.EncryptionLevel = protocol.EncryptionInitial
|
||||
return p
|
||||
}
|
||||
|
||||
var _ = Describe("SentPacketHandler", func() {
|
||||
var (
|
||||
handler *sentPacketHandler
|
||||
streamFrame wire.StreamFrame
|
||||
lostPackets []protocol.PacketNumber
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
lostPackets = nil
|
||||
rttStats := &congestion.RTTStats{}
|
||||
handler = NewSentPacketHandler(42, rttStats, nil, utils.DefaultLogger).(*sentPacketHandler)
|
||||
streamFrame = wire.StreamFrame{
|
||||
|
@ -63,6 +38,35 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
return nil
|
||||
}
|
||||
|
||||
ackElicitingPacket := func(p *Packet) *Packet {
|
||||
if p.EncryptionLevel == protocol.EncryptionUnspecified {
|
||||
p.EncryptionLevel = protocol.Encryption1RTT
|
||||
}
|
||||
if p.Length == 0 {
|
||||
p.Length = 1
|
||||
}
|
||||
if p.SendTime.IsZero() {
|
||||
p.SendTime = time.Now()
|
||||
}
|
||||
p.Frames = []Frame{
|
||||
{Frame: &wire.PingFrame{}, OnLost: func(wire.Frame) { lostPackets = append(lostPackets, p.PacketNumber) }},
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
nonAckElicitingPacket := func(p *Packet) *Packet {
|
||||
p = ackElicitingPacket(p)
|
||||
p.Frames = nil
|
||||
p.LargestAcked = 1
|
||||
return p
|
||||
}
|
||||
|
||||
cryptoPacket := func(p *Packet) *Packet {
|
||||
p = ackElicitingPacket(p)
|
||||
p.EncryptionLevel = protocol.EncryptionInitial
|
||||
return p
|
||||
}
|
||||
|
||||
expectInPacketHistory := func(expected []protocol.PacketNumber, encLevel protocol.EncryptionLevel) {
|
||||
pnSpace := handler.getPacketNumberSpace(encLevel)
|
||||
ExpectWithOffset(1, pnSpace.history.Len()).To(Equal(len(expected)))
|
||||
|
@ -161,21 +165,21 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
})
|
||||
})
|
||||
|
||||
Context("acks and nacks the right packets", func() {
|
||||
Context("acks the right packets", func() {
|
||||
expectInPacketHistoryOrLost := func(expected []protocol.PacketNumber, encLevel protocol.EncryptionLevel) {
|
||||
pnSpace := handler.getPacketNumberSpace(encLevel)
|
||||
ExpectWithOffset(1, pnSpace.history.Len()+len(handler.retransmissionQueue)).To(Equal(len(expected)))
|
||||
ExpectWithOffset(1, pnSpace.history.Len()+len(lostPackets)).To(Equal(len(expected)))
|
||||
expectedLoop:
|
||||
for _, p := range expected {
|
||||
if _, ok := pnSpace.history.packetMap[p]; ok {
|
||||
continue
|
||||
}
|
||||
for _, lost := range handler.retransmissionQueue {
|
||||
if lost.PacketNumber == p {
|
||||
for _, lostP := range lostPackets {
|
||||
if lostP == p {
|
||||
continue expectedLoop
|
||||
}
|
||||
}
|
||||
Fail(fmt.Sprintf("Packet %d neither in packet history nor declared lost.", p))
|
||||
Fail(fmt.Sprintf("Packet %d not in packet history.", p))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,9 +324,26 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
Context("determining which ACKs we have received an ACK for", func() {
|
||||
BeforeEach(func() {
|
||||
morePackets := []*Packet{
|
||||
{PacketNumber: 13, LargestAcked: 100, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.Encryption1RTT},
|
||||
{PacketNumber: 14, LargestAcked: 200, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.Encryption1RTT},
|
||||
{PacketNumber: 15, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.Encryption1RTT},
|
||||
{
|
||||
PacketNumber: 13,
|
||||
LargestAcked: 100,
|
||||
Frames: []Frame{{Frame: &streamFrame, OnLost: func(wire.Frame) {}}},
|
||||
Length: 1,
|
||||
EncryptionLevel: protocol.Encryption1RTT,
|
||||
},
|
||||
{
|
||||
PacketNumber: 14,
|
||||
LargestAcked: 200,
|
||||
Frames: []Frame{{Frame: &streamFrame, OnLost: func(wire.Frame) {}}},
|
||||
Length: 1,
|
||||
EncryptionLevel: protocol.Encryption1RTT,
|
||||
},
|
||||
{
|
||||
PacketNumber: 15,
|
||||
Frames: []Frame{{Frame: &streamFrame, OnLost: func(wire.Frame) {}}},
|
||||
Length: 1,
|
||||
EncryptionLevel: protocol.Encryption1RTT,
|
||||
},
|
||||
}
|
||||
for _, packet := range morePackets {
|
||||
handler.SentPacket(packet)
|
||||
|
@ -355,11 +376,6 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
})
|
||||
})
|
||||
|
||||
It("does not dequeue a packet if no ACK has been received", func() {
|
||||
handler.SentPacket(&Packet{PacketNumber: 1, EncryptionLevel: protocol.Encryption1RTT, SendTime: time.Now().Add(-time.Hour)})
|
||||
Expect(handler.DequeuePacketForRetransmission()).To(BeNil())
|
||||
})
|
||||
|
||||
Context("congestion", func() {
|
||||
var cong *mocks.MockSendAlgorithmWithDebugInfos
|
||||
|
||||
|
@ -380,7 +396,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
handler.SentPacket(&Packet{
|
||||
PacketNumber: 1,
|
||||
Length: 42,
|
||||
Frames: []wire.Frame{&wire.PingFrame{}},
|
||||
Frames: []Frame{{Frame: &wire.PingFrame{}, OnLost: func(wire.Frame) {}}},
|
||||
EncryptionLevel: protocol.Encryption1RTT,
|
||||
})
|
||||
})
|
||||
|
@ -474,32 +490,10 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
Expect(handler.SendMode()).To(Equal(SendAck))
|
||||
})
|
||||
|
||||
It("doesn't allow retransmissions if congestion limited", func() {
|
||||
handler.retransmissionQueue = []*Packet{{PacketNumber: 3}}
|
||||
cong.EXPECT().CanSend(gomock.Any()).Return(false)
|
||||
Expect(handler.SendMode()).To(Equal(SendAck))
|
||||
})
|
||||
|
||||
It("allows sending retransmissions", func() {
|
||||
cong.EXPECT().CanSend(gomock.Any()).Return(true)
|
||||
handler.retransmissionQueue = []*Packet{{PacketNumber: 3}}
|
||||
Expect(handler.SendMode()).To(Equal(SendRetransmission))
|
||||
})
|
||||
|
||||
It("allows retransmissions, if we're keeping track of between MaxOutstandingSentPackets and MaxTrackedSentPackets packets", func() {
|
||||
cong.EXPECT().CanSend(gomock.Any()).Return(true)
|
||||
Expect(protocol.MaxOutstandingSentPackets).To(BeNumerically("<", protocol.MaxTrackedSentPackets))
|
||||
handler.retransmissionQueue = make([]*Packet, protocol.MaxOutstandingSentPackets+10)
|
||||
Expect(handler.SendMode()).To(Equal(SendRetransmission))
|
||||
handler.retransmissionQueue = make([]*Packet, protocol.MaxTrackedSentPackets)
|
||||
Expect(handler.SendMode()).To(Equal(SendNone))
|
||||
})
|
||||
|
||||
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.numProbesToSend = 1
|
||||
handler.retransmissionQueue = []*Packet{{PacketNumber: 3}}
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
})
|
||||
|
||||
|
@ -550,6 +544,19 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
})
|
||||
|
||||
Context("probe packets", func() {
|
||||
It("queues a probe packet", func() {
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 10}))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 11}))
|
||||
queued := handler.QueueProbePacket()
|
||||
Expect(queued).To(BeTrue())
|
||||
Expect(lostPackets).To(Equal([]protocol.PacketNumber{10}))
|
||||
})
|
||||
|
||||
It("says when it can't queue a probe packet", func() {
|
||||
queued := handler.QueueProbePacket()
|
||||
Expect(queued).To(BeFalse())
|
||||
})
|
||||
|
||||
It("implements exponential backoff", func() {
|
||||
sendTime := time.Now().Add(-time.Hour)
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 1, SendTime: sendTime}))
|
||||
|
@ -563,9 +570,16 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
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.OnLossDetectionTimeout()
|
||||
It("sets the PTO send mode until two packets is sent", func() {
|
||||
var lostPackets []protocol.PacketNumber
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{
|
||||
PacketNumber: 1,
|
||||
SendTime: time.Now().Add(-time.Hour),
|
||||
Frames: []Frame{
|
||||
{Frame: &wire.PingFrame{}, OnLost: func(wire.Frame) { lostPackets = append(lostPackets, 1) }},
|
||||
},
|
||||
}))
|
||||
Expect(handler.OnLossDetectionTimeout()).To(Succeed())
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
Expect(handler.ShouldSendNumPackets()).To(Equal(2))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 2}))
|
||||
|
@ -576,7 +590,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.OnLossDetectionTimeout()
|
||||
Expect(handler.OnLossDetectionTimeout()).To(Succeed())
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
Expect(handler.ShouldSendNumPackets()).To(Equal(2))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 2}))
|
||||
|
@ -596,104 +610,49 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
updateRTT(time.Hour)
|
||||
Expect(handler.oneRTTPackets.lossTime.IsZero()).To(BeTrue())
|
||||
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // RTO
|
||||
p, err := handler.DequeueProbePacket()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(p).ToNot(BeNil())
|
||||
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||
p, err = handler.DequeueProbePacket()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(p).ToNot(BeNil())
|
||||
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(2)))
|
||||
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(2)))
|
||||
Expect(handler.OnLossDetectionTimeout()).To(Succeed()) // TLP
|
||||
Expect(handler.ptoCount).To(BeEquivalentTo(1))
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 3}))
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 4}))
|
||||
|
||||
Expect(handler.ptoCount).To(BeEquivalentTo(3))
|
||||
Expect(handler.OnLossDetectionTimeout()).To(Succeed()) // PTO
|
||||
Expect(handler.ptoCount).To(BeEquivalentTo(2))
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 5}))
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 6}))
|
||||
|
||||
Expect(handler.SendMode()).To(Equal(SendAny))
|
||||
})
|
||||
|
||||
It("gets two probe packets if RTO expires, for crypto packets", func() {
|
||||
It("gets two probe packets if PTO expires, for crypto packets", func() {
|
||||
handler.SentPacket(cryptoPacket(&Packet{PacketNumber: 1}))
|
||||
handler.SentPacket(cryptoPacket(&Packet{PacketNumber: 2}))
|
||||
|
||||
updateRTT(time.Hour)
|
||||
Expect(handler.initialPackets.lossTime.IsZero()).To(BeTrue())
|
||||
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // RTO
|
||||
p, err := handler.DequeueProbePacket()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(p).ToNot(BeNil())
|
||||
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||
p, err = handler.DequeueProbePacket()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(p).ToNot(BeNil())
|
||||
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(2)))
|
||||
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(2)))
|
||||
Expect(handler.OnLossDetectionTimeout()).To(Succeed())
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
handler.SentPacket(cryptoPacket(&Packet{PacketNumber: 3}))
|
||||
Expect(handler.SendMode()).To(Equal(SendPTO))
|
||||
handler.SentPacket(cryptoPacket(&Packet{PacketNumber: 3}))
|
||||
|
||||
Expect(handler.ptoCount).To(BeEquivalentTo(3))
|
||||
})
|
||||
|
||||
It("doesn't delete packets transmitted as PTO from the history", 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.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // RTO
|
||||
_, err := handler.DequeueProbePacket()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = handler.DequeueProbePacket()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
expectInPacketHistory([]protocol.PacketNumber{1, 2}, protocol.Encryption1RTT)
|
||||
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(2)))
|
||||
// Send a probe packet and receive an ACK for it.
|
||||
// This verifies the RTO.
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 3}))
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 3, Largest: 3}}}
|
||||
Expect(handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, time.Now())).To(Succeed())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(handler.oneRTTPackets.history.Len()).To(BeZero())
|
||||
Expect(handler.bytesInFlight).To(BeZero())
|
||||
Expect(handler.retransmissionQueue).To(BeEmpty()) // 1 and 2 were already sent as probe packets
|
||||
Expect(handler.SendMode()).To(Equal(SendAny))
|
||||
})
|
||||
|
||||
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.OnLossDetectionTimeout()
|
||||
Expect(handler.OnLossDetectionTimeout()).To(Succeed())
|
||||
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())
|
||||
Expect(handler.SendMode()).To(Equal(SendAny))
|
||||
})
|
||||
|
||||
It("gets packets sent before the probe packet for retransmission", 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.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.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // TLP
|
||||
handler.OnLossDetectionTimeout() // RTO
|
||||
_, err := handler.DequeueProbePacket()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, err = handler.DequeueProbePacket()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
expectInPacketHistory([]protocol.PacketNumber{1, 2, 3, 4, 5}, protocol.Encryption1RTT)
|
||||
// Send a probe packet and receive an ACK for it.
|
||||
// This verifies the RTO.
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 6}))
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 6, Largest: 6}}}
|
||||
err = handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, time.Now())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(handler.oneRTTPackets.history.Len()).To(BeZero())
|
||||
Expect(handler.bytesInFlight).To(BeZero())
|
||||
Expect(handler.retransmissionQueue).To(HaveLen(3)) // packets 3, 4, 5
|
||||
})
|
||||
|
||||
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())
|
||||
|
@ -712,11 +671,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 6, Largest: 6}}}
|
||||
Expect(handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, time.Now())).To(Succeed())
|
||||
expectInPacketHistory([]protocol.PacketNumber{4, 5}, protocol.Encryption1RTT)
|
||||
for _, p := range []protocol.PacketNumber{1, 2, 3} {
|
||||
lost := handler.DequeuePacketForRetransmission()
|
||||
Expect(lost).ToNot(BeNil())
|
||||
Expect(lost.PacketNumber).To(Equal(p))
|
||||
}
|
||||
Expect(lostPackets).To(Equal([]protocol.PacketNumber{1, 2, 3}))
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -729,8 +684,6 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 2, Largest: 2}}}
|
||||
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.oneRTTPackets.lossTime.IsZero()).To(BeTrue())
|
||||
Expect(handler.bytesInFlight).To(BeZero())
|
||||
|
@ -750,11 +703,6 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
// Packet 1 should be considered lost (1+1/8) RTTs after it was sent.
|
||||
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.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())
|
||||
})
|
||||
|
||||
It("sets the early retransmit alarm for crypto packets", func() {
|
||||
|
@ -771,22 +719,15 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
// Packet 1 should be considered lost (1+1/8) RTTs after it was sent.
|
||||
Expect(handler.initialPackets.lossTime.IsZero()).To(BeFalse())
|
||||
Expect(handler.initialPackets.lossTime.Sub(getPacket(1, protocol.EncryptionInitial).SendTime)).To(Equal(time.Second * 9 / 8))
|
||||
|
||||
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())
|
||||
})
|
||||
})
|
||||
|
||||
Context("crypto packets", func() {
|
||||
It("rejects an ACK that acks packets with a higher encryption level", func() {
|
||||
handler.SentPacket(&Packet{
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{
|
||||
PacketNumber: 13,
|
||||
EncryptionLevel: protocol.Encryption1RTT,
|
||||
Frames: []wire.Frame{&streamFrame},
|
||||
Length: 1,
|
||||
})
|
||||
}))
|
||||
ack := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 13, Largest: 13}}}
|
||||
err := handler.ReceivedAck(ack, 1, protocol.EncryptionHandshake, time.Now())
|
||||
Expect(err).To(MatchError("PROTOCOL_VIOLATION: Received ACK for an unsent packet"))
|
||||
|
@ -794,43 +735,43 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
|
||||
It("deletes Initial packets", func() {
|
||||
for i := protocol.PacketNumber(0); i < 6; i++ {
|
||||
p := ackElicitingPacket(&Packet{PacketNumber: i, EncryptionLevel: protocol.EncryptionInitial})
|
||||
handler.SentPacket(p)
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{
|
||||
PacketNumber: i,
|
||||
EncryptionLevel: protocol.EncryptionInitial,
|
||||
}))
|
||||
}
|
||||
for i := protocol.PacketNumber(0); i < 10; i++ {
|
||||
p := ackElicitingPacket(&Packet{PacketNumber: i, EncryptionLevel: protocol.EncryptionHandshake})
|
||||
handler.SentPacket(p)
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{
|
||||
PacketNumber: i,
|
||||
EncryptionLevel: protocol.EncryptionHandshake,
|
||||
}))
|
||||
}
|
||||
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(16)))
|
||||
handler.queuePacketForRetransmission(getPacket(1, protocol.EncryptionInitial), handler.getPacketNumberSpace(protocol.EncryptionInitial))
|
||||
lostPacket := getPacket(3, protocol.EncryptionHandshake)
|
||||
handler.queuePacketForRetransmission(lostPacket, handler.getPacketNumberSpace(protocol.EncryptionHandshake))
|
||||
handler.DropPackets(protocol.EncryptionInitial)
|
||||
Expect(lostPackets).To(BeEmpty()) // frames must not be queued for retransmission
|
||||
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(10)))
|
||||
Expect(handler.initialPackets).To(BeNil())
|
||||
Expect(handler.handshakePackets.history.Len()).ToNot(BeZero())
|
||||
packet := handler.DequeuePacketForRetransmission()
|
||||
Expect(packet).To(Equal(lostPacket))
|
||||
})
|
||||
|
||||
It("deletes Handshake packets", func() {
|
||||
for i := protocol.PacketNumber(0); i < 6; i++ {
|
||||
p := ackElicitingPacket(&Packet{PacketNumber: i, EncryptionLevel: protocol.EncryptionHandshake})
|
||||
handler.SentPacket(p)
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{
|
||||
PacketNumber: i,
|
||||
EncryptionLevel: protocol.EncryptionHandshake,
|
||||
}))
|
||||
}
|
||||
for i := protocol.PacketNumber(0); i < 10; i++ {
|
||||
p := ackElicitingPacket(&Packet{PacketNumber: i, EncryptionLevel: protocol.Encryption1RTT})
|
||||
handler.SentPacket(p)
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{
|
||||
PacketNumber: i,
|
||||
EncryptionLevel: protocol.Encryption1RTT,
|
||||
}))
|
||||
}
|
||||
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(16)))
|
||||
handler.queuePacketForRetransmission(getPacket(1, protocol.EncryptionHandshake), handler.getPacketNumberSpace(protocol.EncryptionInitial))
|
||||
lostPacket := getPacket(3, protocol.Encryption1RTT)
|
||||
handler.queuePacketForRetransmission(lostPacket, handler.getPacketNumberSpace(protocol.EncryptionHandshake))
|
||||
handler.DropPackets(protocol.EncryptionHandshake)
|
||||
Expect(lostPackets).To(BeEmpty()) // frames must not be queued for retransmission
|
||||
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(10)))
|
||||
Expect(handler.handshakePackets).To(BeNil())
|
||||
packet := handler.DequeuePacketForRetransmission()
|
||||
Expect(packet).To(Equal(lostPacket))
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -858,25 +799,16 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
|
||||
Context("resetting for retry", func() {
|
||||
It("queues outstanding packets for retransmission and cancels alarms", func() {
|
||||
packet := &Packet{
|
||||
PacketNumber: 42,
|
||||
EncryptionLevel: protocol.EncryptionInitial,
|
||||
Frames: []wire.Frame{&wire.CryptoFrame{Data: []byte("foobar")}},
|
||||
Length: 100,
|
||||
}
|
||||
handler.SentPacket(packet)
|
||||
handler.SentPacket(ackElicitingPacket(&Packet{PacketNumber: 42, EncryptionLevel: protocol.EncryptionInitial}))
|
||||
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(lostPackets).To(Equal([]protocol.PacketNumber{42}))
|
||||
Expect(handler.bytesInFlight).To(BeZero())
|
||||
Expect(handler.GetLossDetectionTimeout()).To(BeZero())
|
||||
Expect(handler.SendMode()).To(Equal(SendRetransmission))
|
||||
p := handler.DequeuePacketForRetransmission()
|
||||
Expect(p.PacketNumber).To(Equal(packet.PacketNumber))
|
||||
Expect(p.Frames).To(Equal(packet.Frames))
|
||||
Expect(handler.SendMode()).To(Equal(SendAny))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue