From 2c95141ee1fa80d37e4e21bd81e7c0a1de1e3ab4 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 27 Apr 2016 16:04:50 +0700 Subject: [PATCH] add Len() and ContainsPacketNumber() to NackRange --- ackhandler/sent_packet_handler.go | 4 ++-- frames/ack_frame.go | 10 ++------ frames/nack_range.go | 22 +++++++++++++++++ frames/nack_range_test.go | 39 +++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 frames/nack_range.go create mode 100644 frames/nack_range_test.go diff --git a/ackhandler/sent_packet_handler.go b/ackhandler/sent_packet_handler.go index 55b481fc7..3e1400fb7 100644 --- a/ackhandler/sent_packet_handler.go +++ b/ackhandler/sent_packet_handler.go @@ -107,7 +107,7 @@ func (h *sentPacketHandler) calculateExpectedEntropy(ackFrame *frames.AckFrame) nackRange = ackFrame.NackRanges[nackRangeIndex] } } - if i >= nackRange.FirstPacketNumber && i <= nackRange.LastPacketNumber { + if nackRange.ContainsPacketNumber(i) { packet, ok := h.packetHistory[i] if !ok { return 0, ErrMapAccess @@ -156,7 +156,7 @@ func (h *sentPacketHandler) ReceivedAck(ackFrame *frames.AckFrame) error { nackRange = ackFrame.NackRanges[nackRangeIndex] } } - if i >= nackRange.FirstPacketNumber && i <= nackRange.LastPacketNumber { + if nackRange.ContainsPacketNumber(i) { h.nackPacket(i) } else { h.ackPacket(i) diff --git a/frames/ack_frame.go b/frames/ack_frame.go index a01cd5f84..b5820a3ee 100644 --- a/frames/ack_frame.go +++ b/frames/ack_frame.go @@ -8,12 +8,6 @@ import ( "github.com/lucas-clemente/quic-go/utils" ) -// NackRange is a NACK range -type NackRange struct { - FirstPacketNumber protocol.PacketNumber - LastPacketNumber protocol.PacketNumber -} - var errInvalidNackRanges = errors.New("AckFrame: ACK frame contains invalid NACK ranges") // An AckFrame in QUIC @@ -45,7 +39,7 @@ func (f *AckFrame) Write(b *bytes.Buffer, packetNumber protocol.PacketNumber, pa // calculate the number of NackRanges that are about to be written // this number is different from len(f.NackRanges) for the case of contiguous NACK ranges for _, nackRange := range f.NackRanges { - rangeLength := uint64(nackRange.LastPacketNumber - nackRange.FirstPacketNumber) + rangeLength := nackRange.Len() numRanges += rangeLength/0xFF + 1 if rangeLength > 0 && rangeLength%0xFF == 0 { numRanges-- @@ -69,7 +63,7 @@ func (f *AckFrame) Write(b *bytes.Buffer, packetNumber protocol.PacketNumber, pa lastNackRange := f.NackRanges[i-1] missingPacketSequenceNumberDelta = uint64(lastNackRange.FirstPacketNumber) - uint64(nackRange.LastPacketNumber) - 1 } - rangeLength := nackRange.LastPacketNumber - nackRange.FirstPacketNumber + rangeLength := nackRange.Len() utils.WriteUint48(b, missingPacketSequenceNumberDelta) b.WriteByte(uint8(rangeLength % 0x100)) diff --git a/frames/nack_range.go b/frames/nack_range.go new file mode 100644 index 000000000..455478df4 --- /dev/null +++ b/frames/nack_range.go @@ -0,0 +1,22 @@ +package frames + +import "github.com/lucas-clemente/quic-go/protocol" + +// NackRange is a NACK range +type NackRange struct { + FirstPacketNumber protocol.PacketNumber + LastPacketNumber protocol.PacketNumber +} + +// Len gets the lengths of a NackRange +func (n *NackRange) Len() uint64 { + return uint64(n.LastPacketNumber) - uint64(n.FirstPacketNumber) +} + +// IsInRange checks if a packetNumber is contained in a NACK range +func (n *NackRange) ContainsPacketNumber(packetNumber protocol.PacketNumber) bool { + if packetNumber >= n.FirstPacketNumber && packetNumber <= n.LastPacketNumber { + return true + } + return false +} diff --git a/frames/nack_range_test.go b/frames/nack_range_test.go new file mode 100644 index 000000000..5a5d09bc5 --- /dev/null +++ b/frames/nack_range_test.go @@ -0,0 +1,39 @@ +package frames + +import ( + "github.com/lucas-clemente/quic-go/protocol" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("NackRange", func() { + Context("Length", func() { + It("calculates the length for a NACK range with only one packet", func() { + nackRange := NackRange{FirstPacketNumber: 2, LastPacketNumber: 2} + Expect(nackRange.Len()).To(Equal(uint64(0))) + }) + + It("calculates the length for a NACK range with more than one packet", func() { + nackRange := NackRange{FirstPacketNumber: 10, LastPacketNumber: 20} + Expect(nackRange.Len()).To(Equal(uint64(10))) + }) + }) + + Context("ContainsPacketNumber", func() { + It("determines if a packet is in a NACK range with only one packet", func() { + nackRange := NackRange{FirstPacketNumber: 2, LastPacketNumber: 2} + Expect(nackRange.ContainsPacketNumber(protocol.PacketNumber(1))).To(BeFalse()) + Expect(nackRange.ContainsPacketNumber(protocol.PacketNumber(3))).To(BeFalse()) + Expect(nackRange.ContainsPacketNumber(protocol.PacketNumber(2))).To(BeTrue()) + }) + + It("determines if a packet is in a NACK range with more than one packet", func() { + nackRange := NackRange{FirstPacketNumber: 10, LastPacketNumber: 20} + Expect(nackRange.ContainsPacketNumber(protocol.PacketNumber(1))).To(BeFalse()) + Expect(nackRange.ContainsPacketNumber(protocol.PacketNumber(10))).To(BeTrue()) + Expect(nackRange.ContainsPacketNumber(protocol.PacketNumber(15))).To(BeTrue()) + Expect(nackRange.ContainsPacketNumber(protocol.PacketNumber(20))).To(BeTrue()) + Expect(nackRange.ContainsPacketNumber(protocol.PacketNumber(21))).To(BeFalse()) + }) + }) +})