forked from quic-go/quic-go
calculate correct MinLength of an ACK frame with a contiguous NACK range
fixes #183
This commit is contained in:
@@ -58,20 +58,10 @@ func (f *AckFrame) Write(b *bytes.Buffer, version protocol.VersionNumber) error
|
|||||||
utils.WriteUint32(b, 0) // First timestamp
|
utils.WriteUint32(b, 0) // First timestamp
|
||||||
|
|
||||||
if f.HasNACK() {
|
if f.HasNACK() {
|
||||||
numRanges := uint64(0)
|
numRanges := f.numWrittenNackRanges()
|
||||||
// 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 := nackRange.Len()
|
|
||||||
numRanges += rangeLength/0xFF + 1
|
|
||||||
if rangeLength > 0 && rangeLength%0xFF == 0 {
|
|
||||||
numRanges--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if numRanges > 0xFF {
|
if numRanges > 0xFF {
|
||||||
panic("Too many NACK ranges. Truncating not yet implemented.")
|
panic("Too many NACK ranges. Truncating not yet implemented.")
|
||||||
}
|
}
|
||||||
|
|
||||||
b.WriteByte(uint8(numRanges))
|
b.WriteByte(uint8(numRanges))
|
||||||
|
|
||||||
rangeCounter := uint8(0)
|
rangeCounter := uint8(0)
|
||||||
@@ -120,7 +110,7 @@ func (f *AckFrame) MinLength(version protocol.VersionNumber) (protocol.ByteCount
|
|||||||
l += int(protocol.GetPacketNumberLength(f.LargestObserved))
|
l += int(protocol.GetPacketNumberLength(f.LargestObserved))
|
||||||
l += (1 + 2) * 0 /* TODO: num_timestamps */
|
l += (1 + 2) * 0 /* TODO: num_timestamps */
|
||||||
if f.HasNACK() {
|
if f.HasNACK() {
|
||||||
l += 1 + (6+1)*len(f.NackRanges)
|
l += 1 + (6+1)*int(f.numWrittenNackRanges())
|
||||||
l++ // TODO: Remove once we drop support for <32
|
l++ // TODO: Remove once we drop support for <32
|
||||||
}
|
}
|
||||||
return protocol.ByteCount(l), nil
|
return protocol.ByteCount(l), nil
|
||||||
@@ -288,6 +278,21 @@ func ParseAckFrame(r *bytes.Reader, version protocol.VersionNumber) (*AckFrame,
|
|||||||
return frame, nil
|
return frame, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// numWrittenNackRanges calculates 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
|
||||||
|
func (f *AckFrame) numWrittenNackRanges() uint64 {
|
||||||
|
var numRanges uint64
|
||||||
|
for _, nackRange := range f.NackRanges {
|
||||||
|
rangeLength := nackRange.Len()
|
||||||
|
numRanges += rangeLength/0xFF + 1
|
||||||
|
if rangeLength > 0 && rangeLength%0xFF == 0 {
|
||||||
|
numRanges--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return numRanges
|
||||||
|
}
|
||||||
|
|
||||||
func (f *AckFrame) validateNackRanges() bool {
|
func (f *AckFrame) validateNackRanges() bool {
|
||||||
// check the validity of every single NACK range
|
// check the validity of every single NACK range
|
||||||
for _, nackRange := range f.NackRanges {
|
for _, nackRange := range f.NackRanges {
|
||||||
|
|||||||
@@ -512,7 +512,7 @@ var _ = Describe("AckFrame", func() {
|
|||||||
Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len())))
|
Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len())))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("has proper min length with nack ranges", func() {
|
It("has proper min length with NACK ranges", func() {
|
||||||
f := &AckFrame{
|
f := &AckFrame{
|
||||||
Entropy: 2,
|
Entropy: 2,
|
||||||
LargestObserved: 4,
|
LargestObserved: 4,
|
||||||
@@ -522,6 +522,17 @@ var _ = Describe("AckFrame", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len())))
|
Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len())))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("has proper min length with a continuous NACK ranges", func() {
|
||||||
|
f := &AckFrame{
|
||||||
|
Entropy: 2,
|
||||||
|
LargestObserved: 3000,
|
||||||
|
NackRanges: []NackRange{{FirstPacketNumber: 2, LastPacketNumber: 2000}},
|
||||||
|
}
|
||||||
|
err := f.Write(b, protocol.Version31)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len())))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user