forked from quic-go/quic-go
calculate expected entropy in seperate function for ReceivedAck
This commit is contained in:
@@ -8,6 +8,11 @@ import (
|
||||
"github.com/lucas-clemente/quic-go/protocol"
|
||||
)
|
||||
|
||||
var (
|
||||
errEntropy = errors.New("OutgoingPacketAckHandler: Wrong entropy")
|
||||
errMapAccess = errors.New("OutgoingPacketAckHandler: Packet does not exist in PacketHistory")
|
||||
)
|
||||
|
||||
type outgoingPacketAckHandler struct {
|
||||
lastSentPacketNumber protocol.PacketNumber
|
||||
highestInOrderAckedPacketNumber protocol.PacketNumber
|
||||
@@ -52,6 +57,60 @@ func (h *outgoingPacketAckHandler) SentPacket(packet *Packet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *outgoingPacketAckHandler) calculateExpectedEntropy(ackFrame *frames.AckFrame) (EntropyAccumulator, error) {
|
||||
h.packetHistoryMutex.Lock()
|
||||
defer h.packetHistoryMutex.Unlock()
|
||||
|
||||
highestInOrderAckedPacketNumber := ackFrame.GetHighestInOrderPacketNumber()
|
||||
|
||||
var expectedEntropy EntropyAccumulator
|
||||
|
||||
if !ackFrame.HasNACK() { // if the packet doesn't have NACKs, the correct entropy value is the entropy we sent the LargestObserved packet with. Just look it up in the map
|
||||
packet, ok := h.packetHistory[ackFrame.LargestObserved]
|
||||
if !ok {
|
||||
return 0, errMapAccess
|
||||
}
|
||||
expectedEntropy = packet.Entropy
|
||||
} else { // if the packet has NACKs, the entropy value has to be calculated
|
||||
// get the entropy for the highestInOrderAckedPacketNumber
|
||||
// There are two cases:
|
||||
// 1. the packet with highestInOrderAckedPacketNumber has already been ACKed, then it doesn't exist in the packetHistory map anymore, but the value was saved as h.highestInOrderAckedEntropy
|
||||
// 2. the packet with highestInOrderAckedPacketNumber has not yet been ACKed, then it should exist in the packetHistory map, and can just be read from there
|
||||
if highestInOrderAckedPacketNumber == h.highestInOrderAckedPacketNumber {
|
||||
expectedEntropy = h.highestInOrderAckedEntropy
|
||||
} else {
|
||||
packet, ok := h.packetHistory[highestInOrderAckedPacketNumber]
|
||||
if !ok {
|
||||
return 0, errMapAccess
|
||||
}
|
||||
expectedEntropy = packet.Entropy
|
||||
}
|
||||
|
||||
nackRangeIndex := len(ackFrame.NackRanges) - 1
|
||||
nackRange := ackFrame.NackRanges[nackRangeIndex]
|
||||
for i := highestInOrderAckedPacketNumber + 1; i <= ackFrame.LargestObserved; i++ {
|
||||
// select correct NACK range
|
||||
if i > nackRange.LastPacketNumber {
|
||||
nackRangeIndex--
|
||||
if nackRangeIndex >= 0 {
|
||||
nackRange = ackFrame.NackRanges[nackRangeIndex]
|
||||
}
|
||||
}
|
||||
if i >= nackRange.FirstPacketNumber && i <= nackRange.LastPacketNumber { // PacketNumber i is contained in a NACK range, it's entropyBit is irrelevant
|
||||
continue
|
||||
}
|
||||
// PacketNumber i is not contained in a NACK range, it's entropyBit has to be considered
|
||||
packet, ok := h.packetHistory[i]
|
||||
if !ok {
|
||||
return 0, errMapAccess
|
||||
}
|
||||
expectedEntropy.Add(i, packet.EntropyBit)
|
||||
}
|
||||
}
|
||||
|
||||
return expectedEntropy, nil
|
||||
}
|
||||
|
||||
func (h *outgoingPacketAckHandler) ReceivedAck(ackFrame *frames.AckFrame) error {
|
||||
if ackFrame.LargestObserved > h.lastSentPacketNumber {
|
||||
return errors.New("OutgoingPacketAckHandler: Received ACK for an unsent package")
|
||||
@@ -61,80 +120,50 @@ func (h *outgoingPacketAckHandler) ReceivedAck(ackFrame *frames.AckFrame) error
|
||||
return nil
|
||||
}
|
||||
|
||||
entropyError := errors.New("OutgoingPacketAckHandler: Wrong entropy")
|
||||
mapAccessError := errors.New("OutgoingPacketAckHandler: Packet does not exist in PacketHistory")
|
||||
|
||||
h.packetHistoryMutex.Lock()
|
||||
defer h.packetHistoryMutex.Unlock()
|
||||
|
||||
highestInOrderAckedEntropy := h.highestInOrderAckedEntropy
|
||||
highestInOrderAckedPacketNumber := ackFrame.GetHighestInOrderPacketNumber()
|
||||
for i := h.highestInOrderAckedPacketNumber + 1; i <= highestInOrderAckedPacketNumber; i++ {
|
||||
packet, ok := h.packetHistory[i]
|
||||
if !ok {
|
||||
return mapAccessError
|
||||
}
|
||||
highestInOrderAckedEntropy.Add(packet.PacketNumber, packet.EntropyBit)
|
||||
expectedEntropy, err := h.calculateExpectedEntropy(ackFrame)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var expectedEntropy EntropyAccumulator
|
||||
|
||||
if !ackFrame.HasNACK() {
|
||||
packet, ok := h.packetHistory[ackFrame.LargestObserved]
|
||||
if !ok {
|
||||
return mapAccessError
|
||||
}
|
||||
expectedEntropy = packet.Entropy
|
||||
} else {
|
||||
if highestInOrderAckedPacketNumber == h.highestInOrderAckedPacketNumber {
|
||||
expectedEntropy = h.highestInOrderAckedEntropy
|
||||
} else {
|
||||
packet, ok := h.packetHistory[highestInOrderAckedPacketNumber]
|
||||
if !ok {
|
||||
return mapAccessError
|
||||
}
|
||||
expectedEntropy = packet.Entropy
|
||||
}
|
||||
|
||||
nackRangeIndex := len(ackFrame.NackRanges) - 1
|
||||
nackRange := ackFrame.NackRanges[nackRangeIndex]
|
||||
for i := highestInOrderAckedPacketNumber + 1; i <= ackFrame.LargestObserved; i++ {
|
||||
if i > nackRange.LastPacketNumber {
|
||||
nackRangeIndex--
|
||||
if nackRangeIndex >= 0 {
|
||||
nackRange = ackFrame.NackRanges[nackRangeIndex]
|
||||
}
|
||||
}
|
||||
if i >= nackRange.FirstPacketNumber && i <= nackRange.LastPacketNumber {
|
||||
continue
|
||||
}
|
||||
packet, ok := h.packetHistory[i]
|
||||
if !ok {
|
||||
return mapAccessError
|
||||
}
|
||||
expectedEntropy.Add(i, packet.EntropyBit)
|
||||
}
|
||||
}
|
||||
|
||||
if ackFrame.Entropy != byte(expectedEntropy) {
|
||||
return entropyError
|
||||
if byte(expectedEntropy) != ackFrame.Entropy {
|
||||
return errEntropy
|
||||
}
|
||||
|
||||
// Entropy ok. Now actually process the ACK packet
|
||||
h.packetHistoryMutex.Lock()
|
||||
defer h.packetHistoryMutex.Unlock()
|
||||
|
||||
highestInOrderAckedPacketNumber := ackFrame.GetHighestInOrderPacketNumber()
|
||||
highestInOrderAckedEntropy := h.highestInOrderAckedEntropy
|
||||
|
||||
// if this ACK increases the highestInOrderAckedPacketNumber, the packet will be deleted from the packetHistory map, thus we need to save it's Entropy before doing so
|
||||
if highestInOrderAckedPacketNumber > h.highestInOrderAckedPacketNumber {
|
||||
packet, ok := h.packetHistory[highestInOrderAckedPacketNumber]
|
||||
if !ok {
|
||||
return errMapAccess
|
||||
}
|
||||
highestInOrderAckedEntropy = packet.Entropy
|
||||
}
|
||||
|
||||
// delete all packets below the highestInOrderAckedPacketNumber
|
||||
for i := h.highestInOrderAckedPacketNumber; i <= highestInOrderAckedPacketNumber; i++ {
|
||||
delete(h.packetHistory, i)
|
||||
}
|
||||
|
||||
// delete packets with a packet number higher than highestInOrderAckedPacketNumber that have already been ACKed
|
||||
// this is the case if the PacketNumber is *not* contained in any of the NACK ranges
|
||||
if ackFrame.HasNACK() {
|
||||
nackRangeIndex := len(ackFrame.NackRanges) - 1
|
||||
nackRange := ackFrame.NackRanges[nackRangeIndex]
|
||||
for i := highestInOrderAckedPacketNumber + 1; i <= ackFrame.LargestObserved; i++ {
|
||||
// select correct NACK range
|
||||
if i > nackRange.LastPacketNumber {
|
||||
nackRangeIndex--
|
||||
if nackRangeIndex >= 0 {
|
||||
nackRange = ackFrame.NackRanges[nackRangeIndex]
|
||||
}
|
||||
}
|
||||
// PacketNumber i is not contained in a NACK range
|
||||
if i >= nackRange.FirstPacketNumber && i <= nackRange.LastPacketNumber {
|
||||
continue
|
||||
}
|
||||
@@ -144,6 +173,7 @@ func (h *outgoingPacketAckHandler) ReceivedAck(ackFrame *frames.AckFrame) error
|
||||
|
||||
h.highestInOrderAckedPacketNumber = highestInOrderAckedPacketNumber
|
||||
h.highestInOrderAckedEntropy = highestInOrderAckedEntropy
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user