Merge pull request #3083 from lucas-clemente/configure-initial-flow-control-window

make the initial stream / connection flow control windows configurable
This commit is contained in:
Marten Seemann
2021-03-16 22:17:08 +08:00
committed by GitHub
5 changed files with 40 additions and 14 deletions

View File

@@ -71,10 +71,18 @@ func populateConfig(config *Config) *Config {
if config.MaxIdleTimeout != 0 {
idleTimeout = config.MaxIdleTimeout
}
initialStreamFlowControlWindow := config.InitialStreamFlowControlWindow
if initialStreamFlowControlWindow == 0 {
initialStreamFlowControlWindow = protocol.DefaultInitialMaxStreamData
}
maxReceiveStreamFlowControlWindow := config.MaxReceiveStreamFlowControlWindow
if maxReceiveStreamFlowControlWindow == 0 {
maxReceiveStreamFlowControlWindow = protocol.DefaultMaxReceiveStreamFlowControlWindow
}
initialConnectionFlowControlWindow := config.InitialConnectionFlowControlWindow
if initialConnectionFlowControlWindow == 0 {
initialConnectionFlowControlWindow = protocol.DefaultInitialMaxData
}
maxReceiveConnectionFlowControlWindow := config.MaxReceiveConnectionFlowControlWindow
if maxReceiveConnectionFlowControlWindow == 0 {
maxReceiveConnectionFlowControlWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindow
@@ -98,7 +106,9 @@ func populateConfig(config *Config) *Config {
MaxIdleTimeout: idleTimeout,
AcceptToken: config.AcceptToken,
KeepAlive: config.KeepAlive,
InitialStreamFlowControlWindow: initialStreamFlowControlWindow,
MaxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow,
InitialConnectionFlowControlWindow: initialConnectionFlowControlWindow,
MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow,
MaxIncomingStreams: maxIncomingStreams,
MaxIncomingUniStreams: maxIncomingUniStreams,

View File

@@ -57,8 +57,12 @@ var _ = Describe("Config", func() {
f.Set(reflect.ValueOf(time.Hour))
case "TokenStore":
f.Set(reflect.ValueOf(NewLRUTokenStore(2, 3)))
case "InitialStreamFlowControlWindow":
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":
@@ -142,7 +146,9 @@ var _ = Describe("Config", func() {
c := populateConfig(&Config{})
Expect(c.Versions).To(Equal(protocol.SupportedVersions))
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))

View File

@@ -255,9 +255,19 @@ type Config struct {
// The key used to store tokens is the ServerName from the tls.Config, if set
// otherwise the token is associated with the server's IP address.
TokenStore TokenStore
// InitialStreamFlowControlWindow 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 MaxReceiveStreamFlowControlWindow.
// If this value is zero, it will default to 512 KB.
InitialStreamFlowControlWindow uint64
// 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

View File

@@ -21,11 +21,11 @@ const MaxUndecryptablePackets = 32
// This is the value that Chromium is using
const ConnectionFlowControlMultiplier = 1.5
// InitialMaxStreamData is the stream-level flow control window for receiving data
const InitialMaxStreamData = (1 << 10) * 512 // 512 kb
// 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 * InitialMaxStreamData
// 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

View File

@@ -295,10 +295,10 @@ var newSession = func(
initialStream := newCryptoStream()
handshakeStream := newCryptoStream()
params := &wire.TransportParameters{
InitialMaxStreamDataBidiLocal: protocol.InitialMaxStreamData,
InitialMaxStreamDataBidiRemote: protocol.InitialMaxStreamData,
InitialMaxStreamDataUni: protocol.InitialMaxStreamData,
InitialMaxData: protocol.InitialMaxData,
InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxStreamDataUni: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxData: protocol.ByteCount(s.config.InitialConnectionFlowControlWindow),
MaxIdleTimeout: s.config.MaxIdleTimeout,
MaxBidiStreamNum: protocol.StreamNum(s.config.MaxIncomingStreams),
MaxUniStreamNum: protocol.StreamNum(s.config.MaxIncomingUniStreams),
@@ -419,10 +419,10 @@ var newClientSession = func(
initialStream := newCryptoStream()
handshakeStream := newCryptoStream()
params := &wire.TransportParameters{
InitialMaxStreamDataBidiRemote: protocol.InitialMaxStreamData,
InitialMaxStreamDataBidiLocal: protocol.InitialMaxStreamData,
InitialMaxStreamDataUni: protocol.InitialMaxStreamData,
InitialMaxData: protocol.InitialMaxData,
InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxStreamDataUni: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxData: protocol.ByteCount(s.config.InitialConnectionFlowControlWindow),
MaxIdleTimeout: s.config.MaxIdleTimeout,
MaxBidiStreamNum: protocol.StreamNum(s.config.MaxIncomingStreams),
MaxUniStreamNum: protocol.StreamNum(s.config.MaxIncomingUniStreams),
@@ -496,7 +496,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,
@@ -1822,7 +1822,7 @@ func (s *session) newFlowController(id protocol.StreamID) flowcontrol.StreamFlow
return flowcontrol.NewStreamFlowController(
id,
s.connFlowController,
protocol.InitialMaxStreamData,
protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
protocol.ByteCount(s.config.MaxReceiveStreamFlowControlWindow),
initialSendWindow,
s.onHasStreamWindowUpdate,