Send ACKs and SWFs even if we are congestion limited

Fixes #576.
This commit is contained in:
Lucas Clemente 2017-06-20 12:01:28 +02:00 committed by Lucas Clemente
parent fc8d937fce
commit ff8c75a22e
3 changed files with 52 additions and 1 deletions

View file

@ -64,6 +64,25 @@ func (p *packetPacker) PackConnectionClose(ccf *frames.ConnectionCloseFrame, lea
}, err
}
func (p *packetPacker) PackAckPacket(leastUnacked protocol.PacketNumber, ackframe *frames.AckFrame) (*packedPacket, error) {
encLevel, sealer := p.cryptoSetup.GetSealer()
ph := p.getPublicHeader(leastUnacked, encLevel)
frames := []frames.Frame{ackframe}
if p.stopWaiting != nil {
p.stopWaiting.PacketNumber = ph.PacketNumber
p.stopWaiting.PacketNumberLen = ph.PacketNumberLen
frames = append(frames, p.stopWaiting)
p.stopWaiting = nil
}
raw, err := p.writeAndSealPacket(ph, frames, sealer)
return &packedPacket{
number: ph.PacketNumber,
raw: raw,
frames: frames,
encryptionLevel: encLevel,
}, err
}
// RetransmitNonForwardSecurePacket retransmits a handshake packet, that was sent with less than forward-secure encryption
func (p *packetPacker) RetransmitNonForwardSecurePacket(packet *ackhandler.Packet) (*packedPacket, error) {
if packet.EncryptionLevel == protocol.EncryptionForwardSecure {

View file

@ -2,6 +2,7 @@ package quic
import (
"bytes"
"math"
"github.com/lucas-clemente/quic-go/ackhandler"
"github.com/lucas-clemente/quic-go/frames"
@ -703,4 +704,22 @@ var _ = Describe("Packet packer", func() {
Expect(err).To(MatchError("PacketPacker BUG: Handshake retransmissions must contain a StopWaitingFrame"))
})
})
Context("packing ACK packets", func() {
It("packs ACK packets", func() {
p, err := packer.PackAckPacket(0, &frames.AckFrame{})
Expect(err).NotTo(HaveOccurred())
Expect(p.frames).To(Equal([]frames.Frame{&frames.AckFrame{DelayTime: math.MaxInt64}}))
})
It("packs ACK packets with SWFs", func() {
packer.QueueControlFrameForNextPacket(&frames.StopWaitingFrame{})
p, err := packer.PackAckPacket(0, &frames.AckFrame{})
Expect(err).NotTo(HaveOccurred())
Expect(p.frames).To(Equal([]frames.Frame{
&frames.AckFrame{DelayTime: math.MaxInt64},
&frames.StopWaitingFrame{PacketNumber: 1, PacketNumberLen: 2},
}))
})
})
})

View file

@ -572,7 +572,20 @@ func (s *session) sendPacket() error {
// Repeatedly try sending until we don't have any more data, or run out of the congestion window
for {
if !s.sentPacketHandler.SendingAllowed() {
return nil
// If we aren't allowed to send, at least try sending an ACK frame
ack := s.receivedPacketHandler.GetAckFrame()
if ack == nil {
return nil
}
swf := s.sentPacketHandler.GetStopWaitingFrame(false)
if swf != nil {
s.packer.QueueControlFrameForNextPacket(swf)
}
packet, err := s.packer.PackAckPacket(s.sentPacketHandler.GetLeastUnacked(), ack)
if err != nil {
return err
}
return s.sendPackedPacket(packet)
}
// check for retransmissions first