determine if a received packet is new (and not a duplicate / delayed packet)

This commit is contained in:
Marten Seemann 2020-05-12 16:05:00 +07:00
parent f54953fb1d
commit bee5ef624f
2 changed files with 77 additions and 75 deletions

View file

@ -22,25 +22,26 @@ func newReceivedPacketHistory() *receivedPacketHistory {
}
// ReceivedPacket registers a packet with PacketNumber p and updates the ranges
func (h *receivedPacketHistory) ReceivedPacket(p protocol.PacketNumber) {
func (h *receivedPacketHistory) ReceivedPacket(p protocol.PacketNumber) bool /* is a new packet (and not a duplicate / delayed packet) */ {
// ignore delayed packets, if we already deleted the range
if p < h.deletedBelow {
return
return false
}
h.addToRanges(p)
isNew := h.addToRanges(p)
h.maybeDeleteOldRanges()
return isNew
}
func (h *receivedPacketHistory) addToRanges(p protocol.PacketNumber) {
func (h *receivedPacketHistory) addToRanges(p protocol.PacketNumber) bool /* is a new packet (and not a duplicate / delayed packet) */ {
if h.ranges.Len() == 0 {
h.ranges.PushBack(utils.PacketInterval{Start: p, End: p})
return
return true
}
for el := h.ranges.Back(); el != nil; el = el.Prev() {
// p already included in an existing range. Nothing to do here
if p >= el.Value.Start && p <= el.Value.End {
return
return false
}
var rangeExtended bool
@ -58,20 +59,20 @@ func (h *receivedPacketHistory) addToRanges(p protocol.PacketNumber) {
if prev != nil && prev.Value.End+1 == el.Value.Start { // merge two ranges
prev.Value.End = el.Value.End
h.ranges.Remove(el)
return
}
return // if the two ranges were not merge, we're done here
return true // if the two ranges were not merge, we're done here
}
// create a new range at the end
if p > el.Value.End {
h.ranges.InsertAfter(utils.PacketInterval{Start: p, End: p}, el)
return
return true
}
}
// create a new range at the beginning
h.ranges.InsertBefore(utils.PacketInterval{Start: p, End: p}, h.ranges.Front())
return true
}
// Delete old ranges, if we're tracking more than 500 of them.

View file

@ -19,54 +19,55 @@ var _ = Describe("receivedPacketHistory", func() {
Context("ranges", func() {
It("adds the first packet", func() {
hist.ReceivedPacket(4)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 4}))
})
It("doesn't care about duplicate packets", func() {
hist.ReceivedPacket(4)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(4)).To(BeFalse())
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 4}))
})
It("adds a few consecutive packets", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(5)
hist.ReceivedPacket(6)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.ReceivedPacket(6)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 6}))
})
It("doesn't care about a duplicate packet contained in an existing range", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(5)
hist.ReceivedPacket(6)
hist.ReceivedPacket(5)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.ReceivedPacket(6)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeFalse())
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 6}))
})
It("extends a range at the front", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(3)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(3)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 3, End: 4}))
})
It("creates a new range when a packet is lost", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(6)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(6)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(2))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 4}))
Expect(hist.ranges.Back().Value).To(Equal(utils.PacketInterval{Start: 6, End: 6}))
})
It("creates a new range in between two ranges", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(10)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(10)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(2))
hist.ReceivedPacket(7)
Expect(hist.ReceivedPacket(7)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(3))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 4}))
Expect(hist.ranges.Front().Next().Value).To(Equal(utils.PacketInterval{Start: 7, End: 7}))
@ -74,47 +75,47 @@ var _ = Describe("receivedPacketHistory", func() {
})
It("creates a new range before an existing range for a belated packet", func() {
hist.ReceivedPacket(6)
hist.ReceivedPacket(4)
Expect(hist.ReceivedPacket(6)).To(BeTrue())
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(2))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 4}))
Expect(hist.ranges.Back().Value).To(Equal(utils.PacketInterval{Start: 6, End: 6}))
})
It("extends a previous range at the end", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(7)
hist.ReceivedPacket(5)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(7)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(2))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 5}))
Expect(hist.ranges.Back().Value).To(Equal(utils.PacketInterval{Start: 7, End: 7}))
})
It("extends a range at the front", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(7)
hist.ReceivedPacket(6)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(7)).To(BeTrue())
Expect(hist.ReceivedPacket(6)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(2))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 4}))
Expect(hist.ranges.Back().Value).To(Equal(utils.PacketInterval{Start: 6, End: 7}))
})
It("closes a range", func() {
hist.ReceivedPacket(6)
hist.ReceivedPacket(4)
Expect(hist.ReceivedPacket(6)).To(BeTrue())
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(2))
hist.ReceivedPacket(5)
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 6}))
})
It("closes a range in the middle", func() {
hist.ReceivedPacket(1)
hist.ReceivedPacket(10)
hist.ReceivedPacket(4)
hist.ReceivedPacket(6)
Expect(hist.ReceivedPacket(1)).To(BeTrue())
Expect(hist.ReceivedPacket(10)).To(BeTrue())
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(6)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(4))
hist.ReceivedPacket(5)
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.ranges.Len()).To(Equal(3))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 1, End: 1}))
Expect(hist.ranges.Front().Next().Value).To(Equal(utils.PacketInterval{Start: 4, End: 6}))
@ -129,38 +130,38 @@ var _ = Describe("receivedPacketHistory", func() {
})
It("deletes a range", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(5)
hist.ReceivedPacket(10)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.ReceivedPacket(10)).To(BeTrue())
hist.DeleteBelow(6)
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 10, End: 10}))
})
It("deletes multiple ranges", func() {
hist.ReceivedPacket(1)
hist.ReceivedPacket(5)
hist.ReceivedPacket(10)
Expect(hist.ReceivedPacket(1)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.ReceivedPacket(10)).To(BeTrue())
hist.DeleteBelow(8)
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 10, End: 10}))
})
It("adjusts a range, if packets are delete from an existing range", func() {
hist.ReceivedPacket(3)
hist.ReceivedPacket(4)
hist.ReceivedPacket(5)
hist.ReceivedPacket(6)
hist.ReceivedPacket(7)
Expect(hist.ReceivedPacket(3)).To(BeTrue())
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.ReceivedPacket(6)).To(BeTrue())
Expect(hist.ReceivedPacket(7)).To(BeTrue())
hist.DeleteBelow(5)
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 5, End: 7}))
})
It("adjusts a range, if only one packet remains in the range", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(5)
hist.ReceivedPacket(10)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.ReceivedPacket(10)).To(BeTrue())
hist.DeleteBelow(5)
Expect(hist.ranges.Len()).To(Equal(2))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 5, End: 5}))
@ -168,27 +169,27 @@ var _ = Describe("receivedPacketHistory", func() {
})
It("keeps a one-packet range, if deleting up to the packet directly below", func() {
hist.ReceivedPacket(4)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
hist.DeleteBelow(4)
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 4}))
})
It("doesn't add delayed packets below deleted ranges", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(5)
hist.ReceivedPacket(6)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.ReceivedPacket(6)).To(BeTrue())
hist.DeleteBelow(5)
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 5, End: 6}))
hist.ReceivedPacket(2)
Expect(hist.ReceivedPacket(2)).To(BeFalse())
Expect(hist.ranges.Len()).To(Equal(1))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 5, End: 6}))
})
It("doesn't create more than MaxNumAckRanges ranges", func() {
for i := protocol.PacketNumber(0); i < protocol.MaxNumAckRanges; i++ {
hist.ReceivedPacket(2 * i)
Expect(hist.ReceivedPacket(2 * i)).To(BeTrue())
}
Expect(hist.ranges.Len()).To(Equal(protocol.MaxNumAckRanges))
Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 0, End: 0}))
@ -205,21 +206,21 @@ var _ = Describe("receivedPacketHistory", func() {
})
It("gets a single ACK range", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(5)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeTrue())
ackRanges := hist.GetAckRanges()
Expect(ackRanges).To(HaveLen(1))
Expect(ackRanges[0]).To(Equal(wire.AckRange{Smallest: 4, Largest: 5}))
})
It("gets multiple ACK ranges", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(5)
hist.ReceivedPacket(6)
hist.ReceivedPacket(1)
hist.ReceivedPacket(11)
hist.ReceivedPacket(10)
hist.ReceivedPacket(2)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.ReceivedPacket(6)).To(BeTrue())
Expect(hist.ReceivedPacket(1)).To(BeTrue())
Expect(hist.ReceivedPacket(11)).To(BeTrue())
Expect(hist.ReceivedPacket(10)).To(BeTrue())
Expect(hist.ReceivedPacket(2)).To(BeTrue())
ackRanges := hist.GetAckRanges()
Expect(ackRanges).To(HaveLen(3))
Expect(ackRanges[0]).To(Equal(wire.AckRange{Smallest: 10, Largest: 11}))
@ -234,15 +235,15 @@ var _ = Describe("receivedPacketHistory", func() {
})
It("gets a single ACK range", func() {
hist.ReceivedPacket(4)
hist.ReceivedPacket(5)
Expect(hist.ReceivedPacket(4)).To(BeTrue())
Expect(hist.ReceivedPacket(5)).To(BeTrue())
Expect(hist.GetHighestAckRange()).To(Equal(wire.AckRange{Smallest: 4, Largest: 5}))
})
It("gets the highest of multiple ACK ranges", func() {
hist.ReceivedPacket(3)
hist.ReceivedPacket(6)
hist.ReceivedPacket(7)
Expect(hist.ReceivedPacket(3)).To(BeTrue())
Expect(hist.ReceivedPacket(6)).To(BeTrue())
Expect(hist.ReceivedPacket(7)).To(BeTrue())
Expect(hist.GetHighestAckRange()).To(Equal(wire.AckRange{Smallest: 6, Largest: 7}))
})
})