keep track of which packets were sent as retransmissions

When an ACK for a packet that was retransmitted arrives, we don't need
to retransmit the retransmission, even if it was lost.
This commit is contained in:
Marten Seemann
2018-03-14 12:18:54 +01:00
parent 56720edc34
commit fed3bf503e
8 changed files with 415 additions and 71 deletions

View File

@@ -13,10 +13,17 @@ import (
. "github.com/onsi/gomega"
)
func retransmittablePacket(num protocol.PacketNumber) *Packet {
func retransmittablePacket(num protocol.PacketNumber, args ...protocol.ByteCount) *Packet {
length := protocol.ByteCount(1)
if len(args) == 1 {
length = args[0]
}
if len(args) > 1 {
Fail("invalid function parameters")
}
return &Packet{
PacketNumber: num,
Length: 1,
Length: length,
Frames: []wire.Frame{&wire.PingFrame{}},
EncryptionLevel: protocol.EncryptionForwardSecure,
}
@@ -415,6 +422,96 @@ var _ = Describe("SentPacketHandler", func() {
})
})
Context("Ack processing, for retransmitted packets", func() {
losePacket := func(pn protocol.PacketNumber) {
p := getPacket(pn)
ExpectWithOffset(1, p).ToNot(BeNil())
handler.queuePacketForRetransmission(p)
r := handler.DequeuePacketForRetransmission()
ExpectWithOffset(1, r).ToNot(BeNil())
ExpectWithOffset(1, r.PacketNumber).To(Equal(pn))
}
It("sends a packet as retransmission", func() {
// packet 5 was retransmitted as packet 6
handler.SentPacket(retransmittablePacket(5, 10))
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(10)))
losePacket(5)
Expect(handler.bytesInFlight).To(BeZero())
handler.SentPacketsAsRetransmission([]*Packet{retransmittablePacket(6, 11)}, 5)
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(11)))
})
It("removes all retransmissions when the original packet is acked", func() {
// packet 5 was retransmitted as packet 6, which was then retransmitted as packet 8
handler.SentPacket(retransmittablePacket(5, 10))
losePacket(5)
handler.SentPacketsAsRetransmission([]*Packet{retransmittablePacket(6, 11)}, 5)
losePacket(6)
handler.SentPacketsAsRetransmission([]*Packet{retransmittablePacket(8, 12)}, 6)
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(12)))
// ack 5
err := handler.ReceivedAck(&wire.AckFrame{LowestAcked: 5, LargestAcked: 5}, 1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred())
Expect(handler.packetHistory.Len()).To(BeZero())
Expect(handler.bytesInFlight).To(BeZero())
})
It("removes all retransmissions when the retransmission is acked", func() {
// the retransmission for packet 5 was split into packets 6 and 8
handler.SentPacket(retransmittablePacket(5, 10))
losePacket(5)
handler.SentPacketsAsRetransmission([]*Packet{retransmittablePacket(6, 11)}, 5)
losePacket(6)
handler.SentPacketsAsRetransmission([]*Packet{retransmittablePacket(8, 12)}, 6)
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(12)))
// ack 8
err := handler.ReceivedAck(&wire.AckFrame{LowestAcked: 8, LargestAcked: 8}, 1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred())
Expect(handler.packetHistory.Len()).To(BeZero())
Expect(handler.bytesInFlight).To(BeZero())
})
It("removes split retransmissions when the original packet is acked", func() {
// the retransmission for packet 5 was split into 8 and 9
handler.SentPacket(retransmittablePacket(5, 10))
losePacket(5)
handler.SentPacketsAsRetransmission([]*Packet{retransmittablePacket(8, 6), retransmittablePacket(9, 7)}, 5)
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(6 + 7)))
// ack 5
err := handler.ReceivedAck(&wire.AckFrame{LowestAcked: 5, LargestAcked: 5}, 1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred())
Expect(handler.packetHistory.Len()).To(BeZero())
Expect(handler.bytesInFlight).To(BeZero())
})
It("doesn't remove the original packet if a split retransmission is acked", func() {
// the retransmission for packet 5 was split into 10 and 12
handler.SentPacket(retransmittablePacket(5, 10))
losePacket(5)
handler.SentPacketsAsRetransmission([]*Packet{retransmittablePacket(10, 6), retransmittablePacket(12, 7)}, 5)
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(6 + 7)))
// ack 10
err := handler.ReceivedAck(&wire.AckFrame{LowestAcked: 10, LargestAcked: 10}, 1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred())
Expect(handler.bytesInFlight).To(Equal(protocol.ByteCount(7)))
expectInPacketHistory([]protocol.PacketNumber{5, 12})
})
It("handles ACKs that ack the original packet as well as the retransmission", func() {
// packet 5 was retransmitted as packet 7
handler.SentPacket(retransmittablePacket(5, 10))
losePacket(5)
handler.SentPacketsAsRetransmission([]*Packet{retransmittablePacket(7, 11)}, 5)
// ack 5 and 7
ack := createAck([]wire.AckRange{{First: 5, Last: 5}, {First: 7, Last: 7}})
err := handler.ReceivedAck(ack, 1, protocol.EncryptionForwardSecure, time.Now())
Expect(err).ToNot(HaveOccurred())
Expect(handler.packetHistory.Len()).To(BeZero())
Expect(handler.bytesInFlight).To(BeZero())
})
})
Context("Retransmission handling", func() {
It("does not dequeue a packet if no ack has been received", func() {
handler.SentPacket(retransmittablePacket(1))
@@ -683,7 +780,6 @@ var _ = Describe("SentPacketHandler", func() {
p = handler.DequeuePacketForRetransmission()
Expect(p).ToNot(BeNil())
Expect(p.PacketNumber).To(Equal(protocol.PacketNumber(4)))
Expect(handler.packetHistory.Len()).To(Equal(1))
Expect(getPacket(3)).ToNot(BeNil())
Expect(handler.handshakeCount).To(BeEquivalentTo(1))
// make sure the exponential backoff is used