From 7da4e3e5fbf9c1d977b71c1c9bcd5e9fb73d4bc2 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 27 Jun 2016 15:20:03 +0700 Subject: [PATCH] add method to get ACK ranges from packet history ref #190 --- ackhandlernew/received_packet_history.go | 16 ++ ackhandlernew/received_packet_history_test.go | 226 ++++++++++-------- 2 files changed, 145 insertions(+), 97 deletions(-) diff --git a/ackhandlernew/received_packet_history.go b/ackhandlernew/received_packet_history.go index 1cbe19bf..e843668a 100644 --- a/ackhandlernew/received_packet_history.go +++ b/ackhandlernew/received_packet_history.go @@ -1,6 +1,7 @@ package ackhandlernew import ( + "github.com/lucas-clemente/quic-go/frames" "github.com/lucas-clemente/quic-go/protocol" "github.com/lucas-clemente/quic-go/utils" ) @@ -59,3 +60,18 @@ func (h *receivedPacketHistory) ReceivedPacket(p protocol.PacketNumber) { // create a new range at the beginning h.ranges.InsertBefore(utils.PacketInterval{Start: p, End: p}, h.ranges.Front()) } + +// GetAckRanges gets a slice of all AckRanges that can be used in an AckFrame +func (h *receivedPacketHistory) GetAckRanges() []frames.AckRange { + if h.ranges.Len() == 0 { + return nil + } + + var ackRanges []frames.AckRange + + for el := h.ranges.Back(); el != nil; el = el.Prev() { + ackRanges = append(ackRanges, frames.AckRange{FirstPacketNumber: el.Value.Start, LastPacketNumber: el.Value.End}) + } + + return ackRanges +} diff --git a/ackhandlernew/received_packet_history_test.go b/ackhandlernew/received_packet_history_test.go index bc1e1664..5088e83d 100644 --- a/ackhandlernew/received_packet_history_test.go +++ b/ackhandlernew/received_packet_history_test.go @@ -1,6 +1,7 @@ package ackhandlernew import ( + "github.com/lucas-clemente/quic-go/frames" "github.com/lucas-clemente/quic-go/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -15,106 +16,137 @@ var _ = Describe("receivedPacketHistory", func() { hist = newReceivedPacketHistory() }) - It("adds the first packet", func() { - hist.ReceivedPacket(4) - Expect(hist.ranges.Len()).To(Equal(1)) - Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 4})) + Context("ranges", func() { + It("adds the first packet", func() { + hist.ReceivedPacket(4) + 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.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.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.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.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.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.ranges.Len()).To(Equal(2)) + hist.ReceivedPacket(7) + 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})) + Expect(hist.ranges.Back().Value).To(Equal(utils.PacketInterval{Start: 10, End: 10})) + }) + + It("creates a new range before an existing range for a belated packet", func() { + hist.ReceivedPacket(6) + hist.ReceivedPacket(4) + 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.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.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.ranges.Len()).To(Equal(2)) + hist.ReceivedPacket(5) + 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.ranges.Len()).To(Equal(4)) + hist.ReceivedPacket(5) + 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})) + Expect(hist.ranges.Back().Value).To(Equal(utils.PacketInterval{Start: 10, End: 10})) + }) }) - It("doesn't care about duplicate packets", func() { - hist.ReceivedPacket(4) - Expect(hist.ranges.Len()).To(Equal(1)) - Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 4})) - }) + Context("ACK range export", func() { + It("returns nil if there are no ranges", func() { + Expect(hist.GetAckRanges()).To(BeNil()) + }) - It("adds a few consecutive packets", func() { - hist.ReceivedPacket(4) - hist.ReceivedPacket(5) - hist.ReceivedPacket(6) - Expect(hist.ranges.Len()).To(Equal(1)) - Expect(hist.ranges.Front().Value).To(Equal(utils.PacketInterval{Start: 4, End: 6})) - }) + It("gets a single ACK range", func() { + hist.ReceivedPacket(4) + hist.ReceivedPacket(5) + ackRanges := hist.GetAckRanges() + Expect(ackRanges).To(HaveLen(1)) + Expect(ackRanges[0]).To(Equal(frames.AckRange{FirstPacketNumber: 4, LastPacketNumber: 5})) + }) - 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.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.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.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.ranges.Len()).To(Equal(2)) - hist.ReceivedPacket(7) - 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})) - Expect(hist.ranges.Back().Value).To(Equal(utils.PacketInterval{Start: 10, End: 10})) - }) - - It("creates a new range before an existing range for a belated packet", func() { - hist.ReceivedPacket(6) - hist.ReceivedPacket(4) - 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.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.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.ranges.Len()).To(Equal(2)) - hist.ReceivedPacket(5) - 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.ranges.Len()).To(Equal(4)) - hist.ReceivedPacket(5) - 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})) - Expect(hist.ranges.Back().Value).To(Equal(utils.PacketInterval{Start: 10, End: 10})) + 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) + ackRanges := hist.GetAckRanges() + Expect(ackRanges).To(HaveLen(3)) + Expect(ackRanges[0]).To(Equal(frames.AckRange{FirstPacketNumber: 10, LastPacketNumber: 11})) + Expect(ackRanges[1]).To(Equal(frames.AckRange{FirstPacketNumber: 4, LastPacketNumber: 6})) + Expect(ackRanges[2]).To(Equal(frames.AckRange{FirstPacketNumber: 1, LastPacketNumber: 2})) + }) }) })