From 93e2f751b5021f4dd187acccef3bd8f5fbb475e9 Mon Sep 17 00:00:00 2001 From: Thomas De Keulenaer Date: Tue, 13 Jun 2017 14:00:00 +0200 Subject: [PATCH 1/5] Fix typo and clarify --- protocol/server_parameters.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/protocol/server_parameters.go b/protocol/server_parameters.go index 832d3879..b6284685 100644 --- a/protocol/server_parameters.go +++ b/protocol/server_parameters.go @@ -39,11 +39,11 @@ const ReceiveStreamFlowControlWindow ByteCount = (1 << 10) * 32 // 32 kB // This is the value that Google servers are using const ReceiveConnectionFlowControlWindow ByteCount = (1 << 10) * 48 // 48 kB -// MaxReceiveStreamFlowControlWindowServer is the maximum stream-level flow control window for receiving data +// MaxReceiveStreamFlowControlWindowServer is the maximum stream-level flow control window for receiving data, for the server // This is the value that Google servers are using const MaxReceiveStreamFlowControlWindowServer ByteCount = 1 * (1 << 20) // 1 MB -// MaxReceiveConnectionFlowControlWindowServer is the connection-level flow control window for receiving data +// MaxReceiveConnectionFlowControlWindowServer is the connection-level flow control window for receiving data, for the server // This is the value that Google servers are using const MaxReceiveConnectionFlowControlWindowServer ByteCount = 1.5 * (1 << 20) // 1.5 MB @@ -51,7 +51,7 @@ const MaxReceiveConnectionFlowControlWindowServer ByteCount = 1.5 * (1 << 20) // // This is the value that Chromium is using const MaxReceiveStreamFlowControlWindowClient ByteCount = 6 * (1 << 20) // 6 MB -// MaxReceiveConnectionFlowControlWindowClient is the connection-level flow control window for receiving data, for the server +// MaxReceiveConnectionFlowControlWindowClient is the connection-level flow control window for receiving data, for the client // This is the value that Google servers are using const MaxReceiveConnectionFlowControlWindowClient ByteCount = 15 * (1 << 20) // 15 MB From 89f96d1e8927ef282f0f170dee9c1685fbdd25a3 Mon Sep 17 00:00:00 2001 From: Thomas De Keulenaer Date: Tue, 13 Jun 2017 15:52:51 +0200 Subject: [PATCH 2/5] Make max flow control windows configurable --- client.go | 14 ++++--- handshake/connection_parameters_manager.go | 39 ++++++++++++++++--- .../connection_parameters_manager_test.go | 34 ++++++++++++---- handshake/crypto_setup_client_test.go | 7 +++- handshake/crypto_setup_server_test.go | 7 +++- interface.go | 12 ++++++ protocol/server_parameters.go | 16 ++++---- server.go | 6 ++- session.go | 6 ++- 9 files changed, 108 insertions(+), 33 deletions(-) diff --git a/client.go b/client.go index 3bf686f7..2072ffa4 100644 --- a/client.go +++ b/client.go @@ -9,9 +9,9 @@ import ( "sync" "time" + "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/protocol" "github.com/lucas-clemente/quic-go/qerr" - "github.com/lucas-clemente/quic-go/internal/utils" ) type client struct { @@ -124,10 +124,14 @@ func populateClientConfig(config *Config) *Config { } return &Config{ - TLSConfig: config.TLSConfig, - Versions: versions, - HandshakeTimeout: handshakeTimeout, - RequestConnectionIDTruncation: config.RequestConnectionIDTruncation, + TLSConfig: config.TLSConfig, + Versions: versions, + HandshakeTimeout: handshakeTimeout, + RequestConnectionIDTruncation: config.RequestConnectionIDTruncation, + MaxReceiveStreamFlowControlWindowServer: config.MaxReceiveStreamFlowControlWindowServer, + MaxReceiveConnectionFlowControlWindowServer: config.MaxReceiveConnectionFlowControlWindowServer, + MaxReceiveStreamFlowControlWindowClient: config.MaxReceiveStreamFlowControlWindowClient, + MaxReceiveConnectionFlowControlWindowClient: config.MaxReceiveConnectionFlowControlWindowClient, } } diff --git a/handshake/connection_parameters_manager.go b/handshake/connection_parameters_manager.go index 1127471b..799dd4bf 100644 --- a/handshake/connection_parameters_manager.go +++ b/handshake/connection_parameters_manager.go @@ -5,9 +5,9 @@ import ( "sync" "time" + "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/protocol" "github.com/lucas-clemente/quic-go/qerr" - "github.com/lucas-clemente/quic-go/internal/utils" ) // ConnectionParametersManager negotiates and stores the connection parameters @@ -50,6 +50,11 @@ type connectionParametersManager struct { sendConnectionFlowControlWindow protocol.ByteCount receiveStreamFlowControlWindow protocol.ByteCount receiveConnectionFlowControlWindow protocol.ByteCount + + maxReceiveStreamFlowControlWindowServer protocol.ByteCount + maxReceiveConnectionFlowControlWindowServer protocol.ByteCount + maxReceiveStreamFlowControlWindowClient protocol.ByteCount + maxReceiveConnectionFlowControlWindowClient protocol.ByteCount } var _ ConnectionParametersManager = &connectionParametersManager{} @@ -61,7 +66,24 @@ var ( ) // NewConnectionParamatersManager creates a new connection parameters manager -func NewConnectionParamatersManager(pers protocol.Perspective, v protocol.VersionNumber) ConnectionParametersManager { +func NewConnectionParamatersManager( + pers protocol.Perspective, v protocol.VersionNumber, + maxReceiveStreamFlowControlWindowServer protocol.ByteCount, maxReceiveConnectionFlowControlWindowServer protocol.ByteCount, + maxReceiveStreamFlowControlWindowClient protocol.ByteCount, maxReceiveConnectionFlowControlWindowClient protocol.ByteCount, +) ConnectionParametersManager { + if maxReceiveStreamFlowControlWindowServer == 0 { + maxReceiveStreamFlowControlWindowServer = protocol.DefaultMaxReceiveStreamFlowControlWindowServer + } + if maxReceiveConnectionFlowControlWindowServer == 0 { + maxReceiveConnectionFlowControlWindowServer = protocol.DefaultMaxReceiveConnectionFlowControlWindowServer + } + if maxReceiveStreamFlowControlWindowClient == 0 { + maxReceiveStreamFlowControlWindowClient = protocol.DefaultMaxReceiveStreamFlowControlWindowClient + } + if maxReceiveConnectionFlowControlWindowClient == 0 { + maxReceiveConnectionFlowControlWindowClient = protocol.DefaultMaxReceiveConnectionFlowControlWindowClient + } + h := &connectionParametersManager{ perspective: pers, version: v, @@ -69,6 +91,11 @@ func NewConnectionParamatersManager(pers protocol.Perspective, v protocol.Versio sendConnectionFlowControlWindow: protocol.InitialConnectionFlowControlWindow, // can only be changed by the client receiveStreamFlowControlWindow: protocol.ReceiveStreamFlowControlWindow, receiveConnectionFlowControlWindow: protocol.ReceiveConnectionFlowControlWindow, + + maxReceiveStreamFlowControlWindowServer: maxReceiveStreamFlowControlWindowServer, + maxReceiveConnectionFlowControlWindowServer: maxReceiveConnectionFlowControlWindowServer, + maxReceiveStreamFlowControlWindowClient: maxReceiveStreamFlowControlWindowClient, + maxReceiveConnectionFlowControlWindowClient: maxReceiveConnectionFlowControlWindowClient, } if h.perspective == protocol.PerspectiveServer { @@ -208,9 +235,9 @@ func (h *connectionParametersManager) GetReceiveStreamFlowControlWindow() protoc // GetMaxReceiveStreamFlowControlWindow gets the maximum size of the stream-level flow control window for sending data func (h *connectionParametersManager) GetMaxReceiveStreamFlowControlWindow() protocol.ByteCount { if h.perspective == protocol.PerspectiveServer { - return protocol.MaxReceiveStreamFlowControlWindowServer + return h.maxReceiveStreamFlowControlWindowServer } - return protocol.MaxReceiveStreamFlowControlWindowClient + return h.maxReceiveStreamFlowControlWindowClient } // GetReceiveConnectionFlowControlWindow gets the size of the stream-level flow control window for receiving data @@ -223,9 +250,9 @@ func (h *connectionParametersManager) GetReceiveConnectionFlowControlWindow() pr // GetMaxReceiveConnectionFlowControlWindow gets the maximum size of the stream-level flow control window for sending data func (h *connectionParametersManager) GetMaxReceiveConnectionFlowControlWindow() protocol.ByteCount { if h.perspective == protocol.PerspectiveServer { - return protocol.MaxReceiveConnectionFlowControlWindowServer + return h.maxReceiveConnectionFlowControlWindowServer } - return protocol.MaxReceiveConnectionFlowControlWindowClient + return h.maxReceiveConnectionFlowControlWindowClient } // GetMaxOutgoingStreams gets the maximum number of outgoing streams per connection diff --git a/handshake/connection_parameters_manager_test.go b/handshake/connection_parameters_manager_test.go index 425a9278..ba8f427d 100644 --- a/handshake/connection_parameters_manager_test.go +++ b/handshake/connection_parameters_manager_test.go @@ -2,6 +2,7 @@ package handshake import ( "encoding/binary" + "math" "time" "github.com/lucas-clemente/quic-go/protocol" @@ -12,10 +13,20 @@ import ( var _ = Describe("ConnectionsParameterManager", func() { var cpm *connectionParametersManager // a connectionParametersManager for a server var cpmClient *connectionParametersManager - + const MB = 1 << 20 + maxReceiveStreamFlowControlWindowServer := protocol.ByteCount(math.Floor(1.1 * MB)) // default is 1 MB + maxReceiveConnectionFlowControlWindowServer := protocol.ByteCount(math.Floor(1.5 * MB)) // default is 1.5 MB + maxReceiveStreamFlowControlWindowClient := protocol.ByteCount(math.Floor(6.4 * MB)) // default is 6 MB + maxReceiveConnectionFlowControlWindowClient := protocol.ByteCount(math.Floor(13 * MB)) // default is 15 MB BeforeEach(func() { - cpm = NewConnectionParamatersManager(protocol.PerspectiveServer, protocol.Version36).(*connectionParametersManager) - cpmClient = NewConnectionParamatersManager(protocol.PerspectiveClient, protocol.Version36).(*connectionParametersManager) + cpm = NewConnectionParamatersManager(protocol.PerspectiveServer, protocol.Version36, + maxReceiveStreamFlowControlWindowServer, maxReceiveConnectionFlowControlWindowServer, + maxReceiveStreamFlowControlWindowClient, maxReceiveConnectionFlowControlWindowClient, + ).(*connectionParametersManager) + cpmClient = NewConnectionParamatersManager(protocol.PerspectiveClient, protocol.Version36, + maxReceiveStreamFlowControlWindowServer, maxReceiveConnectionFlowControlWindowServer, + maxReceiveStreamFlowControlWindowClient, maxReceiveConnectionFlowControlWindowClient, + ).(*connectionParametersManager) }) Context("SHLO", func() { @@ -137,10 +148,19 @@ var _ = Describe("ConnectionsParameterManager", func() { }) It("has the correct maximum flow control windows", func() { - Expect(cpm.GetMaxReceiveStreamFlowControlWindow()).To(Equal(protocol.MaxReceiveStreamFlowControlWindowServer)) - Expect(cpm.GetMaxReceiveConnectionFlowControlWindow()).To(Equal(protocol.MaxReceiveConnectionFlowControlWindowServer)) - Expect(cpmClient.GetMaxReceiveStreamFlowControlWindow()).To(Equal(protocol.MaxReceiveStreamFlowControlWindowClient)) - Expect(cpmClient.GetMaxReceiveConnectionFlowControlWindow()).To(Equal(protocol.MaxReceiveConnectionFlowControlWindowClient)) + Expect(cpm.GetMaxReceiveStreamFlowControlWindow()).To(Equal(maxReceiveStreamFlowControlWindowServer)) + Expect(cpm.GetMaxReceiveConnectionFlowControlWindow()).To(Equal(maxReceiveConnectionFlowControlWindowServer)) + Expect(cpmClient.GetMaxReceiveStreamFlowControlWindow()).To(Equal(maxReceiveStreamFlowControlWindowClient)) + Expect(cpmClient.GetMaxReceiveConnectionFlowControlWindow()).To(Equal(maxReceiveConnectionFlowControlWindowClient)) + }) + + It("defaults to the correct maximum flow control windows", func() { + cpmDefault := NewConnectionParamatersManager(protocol.PerspectiveServer, protocol.Version36, 0, 0, 0, 0).(*connectionParametersManager) + cpmClientDefault := NewConnectionParamatersManager(protocol.PerspectiveClient, protocol.Version36, 0, 0, 0, 0).(*connectionParametersManager) + Expect(cpmDefault.GetMaxReceiveStreamFlowControlWindow()).To(Equal(protocol.DefaultMaxReceiveStreamFlowControlWindowServer)) + Expect(cpmDefault.GetMaxReceiveConnectionFlowControlWindow()).To(Equal(protocol.DefaultMaxReceiveConnectionFlowControlWindowServer)) + Expect(cpmClientDefault.GetMaxReceiveStreamFlowControlWindow()).To(Equal(protocol.DefaultMaxReceiveStreamFlowControlWindowClient)) + Expect(cpmClientDefault.GetMaxReceiveConnectionFlowControlWindow()).To(Equal(protocol.DefaultMaxReceiveConnectionFlowControlWindowClient)) }) It("sets a new stream-level flow control window for sending", func() { diff --git a/handshake/crypto_setup_client_test.go b/handshake/crypto_setup_client_test.go index 31053694..aeb1f5a2 100644 --- a/handshake/crypto_setup_client_test.go +++ b/handshake/crypto_setup_client_test.go @@ -8,9 +8,9 @@ import ( "time" "github.com/lucas-clemente/quic-go/crypto" + "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/protocol" "github.com/lucas-clemente/quic-go/qerr" - "github.com/lucas-clemente/quic-go/internal/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) @@ -111,7 +111,10 @@ var _ = Describe("Client Crypto Setup", func() { version, stream, nil, - NewConnectionParamatersManager(protocol.PerspectiveClient, version), + NewConnectionParamatersManager(protocol.PerspectiveClient, version, + protocol.DefaultMaxReceiveStreamFlowControlWindowServer, protocol.DefaultMaxReceiveConnectionFlowControlWindowServer, + protocol.DefaultMaxReceiveStreamFlowControlWindowClient, protocol.DefaultMaxReceiveConnectionFlowControlWindowClient, + ), aeadChanged, &TransportParameters{}, nil, diff --git a/handshake/crypto_setup_server_test.go b/handshake/crypto_setup_server_test.go index c326de50..4e681604 100644 --- a/handshake/crypto_setup_server_test.go +++ b/handshake/crypto_setup_server_test.go @@ -7,9 +7,9 @@ import ( "net" "github.com/lucas-clemente/quic-go/crypto" + "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/protocol" "github.com/lucas-clemente/quic-go/qerr" - "github.com/lucas-clemente/quic-go/internal/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -184,7 +184,10 @@ var _ = Describe("Server Crypto Setup", func() { Expect(err).NotTo(HaveOccurred()) version = protocol.SupportedVersions[len(protocol.SupportedVersions)-1] supportedVersions = []protocol.VersionNumber{version, 98, 99} - cpm = NewConnectionParamatersManager(protocol.PerspectiveServer, protocol.VersionWhatever) + cpm = NewConnectionParamatersManager(protocol.PerspectiveServer, protocol.VersionWhatever, + protocol.DefaultMaxReceiveStreamFlowControlWindowServer, protocol.DefaultMaxReceiveConnectionFlowControlWindowServer, + protocol.DefaultMaxReceiveStreamFlowControlWindowClient, protocol.DefaultMaxReceiveConnectionFlowControlWindowClient, + ) csInt, err := NewCryptoSetup( protocol.ConnectionID(42), remoteAddr, diff --git a/interface.go b/interface.go index 30bc9b6c..9901203f 100644 --- a/interface.go +++ b/interface.go @@ -80,6 +80,18 @@ type Config struct { // If not set, it verifies that the address matches, and that the STK was issued within the last 24 hours // This option is only valid for the server. AcceptSTK func(clientAddr net.Addr, stk *STK) bool + // MaxReceiveStreamFlowControlWindowServer is the maximum stream-level flow control window for receiving data, for the server + // If this value is zero, the timeout is set to protocol.DefaultMaxReceiveStreamFlowControlWindowServer + MaxReceiveStreamFlowControlWindowServer protocol.ByteCount + // MaxReceiveConnectionFlowControlWindowServer is the connection-level flow control window for receiving data, for the server + // If this value is zero, the timeout is set to protocol.DefaultMaxReceiveConnectionFlowControlWindowServer + MaxReceiveConnectionFlowControlWindowServer protocol.ByteCount + // MaxReceiveStreamFlowControlWindowClient is the maximum stream-level flow control window for receiving data, for the client + // If this value is zero, the timeout is set to protocol.DefaultMaxReceiveStreamFlowControlWindowClient + MaxReceiveStreamFlowControlWindowClient protocol.ByteCount + // MaxReceiveConnectionFlowControlWindowClient is the connection-level flow control window for receiving data, for the client + // If this value is zero, the timeout is set to protocol.DefaultMaxReceiveConnectionFlowControlWindowClient + MaxReceiveConnectionFlowControlWindowClient protocol.ByteCount } // A Listener for incoming QUIC connections diff --git a/protocol/server_parameters.go b/protocol/server_parameters.go index b6284685..8e632cc1 100644 --- a/protocol/server_parameters.go +++ b/protocol/server_parameters.go @@ -39,21 +39,21 @@ const ReceiveStreamFlowControlWindow ByteCount = (1 << 10) * 32 // 32 kB // This is the value that Google servers are using const ReceiveConnectionFlowControlWindow ByteCount = (1 << 10) * 48 // 48 kB -// MaxReceiveStreamFlowControlWindowServer is the maximum stream-level flow control window for receiving data, for the server +// DefaultMaxReceiveStreamFlowControlWindowServer is the default maximum stream-level flow control window for receiving data, for the server // This is the value that Google servers are using -const MaxReceiveStreamFlowControlWindowServer ByteCount = 1 * (1 << 20) // 1 MB +const DefaultMaxReceiveStreamFlowControlWindowServer ByteCount = 1 * (1 << 20) // 1 MB -// MaxReceiveConnectionFlowControlWindowServer is the connection-level flow control window for receiving data, for the server +// DefaultMaxReceiveConnectionFlowControlWindowServer is the default connection-level flow control window for receiving data, for the server // This is the value that Google servers are using -const MaxReceiveConnectionFlowControlWindowServer ByteCount = 1.5 * (1 << 20) // 1.5 MB +const DefaultMaxReceiveConnectionFlowControlWindowServer ByteCount = 1.5 * (1 << 20) // 1.5 MB -// MaxReceiveStreamFlowControlWindowClient is the maximum stream-level flow control window for receiving data, for the client +// DefaultMaxReceiveStreamFlowControlWindowClient is the default maximum stream-level flow control window for receiving data, for the client // This is the value that Chromium is using -const MaxReceiveStreamFlowControlWindowClient ByteCount = 6 * (1 << 20) // 6 MB +const DefaultMaxReceiveStreamFlowControlWindowClient ByteCount = 6 * (1 << 20) // 6 MB -// MaxReceiveConnectionFlowControlWindowClient is the connection-level flow control window for receiving data, for the client +// DefaultMaxReceiveConnectionFlowControlWindowClient is the default connection-level flow control window for receiving data, for the client // This is the value that Google servers are using -const MaxReceiveConnectionFlowControlWindowClient ByteCount = 15 * (1 << 20) // 15 MB +const DefaultMaxReceiveConnectionFlowControlWindowClient ByteCount = 15 * (1 << 20) // 15 MB // ConnectionFlowControlMultiplier determines how much larger the connection flow control windows needs to be relative to any stream's flow control window // This is the value that Chromium is using diff --git a/server.go b/server.go index c373e99a..a613fe93 100644 --- a/server.go +++ b/server.go @@ -9,9 +9,9 @@ import ( "github.com/lucas-clemente/quic-go/crypto" "github.com/lucas-clemente/quic-go/handshake" + "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/protocol" "github.com/lucas-clemente/quic-go/qerr" - "github.com/lucas-clemente/quic-go/internal/utils" ) // packetHandler handles packets @@ -122,6 +122,10 @@ func populateServerConfig(config *Config) *Config { Versions: versions, HandshakeTimeout: handshakeTimeout, AcceptSTK: vsa, + MaxReceiveStreamFlowControlWindowServer: config.MaxReceiveStreamFlowControlWindowServer, + MaxReceiveConnectionFlowControlWindowServer: config.MaxReceiveConnectionFlowControlWindowServer, + MaxReceiveStreamFlowControlWindowClient: config.MaxReceiveStreamFlowControlWindowClient, + MaxReceiveConnectionFlowControlWindowClient: config.MaxReceiveConnectionFlowControlWindowClient, } } diff --git a/session.go b/session.go index a11bfbb8..22bdaca8 100644 --- a/session.go +++ b/session.go @@ -12,9 +12,9 @@ import ( "github.com/lucas-clemente/quic-go/flowcontrol" "github.com/lucas-clemente/quic-go/frames" "github.com/lucas-clemente/quic-go/handshake" + "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/protocol" "github.com/lucas-clemente/quic-go/qerr" - "github.com/lucas-clemente/quic-go/internal/utils" ) type unpacker interface { @@ -172,7 +172,9 @@ func (s *session) setup( s.sessionCreationTime = now s.rttStats = &congestion.RTTStats{} - s.connectionParameters = handshake.NewConnectionParamatersManager(s.perspective, s.version) + s.connectionParameters = handshake.NewConnectionParamatersManager(s.perspective, s.version, + s.config.MaxReceiveStreamFlowControlWindowServer, s.config.MaxReceiveConnectionFlowControlWindowServer, + s.config.MaxReceiveStreamFlowControlWindowClient, s.config.MaxReceiveConnectionFlowControlWindowClient) s.sentPacketHandler = ackhandler.NewSentPacketHandler(s.rttStats) s.flowControlManager = flowcontrol.NewFlowControlManager(s.connectionParameters, s.rttStats) s.receivedPacketHandler = ackhandler.NewReceivedPacketHandler(s.ackAlarmChanged) From 4fa7b9e569090a0cc9679cf20e9150ef8b7e633a Mon Sep 17 00:00:00 2001 From: Thomas De Keulenaer Date: Tue, 13 Jun 2017 16:42:06 +0200 Subject: [PATCH 3/5] Let server and client fill the flow variables --- client.go | 23 +++++--- handshake/connection_parameters_manager.go | 52 +++++-------------- .../connection_parameters_manager_test.go | 6 +-- handshake/crypto_setup_client_test.go | 1 - handshake/crypto_setup_server_test.go | 1 - interface.go | 18 +++---- server.go | 23 +++++--- session.go | 3 +- 8 files changed, 52 insertions(+), 75 deletions(-) diff --git a/client.go b/client.go index 2072ffa4..aeadee75 100644 --- a/client.go +++ b/client.go @@ -123,15 +123,22 @@ func populateClientConfig(config *Config) *Config { handshakeTimeout = config.HandshakeTimeout } + maxReceiveStreamFlowControlWindow := config.MaxReceiveStreamFlowControlWindow + if maxReceiveStreamFlowControlWindow == 0 { + maxReceiveStreamFlowControlWindow = protocol.DefaultMaxReceiveStreamFlowControlWindowClient + } + maxReceiveConnectionFlowControlWindow := config.MaxReceiveConnectionFlowControlWindow + if maxReceiveConnectionFlowControlWindow == 0 { + maxReceiveConnectionFlowControlWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindowClient + } + return &Config{ - TLSConfig: config.TLSConfig, - Versions: versions, - HandshakeTimeout: handshakeTimeout, - RequestConnectionIDTruncation: config.RequestConnectionIDTruncation, - MaxReceiveStreamFlowControlWindowServer: config.MaxReceiveStreamFlowControlWindowServer, - MaxReceiveConnectionFlowControlWindowServer: config.MaxReceiveConnectionFlowControlWindowServer, - MaxReceiveStreamFlowControlWindowClient: config.MaxReceiveStreamFlowControlWindowClient, - MaxReceiveConnectionFlowControlWindowClient: config.MaxReceiveConnectionFlowControlWindowClient, + TLSConfig: config.TLSConfig, + Versions: versions, + HandshakeTimeout: handshakeTimeout, + RequestConnectionIDTruncation: config.RequestConnectionIDTruncation, + MaxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow, + MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow, } } diff --git a/handshake/connection_parameters_manager.go b/handshake/connection_parameters_manager.go index 799dd4bf..1ad9a3a4 100644 --- a/handshake/connection_parameters_manager.go +++ b/handshake/connection_parameters_manager.go @@ -50,11 +50,8 @@ type connectionParametersManager struct { sendConnectionFlowControlWindow protocol.ByteCount receiveStreamFlowControlWindow protocol.ByteCount receiveConnectionFlowControlWindow protocol.ByteCount - - maxReceiveStreamFlowControlWindowServer protocol.ByteCount - maxReceiveConnectionFlowControlWindowServer protocol.ByteCount - maxReceiveStreamFlowControlWindowClient protocol.ByteCount - maxReceiveConnectionFlowControlWindowClient protocol.ByteCount + maxReceiveStreamFlowControlWindow protocol.ByteCount + maxReceiveConnectionFlowControlWindow protocol.ByteCount } var _ ConnectionParametersManager = &connectionParametersManager{} @@ -68,34 +65,17 @@ var ( // NewConnectionParamatersManager creates a new connection parameters manager func NewConnectionParamatersManager( pers protocol.Perspective, v protocol.VersionNumber, - maxReceiveStreamFlowControlWindowServer protocol.ByteCount, maxReceiveConnectionFlowControlWindowServer protocol.ByteCount, - maxReceiveStreamFlowControlWindowClient protocol.ByteCount, maxReceiveConnectionFlowControlWindowClient protocol.ByteCount, + maxReceiveStreamFlowControlWindow protocol.ByteCount, maxReceiveConnectionFlowControlWindow protocol.ByteCount, ) ConnectionParametersManager { - if maxReceiveStreamFlowControlWindowServer == 0 { - maxReceiveStreamFlowControlWindowServer = protocol.DefaultMaxReceiveStreamFlowControlWindowServer - } - if maxReceiveConnectionFlowControlWindowServer == 0 { - maxReceiveConnectionFlowControlWindowServer = protocol.DefaultMaxReceiveConnectionFlowControlWindowServer - } - if maxReceiveStreamFlowControlWindowClient == 0 { - maxReceiveStreamFlowControlWindowClient = protocol.DefaultMaxReceiveStreamFlowControlWindowClient - } - if maxReceiveConnectionFlowControlWindowClient == 0 { - maxReceiveConnectionFlowControlWindowClient = protocol.DefaultMaxReceiveConnectionFlowControlWindowClient - } - h := &connectionParametersManager{ - perspective: pers, - version: v, - sendStreamFlowControlWindow: protocol.InitialStreamFlowControlWindow, // can only be changed by the client - sendConnectionFlowControlWindow: protocol.InitialConnectionFlowControlWindow, // can only be changed by the client - receiveStreamFlowControlWindow: protocol.ReceiveStreamFlowControlWindow, - receiveConnectionFlowControlWindow: protocol.ReceiveConnectionFlowControlWindow, - - maxReceiveStreamFlowControlWindowServer: maxReceiveStreamFlowControlWindowServer, - maxReceiveConnectionFlowControlWindowServer: maxReceiveConnectionFlowControlWindowServer, - maxReceiveStreamFlowControlWindowClient: maxReceiveStreamFlowControlWindowClient, - maxReceiveConnectionFlowControlWindowClient: maxReceiveConnectionFlowControlWindowClient, + perspective: pers, + version: v, + sendStreamFlowControlWindow: protocol.InitialStreamFlowControlWindow, // can only be changed by the client + sendConnectionFlowControlWindow: protocol.InitialConnectionFlowControlWindow, // can only be changed by the client + receiveStreamFlowControlWindow: protocol.ReceiveStreamFlowControlWindow, + receiveConnectionFlowControlWindow: protocol.ReceiveConnectionFlowControlWindow, + maxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow, + maxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow, } if h.perspective == protocol.PerspectiveServer { @@ -234,10 +214,7 @@ func (h *connectionParametersManager) GetReceiveStreamFlowControlWindow() protoc // GetMaxReceiveStreamFlowControlWindow gets the maximum size of the stream-level flow control window for sending data func (h *connectionParametersManager) GetMaxReceiveStreamFlowControlWindow() protocol.ByteCount { - if h.perspective == protocol.PerspectiveServer { - return h.maxReceiveStreamFlowControlWindowServer - } - return h.maxReceiveStreamFlowControlWindowClient + return h.maxReceiveStreamFlowControlWindow } // GetReceiveConnectionFlowControlWindow gets the size of the stream-level flow control window for receiving data @@ -249,10 +226,7 @@ func (h *connectionParametersManager) GetReceiveConnectionFlowControlWindow() pr // GetMaxReceiveConnectionFlowControlWindow gets the maximum size of the stream-level flow control window for sending data func (h *connectionParametersManager) GetMaxReceiveConnectionFlowControlWindow() protocol.ByteCount { - if h.perspective == protocol.PerspectiveServer { - return h.maxReceiveConnectionFlowControlWindowServer - } - return h.maxReceiveConnectionFlowControlWindowClient + return h.maxReceiveConnectionFlowControlWindow } // GetMaxOutgoingStreams gets the maximum number of outgoing streams per connection diff --git a/handshake/connection_parameters_manager_test.go b/handshake/connection_parameters_manager_test.go index ba8f427d..1901051b 100644 --- a/handshake/connection_parameters_manager_test.go +++ b/handshake/connection_parameters_manager_test.go @@ -21,10 +21,8 @@ var _ = Describe("ConnectionsParameterManager", func() { BeforeEach(func() { cpm = NewConnectionParamatersManager(protocol.PerspectiveServer, protocol.Version36, maxReceiveStreamFlowControlWindowServer, maxReceiveConnectionFlowControlWindowServer, - maxReceiveStreamFlowControlWindowClient, maxReceiveConnectionFlowControlWindowClient, ).(*connectionParametersManager) cpmClient = NewConnectionParamatersManager(protocol.PerspectiveClient, protocol.Version36, - maxReceiveStreamFlowControlWindowServer, maxReceiveConnectionFlowControlWindowServer, maxReceiveStreamFlowControlWindowClient, maxReceiveConnectionFlowControlWindowClient, ).(*connectionParametersManager) }) @@ -155,8 +153,8 @@ var _ = Describe("ConnectionsParameterManager", func() { }) It("defaults to the correct maximum flow control windows", func() { - cpmDefault := NewConnectionParamatersManager(protocol.PerspectiveServer, protocol.Version36, 0, 0, 0, 0).(*connectionParametersManager) - cpmClientDefault := NewConnectionParamatersManager(protocol.PerspectiveClient, protocol.Version36, 0, 0, 0, 0).(*connectionParametersManager) + cpmDefault := NewConnectionParamatersManager(protocol.PerspectiveServer, protocol.Version36, 0, 0).(*connectionParametersManager) + cpmClientDefault := NewConnectionParamatersManager(protocol.PerspectiveClient, protocol.Version36, 0, 0).(*connectionParametersManager) Expect(cpmDefault.GetMaxReceiveStreamFlowControlWindow()).To(Equal(protocol.DefaultMaxReceiveStreamFlowControlWindowServer)) Expect(cpmDefault.GetMaxReceiveConnectionFlowControlWindow()).To(Equal(protocol.DefaultMaxReceiveConnectionFlowControlWindowServer)) Expect(cpmClientDefault.GetMaxReceiveStreamFlowControlWindow()).To(Equal(protocol.DefaultMaxReceiveStreamFlowControlWindowClient)) diff --git a/handshake/crypto_setup_client_test.go b/handshake/crypto_setup_client_test.go index aeb1f5a2..a4705957 100644 --- a/handshake/crypto_setup_client_test.go +++ b/handshake/crypto_setup_client_test.go @@ -112,7 +112,6 @@ var _ = Describe("Client Crypto Setup", func() { stream, nil, NewConnectionParamatersManager(protocol.PerspectiveClient, version, - protocol.DefaultMaxReceiveStreamFlowControlWindowServer, protocol.DefaultMaxReceiveConnectionFlowControlWindowServer, protocol.DefaultMaxReceiveStreamFlowControlWindowClient, protocol.DefaultMaxReceiveConnectionFlowControlWindowClient, ), aeadChanged, diff --git a/handshake/crypto_setup_server_test.go b/handshake/crypto_setup_server_test.go index 4e681604..7e2aeb88 100644 --- a/handshake/crypto_setup_server_test.go +++ b/handshake/crypto_setup_server_test.go @@ -186,7 +186,6 @@ var _ = Describe("Server Crypto Setup", func() { supportedVersions = []protocol.VersionNumber{version, 98, 99} cpm = NewConnectionParamatersManager(protocol.PerspectiveServer, protocol.VersionWhatever, protocol.DefaultMaxReceiveStreamFlowControlWindowServer, protocol.DefaultMaxReceiveConnectionFlowControlWindowServer, - protocol.DefaultMaxReceiveStreamFlowControlWindowClient, protocol.DefaultMaxReceiveConnectionFlowControlWindowClient, ) csInt, err := NewCryptoSetup( protocol.ConnectionID(42), diff --git a/interface.go b/interface.go index 9901203f..9169ccca 100644 --- a/interface.go +++ b/interface.go @@ -80,18 +80,12 @@ type Config struct { // If not set, it verifies that the address matches, and that the STK was issued within the last 24 hours // This option is only valid for the server. AcceptSTK func(clientAddr net.Addr, stk *STK) bool - // MaxReceiveStreamFlowControlWindowServer is the maximum stream-level flow control window for receiving data, for the server - // If this value is zero, the timeout is set to protocol.DefaultMaxReceiveStreamFlowControlWindowServer - MaxReceiveStreamFlowControlWindowServer protocol.ByteCount - // MaxReceiveConnectionFlowControlWindowServer is the connection-level flow control window for receiving data, for the server - // If this value is zero, the timeout is set to protocol.DefaultMaxReceiveConnectionFlowControlWindowServer - MaxReceiveConnectionFlowControlWindowServer protocol.ByteCount - // MaxReceiveStreamFlowControlWindowClient is the maximum stream-level flow control window for receiving data, for the client - // If this value is zero, the timeout is set to protocol.DefaultMaxReceiveStreamFlowControlWindowClient - MaxReceiveStreamFlowControlWindowClient protocol.ByteCount - // MaxReceiveConnectionFlowControlWindowClient is the connection-level flow control window for receiving data, for the client - // If this value is zero, the timeout is set to protocol.DefaultMaxReceiveConnectionFlowControlWindowClient - MaxReceiveConnectionFlowControlWindowClient protocol.ByteCount + // MaxReceiveStreamFlowControlWindowServer is the maximum stream-level flow control window for receiving data + // If this value is zero, it will default to 1 MB for the server and 6 MB for the client + MaxReceiveStreamFlowControlWindow protocol.ByteCount + // MaxReceiveConnectionFlowControlWindowServer is the connection-level flow control window for receiving data + // If this value is zero, it will default to 1.5 MB for the server and 15 MB for the client + MaxReceiveConnectionFlowControlWindow protocol.ByteCount } // A Listener for incoming QUIC connections diff --git a/server.go b/server.go index a613fe93..5048df5f 100644 --- a/server.go +++ b/server.go @@ -117,15 +117,22 @@ func populateServerConfig(config *Config) *Config { handshakeTimeout = config.HandshakeTimeout } + maxReceiveStreamFlowControlWindow := config.MaxReceiveStreamFlowControlWindow + if maxReceiveStreamFlowControlWindow == 0 { + maxReceiveStreamFlowControlWindow = protocol.DefaultMaxReceiveStreamFlowControlWindowServer + } + maxReceiveConnectionFlowControlWindow := config.MaxReceiveConnectionFlowControlWindow + if maxReceiveConnectionFlowControlWindow == 0 { + maxReceiveConnectionFlowControlWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindowServer + } + return &Config{ - TLSConfig: config.TLSConfig, - Versions: versions, - HandshakeTimeout: handshakeTimeout, - AcceptSTK: vsa, - MaxReceiveStreamFlowControlWindowServer: config.MaxReceiveStreamFlowControlWindowServer, - MaxReceiveConnectionFlowControlWindowServer: config.MaxReceiveConnectionFlowControlWindowServer, - MaxReceiveStreamFlowControlWindowClient: config.MaxReceiveStreamFlowControlWindowClient, - MaxReceiveConnectionFlowControlWindowClient: config.MaxReceiveConnectionFlowControlWindowClient, + TLSConfig: config.TLSConfig, + Versions: versions, + HandshakeTimeout: handshakeTimeout, + AcceptSTK: vsa, + MaxReceiveStreamFlowControlWindow: maxReceiveStreamFlowControlWindow, + MaxReceiveConnectionFlowControlWindow: maxReceiveConnectionFlowControlWindow, } } diff --git a/session.go b/session.go index 22bdaca8..c3859a97 100644 --- a/session.go +++ b/session.go @@ -173,8 +173,7 @@ func (s *session) setup( s.rttStats = &congestion.RTTStats{} s.connectionParameters = handshake.NewConnectionParamatersManager(s.perspective, s.version, - s.config.MaxReceiveStreamFlowControlWindowServer, s.config.MaxReceiveConnectionFlowControlWindowServer, - s.config.MaxReceiveStreamFlowControlWindowClient, s.config.MaxReceiveConnectionFlowControlWindowClient) + s.config.MaxReceiveStreamFlowControlWindow, s.config.MaxReceiveConnectionFlowControlWindow) s.sentPacketHandler = ackhandler.NewSentPacketHandler(s.rttStats) s.flowControlManager = flowcontrol.NewFlowControlManager(s.connectionParameters, s.rttStats) s.receivedPacketHandler = ackhandler.NewReceivedPacketHandler(s.ackAlarmChanged) From 9a6cb5eb4d36cacc8412fd3103f99184427ce7a3 Mon Sep 17 00:00:00 2001 From: Thomas De Keulenaer Date: Tue, 13 Jun 2017 16:43:46 +0200 Subject: [PATCH 4/5] Default flow lvls should be tested at client/server.go lvl --- handshake/connection_parameters_manager_test.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/handshake/connection_parameters_manager_test.go b/handshake/connection_parameters_manager_test.go index 1901051b..99425143 100644 --- a/handshake/connection_parameters_manager_test.go +++ b/handshake/connection_parameters_manager_test.go @@ -152,15 +152,6 @@ var _ = Describe("ConnectionsParameterManager", func() { Expect(cpmClient.GetMaxReceiveConnectionFlowControlWindow()).To(Equal(maxReceiveConnectionFlowControlWindowClient)) }) - It("defaults to the correct maximum flow control windows", func() { - cpmDefault := NewConnectionParamatersManager(protocol.PerspectiveServer, protocol.Version36, 0, 0).(*connectionParametersManager) - cpmClientDefault := NewConnectionParamatersManager(protocol.PerspectiveClient, protocol.Version36, 0, 0).(*connectionParametersManager) - Expect(cpmDefault.GetMaxReceiveStreamFlowControlWindow()).To(Equal(protocol.DefaultMaxReceiveStreamFlowControlWindowServer)) - Expect(cpmDefault.GetMaxReceiveConnectionFlowControlWindow()).To(Equal(protocol.DefaultMaxReceiveConnectionFlowControlWindowServer)) - Expect(cpmClientDefault.GetMaxReceiveStreamFlowControlWindow()).To(Equal(protocol.DefaultMaxReceiveStreamFlowControlWindowClient)) - Expect(cpmClientDefault.GetMaxReceiveConnectionFlowControlWindow()).To(Equal(protocol.DefaultMaxReceiveConnectionFlowControlWindowClient)) - }) - It("sets a new stream-level flow control window for sending", func() { values := map[Tag][]byte{TagSFCW: {0xDE, 0xAD, 0xBE, 0xEF}} err := cpm.SetFromMap(values) From 798a95aa01ad5fafb72326e780e2b2c07ce7dac6 Mon Sep 17 00:00:00 2001 From: Thomas De Keulenaer Date: Wed, 14 Jun 2017 09:38:18 +0200 Subject: [PATCH 5/5] Updated Changelog and comments --- Changelog.md | 1 + interface.go | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Changelog.md b/Changelog.md index f009adce..666f2a77 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,7 @@ ## v0.6.0 (unreleased) +- Added `quic.Config` options for maximal flow control windows - Add a `quic.Config` option for QUIC versions - Add a `quic.Config` option to request truncation of the connection ID from a server - Add a `quic.Config` option to configure the source address validation diff --git a/interface.go b/interface.go index 9169ccca..bb608692 100644 --- a/interface.go +++ b/interface.go @@ -77,14 +77,14 @@ type Config struct { HandshakeTimeout time.Duration // AcceptSTK determines if an STK is accepted. // It is called with stk = nil if the client didn't send an STK. - // If not set, it verifies that the address matches, and that the STK was issued within the last 24 hours + // If not set, it verifies that the address matches, and that the STK was issued within the last 24 hours. // This option is only valid for the server. AcceptSTK func(clientAddr net.Addr, stk *STK) bool - // MaxReceiveStreamFlowControlWindowServer is the maximum stream-level flow control window for receiving data - // If this value is zero, it will default to 1 MB for the server and 6 MB for the client + // MaxReceiveStreamFlowControlWindow is the maximum stream-level flow control window for receiving data. + // If this value is zero, it will default to 1 MB for the server and 6 MB for the client. MaxReceiveStreamFlowControlWindow protocol.ByteCount - // MaxReceiveConnectionFlowControlWindowServer is the connection-level flow control window for receiving data - // If this value is zero, it will default to 1.5 MB for the server and 15 MB for the client + // MaxReceiveConnectionFlowControlWindow is the connection-level flow control window for receiving data. + // If this value is zero, it will default to 1.5 MB for the server and 15 MB for the client. MaxReceiveConnectionFlowControlWindow protocol.ByteCount }