From 90a824a84974b47f88f2b1698b7b6aa455787237 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 28 Nov 2024 15:48:42 +0800 Subject: [PATCH] flowcontrol: fix start of the flow-control auto-tuning period (#4730) The period should start when the first frame is received, not when the data is first read. This makes a difference when the first STREAM frame is received out of order. --- internal/flowcontrol/base_flow_controller.go | 5 ----- internal/flowcontrol/connection_flow_controller.go | 5 +++++ internal/flowcontrol/stream_flow_controller.go | 9 +++++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/internal/flowcontrol/base_flow_controller.go b/internal/flowcontrol/base_flow_controller.go index 3d88d577e..c47e6e0fd 100644 --- a/internal/flowcontrol/base_flow_controller.go +++ b/internal/flowcontrol/base_flow_controller.go @@ -66,11 +66,6 @@ func (c *baseFlowController) sendWindowSize() protocol.ByteCount { // needs to be called with locked mutex func (c *baseFlowController) addBytesRead(n protocol.ByteCount) { - // pretend we sent a WindowUpdate when reading the first byte - // this way auto-tuning of the window size already works for the first WindowUpdate - if c.bytesRead == 0 { - c.startNewAutoTuningEpoch(time.Now()) - } c.bytesRead += n } diff --git a/internal/flowcontrol/connection_flow_controller.go b/internal/flowcontrol/connection_flow_controller.go index 2efcad747..2cb7c5ad1 100644 --- a/internal/flowcontrol/connection_flow_controller.go +++ b/internal/flowcontrol/connection_flow_controller.go @@ -46,7 +46,12 @@ func (c *connectionFlowController) IncrementHighestReceived(increment protocol.B c.mutex.Lock() defer c.mutex.Unlock() + // If this is the first frame received on this connection, start flow-control auto-tuning. + if c.highestReceived == 0 { + c.startNewAutoTuningEpoch(time.Now()) + } c.highestReceived += increment + if c.checkFlowControlViolation() { return &qerr.TransportError{ ErrorCode: qerr.FlowControlError, diff --git a/internal/flowcontrol/stream_flow_controller.go b/internal/flowcontrol/stream_flow_controller.go index 2d58351cb..7c7b0ee53 100644 --- a/internal/flowcontrol/stream_flow_controller.go +++ b/internal/flowcontrol/stream_flow_controller.go @@ -2,6 +2,7 @@ package flowcontrol import ( "fmt" + "time" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/qerr" @@ -70,8 +71,7 @@ func (c *streamFlowController) UpdateHighestReceived(offset protocol.ByteCount, if offset == c.highestReceived { return nil } - // A higher offset was received before. - // This can happen due to reordering. + // A higher offset was received before. This can happen due to reordering. if offset <= c.highestReceived { if final { return &qerr.TransportError{ @@ -82,8 +82,13 @@ func (c *streamFlowController) UpdateHighestReceived(offset protocol.ByteCount, return nil } + // If this is the first frame received for this stream, start flow-control auto-tuning. + if c.highestReceived == 0 { + c.startNewAutoTuningEpoch(time.Now()) + } increment := offset - c.highestReceived c.highestReceived = offset + if c.checkFlowControlViolation() { return &qerr.TransportError{ ErrorCode: qerr.FlowControlError,