Merge pull request #2377 from lucas-clemente/dont-send-after-close

don't send packets after receiving a CONNECTION_CLOSE
This commit is contained in:
Marten Seemann 2020-02-25 19:43:26 +07:00 committed by GitHub
commit 3e083d19f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 0 deletions

View file

@ -535,6 +535,12 @@ runLoop:
if wasProcessed := s.handlePacketImpl(p); !wasProcessed {
continue
}
// Don't set timers and send packets if the packet made us close the session.
select {
case closeErr = <-s.closeChan:
break runLoop
default:
}
case <-s.handshakeCompleteChan:
s.handleHandshakeComplete()
}
@ -1105,6 +1111,7 @@ func (s *session) closeForRecreating() protocol.PacketNumber {
func (s *session) closeRemote(e error) {
s.closeOnce.Do(func() {
s.logger.Errorf("Peer closed session with error: %s", e)
s.logger.Debugf("sending to close chan")
s.closeChan <- closeError{err: e, immediate: true, remote: true}
})
}

View file

@ -502,6 +502,34 @@ var _ = Describe("Session", func() {
sess.shutdown()
Eventually(returned).Should(BeClosed())
})
It("doesn't send any more packets after receiving a CONNECTION_CLOSE", func() {
unpacker := NewMockUnpacker(mockCtrl)
sess.handshakeConfirmed = true
sess.unpacker = unpacker
cryptoSetup.EXPECT().Close()
streamManager.EXPECT().CloseWithError(gomock.Any())
sessionRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any()).AnyTimes()
buf := &bytes.Buffer{}
Expect((&wire.ExtendedHeader{
Header: wire.Header{DestConnectionID: srcConnID},
PacketNumberLen: protocol.PacketNumberLen2,
}).Write(buf, sess.version)).To(Succeed())
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(*wire.Header, time.Time, []byte) (*unpackedPacket, error) {
buf := &bytes.Buffer{}
Expect((&wire.ConnectionCloseFrame{ErrorCode: qerr.StreamLimitError}).Write(buf, sess.version)).To(Succeed())
return &unpackedPacket{data: buf.Bytes(), encryptionLevel: protocol.Encryption1RTT}, nil
})
// don't EXPECT any calls to packer.PackPacket()
sess.handlePacket(&receivedPacket{
rcvTime: time.Now(),
remoteAddr: &net.UDPAddr{},
buffer: getPacketBuffer(),
data: buf.Bytes(),
})
// Consistently(pack).ShouldNot(Receive())
Eventually(sess.Context().Done()).Should(BeClosed())
})
})
Context("receiving packets", func() {