diff --git a/session.go b/session.go index 97327edff..63fd72cf7 100644 --- a/session.go +++ b/session.go @@ -1563,6 +1563,11 @@ func (s *session) sendPackets() error { default: return fmt.Errorf("BUG: invalid send mode %d", sendMode) } + // Prioritize receiving of packets over sending out more packets. + if len(s.receivedPackets) > 0 { + s.pacingDeadline = deadlineSendImmediately + return nil + } if s.sendQueue.WouldBlock() { return nil } diff --git a/session_test.go b/session_test.go index 23b5377c4..ff3325a2a 100644 --- a/session_test.go +++ b/session_test.go @@ -1571,6 +1571,32 @@ var _ = Describe("Session", func() { Eventually(written).Should(BeClosed()) }) + It("stops sending when there are new packets to receive", func() { + sender.EXPECT().WouldBlock().AnyTimes() + go func() { + defer GinkgoRecover() + cryptoSetup.EXPECT().RunHandshake().MaxTimes(1) + sess.run() + }() + + written := make(chan struct{}) + sender.EXPECT().WouldBlock().AnyTimes() + sph.EXPECT().SentPacket(gomock.Any()).Do(func(*ackhandler.Packet) { + sph.EXPECT().ReceivedBytes(gomock.Any()) + sess.handlePacket(&receivedPacket{buffer: getPacketBuffer()}) + }) + sph.EXPECT().HasPacingBudget().Return(true).AnyTimes() + sph.EXPECT().SendMode().Return(ackhandler.SendAny).AnyTimes() + packer.EXPECT().PackPacket().Return(getPacket(1000), nil) + packer.EXPECT().PackPacket().Return(nil, nil) + sender.EXPECT().Send(gomock.Any()).DoAndReturn(func(p *packetBuffer) { close(written) }) + + sess.scheduleSending() + time.Sleep(scaleDuration(50 * time.Millisecond)) + + Eventually(written).Should(BeClosed()) + }) + It("stops sending when the send queue is full", func() { sph.EXPECT().SentPacket(gomock.Any()) sph.EXPECT().HasPacingBudget().Return(true).AnyTimes()