Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions api/v1alpha1/timeout_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ type TCPClientTimeout struct {
//
// +optional
IdleTimeout *gwapiv1.Duration `json:"idleTimeout,omitempty"`

// TLSHandshakeTimeout for a TCP connection. The maximum time to complete transport level connection negotiation
// (e.g. the TLS handshake) after a connection is accepted.
// If this expires before the transport reports connection establishment, the connection is summarily closed.
//
// +optional
TLSHandshakeTimeout *gwapiv1.Duration `json:"tlsHandshakeTimeout,omitempty"`

// ConnectionInspectionTimeout is the maximum time to wait for initial inspection
// (TLS / SNI and protocol detection, or HTTP protocol parsing) of an incoming connection.
// If exceeded, the connection is dropped.
// Default: 15 seconds.
//
// +optional
ConnectionInspectionTimeout *gwapiv1.Duration `json:"connectionInspectionTimeout,omitempty"`
}

type HTTPClientTimeout struct {
Expand All @@ -90,6 +105,14 @@ type HTTPClientTimeout struct {
// +optional
RequestReceivedTimeout *gwapiv1.Duration `json:"requestReceivedTimeout,omitempty"`

// RequestHeadersReceivedTimeout is the duration envoy waits for the request headers to arrive.
// The timer is activated when the first byte of the headers is received,
// and is disarmed when the last byte of the headers has been received.
// If not specified or set to 0, this timeout is disabled.
//
// +optional
RequestHeadersReceivedTimeout *gwapiv1.Duration `json:"requestHeadersReceivedTimeout,omitempty"`

// IdleTimeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
// Default: 1 hour.
//
Expand Down
15 changes: 15 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -1336,6 +1336,14 @@ spec:
Default: 1 hour.
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
requestHeadersReceivedTimeout:
description: |-
RequestHeadersReceivedTimeout is the duration envoy waits for the request headers to arrive.
The timer is activated when the first byte of the headers is received,
and is disarmed when the last byte of the headers has been received.
If not specified or set to 0, this timeout is disabled.
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
requestReceivedTimeout:
description: |-
RequestReceivedTimeout is the duration envoy waits for the complete request reception. This timer starts upon request
Expand All @@ -1352,13 +1360,28 @@ spec:
tcp:
description: Timeout settings for TCP.
properties:
connectionInspectionTimeout:
description: |-
ConnectionInspectionTimeout is the maximum time to wait for initial inspection
(TLS / SNI and protocol detection, or HTTP protocol parsing) of an incoming connection.
If exceeded, the connection is dropped.
Default: 15 seconds.
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
idleTimeout:
description: |-
IdleTimeout for a TCP connection. Idle time is defined as a period in which there are no
bytes sent or received on either the upstream or downstream connection.
Default: 1 hour.
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tlsHandshakeTimeout:
description: |-
TLSHandshakeTimeout for a TCP connection. The maximum time to complete transport level connection negotiation
(e.g. the TLS handshake) after a connection is accepted.
If this expires before the transport reports connection establishment, the connection is summarily closed.
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
type: object
tls:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,14 @@ spec:
Default: 1 hour.
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
requestHeadersReceivedTimeout:
description: |-
RequestHeadersReceivedTimeout is the duration envoy waits for the request headers to arrive.
The timer is activated when the first byte of the headers is received,
and is disarmed when the last byte of the headers has been received.
If not specified or set to 0, this timeout is disabled.
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
requestReceivedTimeout:
description: |-
RequestReceivedTimeout is the duration envoy waits for the complete request reception. This timer starts upon request
Expand All @@ -1351,13 +1359,28 @@ spec:
tcp:
description: Timeout settings for TCP.
properties:
connectionInspectionTimeout:
description: |-
ConnectionInspectionTimeout is the maximum time to wait for initial inspection
(TLS / SNI and protocol detection, or HTTP protocol parsing) of an incoming connection.
If exceeded, the connection is dropped.
Default: 15 seconds.
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
idleTimeout:
description: |-
IdleTimeout for a TCP connection. Idle time is defined as a period in which there are no
bytes sent or received on either the upstream or downstream connection.
Default: 1 hour.
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tlsHandshakeTimeout:
description: |-
TLSHandshakeTimeout for a TCP connection. The maximum time to complete transport level connection negotiation
(e.g. the TLS handshake) after a connection is accepted.
If this expires before the transport reports connection establishment, the connection is summarily closed.
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
type: object
tls:
Expand Down
22 changes: 22 additions & 0 deletions internal/gatewayapi/clienttrafficpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,20 @@ func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout,
}
irTCPTimeout.IdleTimeout = ir.MetaV1DurationPtr(d)
}
if clientTimeout.TCP.TLSHandshakeTimeout != nil {
d, err := time.ParseDuration(string(*clientTimeout.TCP.TLSHandshakeTimeout))
if err != nil {
return nil, fmt.Errorf("invalid TCP TLSHandshakeTimeout value %s", *clientTimeout.TCP.TLSHandshakeTimeout)
}
irTCPTimeout.TLSHandshakeTimeout = ir.MetaV1DurationPtr(d)
}
if clientTimeout.TCP.ConnectionInspectionTimeout != nil {
d, err := time.ParseDuration(string(*clientTimeout.TCP.ConnectionInspectionTimeout))
if err != nil {
return nil, fmt.Errorf("invalid TCP ConnectionInspectionTimeout value %s", *clientTimeout.TCP.ConnectionInspectionTimeout)
}
irTCPTimeout.ConnectionInspectionTimeout = ir.MetaV1DurationPtr(d)
}
irClientTimeout.TCP = irTCPTimeout
}

