From 8a7ab6d6cd74517c40845fb1f43b486d9dc49723 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 11 Aug 2016 12:11:54 +0700 Subject: [PATCH] add a function to check if an ACK frame acks a certain packet number --- frames/ack_frame.go | 19 +++++++++++++++++++ frames/ack_frame_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/frames/ack_frame.go b/frames/ack_frame.go index 87c8cb5c2..724585ab1 100644 --- a/frames/ack_frame.go +++ b/frames/ack_frame.go @@ -469,3 +469,22 @@ func (f *AckFrame) getMissingSequenceNumberDeltaLen() protocol.PacketNumberLen { return protocol.PacketNumberLen6 } + +// AcksPacket determines if this ACK frame acks a certain packet number +func (f *AckFrame) AcksPacket(p protocol.PacketNumber) bool { + if p < f.LowestAcked || p > f.LargestAcked { // this is just a performance optimization + return false + } + + if f.HasMissingRanges() { + // TODO: this could be implemented as a binary search + for _, ackRange := range f.AckRanges { + if p >= ackRange.FirstPacketNumber && p <= ackRange.LastPacketNumber { + return true + } + } + return false + } + // if packet doesn't have missing ranges + return (p >= f.LowestAcked && p <= f.LargestAcked) +} diff --git a/frames/ack_frame_test.go b/frames/ack_frame_test.go index 9c7ffaa91..d9106e153 100644 --- a/frames/ack_frame_test.go +++ b/frames/ack_frame_test.go @@ -843,6 +843,43 @@ var _ = Describe("AckFrame", func() { }) }) + Context("check if ACK frame acks a certain packet", func() { + It("works with an ACK without any ranges", func() { + f := AckFrame{ + LowestAcked: 5, + LargestAcked: 10, + } + Expect(f.AcksPacket(1)).To(BeFalse()) + Expect(f.AcksPacket(4)).To(BeFalse()) + Expect(f.AcksPacket(5)).To(BeTrue()) + Expect(f.AcksPacket(8)).To(BeTrue()) + Expect(f.AcksPacket(10)).To(BeTrue()) + Expect(f.AcksPacket(11)).To(BeFalse()) + Expect(f.AcksPacket(20)).To(BeFalse()) + }) + + It("works with an ACK with multiple ACK ranges", func() { + f := AckFrame{ + LowestAcked: 5, + LargestAcked: 20, + AckRanges: []AckRange{ + {FirstPacketNumber: 15, LastPacketNumber: 20}, + {FirstPacketNumber: 5, LastPacketNumber: 8}, + }, + } + Expect(f.AcksPacket(4)).To(BeFalse()) + Expect(f.AcksPacket(5)).To(BeTrue()) + Expect(f.AcksPacket(7)).To(BeTrue()) + Expect(f.AcksPacket(8)).To(BeTrue()) + Expect(f.AcksPacket(9)).To(BeFalse()) + Expect(f.AcksPacket(14)).To(BeFalse()) + Expect(f.AcksPacket(15)).To(BeTrue()) + Expect(f.AcksPacket(18)).To(BeTrue()) + Expect(f.AcksPacket(20)).To(BeTrue()) + Expect(f.AcksPacket(21)).To(BeFalse()) + }) + }) + Context("Legacy AckFrame wrapping", func() { It("parses a ACK frame", func() { b := bytes.NewReader([]byte{0x40, 0xA4, 0x03, 0x23, 0x45, 0x01, 0x02, 0xFF, 0xEE, 0xDD, 0xCC})