From 48ed55a01d63ed7cbe4a6434f39e0f4af3ebd9f9 Mon Sep 17 00:00:00 2001 From: Quentin De Coninck Date: Fri, 26 May 2017 11:45:21 +0200 Subject: [PATCH] fix stalls when retransmitting connection-level Window Update Frames When a Window Update Frame with streamID 0 is lost, we want to know the receive window when retransmitting the frame. However, the connection flow controller is not in streamFlowController, leading to map access errors and then connections stalls since the sender is stuck by the not-updated receive window it previously received. --- flowcontrol/flow_control_manager.go | 5 +++++ flowcontrol/flow_control_manager_test.go | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/flowcontrol/flow_control_manager.go b/flowcontrol/flow_control_manager.go index d9f4af21f..c5b4e7541 100644 --- a/flowcontrol/flow_control_manager.go +++ b/flowcontrol/flow_control_manager.go @@ -157,6 +157,11 @@ func (f *flowControlManager) GetReceiveWindow(streamID protocol.StreamID) (proto f.mutex.RLock() defer f.mutex.RUnlock() + // StreamID can be 0 when retransmitting + if streamID == 0 { + return f.connFlowController.receiveWindow, nil + } + flowController, err := f.getFlowController(streamID) if err != nil { return 0, err diff --git a/flowcontrol/flow_control_manager_test.go b/flowcontrol/flow_control_manager_test.go index 92fde3b25..b0a2a8999 100644 --- a/flowcontrol/flow_control_manager_test.go +++ b/flowcontrol/flow_control_manager_test.go @@ -103,6 +103,12 @@ var _ = Describe("Flow Control Manager", func() { Expect(err).To(MatchError(errMapAccess)) }) + It("gets the offset of the connection-level receive window", func() { + offset, err := fcm.GetReceiveWindow(0) + Expect(err).ToNot(HaveOccurred()) + Expect(offset).To(Equal(protocol.ByteCount(200))) + }) + Context("flow control violations", func() { It("errors when encountering a stream level flow control violation", func() { err := fcm.UpdateHighestReceived(4, 101)