don't retransmit Initial packets after receiving the first packet

This commit is contained in:
Marten Seemann 2018-02-23 15:53:47 +08:00
parent d16dea09cc
commit 26013b8d64
2 changed files with 35 additions and 0 deletions

View file

@ -111,6 +111,7 @@ type session struct {
handshakeChan chan error
handshakeComplete bool
receivedFirstPacket bool // since packet numbers start at 0, we can't use largestRcvdPacketNumber != 0 for this
lastRcvdPacketNumber protocol.PacketNumber
// Used to calculate the next packet number from the truncated wire
// representation, and sent back in public reset packets
@ -509,6 +510,7 @@ func (s *session) handlePacketImpl(p *receivedPacket) error {
p.rcvTime = time.Now()
}
s.receivedFirstPacket = true
s.lastNetworkActivityTime = p.rcvTime
s.keepAlivePingSent = false
hdr := p.header
@ -819,6 +821,13 @@ func (s *session) sendPacket() (bool, error) {
if retransmitPacket == nil {
break
}
// Don't retransmit Initial packets if we already received a response.
// An Initial might have been retransmitted multiple times before we receive a response.
// As soon as we receive one response, we don't need to send any more Initials.
if s.receivedFirstPacket && retransmitPacket.PacketType == protocol.PacketTypeInitial {
utils.Debugf("Skipping retransmission of packet %d. Already received a response to an Initial.", retransmitPacket.PacketNumber)
continue
}
// retransmit handshake packets
if retransmitPacket.EncryptionLevel != protocol.EncryptionForwardSecure {
@ -870,6 +879,7 @@ func (s *session) sendPackedPacket(packet *packedPacket) error {
defer putPacketBuffer(packet.raw)
err := s.sentPacketHandler.SentPacket(&ackhandler.Packet{
PacketNumber: packet.header.PacketNumber,
PacketType: packet.header.Type,
Frames: packet.frames,
Length: protocol.ByteCount(len(packet.raw)),
EncryptionLevel: packet.encryptionLevel,

View file

@ -755,6 +755,31 @@ var _ = Describe("Session", func() {
Expect(sentPacket.EncryptionLevel).To(Equal(protocol.EncryptionForwardSecure))
Expect(sentPacket.Length).To(BeEquivalentTo(len(<-mconn.written)))
})
It("doesn't retransmit an initial packet if it already received a response", func() {
sess.unpacker = &mockUnpacker{}
sph := mockackhandler.NewMockSentPacketHandler(mockCtrl)
sph.EXPECT().GetLeastUnacked().AnyTimes()
sph.EXPECT().DequeuePacketForRetransmission().Return(&ackhandler.Packet{
PacketNumber: 10,
PacketType: protocol.PacketTypeInitial,
})
sph.EXPECT().DequeuePacketForRetransmission()
rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl)
rph.EXPECT().ReceivedPacket(gomock.Any(), gomock.Any(), gomock.Any())
rph.EXPECT().GetAckFrame()
sess.receivedPacketHandler = rph
sess.sentPacketHandler = sph
err := sess.handlePacketImpl(&receivedPacket{
header: &wire.Header{},
data: []byte{0},
})
Expect(err).ToNot(HaveOccurred())
Expect(sess.receivedFirstPacket).To(BeTrue())
sent, err := sess.sendPacket()
Expect(err).NotTo(HaveOccurred())
Expect(sent).To(BeFalse())
})
})
Context("packet pacing", func() {