forked from quic-go/quic-go
146 lines
6.1 KiB
Go
146 lines
6.1 KiB
Go
package ackhandler
|
|
|
|
import (
|
|
"github.com/lucas-clemente/quic-go/frames"
|
|
"github.com/lucas-clemente/quic-go/protocol"
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("AckHandler", func() {
|
|
var handler *outgoingPacketAckHandler
|
|
BeforeEach(func() {
|
|
handler = NewOutgoingPacketAckHandler().(*outgoingPacketAckHandler)
|
|
})
|
|
|
|
Context("SentPacket", func() {
|
|
It("accepts three consecutive packets", func() {
|
|
entropy := EntropyAccumulator(0)
|
|
packet1 := Packet{PacketNumber: 1, Plaintext: []byte{0x13, 0x37}, EntropyBit: true}
|
|
packet2 := Packet{PacketNumber: 2, Plaintext: []byte{0xBE, 0xEF}, EntropyBit: true}
|
|
err := handler.SentPacket(&packet1)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
err = handler.SentPacket(&packet2)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(2)))
|
|
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1)))
|
|
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(2)))
|
|
entropy.Add(packet1.PacketNumber, packet1.EntropyBit)
|
|
Expect(handler.packetHistory[1].PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
|
Expect(handler.packetHistory[1].Entropy).To(Equal(entropy))
|
|
entropy.Add(packet2.PacketNumber, packet2.EntropyBit)
|
|
Expect(handler.packetHistory[2].PacketNumber).To(Equal(protocol.PacketNumber(2)))
|
|
Expect(handler.packetHistory[2].Entropy).To(Equal(entropy))
|
|
})
|
|
|
|
It("rejects packets with the same packet number", func() {
|
|
packet1 := Packet{PacketNumber: 1, Plaintext: []byte{0x13, 0x37}, EntropyBit: true}
|
|
packet2 := Packet{PacketNumber: 1, Plaintext: []byte{0xBE, 0xEF}, EntropyBit: false}
|
|
err := handler.SentPacket(&packet1)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
err = handler.SentPacket(&packet2)
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(1)))
|
|
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1)))
|
|
})
|
|
|
|
It("rejects non-consecutive packets", func() {
|
|
packet1 := Packet{PacketNumber: 1, Plaintext: []byte{0x13, 0x37}, EntropyBit: true}
|
|
packet2 := Packet{PacketNumber: 3, Plaintext: []byte{0xBE, 0xEF}, EntropyBit: false}
|
|
err := handler.SentPacket(&packet1)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
err = handler.SentPacket(&packet2)
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(1)))
|
|
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1)))
|
|
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(2)))
|
|
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(2)))
|
|
})
|
|
|
|
It("correctly calculates the entropy, even if the last packet has already been ACKed", func() {
|
|
packet1 := Packet{PacketNumber: 1, Plaintext: []byte{0x13, 0x37}, EntropyBit: true}
|
|
packet2 := Packet{PacketNumber: 2, Plaintext: []byte{0xBE, 0xEF}, EntropyBit: true}
|
|
err := handler.SentPacket(&packet1)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
expectedEntropy := EntropyAccumulator(0)
|
|
expectedEntropy.Add(packet1.PacketNumber, packet1.EntropyBit)
|
|
ack := frames.AckFrame{
|
|
LargestObserved: 1,
|
|
Entropy: byte(expectedEntropy),
|
|
}
|
|
err = handler.ReceivedAck(&ack)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
err = handler.SentPacket(&packet2)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(handler.lastSentPacketNumber).To(Equal(protocol.PacketNumber(2)))
|
|
expectedEntropy.Add(packet2.PacketNumber, packet2.EntropyBit)
|
|
Expect(handler.packetHistory[2].Entropy).To(Equal(expectedEntropy))
|
|
})
|
|
})
|
|
|
|
Context("ACK handling", func() {
|
|
var (
|
|
packets []*Packet
|
|
)
|
|
BeforeEach(func() {
|
|
packets = []*Packet{
|
|
&Packet{PacketNumber: 1, Plaintext: []byte{0x13, 0x37}, EntropyBit: true},
|
|
&Packet{PacketNumber: 2, Plaintext: []byte{0xBE, 0xEF}, EntropyBit: false},
|
|
&Packet{PacketNumber: 3, Plaintext: []byte{0xCA, 0xFE}, EntropyBit: true},
|
|
&Packet{PacketNumber: 4, Plaintext: []byte{0x54, 0x32}, EntropyBit: true},
|
|
&Packet{PacketNumber: 5, Plaintext: []byte{0x54, 0x32}, EntropyBit: false},
|
|
&Packet{PacketNumber: 6, Plaintext: []byte{0x54, 0x32}, EntropyBit: true},
|
|
}
|
|
for _, packet := range packets {
|
|
handler.SentPacket(packet)
|
|
}
|
|
})
|
|
|
|
It("rejects ACKs with a too high LargestObserved packet number", func() {
|
|
ack := frames.AckFrame{
|
|
LargestObserved: 1337,
|
|
}
|
|
err := handler.ReceivedAck(&ack)
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(handler.highestInOrderAckedPacketNumber).To(Equal(protocol.PacketNumber(0)))
|
|
})
|
|
|
|
Context("ACKs without NACK ranges", func() {
|
|
It("handles an ACK with the correct entropy", func() {
|
|
expectedEntropy := EntropyAccumulator(0)
|
|
largestObserved := 4
|
|
for i := 0; i < largestObserved; i++ {
|
|
expectedEntropy.Add(packets[i].PacketNumber, packets[i].EntropyBit)
|
|
}
|
|
ack := frames.AckFrame{
|
|
LargestObserved: protocol.PacketNumber(largestObserved),
|
|
Entropy: byte(expectedEntropy),
|
|
}
|
|
err := handler.ReceivedAck(&ack)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(handler.highestInOrderAckedPacketNumber).To(Equal(protocol.PacketNumber(largestObserved)))
|
|
Expect(handler.highestInOrderAckedEntropy).To(Equal(expectedEntropy))
|
|
// all packets with packetNumbers smaller or equal largestObserved should be deleted
|
|
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(1)))
|
|
Expect(handler.packetHistory).ToNot(HaveKey(protocol.PacketNumber(4)))
|
|
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(5)))
|
|
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(6)))
|
|
})
|
|
|
|
It("rejects an ACK with incorrect entropy", func() {
|
|
ack := frames.AckFrame{
|
|
LargestObserved: 3,
|
|
Entropy: 0,
|
|
}
|
|
err := handler.ReceivedAck(&ack)
|
|
Expect(err).To(HaveOccurred())
|
|
Expect(handler.highestInOrderAckedPacketNumber).To(Equal(protocol.PacketNumber(0)))
|
|
Expect(handler.highestInOrderAckedEntropy).To(Equal(EntropyAccumulator(0)))
|
|
// nothing should be deleted from the packetHistory map
|
|
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(1)))
|
|
Expect(handler.packetHistory).To(HaveKey(protocol.PacketNumber(3)))
|
|
})
|
|
})
|
|
})
|
|
})
|