From 3fd193d5aa85fe7ce4ee43ad8307f5202fd57ef0 Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Tue, 23 Jul 2024 14:50:55 -0500 Subject: [PATCH] implement BTP HTTP2 Signed-off-by: Guy Daich --- api/v1alpha1/backendtrafficpolicy_types.go | 5 + api/v1alpha1/clienttrafficpolicy_types.go | 25 -- api/v1alpha1/shared_types.go | 31 ++ api/v1alpha1/zz_generated.deepcopy.go | 10 + ....envoyproxy.io_backendtrafficpolicies.yaml | 44 +++ ...y.envoyproxy.io_clienttrafficpolicies.yaml | 6 + .../translate/out/default-resources.all.yaml | 4 +- .../out/from-gateway-api-to-xds.all.json | 5 +- .../out/from-gateway-api-to-xds.all.yaml | 4 +- .../out/from-gateway-api-to-xds.cluster.yaml | 4 +- internal/gatewayapi/backendtrafficpolicy.go | 17 + internal/gatewayapi/clienttrafficpolicy.go | 6 +- internal/gatewayapi/http.go | 66 ++++ .../backendtrafficpolicy-with-http2.in.yaml | 94 +++++ .../backendtrafficpolicy-with-http2.out.yaml | 334 ++++++++++++++++++ internal/ir/xds.go | 5 + internal/ir/zz_generated.deepcopy.go | 10 + internal/xds/translator/cluster.go | 37 +- internal/xds/translator/listener.go | 10 +- .../testdata/in/xds-ir/http2-route.yaml | 56 +++ .../xds-ir/accesslog-als-tcp.clusters.yaml | 4 +- .../out/xds-ir/accesslog-cel.clusters.yaml | 4 +- .../accesslog-endpoint-stats.clusters.yaml | 4 +- .../xds-ir/accesslog-formatters.clusters.yaml | 4 +- .../xds-ir/accesslog-multi-cel.clusters.yaml | 4 +- .../accesslog-without-format.clusters.yaml | 8 +- .../out/xds-ir/accesslog.clusters.yaml | 8 +- .../out/xds-ir/ext-auth.clusters.yaml | 4 +- .../out/xds-ir/ext-proc.clusters.yaml | 16 +- ...ttp-preserve-client-protocol.clusters.yaml | 4 +- .../out/xds-ir/http2-route.clusters.yaml | 74 +++- .../out/xds-ir/http2-route.endpoints.yaml | 36 ++ .../out/xds-ir/http2-route.routes.yaml | 21 ++ .../out/xds-ir/jwt-ratelimit.clusters.yaml | 4 +- .../ratelimit-custom-domain.clusters.yaml | 4 +- .../ratelimit-disable-headers.clusters.yaml | 4 +- .../ratelimit-endpoint-stats.clusters.yaml | 4 +- .../xds-ir/ratelimit-sourceip.clusters.yaml | 4 +- .../out/xds-ir/ratelimit.clusters.yaml | 4 +- .../tracing-endpoint-stats.clusters.yaml | 4 +- .../testdata/out/xds-ir/tracing.clusters.yaml | 4 +- internal/xds/translator/translator.go | 1 + site/content/en/latest/api/extension_types.md | 5 +- site/content/zh/latest/api/extension_types.md | 5 +- 44 files changed, 944 insertions(+), 63 deletions(-) create mode 100644 internal/gatewayapi/http.go create mode 100644 internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.in.yaml create mode 100644 internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.out.yaml diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index f484f44b409..6fde678c13a 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -110,6 +110,11 @@ type BackendTrafficPolicySpec struct { // // +optional Connection *BackendConnection `json:"connection,omitempty"` + + // HTTP2 provides HTTP/2 configuration for backend connections. + // + // +optional + HTTP2 *HTTP2Settings `json:"http2,omitempty"` } // +kubebuilder:object:root=true diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go index 397535ebf43..347eb946353 100644 --- a/api/v1alpha1/clienttrafficpolicy_types.go +++ b/api/v1alpha1/clienttrafficpolicy_types.go @@ -6,7 +6,6 @@ package v1alpha1 import ( - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) @@ -289,30 +288,6 @@ type HTTP10Settings struct { UseDefaultHost *bool `json:"useDefaultHost,omitempty"` } -// HTTP2Settings provides HTTP/2 configuration on the listener. -type HTTP2Settings struct { - // InitialStreamWindowSize sets the initial window size for HTTP/2 streams. - // If not set, the default value is 64 KiB(64*1024). - // - // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialStreamWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" - // +optional - InitialStreamWindowSize *resource.Quantity `json:"initialStreamWindowSize,omitempty"` - - // InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. - // If not set, the default value is 1 MiB. - // - // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialConnectionWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" - // +optional - InitialConnectionWindowSize *resource.Quantity `json:"initialConnectionWindowSize,omitempty"` - - // MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. - // If not set, the default value is 100. - // +kubebuilder:validation:Minimum=1 - // +kubebuilder:validation:Maximum=2147483647 - // +optional - MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty"` -} - // HealthCheckSettings provides HealthCheck configuration on the HTTP/HTTPS listener. type HealthCheckSettings struct { // Path specifies the HTTP path to match on for health check requests. diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go index 6ad310859bc..0c620d942f5 100644 --- a/api/v1alpha1/shared_types.go +++ b/api/v1alpha1/shared_types.go @@ -10,6 +10,7 @@ import ( autoscalingv2 "k8s.io/api/autoscaling/v2" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/api/resource" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) @@ -478,3 +479,33 @@ type BackendRef struct { // A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address range such as "2001:0db8:11a3:09d7::/64". // +kubebuilder:validation:Pattern=`((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]+))|((([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/([0-9]+))` type CIDR string + +// HTTP2Settings provides HTTP/2 configuration for listeners and backends. +type HTTP2Settings struct { + // InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + // If not set, the default value is 64 KiB(64*1024). + // + // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialStreamWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +optional + InitialStreamWindowSize *resource.Quantity `json:"initialStreamWindowSize,omitempty"` + + // InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + // If not set, the default value is 1 MiB. + // + // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialConnectionWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +optional + InitialConnectionWindowSize *resource.Quantity `json:"initialConnectionWindowSize,omitempty"` + + // MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + // If not set, the default value is 100. + // +kubebuilder:validation:Minimum=1 + // +kubebuilder:validation:Maximum=2147483647 + // +optional + MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty"` + + // ResetStreamOnError determines if Envoy will terminate the stream or the connection in the event of HTTP messaging error + // It's recommended for L2 Envoy deployments to set this value to true. + // https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + // +optional + ResetStreamOnError *bool `json:"resetStreamOnError,omitempty"` +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 3ea39b669c6..65ba31eb67f 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -569,6 +569,11 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec) *out = new(BackendConnection) (*in).DeepCopyInto(*out) } + if in.HTTP2 != nil { + in, out := &in.HTTP2, &out.HTTP2 + *out = new(HTTP2Settings) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTrafficPolicySpec. @@ -2418,6 +2423,11 @@ func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) { *out = new(uint32) **out = **in } + if in.ResetStreamOnError != nil { + in, out := &in.ResetStreamOnError, &out.ResetStreamOnError + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2Settings. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 20ffe833923..9b948ac67df 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -421,6 +421,50 @@ spec: type: boolean type: object type: object + http2: + description: HTTP2 provides HTTP/2 configuration for backend connections. + properties: + initialConnectionWindowSize: + anyOf: + - type: integer + - type: string + description: |- + InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + If not set, the default value is 1 MiB. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + x-kubernetes-validations: + - message: initialConnectionWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" + rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") + : type(self) == int' + initialStreamWindowSize: + anyOf: + - type: integer + - type: string + description: |- + InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + If not set, the default value is 64 KiB(64*1024). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + x-kubernetes-validations: + - message: initialStreamWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" + rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") + : type(self) == int' + maxConcurrentStreams: + description: |- + MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + If not set, the default value is 100. + format: int32 + maximum: 2147483647 + minimum: 1 + type: integer + resetStreamOnError: + description: |- + ResetStreamOnError determines if Envoy will terminate the stream or the connection in the event of HTTP messaging error + It's recommended for L2 Envoy deployments to set this value to true. + https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + type: boolean + type: object loadBalancer: description: |- LoadBalancer policy to apply when routing traffic from the gateway to diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml index 48cfb9f3aad..3eda751e351 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -300,6 +300,12 @@ spec: maximum: 2147483647 minimum: 1 type: integer + resetStreamOnError: + description: |- + ResetStreamOnError determines if Envoy will terminate the stream or the connection in the event of HTTP messaging error + It's recommended for L2 Envoy deployments to set this value to true. + https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + type: boolean type: object http3: description: HTTP3 provides HTTP/3 configuration on the listener. diff --git a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml index 86df2f9de4c..ee653eb8588 100644 --- a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml @@ -804,7 +804,9 @@ xds: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - cluster: '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster circuitBreakers: diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json index 14d29a32be2..a68abb29dd0 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json @@ -504,7 +504,10 @@ "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", "explicitHttpConfig": { - "http2ProtocolOptions": {} + "http2ProtocolOptions": { + "initialConnectionWindowSize": 1048576, + "initialStreamWindowSize": 65536 + } } } } diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml index a8fb322e28b..5e166b0fa37 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml @@ -285,7 +285,9 @@ xds: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - cluster: '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster circuitBreakers: diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml index 3d9bce8ad21..c9f782804a4 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.cluster.yaml @@ -44,7 +44,9 @@ xds: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - cluster: '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster circuitBreakers: diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index 6babdfa81d8..90b7046542d 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -319,6 +319,7 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen ka *ir.TCPKeepalive rt *ir.Retry bc *ir.BackendConnection + h2 *ir.HTTP2Settings err, errs error ) @@ -373,6 +374,13 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen } } + if policy.Spec.HTTP2 != nil { + if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil { + err = perr.WithMessage(err, "HTTP2") + errs = errors.Join(errs, err) + } + } + // Early return if got any errors if errs != nil { return errs @@ -422,6 +430,7 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen TCPKeepalive: ka, Retry: rt, BackendConnection: bc, + HTTP2: h2, } // Update the Host field in HealthCheck, now that we have access to the Route Hostname. @@ -456,6 +465,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back ct *ir.Timeout ka *ir.TCPKeepalive rt *ir.Retry + h2 *ir.HTTP2Settings err, errs error ) @@ -502,6 +512,12 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back errs = errors.Join(errs, err) } } + if policy.Spec.HTTP2 != nil { + if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil { + err = perr.WithMessage(err, "HTTP2") + errs = errors.Join(errs, err) + } + } // Early return if got any errors if errs != nil { @@ -590,6 +606,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back FaultInjection: fi, TCPKeepalive: ka, Retry: rt, + HTTP2: h2, } // Update the Host field in HealthCheck, now that we have access to the Route Hostname. diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index 7a25a661334..c13c0efaf92 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -28,11 +28,7 @@ import ( const ( // Use an invalid string to represent all sections (listeners) within a Gateway - AllSections = "/" - MinHTTP2InitialStreamWindowSize = 65535 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size - MaxHTTP2InitialStreamWindowSize = 2147483647 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size - MinHTTP2InitialConnectionWindowSize = MinHTTP2InitialStreamWindowSize - MaxHTTP2InitialConnectionWindowSize = MaxHTTP2InitialStreamWindowSize + AllSections = "/" ) func hasSectionName(target *gwapiv1a2.LocalPolicyTargetReferenceWithSectionName) bool { diff --git a/internal/gatewayapi/http.go b/internal/gatewayapi/http.go new file mode 100644 index 00000000000..206ec930ad8 --- /dev/null +++ b/internal/gatewayapi/http.go @@ -0,0 +1,66 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package gatewayapi + +import ( + "errors" + "fmt" + + "k8s.io/utils/ptr" + + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/ir" +) + +const ( + MinHTTP2InitialStreamWindowSize = 65535 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size + MaxHTTP2InitialStreamWindowSize = 2147483647 // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-http2protocoloptions-initial-stream-window-size + MinHTTP2InitialConnectionWindowSize = MinHTTP2InitialStreamWindowSize + MaxHTTP2InitialConnectionWindowSize = MaxHTTP2InitialStreamWindowSize +) + +func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Settings, error) { + var ( + http2 = &ir.HTTP2Settings{} + errs error + ) + + if http2Settings.InitialStreamWindowSize != nil { + initialStreamWindowSize, ok := http2Settings.InitialStreamWindowSize.AsInt64() + switch { + case !ok: + errs = errors.Join(errs, fmt.Errorf("invalid InitialStreamWindowSize value %s", http2Settings.InitialStreamWindowSize.String())) + case initialStreamWindowSize < MinHTTP2InitialStreamWindowSize || initialStreamWindowSize > MaxHTTP2InitialStreamWindowSize: + errs = errors.Join(errs, fmt.Errorf("InitialStreamWindowSize value %s is out of range, must be between %d and %d", + http2Settings.InitialStreamWindowSize.String(), + MinHTTP2InitialStreamWindowSize, + MaxHTTP2InitialStreamWindowSize)) + default: + http2.InitialStreamWindowSize = ptr.To(uint32(initialStreamWindowSize)) + } + } + + if http2Settings.InitialConnectionWindowSize != nil { + initialConnectionWindowSize, ok := http2Settings.InitialConnectionWindowSize.AsInt64() + switch { + case !ok: + errs = errors.Join(errs, fmt.Errorf("invalid InitialConnectionWindowSize value %s", http2Settings.InitialConnectionWindowSize.String())) + case initialConnectionWindowSize < MinHTTP2InitialConnectionWindowSize || initialConnectionWindowSize > MaxHTTP2InitialConnectionWindowSize: + errs = errors.Join(errs, fmt.Errorf("InitialConnectionWindowSize value %s is out of range, must be between %d and %d", + http2Settings.InitialConnectionWindowSize.String(), + MinHTTP2InitialConnectionWindowSize, + MaxHTTP2InitialConnectionWindowSize)) + default: + http2.InitialConnectionWindowSize = ptr.To(uint32(initialConnectionWindowSize)) + } + } + + http2.MaxConcurrentStreams = http2Settings.MaxConcurrentStreams + + http2.ResetStreamOnError = http2Settings.ResetStreamOnError + + return http2, errs +} diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.in.yaml new file mode 100644 index 00000000000..211f6ace6e0 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.in.yaml @@ -0,0 +1,94 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-2 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +grpcRoutes: + - apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: GRPCRoute + metadata: + namespace: default + name: grpcroute-1 + spec: + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-2 + sectionName: http + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +backendTrafficPolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + http2: + initialStreamWindowSize: 2Mi + initialConnectionWindowSize: 1Gi + maxConcurrentStreams: 500 + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-for-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + http2: + initialStreamWindowSize: 1Mi + initialConnectionWindowSize: 500Mi + maxConcurrentStreams: 200 + resetStreamOnError: true \ No newline at end of file diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.out.yaml new file mode 100644 index 00000000000..4f62f0fd27b --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-http2.out.yaml @@ -0,0 +1,334 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + creationTimestamp: null + name: policy-for-route + namespace: default + spec: + http2: + initialConnectionWindowSize: 500Mi + initialStreamWindowSize: 1Mi + maxConcurrentStreams: 200 + resetStreamOnError: true + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + namespace: envoy-gateway + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + creationTimestamp: null + name: policy-for-gateway + namespace: envoy-gateway + spec: + http2: + initialConnectionWindowSize: 1Gi + initialStreamWindowSize: 2Mi + maxConcurrentStreams: 500 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-2 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +grpcRoutes: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: GRPCRoute + metadata: + creationTimestamp: null + name: grpcroute-1 + namespace: default + spec: + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - name: gateway-2 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-2 + namespace: envoy-gateway + sectionName: http +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 + envoy-gateway/gateway-2: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-2/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-2 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-2 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: true + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + name: grpcroute/default/grpcroute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: GRPC + weight: 1 + hostname: '*' + isHTTP2: true + metadata: + kind: GRPCRoute + name: grpcroute-1 + namespace: default + name: grpcroute/default/grpcroute-1/rule/0/match/-1/* + traffic: + http2: + initialConnectionWindowSize: 2097152 + initialStreamWindowSize: 1073741824 + maxConcurrentStreams: 500 + envoy-gateway/gateway-2: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + metadata: + kind: Gateway + name: gateway-2 + namespace: envoy-gateway + sectionName: http + name: envoy-gateway/gateway-2/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: gateway.envoyproxy.io + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: / + traffic: + http2: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 524288000 + maxConcurrentStreams: 200 + resetStreamOnError: true diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 3d300f1a539..1955856dca5 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -456,6 +456,8 @@ type HTTP2Settings struct { InitialConnectionWindowSize *uint32 `json:"initialStreamWindowSize,omitempty" yaml:"initialStreamWindowSize,omitempty"` // MaxConcurrentStreams is the maximum number of concurrent streams that can be opened on a connection. MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty" yaml:"maxConcurrentStreams,omitempty"` + // ResetStreamOnError determines if a stream or connection is reset on messaging error. + ResetStreamOnError *bool `json:"resetStreamOnError,omitempty" yaml:"resetStreamOnError,omitempty"` } // HealthCheckSettings provides HealthCheck configuration on the HTTP/HTTPS listener. @@ -589,6 +591,9 @@ type TrafficFeatures struct { Retry *Retry `json:"retry,omitempty" yaml:"retry,omitempty"` // settings of upstream connection BackendConnection *BackendConnection `json:"backendConnection,omitempty" yaml:"backendConnection,omitempty"` + // HTTP2 provides HTTP/2 configuration for clusters + // +optional + HTTP2 *HTTP2Settings `json:"http2,omitempty" yaml:"http2,omitempty"` } func (b *TrafficFeatures) Validate() error { diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 273eeb1c3ca..7a925065d50 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -1005,6 +1005,11 @@ func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) { *out = new(uint32) **out = **in } + if in.ResetStreamOnError != nil { + in, out := &in.ResetStreamOnError, &out.ResetStreamOnError + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2Settings. @@ -2858,6 +2863,11 @@ func (in *TrafficFeatures) DeepCopyInto(out *TrafficFeatures) { *out = new(BackendConnection) (*in).DeepCopyInto(*out) } + if in.HTTP2 != nil { + in, out := &in.HTTP2, &out.HTTP2 + *out = new(HTTP2Settings) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficFeatures. diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go index e646f410944..31057268b2e 100644 --- a/internal/xds/translator/cluster.go +++ b/internal/xds/translator/cluster.go @@ -48,6 +48,7 @@ type xdsClusterArgs struct { circuitBreaker *ir.CircuitBreaker healthCheck *ir.HealthCheck http1Settings *ir.HTTP1Settings + http2Settings *ir.HTTP2Settings timeout *ir.Timeout tcpkeepalive *ir.TCPKeepalive metrics *ir.Metrics @@ -504,13 +505,15 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb. protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_UseDownstreamProtocolConfig{ UseDownstreamProtocolConfig: &httpv3.HttpProtocolOptions_UseDownstreamHttpConfig{ HttpProtocolOptions: http1opts, - Http2ProtocolOptions: &corev3.Http2ProtocolOptions{}, + Http2ProtocolOptions: buildHTTP2Settings(args.http2Settings), }, } case requiresHTTP2Options: protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_ExplicitHttpConfig_{ ExplicitHttpConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig{ - ProtocolConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig_Http2ProtocolOptions{}, + ProtocolConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig_Http2ProtocolOptions{ + Http2ProtocolOptions: buildHTTP2Settings(args.http2Settings), + }, }, } case requiresHTTP1Options: @@ -649,3 +652,33 @@ func buildBackandConnectionBufferLimitBytes(bc *ir.BackendConnection) *wrappers. return wrapperspb.UInt32(tcpClusterPerConnectionBufferLimitBytes) } + +func buildHTTP2Settings(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { + if opts == nil { + opts = &ir.HTTP2Settings{} + } + + // defaults based on https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/edge + out := &corev3.Http2ProtocolOptions{ + InitialStreamWindowSize: &wrapperspb.UInt32Value{ + Value: ptr.Deref(opts.InitialStreamWindowSize, http2InitialStreamWindowSize), + }, + InitialConnectionWindowSize: &wrapperspb.UInt32Value{ + Value: ptr.Deref(opts.InitialConnectionWindowSize, http2InitialConnectionWindowSize), + }, + } + + if opts.MaxConcurrentStreams != nil { + out.MaxConcurrentStreams = &wrapperspb.UInt32Value{ + Value: *opts.MaxConcurrentStreams, + } + } + + if opts.ResetStreamOnError != nil { + out.OverrideStreamErrorOnInvalidHttpMessage = &wrapperspb.BoolValue{ + Value: *opts.ResetStreamOnError, + } + } + + return out +} diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index ee1f5c7d133..9d445423e74 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -84,7 +84,7 @@ func http2ProtocolOptions(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { opts = &ir.HTTP2Settings{} } - return &corev3.Http2ProtocolOptions{ + out := &corev3.Http2ProtocolOptions{ MaxConcurrentStreams: &wrapperspb.UInt32Value{ Value: ptr.Deref(opts.MaxConcurrentStreams, http2MaxConcurrentStreamsLimit), }, @@ -95,6 +95,14 @@ func http2ProtocolOptions(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { Value: ptr.Deref(opts.InitialConnectionWindowSize, http2InitialConnectionWindowSize), }, } + + if opts.ResetStreamOnError != nil { + out.OverrideStreamErrorOnInvalidHttpMessage = &wrapperspb.BoolValue{ + Value: *opts.ResetStreamOnError, + } + } + + return out } func xffNumTrustedHops(clientIPDetection *ir.ClientIPDetectionSettings) uint32 { diff --git a/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml b/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml index f3dc12c5aae..4dc83db7c9b 100644 --- a/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml @@ -28,3 +28,59 @@ http: - host: "1.2.3.4" port: 50000 protocol: GRPC + traffic: + http2: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 524288000 + maxConcurrentStreams: 200 + resetStreamOnError: true + - name: "second-route" + hostname: "*" + pathMatch: + name: "test" + exact: "bar/foo" + destination: + name: "second-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + protocol: GRPC + traffic: + http2: {} + - name: "third-route-use-client" + hostname: "*" + pathMatch: + name: "test" + exact: "bar/bar" + destination: + name: "third-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + protocol: HTTP + useClientProtocol: true + traffic: + http2: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 524288000 + maxConcurrentStreams: 200 + resetStreamOnError: true + - name: "fourth-route-not-http2" + hostname: "*" + pathMatch: + name: "test" + exact: "foo/foo" + destination: + name: "fourth-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + traffic: + http2: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 524288000 + maxConcurrentStreams: 200 + resetStreamOnError: true \ No newline at end of file diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml index 18b309bb74d..9603f302b73 100755 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml @@ -19,4 +19,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.clusters.yaml index b8874bf24f9..6d040000dbb 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-cel.clusters.yaml @@ -46,4 +46,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml index cbf453a1f17..ea9ef9405ee 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-endpoint-stats.clusters.yaml @@ -50,4 +50,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml index b8874bf24f9..6d040000dbb 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-formatters.clusters.yaml @@ -46,4 +46,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.clusters.yaml index b8874bf24f9..6d040000dbb 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-multi-cel.clusters.yaml @@ -46,4 +46,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.clusters.yaml index 6ba4705c13f..d9c561cee48 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-without-format.clusters.yaml @@ -36,7 +36,9 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - circuitBreakers: thresholds: - maxRetries: 1024 @@ -68,4 +70,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml index 6ba4705c13f..d9c561cee48 100644 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog.clusters.yaml @@ -36,7 +36,9 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - circuitBreakers: thresholds: - maxRetries: 1024 @@ -68,4 +70,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml index cf4fbc9b274..e478c2054cd 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth.clusters.yaml @@ -70,7 +70,9 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - circuitBreakers: thresholds: - maxRetries: 1024 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml index 08b38495e69..6ea0615cb31 100755 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml @@ -53,7 +53,9 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - circuitBreakers: thresholds: - maxRetries: 1024 @@ -75,7 +77,9 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - circuitBreakers: thresholds: - maxRetries: 1024 @@ -97,7 +101,9 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 - circuitBreakers: thresholds: - maxRetries: 1024 @@ -119,4 +125,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml index 5de1d1cce34..f8cfa834cdd 100644 --- a/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/http-preserve-client-protocol.clusters.yaml @@ -19,5 +19,7 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions useDownstreamProtocolConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 httpProtocolOptions: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml index 6086cfbb86f..85eb367562d 100644 --- a/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml @@ -19,4 +19,76 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 524288000 + initialStreamWindowSize: 1048576 + maxConcurrentStreams: 200 + overrideStreamErrorOnInvalidHttpMessage: true +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: second-route-dest + lbPolicy: LEAST_REQUEST + name: second-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: third-route-dest + lbPolicy: LEAST_REQUEST + name: third-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + useDownstreamProtocolConfig: + http2ProtocolOptions: + initialConnectionWindowSize: 524288000 + initialStreamWindowSize: 1048576 + maxConcurrentStreams: 200 + overrideStreamErrorOnInvalidHttpMessage: true + httpProtocolOptions: {} +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: fourth-route-dest + lbPolicy: LEAST_REQUEST + name: fourth-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml index 3b3f2d09076..f185af17da7 100644 --- a/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.endpoints.yaml @@ -10,3 +10,39 @@ loadBalancingWeight: 1 locality: region: first-route-dest/backend/0 +- clusterName: second-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: second-route-dest/backend/0 +- clusterName: third-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: third-route-dest/backend/0 +- clusterName: fourth-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: fourth-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml index a32852fcd88..4fdedfabf67 100644 --- a/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.routes.yaml @@ -20,3 +20,24 @@ cluster: first-route-dest upgradeConfigs: - upgradeType: websocket + - match: + path: bar/foo + name: second-route + route: + cluster: second-route-dest + upgradeConfigs: + - upgradeType: websocket + - match: + path: bar/bar + name: third-route-use-client + route: + cluster: third-route-dest + upgradeConfigs: + - upgradeType: websocket + - match: + path: foo/foo + name: fourth-route-not-http2 + route: + cluster: fourth-route-dest + upgradeConfigs: + - upgradeType: websocket diff --git a/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml index d4e9db34e33..e75a68919d1 100644 --- a/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/jwt-ratelimit.clusters.yaml @@ -119,4 +119,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml index bd23f61ee21..45e8e0898ce 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-custom-domain.clusters.yaml @@ -93,4 +93,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml index 9f9bc9f1dff..0ba1749076a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-disable-headers.clusters.yaml @@ -93,4 +93,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml index 21ea0681611..a3c9b6623c9 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-endpoint-stats.clusters.yaml @@ -101,4 +101,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml index 33fc01336b8..427f6d15340 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit-sourceip.clusters.yaml @@ -110,4 +110,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml index 9f9bc9f1dff..0ba1749076a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ratelimit.clusters.yaml @@ -93,4 +93,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml index 0936f4b459a..9e7469dd278 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-endpoint-stats.clusters.yaml @@ -50,4 +50,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml index 35bc81158da..dce48b2c083 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml @@ -46,4 +46,6 @@ envoy.extensions.upstreams.http.v3.HttpProtocolOptions: '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: - http2ProtocolOptions: {} + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index a58903e88ad..e1e5f2094a0 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -770,6 +770,7 @@ func processXdsCluster(tCtx *types.ResourceVersionTable, httpRoute *ir.HTTPRoute clusterArgs.timeout = bt.Timeout clusterArgs.tcpkeepalive = bt.TCPKeepalive clusterArgs.backendConnection = bt.BackendConnection + clusterArgs.http2Settings = bt.HTTP2 } if err := addXdsCluster(tCtx, clusterArgs); err != nil && !errors.Is(err, ErrXdsClusterExists) { diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 4dc4ccd890c..e0557e854da 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -460,6 +460,7 @@ _Appears in:_ | `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using
the same HTTP protocol that the incoming request used. Defaults to false, which means
that Envoy will use the protocol indicated by the attached BackendRef. | | `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. | | `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. | +| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. | #### BasicAuth @@ -1772,9 +1773,10 @@ _Appears in:_ -HTTP2Settings provides HTTP/2 configuration on the listener. +HTTP2Settings provides HTTP/2 configuration for listeners and backends. _Appears in:_ +- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - [ClientTrafficPolicySpec](#clienttrafficpolicyspec) | Field | Type | Required | Description | @@ -1782,6 +1784,7 @@ _Appears in:_ | `initialStreamWindowSize` | _[Quantity](#quantity)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
If not set, the default value is 64 KiB(64*1024). | | `initialConnectionWindowSize` | _[Quantity](#quantity)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
If not set, the default value is 1 MiB. | | `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
If not set, the default value is 100. | +| `resetStreamOnError` | _boolean_ | false | ResetStreamOnError determines if Envoy will terminate the stream or the connection in the event of HTTP messaging error
It's recommended for L2 Envoy deployments to set this value to true.
https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two | #### HTTP3Settings diff --git a/site/content/zh/latest/api/extension_types.md b/site/content/zh/latest/api/extension_types.md index 4dc4ccd890c..e0557e854da 100644 --- a/site/content/zh/latest/api/extension_types.md +++ b/site/content/zh/latest/api/extension_types.md @@ -460,6 +460,7 @@ _Appears in:_ | `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using
the same HTTP protocol that the incoming request used. Defaults to false, which means
that Envoy will use the protocol indicated by the attached BackendRef. | | `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. | | `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. | +| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. | #### BasicAuth @@ -1772,9 +1773,10 @@ _Appears in:_ -HTTP2Settings provides HTTP/2 configuration on the listener. +HTTP2Settings provides HTTP/2 configuration for listeners and backends. _Appears in:_ +- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - [ClientTrafficPolicySpec](#clienttrafficpolicyspec) | Field | Type | Required | Description | @@ -1782,6 +1784,7 @@ _Appears in:_ | `initialStreamWindowSize` | _[Quantity](#quantity)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
If not set, the default value is 64 KiB(64*1024). | | `initialConnectionWindowSize` | _[Quantity](#quantity)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
If not set, the default value is 1 MiB. | | `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
If not set, the default value is 100. | +| `resetStreamOnError` | _boolean_ | false | ResetStreamOnError determines if Envoy will terminate the stream or the connection in the event of HTTP messaging error
It's recommended for L2 Envoy deployments to set this value to true.
https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two | #### HTTP3Settings