send shorter Missing Packet Sequence Number Delta in new ACK frames

fixes #184
This commit is contained in:
Marten Seemann
2016-07-25 17:43:31 +07:00
parent 99d22b0908
commit 03e25d1e85
2 changed files with 191 additions and 10 deletions

View File

@@ -195,14 +195,13 @@ func (f *AckFrameNew) Write(b *bytes.Buffer, version protocol.VersionNumber) err
typeByte ^= (uint8(largestAckedLen / 2)) << 2
}
// TODO: send shorter values, if possible
missingSequenceNumberDeltaLen := protocol.PacketNumberLen6
missingSequenceNumberDeltaLen := f.getMissingSequenceNumberDeltaLen()
if missingSequenceNumberDeltaLen != protocol.PacketNumberLen1 {
typeByte ^= (uint8(missingSequenceNumberDeltaLen / 2))
}
if f.HasMissingRanges() {
typeByte |= (0x20 | 0x03)
typeByte |= 0x20
}
b.WriteByte(typeByte)
@@ -231,8 +230,9 @@ func (f *AckFrameNew) Write(b *bytes.Buffer, version protocol.VersionNumber) err
b.WriteByte(uint8(numRanges - 1))
}
var firstAckBlockLength protocol.PacketNumber
if !f.HasMissingRanges() {
utils.WriteUint48(b, uint64(f.LargestAcked-f.LowestAcked+1))
firstAckBlockLength = f.LargestAcked - f.LowestAcked + 1
} else {
if f.LargestAcked != f.AckRanges[0].LastPacketNumber {
return errInconsistentAckLargestAcked
@@ -240,11 +240,21 @@ func (f *AckFrameNew) Write(b *bytes.Buffer, version protocol.VersionNumber) err
if f.LowestAcked != f.AckRanges[len(f.AckRanges)-1].FirstPacketNumber {
return errInconsistentAckLowestAcked
}
length := f.LargestAcked - f.AckRanges[0].FirstPacketNumber + 1
utils.WriteUint48(b, uint64(length))
firstAckBlockLength = f.LargestAcked - f.AckRanges[0].FirstPacketNumber + 1
numRangesWritten++
}
switch missingSequenceNumberDeltaLen {
case protocol.PacketNumberLen1:
b.WriteByte(uint8(firstAckBlockLength))
case protocol.PacketNumberLen2:
utils.WriteUint16(b, uint16(firstAckBlockLength))
case protocol.PacketNumberLen4:
utils.WriteUint32(b, uint32(firstAckBlockLength))
case protocol.PacketNumberLen6:
utils.WriteUint48(b, uint64(firstAckBlockLength))
}
for i, ackRange := range f.AckRanges {
if i == 0 {
continue
@@ -260,7 +270,16 @@ func (f *AckFrameNew) Write(b *bytes.Buffer, version protocol.VersionNumber) err
if num == 1 {
b.WriteByte(uint8(gap))
utils.WriteUint48(b, uint64(length))
switch missingSequenceNumberDeltaLen {
case protocol.PacketNumberLen1:
b.WriteByte(uint8(length))
case protocol.PacketNumberLen2:
utils.WriteUint16(b, uint16(length))
case protocol.PacketNumberLen4:
utils.WriteUint32(b, uint32(length))
case protocol.PacketNumberLen6:
utils.WriteUint48(b, uint64(length))
}
numRangesWritten++
} else {
for i := 0; i < int(num); i++ {
@@ -276,7 +295,17 @@ func (f *AckFrameNew) Write(b *bytes.Buffer, version protocol.VersionNumber) err
}
b.WriteByte(uint8(gapWritten))
utils.WriteUint48(b, lengthWritten)
switch missingSequenceNumberDeltaLen {
case protocol.PacketNumberLen1:
b.WriteByte(uint8(lengthWritten))
case protocol.PacketNumberLen2:
utils.WriteUint16(b, uint16(lengthWritten))
case protocol.PacketNumberLen4:
utils.WriteUint32(b, uint32(lengthWritten))
case protocol.PacketNumberLen6:
utils.WriteUint48(b, uint64(lengthWritten))
}
numRangesWritten++
}
}
@@ -302,7 +331,7 @@ func (f *AckFrameNew) MinLength(version protocol.VersionNumber) (protocol.ByteCo
length = 1 + 2 + 1 // 1 TypeByte, 2 ACK delay time, 1 Num Timestamp
length += protocol.ByteCount(protocol.GetPacketNumberLength(f.LargestAcked))
missingSequenceNumberDeltaLen := protocol.ByteCount(protocol.PacketNumberLen6)
missingSequenceNumberDeltaLen := protocol.ByteCount(f.getMissingSequenceNumberDeltaLen())
if f.HasMissingRanges() {
length += (1 + missingSequenceNumberDeltaLen) * protocol.ByteCount(f.numWritableNackRanges())
@@ -390,3 +419,30 @@ func (f *AckFrameNew) numWritableNackRanges() uint64 {
return numRanges + 1
}
func (f *AckFrameNew) getMissingSequenceNumberDeltaLen() protocol.PacketNumberLen {
var maxRangeLength protocol.PacketNumber
if f.HasMissingRanges() {
for _, ackRange := range f.AckRanges {
rangeLength := ackRange.LastPacketNumber - ackRange.FirstPacketNumber + 1
if rangeLength > maxRangeLength {
maxRangeLength = rangeLength
}
}
} else {
maxRangeLength = f.LargestAcked - f.LowestAcked + 1
}
if maxRangeLength <= 0xFF {
return protocol.PacketNumberLen1
}
if maxRangeLength <= 0xFFFF {
return protocol.PacketNumberLen2
}
if maxRangeLength <= 0xFFFFFFFF {
return protocol.PacketNumberLen4
}
return protocol.PacketNumberLen6
}

View File

@@ -377,7 +377,7 @@ var _ = Describe("AckFrame", func() {
Expect(err).To(MatchError(errInconsistentAckLowestAcked))
})
Context("longer ACK blocks", func() {
Context("longer gaps between ACK blocks", func() {
It("only writes one block for 254 lost packets", func() {
frameOrig := &AckFrameNew{
LargestAcked: 300,
@@ -475,6 +475,115 @@ var _ = Describe("AckFrame", func() {
})
})
Context("longer ACK blocks", func() {
It("writes a 1 byte Missing Sequence Number Delta", func() {
frameOrig := &AckFrameNew{
LargestAcked: 200,
LowestAcked: 1,
}
err := frameOrig.Write(b, 0)
Expect(err).ToNot(HaveOccurred())
Expect(b.Bytes()[0] & 0x3).To(Equal(byte(0x0)))
r := bytes.NewReader(b.Bytes())
frame, err := ParseAckFrameNew(r, 0)
Expect(err).ToNot(HaveOccurred())
Expect(frame.LargestAcked).To(Equal(frameOrig.LargestAcked))
Expect(frame.LowestAcked).To(Equal(frameOrig.LowestAcked))
Expect(r.Len()).To(BeZero())
})
It("writes a 2 byte Missing Sequence Number Delta", func() {
frameOrig := &AckFrameNew{
LargestAcked: 0x100,
LowestAcked: 1,
}
err := frameOrig.Write(b, 0)
Expect(err).ToNot(HaveOccurred())
Expect(b.Bytes()[0] & 0x3).To(Equal(byte(0x1)))
r := bytes.NewReader(b.Bytes())
frame, err := ParseAckFrameNew(r, 0)
Expect(err).ToNot(HaveOccurred())
Expect(frame.LargestAcked).To(Equal(frameOrig.LargestAcked))
Expect(frame.LowestAcked).To(Equal(frameOrig.LowestAcked))
Expect(r.Len()).To(BeZero())
})
It("writes a 4 byte Missing Sequence Number Delta", func() {
frameOrig := &AckFrameNew{
LargestAcked: 0x10000,
LowestAcked: 1,
}
err := frameOrig.Write(b, 0)
Expect(err).ToNot(HaveOccurred())
Expect(b.Bytes()[0] & 0x3).To(Equal(byte(0x2)))
r := bytes.NewReader(b.Bytes())
frame, err := ParseAckFrameNew(r, 0)
Expect(err).ToNot(HaveOccurred())
Expect(frame.LargestAcked).To(Equal(frameOrig.LargestAcked))
Expect(frame.LowestAcked).To(Equal(frameOrig.LowestAcked))
Expect(r.Len()).To(BeZero())
})
It("writes a 6 byte Missing Sequence Number Delta", func() {
frameOrig := &AckFrameNew{
LargestAcked: 0x100000000,
LowestAcked: 1,
}
err := frameOrig.Write(b, 0)
Expect(err).ToNot(HaveOccurred())
Expect(b.Bytes()[0] & 0x3).To(Equal(byte(0x3)))
r := bytes.NewReader(b.Bytes())
frame, err := ParseAckFrameNew(r, 0)
Expect(err).ToNot(HaveOccurred())
Expect(frame.LargestAcked).To(Equal(frameOrig.LargestAcked))
Expect(frame.LowestAcked).To(Equal(frameOrig.LowestAcked))
Expect(r.Len()).To(BeZero())
})
It("writes a 1 byte Missing Sequence Number Delta, if all ACK blocks are short", func() {
frameOrig := &AckFrameNew{
LargestAcked: 5001,
LowestAcked: 1,
AckRanges: []AckRange{
AckRange{FirstPacketNumber: 5000, LastPacketNumber: 5001},
AckRange{FirstPacketNumber: 250, LastPacketNumber: 300},
AckRange{FirstPacketNumber: 1, LastPacketNumber: 200},
},
}
err := frameOrig.Write(b, 0)
Expect(err).ToNot(HaveOccurred())
Expect(b.Bytes()[0] & 0x3).To(Equal(byte(0x0)))
r := bytes.NewReader(b.Bytes())
frame, err := ParseAckFrameNew(r, 0)
Expect(err).ToNot(HaveOccurred())
Expect(frame.LargestAcked).To(Equal(frameOrig.LargestAcked))
Expect(frame.LowestAcked).To(Equal(frameOrig.LowestAcked))
Expect(frame.AckRanges).To(Equal(frameOrig.AckRanges))
Expect(r.Len()).To(BeZero())
})
It("writes a 2 byte Missing Sequence Number Delta, for a frame with 2 ACK ranges", func() {
frameOrig := &AckFrameNew{
LargestAcked: 10000,
LowestAcked: 1,
AckRanges: []AckRange{
AckRange{FirstPacketNumber: 9990, LastPacketNumber: 10000},
AckRange{FirstPacketNumber: 1, LastPacketNumber: 256},
},
}
err := frameOrig.Write(b, 0)
Expect(err).ToNot(HaveOccurred())
Expect(b.Bytes()[0] & 0x3).To(Equal(byte(0x1)))
r := bytes.NewReader(b.Bytes())
frame, err := ParseAckFrameNew(r, 0)
Expect(err).ToNot(HaveOccurred())
Expect(frame.LargestAcked).To(Equal(frameOrig.LargestAcked))
Expect(frame.LowestAcked).To(Equal(frameOrig.LowestAcked))
Expect(frame.AckRanges).To(Equal(frameOrig.AckRanges))
Expect(r.Len()).To(BeZero())
})
})
Context("too many ACK blocks", func() {
It("skips the lowest ACK ranges, if there are more than 255 AckRanges", func() {
ackRanges := make([]AckRange, 300)
@@ -590,6 +699,22 @@ var _ = Describe("AckFrame", func() {
Expect(err).ToNot(HaveOccurred())
Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len())))
})
It("has the proper min length for an ACK with a long ACK range", func() {
largestAcked := protocol.PacketNumber(2 + 0xFFFFFF)
f := &AckFrameNew{
LargestAcked: largestAcked,
LowestAcked: 1,
AckRanges: []AckRange{
AckRange{FirstPacketNumber: 1500, LastPacketNumber: largestAcked},
AckRange{FirstPacketNumber: 290, LastPacketNumber: 295},
AckRange{FirstPacketNumber: 1, LastPacketNumber: 19},
},
}
err := f.Write(b, 0)
Expect(err).ToNot(HaveOccurred())
Expect(f.MinLength(0)).To(Equal(protocol.ByteCount(b.Len())))
})
})
})