route/vendor/github.com/lucas-clemente/quic-go/internal/wire/ack_frame_legacy.go

382 lines
9.6 KiB
Go
Raw Normal View History

2018-01-03 19:19:49 +00:00
package wire
2017-12-12 02:51:45 +00:00
import (
"bytes"
"errors"
"time"
2018-01-03 19:19:49 +00:00
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/utils"
2017-12-12 02:51:45 +00:00
)
var (
errInconsistentAckLargestAcked = errors.New("internal inconsistency: LargestAcked does not match ACK ranges")
errInconsistentAckLowestAcked = errors.New("internal inconsistency: LowestAcked does not match ACK ranges")
2018-01-03 19:19:49 +00:00
errInvalidAckRanges = errors.New("AckFrame: ACK frame contains invalid ACK ranges")
2017-12-12 02:51:45 +00:00
)
2018-01-03 19:19:49 +00:00
func parseAckFrameLegacy(r *bytes.Reader, _ protocol.VersionNumber) (*AckFrame, error) {
2017-12-12 02:51:45 +00:00
frame := &AckFrame{}
typeByte, err := r.ReadByte()
if err != nil {
return nil, err
}
hasMissingRanges := false
if typeByte&0x20 == 0x20 {
hasMissingRanges = true
}
largestAckedLen := 2 * ((typeByte & 0x0C) >> 2)
if largestAckedLen == 0 {
largestAckedLen = 1
}
missingSequenceNumberDeltaLen := 2 * (typeByte & 0x03)
if missingSequenceNumberDeltaLen == 0 {
missingSequenceNumberDeltaLen = 1
}
2018-01-03 19:19:49 +00:00
largestAcked, err := utils.BigEndian.ReadUintN(r, largestAckedLen)
2017-12-12 02:51:45 +00:00
if err != nil {
return nil, err
}
frame.LargestAcked = protocol.PacketNumber(largestAcked)
2018-01-03 19:19:49 +00:00
delay, err := utils.BigEndian.ReadUfloat16(r)
2017-12-12 02:51:45 +00:00
if err != nil {
return nil, err
}
frame.DelayTime = time.Duration(delay) * time.Microsecond
var numAckBlocks uint8
if hasMissingRanges {
numAckBlocks, err = r.ReadByte()
if err != nil {
return nil, err
}
}
if hasMissingRanges && numAckBlocks == 0 {
2018-01-03 19:19:49 +00:00
return nil, errInvalidAckRanges
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
ackBlockLength, err := utils.BigEndian.ReadUintN(r, missingSequenceNumberDeltaLen)
2017-12-12 02:51:45 +00:00
if err != nil {
return nil, err
}
if frame.LargestAcked > 0 && ackBlockLength < 1 {
2018-01-03 19:19:49 +00:00
return nil, errors.New("invalid first ACK range")
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
if ackBlockLength > largestAcked+1 {
return nil, errInvalidAckRanges
2017-12-12 02:51:45 +00:00
}
if hasMissingRanges {
ackRange := AckRange{
2018-01-03 19:19:49 +00:00
First: protocol.PacketNumber(largestAcked-ackBlockLength) + 1,
Last: frame.LargestAcked,
2017-12-12 02:51:45 +00:00
}
frame.AckRanges = append(frame.AckRanges, ackRange)
var inLongBlock bool
var lastRangeComplete bool
for i := uint8(0); i < numAckBlocks; i++ {
var gap uint8
gap, err = r.ReadByte()
if err != nil {
return nil, err
}
2018-01-03 19:19:49 +00:00
ackBlockLength, err = utils.BigEndian.ReadUintN(r, missingSequenceNumberDeltaLen)
2017-12-12 02:51:45 +00:00
if err != nil {
return nil, err
}
length := protocol.PacketNumber(ackBlockLength)
if inLongBlock {
2018-01-03 19:19:49 +00:00
frame.AckRanges[len(frame.AckRanges)-1].First -= protocol.PacketNumber(gap) + length
frame.AckRanges[len(frame.AckRanges)-1].Last -= protocol.PacketNumber(gap)
2017-12-12 02:51:45 +00:00
} else {
lastRangeComplete = false
ackRange := AckRange{
2018-01-03 19:19:49 +00:00
Last: frame.AckRanges[len(frame.AckRanges)-1].First - protocol.PacketNumber(gap) - 1,
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
ackRange.First = ackRange.Last - length + 1
2017-12-12 02:51:45 +00:00
frame.AckRanges = append(frame.AckRanges, ackRange)
}
if length > 0 {
lastRangeComplete = true
}
inLongBlock = (ackBlockLength == 0)
}
2018-01-03 19:19:49 +00:00
// if the last range was not complete, First and Last make no sense
2017-12-12 02:51:45 +00:00
// remove the range from frame.AckRanges
if !lastRangeComplete {
frame.AckRanges = frame.AckRanges[:len(frame.AckRanges)-1]
}
2018-01-03 19:19:49 +00:00
frame.LowestAcked = frame.AckRanges[len(frame.AckRanges)-1].First
2017-12-12 02:51:45 +00:00
} else {
if frame.LargestAcked == 0 {
frame.LowestAcked = 0
} else {
frame.LowestAcked = protocol.PacketNumber(largestAcked + 1 - ackBlockLength)
}
}
if !frame.validateAckRanges() {
2018-01-03 19:19:49 +00:00
return nil, errInvalidAckRanges
2017-12-12 02:51:45 +00:00
}
var numTimestamp byte
numTimestamp, err = r.ReadByte()
if err != nil {
return nil, err
}
if numTimestamp > 0 {
// Delta Largest acked
_, err = r.ReadByte()
if err != nil {
return nil, err
}
// First Timestamp
2018-01-03 19:19:49 +00:00
_, err = utils.BigEndian.ReadUint32(r)
2017-12-12 02:51:45 +00:00
if err != nil {
return nil, err
}
for i := 0; i < int(numTimestamp)-1; i++ {
// Delta Largest acked
_, err = r.ReadByte()
if err != nil {
return nil, err
}
// Time Since Previous Timestamp
2018-01-03 19:19:49 +00:00
_, err = utils.BigEndian.ReadUint16(r)
2017-12-12 02:51:45 +00:00
if err != nil {
return nil, err
}
}
}
return frame, nil
}
2018-01-03 19:19:49 +00:00
func (f *AckFrame) writeLegacy(b *bytes.Buffer, _ protocol.VersionNumber) error {
2017-12-12 02:51:45 +00:00
largestAckedLen := protocol.GetPacketNumberLength(f.LargestAcked)
typeByte := uint8(0x40)
if largestAckedLen != protocol.PacketNumberLen1 {
typeByte ^= (uint8(largestAckedLen / 2)) << 2
}
missingSequenceNumberDeltaLen := f.getMissingSequenceNumberDeltaLen()
if missingSequenceNumberDeltaLen != protocol.PacketNumberLen1 {
typeByte ^= (uint8(missingSequenceNumberDeltaLen / 2))
}
if f.HasMissingRanges() {
typeByte |= 0x20
}
b.WriteByte(typeByte)
switch largestAckedLen {
case protocol.PacketNumberLen1:
b.WriteByte(uint8(f.LargestAcked))
case protocol.PacketNumberLen2:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint16(b, uint16(f.LargestAcked))
2017-12-12 02:51:45 +00:00
case protocol.PacketNumberLen4:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint32(b, uint32(f.LargestAcked))
2017-12-12 02:51:45 +00:00
case protocol.PacketNumberLen6:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint48(b, uint64(f.LargestAcked)&(1<<48-1))
2017-12-12 02:51:45 +00:00
}
2018-01-03 19:19:49 +00:00
f.DelayTime = time.Since(f.PacketReceivedTime)
utils.BigEndian.WriteUfloat16(b, uint64(f.DelayTime/time.Microsecond))
2017-12-12 02:51:45 +00:00
var numRanges uint64
var numRangesWritten uint64
if f.HasMissingRanges() {
numRanges = f.numWritableNackRanges()
if numRanges > 0xFF {
panic("AckFrame: Too many ACK ranges")
}
b.WriteByte(uint8(numRanges - 1))
}
var firstAckBlockLength protocol.PacketNumber
if !f.HasMissingRanges() {
firstAckBlockLength = f.LargestAcked - f.LowestAcked + 1
} else {
2018-01-03 19:19:49 +00:00
if f.LargestAcked != f.AckRanges[0].Last {
2017-12-12 02:51:45 +00:00
return errInconsistentAckLargestAcked
}
2018-01-03 19:19:49 +00:00
if f.LowestAcked != f.AckRanges[len(f.AckRanges)-1].First {
2017-12-12 02:51:45 +00:00
return errInconsistentAckLowestAcked
}
2018-01-03 19:19:49 +00:00
firstAckBlockLength = f.LargestAcked - f.AckRanges[0].First + 1
2017-12-12 02:51:45 +00:00
numRangesWritten++
}
switch missingSequenceNumberDeltaLen {
case protocol.PacketNumberLen1:
b.WriteByte(uint8(firstAckBlockLength))
case protocol.PacketNumberLen2:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint16(b, uint16(firstAckBlockLength))
2017-12-12 02:51:45 +00:00
case protocol.PacketNumberLen4:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint32(b, uint32(firstAckBlockLength))
2017-12-12 02:51:45 +00:00
case protocol.PacketNumberLen6:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint48(b, uint64(firstAckBlockLength)&(1<<48-1))
2017-12-12 02:51:45 +00:00
}
for i, ackRange := range f.AckRanges {
if i == 0 {
continue
}
2018-01-03 19:19:49 +00:00
length := ackRange.Last - ackRange.First + 1
gap := f.AckRanges[i-1].First - ackRange.Last - 1
2017-12-12 02:51:45 +00:00
num := gap/0xFF + 1
if gap%0xFF == 0 {
num--
}
if num == 1 {
b.WriteByte(uint8(gap))
switch missingSequenceNumberDeltaLen {
case protocol.PacketNumberLen1:
b.WriteByte(uint8(length))
case protocol.PacketNumberLen2:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint16(b, uint16(length))
2017-12-12 02:51:45 +00:00
case protocol.PacketNumberLen4:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint32(b, uint32(length))
2017-12-12 02:51:45 +00:00
case protocol.PacketNumberLen6:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint48(b, uint64(length)&(1<<48-1))
2017-12-12 02:51:45 +00:00
}
numRangesWritten++
} else {
for i := 0; i < int(num); i++ {
var lengthWritten uint64
var gapWritten uint8
if i == int(num)-1 { // last block
lengthWritten = uint64(length)
gapWritten = uint8(1 + ((gap - 1) % 255))
} else {
lengthWritten = 0
gapWritten = 0xFF
}
b.WriteByte(gapWritten)
switch missingSequenceNumberDeltaLen {
case protocol.PacketNumberLen1:
b.WriteByte(uint8(lengthWritten))
case protocol.PacketNumberLen2:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint16(b, uint16(lengthWritten))
2017-12-12 02:51:45 +00:00
case protocol.PacketNumberLen4:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint32(b, uint32(lengthWritten))
2017-12-12 02:51:45 +00:00
case protocol.PacketNumberLen6:
2018-01-03 19:19:49 +00:00
utils.BigEndian.WriteUint48(b, lengthWritten&(1<<48-1))
2017-12-12 02:51:45 +00:00
}
numRangesWritten++
}
}
// this is needed if not all AckRanges can be written to the ACK frame (if there are more than 0xFF)
if numRangesWritten >= numRanges {
break
}
}
if numRanges != numRangesWritten {
return errors.New("BUG: Inconsistent number of ACK ranges written")
}
b.WriteByte(0) // no timestamps
return nil
}
2018-01-20 18:07:01 +00:00
func (f *AckFrame) minLengthLegacy(_ protocol.VersionNumber) protocol.ByteCount {
2018-01-03 19:19:49 +00:00
length := protocol.ByteCount(1 + 2 + 1) // 1 TypeByte, 2 ACK delay time, 1 Num Timestamp
2017-12-12 02:51:45 +00:00
length += protocol.ByteCount(protocol.GetPacketNumberLength(f.LargestAcked))
missingSequenceNumberDeltaLen := protocol.ByteCount(f.getMissingSequenceNumberDeltaLen())
if f.HasMissingRanges() {
length += (1 + missingSequenceNumberDeltaLen) * protocol.ByteCount(f.numWritableNackRanges())
} else {
length += missingSequenceNumberDeltaLen
}
2018-01-03 19:19:49 +00:00
// we don't write
2018-01-20 18:07:01 +00:00
return length
2017-12-12 02:51:45 +00:00
}
// numWritableNackRanges calculates the number of ACK blocks that are about to be written
// this number is different from len(f.AckRanges) for the case of long gaps (> 255 packets)
func (f *AckFrame) numWritableNackRanges() uint64 {
if len(f.AckRanges) == 0 {
return 0
}
var numRanges uint64
for i, ackRange := range f.AckRanges {
if i == 0 {
continue
}
lastAckRange := f.AckRanges[i-1]
2018-01-03 19:19:49 +00:00
gap := lastAckRange.First - ackRange.Last - 1
2017-12-12 02:51:45 +00:00
rangeLength := 1 + uint64(gap)/0xFF
if uint64(gap)%0xFF == 0 {
rangeLength--
}
if numRanges+rangeLength < 0xFF {
numRanges += rangeLength
} else {
break
}
}
return numRanges + 1
}
func (f *AckFrame) getMissingSequenceNumberDeltaLen() protocol.PacketNumberLen {
var maxRangeLength protocol.PacketNumber
if f.HasMissingRanges() {
for _, ackRange := range f.AckRanges {
2018-01-03 19:19:49 +00:00
rangeLength := ackRange.Last - ackRange.First + 1
2017-12-12 02:51:45 +00:00
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
}