fix usage of ackhandler.Packet pool for non-ack-eliciting packets (#3538)

This commit is contained in:
Marten Seemann 2022-08-30 14:09:11 +03:00 committed by GitHub
parent 31995601a9
commit 80c3afed34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 54 deletions

View file

@ -226,14 +226,20 @@ func (h *sentPacketHandler) packetsInFlight() int {
return packetsInFlight
}
func (h *sentPacketHandler) SentPacket(packet *Packet) {
h.bytesSent += packet.Length
func (h *sentPacketHandler) SentPacket(p *Packet) {
h.bytesSent += p.Length
// For the client, drop the Initial packet number space when the first Handshake packet is sent.
if h.perspective == protocol.PerspectiveClient && packet.EncryptionLevel == protocol.EncryptionHandshake && h.initialPackets != nil {
if h.perspective == protocol.PerspectiveClient && p.EncryptionLevel == protocol.EncryptionHandshake && h.initialPackets != nil {
h.dropPackets(protocol.EncryptionInitial)
}
isAckEliciting := h.sentPacketImpl(packet)
h.getPacketNumberSpace(packet.EncryptionLevel).history.SentPacket(packet, isAckEliciting)
isAckEliciting := h.sentPacketImpl(p)
if isAckEliciting {
h.getPacketNumberSpace(p.EncryptionLevel).history.SentAckElicitingPacket(p)
} else {
h.getPacketNumberSpace(p.EncryptionLevel).history.SentNonAckElicitingPacket(p.PacketNumber, p.EncryptionLevel, p.SendTime)
putPacket(p)
p = nil //nolint:ineffassign // This is just to be on the safe side.
}
if h.tracer != nil && isAckEliciting {
h.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight())
}

View file

@ -27,31 +27,37 @@ func newSentPacketHistory(rttStats *utils.RTTStats) *sentPacketHistory {
}
}
func (h *sentPacketHistory) SentPacket(p *Packet, isAckEliciting bool) {
if p.PacketNumber <= h.highestSent {
func (h *sentPacketHistory) SentNonAckElicitingPacket(pn protocol.PacketNumber, encLevel protocol.EncryptionLevel, t time.Time) {
h.registerSentPacket(pn, encLevel, t)
}
func (h *sentPacketHistory) SentAckElicitingPacket(p *Packet) {
h.registerSentPacket(p.PacketNumber, p.EncryptionLevel, p.SendTime)
var el *list.Element[*Packet]
if p.outstanding() {
el = h.outstandingPacketList.PushBack(p)
} else {
el = h.etcPacketList.PushBack(p)
}
h.packetMap[p.PacketNumber] = el
}
func (h *sentPacketHistory) registerSentPacket(pn protocol.PacketNumber, encLevel protocol.EncryptionLevel, t time.Time) {
if pn <= h.highestSent {
panic("non-sequential packet number use")
}
// Skipped packet numbers.
for pn := h.highestSent + 1; pn < p.PacketNumber; pn++ {
for p := h.highestSent + 1; p < pn; p++ {
el := h.etcPacketList.PushBack(&Packet{
PacketNumber: pn,
EncryptionLevel: p.EncryptionLevel,
SendTime: p.SendTime,
PacketNumber: p,
EncryptionLevel: encLevel,
SendTime: t,
skippedPacket: true,
})
h.packetMap[pn] = el
}
h.highestSent = p.PacketNumber
if isAckEliciting {
var el *list.Element[*Packet]
if p.outstanding() {
el = h.outstandingPacketList.PushBack(p)
} else {
el = h.etcPacketList.PushBack(p)
}
h.packetMap[p.PacketNumber] = el
h.packetMap[p] = el
}
h.highestSent = pn
}
// Iterate iterates through all packets.

View file

@ -53,16 +53,16 @@ var _ = Describe("SentPacketHistory", func() {
})
It("saves sent packets", func() {
hist.SentPacket(&Packet{PacketNumber: 1}, true)
hist.SentPacket(&Packet{PacketNumber: 3}, true)
hist.SentPacket(&Packet{PacketNumber: 4}, true)
hist.SentAckElicitingPacket(&Packet{PacketNumber: 1})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 3})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 4})
expectInHistory([]protocol.PacketNumber{1, 3, 4})
})
It("doesn't save non-ack-eliciting packets", func() {
hist.SentPacket(&Packet{PacketNumber: 1}, true)
hist.SentPacket(&Packet{PacketNumber: 3}, false)
hist.SentPacket(&Packet{PacketNumber: 4}, true)
hist.SentAckElicitingPacket(&Packet{PacketNumber: 1})
hist.SentNonAckElicitingPacket(3, protocol.EncryptionLevel(0), time.Time{})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 4})
expectInHistory([]protocol.PacketNumber{1, 4})
hist.Iterate(func(p *Packet) (bool, error) {
Expect(p.PacketNumber).ToNot(Equal(protocol.PacketNumber(3)))
@ -71,9 +71,9 @@ var _ = Describe("SentPacketHistory", func() {
})
It("gets the length", func() {
hist.SentPacket(&Packet{PacketNumber: 0}, true)
hist.SentPacket(&Packet{PacketNumber: 1}, true)
hist.SentPacket(&Packet{PacketNumber: 2}, true)
hist.SentAckElicitingPacket(&Packet{PacketNumber: 0})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 1})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 2})
Expect(hist.Len()).To(Equal(3))
})
@ -83,16 +83,16 @@ var _ = Describe("SentPacketHistory", func() {
})
It("gets the first outstanding packet", func() {
hist.SentPacket(&Packet{PacketNumber: 2}, true)
hist.SentPacket(&Packet{PacketNumber: 3}, true)
hist.SentAckElicitingPacket(&Packet{PacketNumber: 2})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 3})
front := hist.FirstOutstanding()
Expect(front).ToNot(BeNil())
Expect(front.PacketNumber).To(Equal(protocol.PacketNumber(2)))
})
It("doesn't regard path MTU packets as outstanding", func() {
hist.SentPacket(&Packet{PacketNumber: 2}, true)
hist.SentPacket(&Packet{PacketNumber: 4, IsPathMTUProbePacket: true}, true)
hist.SentAckElicitingPacket(&Packet{PacketNumber: 2})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 4, IsPathMTUProbePacket: true})
front := hist.FirstOutstanding()
Expect(front).ToNot(BeNil())
Expect(front.PacketNumber).To(Equal(protocol.PacketNumber(2)))
@ -100,25 +100,25 @@ var _ = Describe("SentPacketHistory", func() {
})
It("removes packets", func() {
hist.SentPacket(&Packet{PacketNumber: 1}, true)
hist.SentPacket(&Packet{PacketNumber: 4}, true)
hist.SentPacket(&Packet{PacketNumber: 8}, true)
hist.SentAckElicitingPacket(&Packet{PacketNumber: 1})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 4})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 8})
err := hist.Remove(4)
Expect(err).ToNot(HaveOccurred())
expectInHistory([]protocol.PacketNumber{1, 8})
})
It("errors when trying to remove a non existing packet", func() {
hist.SentPacket(&Packet{PacketNumber: 1}, true)
hist.SentAckElicitingPacket(&Packet{PacketNumber: 1})
err := hist.Remove(2)
Expect(err).To(MatchError("packet 2 not found in sent packet history"))
})
Context("iterating", func() {
BeforeEach(func() {
hist.SentPacket(&Packet{PacketNumber: 1}, true)
hist.SentPacket(&Packet{PacketNumber: 4}, true)
hist.SentPacket(&Packet{PacketNumber: 8}, true)
hist.SentAckElicitingPacket(&Packet{PacketNumber: 1})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 4})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 8})
})
It("iterates over all packets", func() {
@ -197,29 +197,29 @@ var _ = Describe("SentPacketHistory", func() {
Context("outstanding packets", func() {
It("says if it has outstanding packets", func() {
Expect(hist.HasOutstandingPackets()).To(BeFalse())
hist.SentPacket(&Packet{EncryptionLevel: protocol.Encryption1RTT}, true)
hist.SentAckElicitingPacket(&Packet{EncryptionLevel: protocol.Encryption1RTT})
Expect(hist.HasOutstandingPackets()).To(BeTrue())
})
It("accounts for deleted packets", func() {
hist.SentPacket(&Packet{
hist.SentAckElicitingPacket(&Packet{
PacketNumber: 10,
EncryptionLevel: protocol.Encryption1RTT,
}, true)
})
Expect(hist.HasOutstandingPackets()).To(BeTrue())
Expect(hist.Remove(10)).To(Succeed())
Expect(hist.HasOutstandingPackets()).To(BeFalse())
})
It("counts the number of packets", func() {
hist.SentPacket(&Packet{
hist.SentAckElicitingPacket(&Packet{
PacketNumber: 10,
EncryptionLevel: protocol.Encryption1RTT,
}, true)
hist.SentPacket(&Packet{
})
hist.SentAckElicitingPacket(&Packet{
PacketNumber: 11,
EncryptionLevel: protocol.Encryption1RTT,
}, true)
})
Expect(hist.Remove(11)).To(Succeed())
Expect(hist.HasOutstandingPackets()).To(BeTrue())
Expect(hist.Remove(10)).To(Succeed())
@ -237,7 +237,7 @@ var _ = Describe("SentPacketHistory", func() {
It("deletes old packets after 3 PTOs", func() {
now := time.Now()
hist.SentPacket(&Packet{PacketNumber: 10, SendTime: now.Add(-3 * pto), declaredLost: true}, true)
hist.SentAckElicitingPacket(&Packet{PacketNumber: 10, SendTime: now.Add(-3 * pto), declaredLost: true})
expectInHistory([]protocol.PacketNumber{10})
hist.DeleteOldPackets(now.Add(-time.Nanosecond))
expectInHistory([]protocol.PacketNumber{10})
@ -247,8 +247,8 @@ var _ = Describe("SentPacketHistory", func() {
It("doesn't delete a packet if it hasn't been declared lost yet", func() {
now := time.Now()
hist.SentPacket(&Packet{PacketNumber: 10, SendTime: now.Add(-3 * pto), declaredLost: true}, true)
hist.SentPacket(&Packet{PacketNumber: 11, SendTime: now.Add(-3 * pto), declaredLost: false}, true)
hist.SentAckElicitingPacket(&Packet{PacketNumber: 10, SendTime: now.Add(-3 * pto), declaredLost: true})
hist.SentAckElicitingPacket(&Packet{PacketNumber: 11, SendTime: now.Add(-3 * pto), declaredLost: false})
expectInHistory([]protocol.PacketNumber{10, 11})
hist.DeleteOldPackets(now)
expectInHistory([]protocol.PacketNumber{11})
@ -256,7 +256,7 @@ var _ = Describe("SentPacketHistory", func() {
It("deletes skipped packets", func() {
now := time.Now()
hist.SentPacket(&Packet{PacketNumber: 10, SendTime: now.Add(-3 * pto)}, true)
hist.SentAckElicitingPacket(&Packet{PacketNumber: 10, SendTime: now.Add(-3 * pto)})
expectInHistory([]protocol.PacketNumber{10})
Expect(hist.Len()).To(Equal(11))
hist.DeleteOldPackets(now)