make the initial stream flow control window configurable

This commit is contained in:
Marten Seemann
2021-03-10 14:55:42 +08:00
parent 9dcb56b76f
commit d9434f523e
5 changed files with 23 additions and 10 deletions

View File

@@ -71,6 +71,10 @@ 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
@@ -98,6 +102,7 @@ func populateConfig(config *Config) *Config {
MaxIdleTimeout: idleTimeout,
AcceptToken: config.AcceptToken,
KeepAlive: config.KeepAlive,
InitialStreamFlowControlWindow: initialStreamFlowControlWindow,
MaxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow,
MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow,
MaxIncomingStreams: maxIncomingStreams,

View File

@@ -57,6 +57,8 @@ 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 "MaxReceiveConnectionFlowControlWindow":
@@ -142,6 +144,7 @@ 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.MaxReceiveConnectionFlowControlWindow).To(BeEquivalentTo(protocol.DefaultMaxReceiveConnectionFlowControlWindow))
Expect(c.MaxIncomingStreams).To(BeEquivalentTo(protocol.DefaultMaxIncomingStreams))

View File

@@ -245,6 +245,11 @@ 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

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
const InitialMaxData = ConnectionFlowControlMultiplier * DefaultInitialMaxStreamData
// DefaultMaxReceiveStreamFlowControlWindow is the default maximum stream-level flow control window for receiving data
const DefaultMaxReceiveStreamFlowControlWindow = 6 * (1 << 20) // 6 MB

View File

@@ -283,9 +283,9 @@ var newSession = func(
initialStream := newCryptoStream()
handshakeStream := newCryptoStream()
params := &wire.TransportParameters{
InitialMaxStreamDataBidiLocal: protocol.InitialMaxStreamData,
InitialMaxStreamDataBidiRemote: protocol.InitialMaxStreamData,
InitialMaxStreamDataUni: protocol.InitialMaxStreamData,
InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxStreamDataUni: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxData: protocol.InitialMaxData,
MaxIdleTimeout: s.config.MaxIdleTimeout,
MaxBidiStreamNum: protocol.StreamNum(s.config.MaxIncomingStreams),
@@ -407,9 +407,9 @@ var newClientSession = func(
initialStream := newCryptoStream()
handshakeStream := newCryptoStream()
params := &wire.TransportParameters{
InitialMaxStreamDataBidiRemote: protocol.InitialMaxStreamData,
InitialMaxStreamDataBidiLocal: protocol.InitialMaxStreamData,
InitialMaxStreamDataUni: protocol.InitialMaxStreamData,
InitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxStreamDataBidiLocal: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxStreamDataUni: protocol.ByteCount(s.config.InitialStreamFlowControlWindow),
InitialMaxData: protocol.InitialMaxData,
MaxIdleTimeout: s.config.MaxIdleTimeout,
MaxBidiStreamNum: protocol.StreamNum(s.config.MaxIncomingStreams),
@@ -1791,7 +1791,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,