Expand Down Expand Up @@ -986,6 +1000,14 @@ func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout,
}
irHTTPTimeout.StreamIdleTimeout = ir.MetaV1DurationPtr(d)
}

if clientTimeout.HTTP.RequestHeadersReceivedTimeout != nil {
d, err := time.ParseDuration(string(*clientTimeout.HTTP.RequestHeadersReceivedTimeout))
if err != nil {
return nil, fmt.Errorf("invalid HTTP RequestHeadersReceivedTimeout value %s", *clientTimeout.HTTP.RequestHeadersReceivedTimeout)
}
irHTTPTimeout.RequestHeadersReceivedTimeout = ir.MetaV1DurationPtr(d)
}
irClientTimeout.HTTP = irHTTPTimeout
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ clientTrafficPolicies:
name: gateway
sectionName: http-1
timeout:
tcp:
tlsHandshakeTimeout: "10s"
connectionInspectionTimeout: "60s"
http:
requestReceivedTimeout: "5s"
requestHeadersReceivedTimeout: "5s"
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ clientTrafficPolicies:
sectionName: http-1
timeout:
http:
requestHeadersReceivedTimeout: 5s
requestReceivedTimeout: 5s
tcp:
connectionInspectionTimeout: 60s
tlsHandshakeTimeout: 10s
status:
ancestors:
- ancestorRef:
Expand Down Expand Up @@ -170,7 +174,11 @@ xdsIR:
port: 10080
timeout:
http:
requestHeadersReceivedTimeout: 5s
requestReceivedTimeout: 5s
tcp:
connectionInspectionTimeout: 1m0s
tlsHandshakeTimeout: 10s
- address: 0.0.0.0
externalPort: 8080
hostnames:
Expand Down
12 changes: 12 additions & 0 deletions internal/ir/xds.go
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,14 @@ type TCPClientTimeout struct {
// IdleTimeout for a TCP connection. Idle time is defined as a period in which there are no
// bytes sent or received on either the upstream or downstream connection.
IdleTimeout *metav1.Duration `json:"idleTimeout,omitempty" yaml:"idleTimeout,omitempty"`
// TLSHandshakeTimeout for a TCP connection. The maximum time to complete transport level connection negotiation
// (e.g. the TLS handshake) after a connection is accepted.
// If this expires before the transport reports connection establishment, the connection is summarily closed.
TLSHandshakeTimeout *metav1.Duration `json:"tlsHandshakeTimeout,omitempty" yaml:"handshakeTimeout,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TLSHandshakeTimeout *metav1.Duration `json:"tlsHandshakeTimeout,omitempty" yaml:"handshakeTimeout,omitempty"`
TLSHandshakeTimeout *metav1.Duration `json:"tlsHandshakeTimeout,omitempty" yaml:"tlsHandshakeTimeout,omitempty"`

// ConnectionInspectionTimeout is the maximum time to wait for initial inspection
// (TLS / SNI and protocol detection, or HTTP protocol parsing) of an incoming connection.
// If exceeded, the connection is dropped.
ConnectionInspectionTimeout *metav1.Duration `json:"connectionInspectionTimeout,omitempty" yaml:"connectionInspectionTimeout,omitempty"`
}

// HTTPClientTimeout set the configuration for client HTTP.
Expand All @@ -977,6 +985,10 @@ type HTTPClientTimeout struct {
// The duration envoy waits for the complete request reception. This timer starts upon request
// initiation and stops when either the last byte of the request is sent upstream or when the response begins.
RequestReceivedTimeout *metav1.Duration `json:"requestReceivedTimeout,omitempty" yaml:"requestReceivedTimeout,omitempty"`
// RequestHeadersReceivedTimeout is the duration envoy waits for the request headers to arrive.
// The timer is activated when the first byte of the headers is received,
// and is disarmed when the last byte of the headers has been received.
RequestHeadersReceivedTimeout *metav1.Duration `json:"requestHeadersReceivedTimeout,omitempty" yaml:"requestHeadersReceivedTimeout,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 stream idle timeout for connections managed by the connection manager.
Expand Down
15 changes: 15 additions & 0 deletions internal/ir/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 21 additions & 2 deletions internal/xds/translator/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ func (t *Translator) buildXdsTCPListener(
listenerDetails *ir.CoreListenerDetails,
keepalive *ir.TCPKeepalive,
connection *ir.ClientConnection,
timeout *ir.ClientTimeout,
accesslog *ir.AccessLog,
) (*listenerv3.Listener, error) {
socketOptions := buildTCPSocketOptions(keepalive)
Expand Down Expand Up @@ -249,6 +250,10 @@ func (t *Translator) buildXdsTCPListener(
socketAddress.Ipv4Compat = true
}

if timeout != nil && timeout.TCP != nil && timeout.TCP.ConnectionInspectionTimeout != nil {
listener.ListenerFiltersTimeout = durationpb.New(timeout.TCP.ConnectionInspectionTimeout.Duration)
Comment on lines +253 to +254

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Apply inspection timeouts to reused listeners

When multiple HTTPS or TLS listeners share an address and port, only the first IR listener creates the xDS listener; subsequent listeners reuse it without revisiting ListenerFiltersTimeout. Consequently, a ClientTrafficPolicy targeting a later listener has its connectionInspectionTimeout silently ignored, while a timeout on the first listener affects every filter chain on that socket. The existing overlap validation only covers non-HTTPS listeners, so this global setting must either be reconciled across shared listeners or conflicting policies must be rejected.

Useful? React with 👍 / 👎.

}

return listener, nil
}

Expand Down Expand Up @@ -440,6 +445,10 @@ func (t *Translator) addHCMToXDSListener(
mgr.RequestTimeout = durationpb.New(irListener.Timeout.HTTP.RequestReceivedTimeout.Duration)
}

if irListener.Timeout.HTTP.RequestHeadersReceivedTimeout != nil {
mgr.RequestHeadersTimeout = durationpb.New(irListener.Timeout.HTTP.RequestHeadersReceivedTimeout.Duration)
}

if irListener.Timeout.HTTP.IdleTimeout != nil {
mgr.CommonHttpProtocolOptions.IdleTimeout = durationpb.New(irListener.Timeout.HTTP.IdleTimeout.Duration)
}
Expand Down Expand Up @@ -508,6 +517,10 @@ func (t *Translator) addHCMToXDSListener(
Filters: filters,
}

if irListener.Timeout != nil && irListener.Timeout.TCP != nil && irListener.Timeout.TCP.TLSHandshakeTimeout != nil {
filterChain.TransportSocketConnectTimeout = durationpb.New(irListener.Timeout.TCP.TLSHandshakeTimeout.Duration)
}

if irListener.TLS != nil {
var tSocket *corev3.TransportSocket

Expand Down Expand Up @@ -805,10 +818,16 @@ func buildTCPFilterChain(
return nil, err
}

return &listenerv3.FilterChain{
filterChain := &listenerv3.FilterChain{
Filters: filters,
Name: tlsListenerFilterChainName(irRoute),
}, nil
}

if timeout != nil && timeout.TCP != nil && timeout.TCP.TLSHandshakeTimeout != nil {
filterChain.TransportSocketConnectTimeout = durationpb.New(timeout.TCP.TLSHandshakeTimeout.Duration)
}

return filterChain, nil
}

func buildConnectionLimitFilter(statPrefix string, connection *ir.ClientConnection) *connection_limitv3.ConnectionLimit {
Expand Down
2 changes: 2 additions & 0 deletions internal/xds/translator/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ func (t *Translator) processHTTPListenerXdsTranslation(
&httpListener.CoreListenerDetails,
httpListener.TCPKeepalive,
httpListener.Connection,
httpListener.Timeout,
accessLog,
); err != nil {
errs = errors.Join(errs, err)
Expand Down Expand Up @@ -846,6 +847,7 @@ func (t *Translator) processTCPListenerXdsTranslation(
&tcpListener.CoreListenerDetails,
tcpListener.TCPKeepalive,
tcpListener.Connection,
tcpListener.Timeout,
accesslog,
); err != nil {
// skip this listener if failed to build xds listener
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for more client timeout settings. The settings are [`ConnectionInspectionTimeout`](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener.proto#envoy-v3-api-field-config-listener-v3-listener-listener-filters-timeout), [`RequestHeadersReceivedTimeout`](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-request-headers-timeout) and [`TLSHandshakeTimeout`](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener_components.proto.html#envoy-v3-api-field-config-listener-v3-filterchain-transport-socket-connect-timeout)
3 changes: 3 additions & 0 deletions site/content/en/latest/api/extension_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -3088,6 +3088,7 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `requestReceivedTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/api-spec/1.5/spec/#duration)_ | false | | RequestReceivedTimeout is the duration envoy waits for the complete request reception. This timer starts upon request<br />initiation and stops when either the last byte of the request is sent upstream or when the response begins. |
| `requestHeadersReceivedTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/api-spec/1.5/spec/#duration)_ | false | | RequestHeadersReceivedTimeout is the duration envoy waits for the request headers to arrive.<br />The timer is activated when the first byte of the headers is received,<br />and is disarmed when the last byte of the headers has been received.<br />If not specified or set to 0, this timeout is disabled. |
| `idleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/api-spec/1.5/spec/#duration)_ | false | | IdleTimeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.<br />Default: 1 hour. |
| `streamIdleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/api-spec/1.5/spec/#duration)_ | false | | The stream idle timeout defines the amount of time a stream can exist without any upstream or downstream activity.<br /> Default: 5 minutes. |

Expand Down Expand Up @@ -6300,6 +6301,8 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `idleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/api-spec/1.5/spec/#duration)_ | false | | IdleTimeout for a TCP connection. Idle time is defined as a period in which there are no<br />bytes sent or received on either the upstream or downstream connection.<br />Default: 1 hour. |
| `tlsHandshakeTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/api-spec/1.5/spec/#duration)_ | false | | TLSHandshakeTimeout for a TCP connection. The maximum time to complete transport level connection negotiation<br />(e.g. the TLS handshake) after a connection is accepted.<br />If this expires before the transport reports connection establishment, the connection is summarily closed. |
| `connectionInspectionTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/api-spec/1.5/spec/#duration)_ | false | | ConnectionInspectionTimeout is the maximum time to wait for initial inspection<br />(TLS / SNI and protocol detection, or HTTP protocol parsing) of an incoming connection.<br />If exceeded, the connection is dropped.<br />Default: 15 seconds. |


#### TCPKeepalive
Expand Down
Loading
Loading