handle ACKs separately in the sent packet handler packet struct

This commit is contained in:
Marten Seemann
2019-04-21 20:37:18 +09:00
parent ae685f9d42
commit 5d999f3927
6 changed files with 25 additions and 33 deletions

View File

@@ -2,17 +2,6 @@ package ackhandler
import "github.com/lucas-clemente/quic-go/internal/wire" import "github.com/lucas-clemente/quic-go/internal/wire"
// Returns a new slice with all non-ack-eliciting frames deleted.
func stripNonAckElicitingFrames(fs []wire.Frame) []wire.Frame {
res := make([]wire.Frame, 0, len(fs))
for _, f := range fs {
if IsFrameAckEliciting(f) {
res = append(res, f)
}
}
return res
}
// IsFrameAckEliciting returns true if the frame is ack-eliciting. // IsFrameAckEliciting returns true if the frame is ack-eliciting.
func IsFrameAckEliciting(f wire.Frame) bool { func IsFrameAckEliciting(f wire.Frame) bool {
switch f.(type) { switch f.(type) {

View File

@@ -27,15 +27,6 @@ var _ = Describe("ack-eliciting frames", func() {
Expect(IsFrameAckEliciting(f)).To(Equal(e)) Expect(IsFrameAckEliciting(f)).To(Equal(e))
}) })
It("stripping non-ack-elicinting frames works for "+fName, func() {
s := []wire.Frame{f}
if e {
Expect(stripNonAckElicitingFrames(s)).To(Equal([]wire.Frame{f}))
} else {
Expect(stripNonAckElicitingFrames(s)).To(BeEmpty())
}
})
It("HasAckElicitingFrames works for "+fName, func() { It("HasAckElicitingFrames works for "+fName, func() {
Expect(HasAckElicitingFrames([]wire.Frame{f})).To(Equal(e)) Expect(HasAckElicitingFrames([]wire.Frame{f})).To(Equal(e))
}) })

View File

@@ -11,6 +11,7 @@ import (
type Packet struct { type Packet struct {
PacketNumber protocol.PacketNumber PacketNumber protocol.PacketNumber
PacketType protocol.PacketType PacketType protocol.PacketType
Ack *wire.AckFrame
Frames []wire.Frame Frames []wire.Frame
Length protocol.ByteCount Length protocol.ByteCount
EncryptionLevel protocol.EncryptionLevel EncryptionLevel protocol.EncryptionLevel

View File

@@ -166,14 +166,12 @@ func (h *sentPacketHandler) sentPacketImpl(packet *Packet) bool /* is ack-elicit
pnSpace.largestSent = packet.PacketNumber pnSpace.largestSent = packet.PacketNumber
if len(packet.Frames) > 0 { if packet.Ack != nil {
if ackFrame, ok := packet.Frames[0].(*wire.AckFrame); ok { packet.largestAcked = packet.Ack.LargestAcked()
packet.largestAcked = ackFrame.LargestAcked()
}
} }
packet.Ack = nil // no need to save the ACK
packet.Frames = stripNonAckElicitingFrames(packet.Frames) isAckEliciting := len(packet.Frames) > 0
isAckEliciting := len(packet.Frames) != 0
if isAckEliciting { if isAckEliciting {
if packet.EncryptionLevel != protocol.Encryption1RTT { if packet.EncryptionLevel != protocol.Encryption1RTT {

View File

@@ -29,9 +29,8 @@ func ackElicitingPacket(p *Packet) *Packet {
func nonAckElicitingPacket(p *Packet) *Packet { func nonAckElicitingPacket(p *Packet) *Packet {
p = ackElicitingPacket(p) p = ackElicitingPacket(p)
p.Frames = []wire.Frame{ p.Frames = nil
&wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}}, p.Ack = &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}}}
}
return p return p
} }
@@ -313,8 +312,8 @@ var _ = Describe("SentPacketHandler", func() {
ack1 := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 80, Largest: 100}}} ack1 := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 80, Largest: 100}}}
ack2 := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 50, Largest: 200}}} ack2 := &wire.AckFrame{AckRanges: []wire.AckRange{{Smallest: 50, Largest: 200}}}
morePackets := []*Packet{ morePackets := []*Packet{
{PacketNumber: 13, Frames: []wire.Frame{ack1, &streamFrame}, Length: 1, EncryptionLevel: protocol.Encryption1RTT}, {PacketNumber: 13, Ack: ack1, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.Encryption1RTT},
{PacketNumber: 14, Frames: []wire.Frame{ack2, &streamFrame}, Length: 1, EncryptionLevel: protocol.Encryption1RTT}, {PacketNumber: 14, Ack: ack2, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.Encryption1RTT},
{PacketNumber: 15, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.Encryption1RTT}, {PacketNumber: 15, Frames: []wire.Frame{&streamFrame}, Length: 1, EncryptionLevel: protocol.Encryption1RTT},
} }
for _, packet := range morePackets { for _, packet := range morePackets {

View File

@@ -52,10 +52,24 @@ func (p *packedPacket) IsAckEliciting() bool {
} }
func (p *packedPacket) ToAckHandlerPacket() *ackhandler.Packet { func (p *packedPacket) ToAckHandlerPacket() *ackhandler.Packet {
var frames []wire.Frame
var ack *wire.AckFrame
if len(p.frames) > 0 {
var ok bool
ack, ok = p.frames[0].(*wire.AckFrame)
if ok {
// make a copy, so that the ACK can be garbage collected
frames = make([]wire.Frame, len(p.frames)-1)
copy(frames, p.frames[1:])
} else {
frames = p.frames
}
}
return &ackhandler.Packet{ return &ackhandler.Packet{
PacketNumber: p.header.PacketNumber, PacketNumber: p.header.PacketNumber,
PacketType: p.header.Type, PacketType: p.header.Type,
Frames: p.frames, Ack: ack,
Frames: frames,
Length: protocol.ByteCount(len(p.raw)), Length: protocol.ByteCount(len(p.raw)),
EncryptionLevel: p.EncryptionLevel(), EncryptionLevel: p.EncryptionLevel(),
SendTime: time.Now(), SendTime: time.Now(),
@@ -330,7 +344,7 @@ func (p *packetPacker) composeNextPacket(maxFrameSize protocol.ByteCount) ([]wir
var length protocol.ByteCount var length protocol.ByteCount
var frames []wire.Frame var frames []wire.Frame
// ACKs need to go first, so that the sentPacketHandler will recognize them // ACKs need to go first, so we recognize them in packedPacket.ToAckHandlerPacket()
if ack := p.acks.GetAckFrame(protocol.Encryption1RTT); ack != nil { if ack := p.acks.GetAckFrame(protocol.Encryption1RTT); ack != nil {
frames = append(frames, ack) frames = append(frames, ack)
length += ack.Length(p.version) length += ack.Length(p.version)