From 0c17e2c23481fc8f57aac59db15327892e3a59bb Mon Sep 17 00:00:00 2001 From: bjlhlin Date: Fri, 27 Sep 2024 17:20:25 +0800 Subject: [PATCH] Support DelayedCloseTimeout --- api/v1alpha1/timeout_types.go | 15 ++++++++++++++- internal/gatewayapi/clienttrafficpolicy.go | 9 +++++++++ internal/ir/xds.go | 6 ++++++ internal/xds/translator/listener.go | 4 +++- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/api/v1alpha1/timeout_types.go b/api/v1alpha1/timeout_types.go index 36c0c320ed2..a5b8450ae37 100644 --- a/api/v1alpha1/timeout_types.go +++ b/api/v1alpha1/timeout_types.go @@ -5,7 +5,9 @@ package v1alpha1 -import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" +import ( + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" +) // Timeout defines configuration for timeouts related to connections. type Timeout struct { @@ -76,4 +78,15 @@ type HTTPClientTimeout struct { // // +optional IdleTimeout *gwapiv1.Duration `json:"idleTimeout,omitempty"` + + // The delayed close timeout is for downstream connections managed by the HTTP connection manager. + // It is defined as a grace period after connection close processing has been locally initiated + // during which Envoy will wait for the peer to close (i.e., a TCP FIN/RST is received by Envoy + // from the downstream connection) prior to Envoy closing the socket associated with that + // connection. + + //The default timeout is 1000 ms if this option is not specified. + + // +optional + DelayedCloseTimeout *gwapiv1.Duration `json:"delayedCloseTimeout,omitempty" yaml:"delayedCloseTimeout,omitempty"` } diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index cfa108bf73d..484f9a93cfd 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -608,6 +608,15 @@ func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout, Duration: d, } } + if clientTimeout.HTTP.DelayedCloseTimeout != nil { + d, err := time.ParseDuration(string(*clientTimeout.HTTP.DelayedCloseTimeout)) + if err != nil { + return nil, fmt.Errorf("invalid HTTP DelayedCloseTimeout value %s", *clientTimeout.HTTP.DelayedCloseTimeout) + } + irHTTPTimeout.DelayedCloseTimeout = &metav1.Duration{ + Duration: d, + } + } irClientTimeout.HTTP = irHTTPTimeout } diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 9de48f29b33..8e0c582ea76 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -514,6 +514,12 @@ type HTTPClientTimeout struct { RequestReceivedTimeout *metav1.Duration `json:"requestReceivedTimeout,omitempty" yaml:"requestReceivedTimeout,omitempty"` // IdleTimeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. IdleTimeout *metav1.Duration `json:"idleTimeout,omitempty" yaml:"idleTimeout,omitempty"` + // The delayed close timeout is for downstream connections managed by the HTTP connection manager. + // It is defined as a grace period after connection close processing has been locally initiated + // during which Envoy will wait for the peer to close (i.e., a TCP FIN/RST is received by Envoy + // from the downstream connection) prior to Envoy closing the socket associated with that + // connection. + DelayedCloseTimeout *metav1.Duration `json:"delayedCloseTimeout,omitempty" yaml:"delayedCloseTimeout,omitempty"` } // HTTPRoute holds the route information associated with the HTTP Route diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index e72cf797d4c..43dd8920ace 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -274,10 +274,12 @@ func (t *Translator) addHCMToXDSListener(xdsListener *listenerv3.Listener, irLis if irListener.Timeout.HTTP.RequestReceivedTimeout != nil { mgr.RequestTimeout = durationpb.New(irListener.Timeout.HTTP.RequestReceivedTimeout.Duration) } - if irListener.Timeout.HTTP.IdleTimeout != nil { mgr.CommonHttpProtocolOptions.IdleTimeout = durationpb.New(irListener.Timeout.HTTP.IdleTimeout.Duration) } + if irListener.Timeout.HTTP.DelayedCloseTimeout != nil { + mgr.DelayedCloseTimeout = durationpb.New(irListener.Timeout.HTTP.DelayedCloseTimeout.Duration) + } } // Add the proxy protocol filter if needed