diff --git a/config.go b/config.go index c82880ac..886ef0d6 100644 --- a/config.go +++ b/config.go @@ -79,6 +79,10 @@ func populateConfig(config *Config) *Config { if maxReceiveStreamFlowControlWindow == 0 { maxReceiveStreamFlowControlWindow = protocol.DefaultMaxReceiveStreamFlowControlWindow } + initialConnectionFlowControlWindow := config.InitialConnectionFlowControlWindow + if initialConnectionFlowControlWindow == 0 { + initialConnectionFlowControlWindow = protocol.DefaultInitialMaxData + } maxReceiveConnectionFlowControlWindow := config.MaxReceiveConnectionFlowControlWindow if maxReceiveConnectionFlowControlWindow == 0 { maxReceiveConnectionFlowControlWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindow @@ -104,6 +108,7 @@ func populateConfig(config *Config) *Config { KeepAlive: config.KeepAlive, InitialStreamFlowControlWindow: initialStreamFlowControlWindow, MaxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow, + InitialConnectionFlowControlWindow: initialConnectionFlowControlWindow, MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow, MaxIncomingStreams: maxIncomingStreams, MaxIncomingUniStreams: maxIncomingUniStreams, diff --git a/config_test.go b/config_test.go index f3402a7e..e5a1b04d 100644 --- a/config_test.go +++ b/config_test.go @@ -61,6 +61,8 @@ var _ = Describe("Config", func() { f.Set(reflect.ValueOf(uint64(1234))) case "MaxReceiveStreamFlowControlWindow": f.Set(reflect.ValueOf(uint64(9))) + case "InitialConnectionFlowControlWindow": + f.Set(reflect.ValueOf(uint64(4321))) case "MaxReceiveConnectionFlowControlWindow": f.Set(reflect.ValueOf(uint64(10))) case "MaxIncomingStreams": @@ -146,6 +148,7 @@ var _ = Describe("Config", func() { Expect(c.HandshakeIdleTimeout).To(Equal(protocol.DefaultHandshakeIdleTimeout)) Expect(c.InitialStreamFlowControlWindow).To(BeEquivalentTo(protocol.DefaultInitialMaxStreamData)) Expect(c.MaxReceiveStreamFlowControlWindow).To(BeEquivalentTo(protocol.DefaultMaxReceiveStreamFlowControlWindow)) + Expect(c.InitialConnectionFlowControlWindow).To(BeEquivalentTo(protocol.DefaultInitialMaxData)) Expect(c.MaxReceiveConnectionFlowControlWindow).To(BeEquivalentTo(protocol.DefaultMaxReceiveConnectionFlowControlWindow)) Expect(c.MaxIncomingStreams).To(BeEquivalentTo(protocol.DefaultMaxIncomingStreams)) Expect(c.MaxIncomingUniStreams).To(BeEquivalentTo(protocol.DefaultMaxIncomingUniStreams)) diff --git a/interface.go b/interface.go index 64a22ba1..0651101c 100644 --- a/interface.go +++ b/interface.go @@ -253,6 +253,11 @@ type Config struct { // MaxReceiveStreamFlowControlWindow is the maximum stream-level flow control window for receiving data. // If this value is zero, it will default to 6 MB. MaxReceiveStreamFlowControlWindow uint64 + // InitialConnectionFlowControlWindow is the initial size of the stream-level flow control window for receiving data. + // If the application is consuming data quickly enough, the flow control auto-tuning algorithm + // will increase the window up to MaxReceiveConnectionFlowControlWindow. + // If this value is zero, it will default to 512 KB. + InitialConnectionFlowControlWindow uint64 // MaxReceiveConnectionFlowControlWindow is the connection-level flow control window for receiving data. // If this value is zero, it will default to 15 MB. MaxReceiveConnectionFlowControlWindow uint64 diff --git a/internal/protocol/params.go b/internal/protocol/params.go index dcc7a349..4bc33e27 100644 --- a/internal/protocol/params.go +++ b/internal/protocol/params.go @@ -24,8 +24,8 @@ const ConnectionFlowControlMultiplier = 1.5 // DefaultInitialMaxStreamData is the default initial stream-level flow control window for receiving data const DefaultInitialMaxStreamData = (1 << 10) * 512 // 512 kb -// InitialMaxData is the connection-level flow control window for receiving data -const InitialMaxData = ConnectionFlowControlMultiplier * DefaultInitialMaxStreamData +// DefaultInitialMaxData is the connection-level flow control window for receiving data +const DefaultInitialMaxData = ConnectionFlowControlMultiplier * DefaultInitialMaxStreamData // DefaultMaxReceiveStreamFlowControlWindow is the default maximum stream-level flow control window for receiving data const DefaultMaxReceiveStreamFlowControlWindow = 6 * (1 << 20) // 6 MB diff --git a/session.go b/session.go index 89b51f8c..9b40dc75 100644 --- a/session.go +++ b/session.go @@ -286,7 +286,7 @@ var newSession = func( InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamFlowControlWindow), InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamFlowControlWindow), InitialMaxStreamDataUni: protocol.ByteCount(s.config.InitialStreamFlowControlWindow), - InitialMaxData: protocol.InitialMaxData, + InitialMaxData: protocol.ByteCount(s.config.InitialConnectionFlowControlWindow), MaxIdleTimeout: s.config.MaxIdleTimeout, MaxBidiStreamNum: protocol.StreamNum(s.config.MaxIncomingStreams), MaxUniStreamNum: protocol.StreamNum(s.config.MaxIncomingUniStreams), @@ -410,7 +410,7 @@ var newClientSession = func( InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamFlowControlWindow), InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamFlowControlWindow), InitialMaxStreamDataUni: protocol.ByteCount(s.config.InitialStreamFlowControlWindow), - InitialMaxData: protocol.InitialMaxData, + InitialMaxData: protocol.ByteCount(s.config.InitialConnectionFlowControlWindow), MaxIdleTimeout: s.config.MaxIdleTimeout, MaxBidiStreamNum: protocol.StreamNum(s.config.MaxIncomingStreams), MaxUniStreamNum: protocol.StreamNum(s.config.MaxIncomingUniStreams), @@ -484,7 +484,7 @@ func (s *session) preSetup() { s.frameParser = wire.NewFrameParser(s.config.EnableDatagrams, s.version) s.rttStats = &utils.RTTStats{} s.connFlowController = flowcontrol.NewConnectionFlowController( - protocol.InitialMaxData, + protocol.ByteCount(s.config.InitialConnectionFlowControlWindow), protocol.ByteCount(s.config.MaxReceiveConnectionFlowControlWindow), s.onHasConnectionWindowUpdate, s.rttStats,