diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml index 8b0b416a06..f50d6e0f63 100755 --- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml @@ -42,6 +42,49 @@ '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuth users: inlineBytes: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo= + - disabled: true + name: envoy.filters.http.oauth2/securitypolicy/default/policy-for-gateway-2 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2 + config: + authScopes: + - openid + - email + - profile + authType: BASIC_AUTH + authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth + credentials: + clientId: client.oauth.foo.com + cookieNames: + bearerToken: AccessToken-5F93C2E4 + idToken: IdToken-5F93C2E4 + oauthExpires: OauthExpires-5F93C2E4 + oauthHmac: OauthHMAC-5F93C2E4 + oauthNonce: OauthNonce-5F93C2E4 + refreshToken: RefreshToken-5F93C2E4 + hmacSecret: + name: oauth2/hmac_secret/securitypolicy/default/policy-for-gateway-2 + sdsConfig: + ads: {} + resourceApiVersion: V3 + tokenSecret: + name: oauth2/client_secret/securitypolicy/default/policy-for-gateway-2 + sdsConfig: + ads: {} + resourceApiVersion: V3 + preserveAuthorizationHeader: true + redirectPathMatcher: + path: + exact: /foo/oauth2/callback + redirectUri: https://www.example.com/foo/oauth2/callback + signoutPath: + path: + exact: /foo/logout + tokenEndpoint: + cluster: oauth_foo_com_443 + timeout: 10s + uri: https://oauth.foo.com/token + useRefreshToken: false - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml index 5ce26e0d75..445fa03249 100755 --- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml @@ -45,6 +45,11 @@ - match: pathSeparatedPrefix: /bar name: httproute/default/httproute-3/rule/0/match/0/www_bar_com + responseHeadersToAdd: + - append: true + header: + key: alt-svc + value: h3=":443"; ma=86400 route: cluster: httproute/default/httproute-3/rule/0 upgradeConfigs: diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index 0b3dbe724e..706ee59990 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -245,6 +245,11 @@ func (t *Translator) processHTTPReadyListenerXdsTranslation(tCtx *types.Resource return nil } +type listenerKey struct { + Address string + Port uint32 +} + func (t *Translator) processHTTPListenerXdsTranslation( tCtx *types.ResourceVersionTable, httpListeners []*ir.HTTPListener, @@ -254,10 +259,23 @@ func (t *Translator) processHTTPListenerXdsTranslation( ) error { // The XDS translation is done in a best-effort manner, so we collect all // errors and return them at the end. - var errs error + var ( + http3EnabledListeners = make(map[listenerKey]*ir.HTTP3Settings) // Map to track HTTP3 settings for listeners by address and port + errs error + ) + + // HTTP3 is enabled for a xDS listener if one of the HTTPListeners on the same address + port combination has HTTP3 enabled. + for _, httpListener := range httpListeners { + // If HTTP3 is enabled, we need to track it for the listener + if httpListener.HTTP3 != nil { + http3EnabledListeners[listenerKey{Address: httpListener.Address, Port: httpListener.Port}] = httpListener.HTTP3 + } + } + for _, httpListener := range httpListeners { var ( - http3Enabled = httpListener.HTTP3 != nil // Whether HTTP3 is enabled + http3Settings *ir.HTTP3Settings // HTTP3 settings for the listener, if any + http3Enabled bool tcpXDSListener *listenerv3.Listener // TCP Listener for HTTP1/HTTP2 traffic quicXDSListener *listenerv3.Listener // UDP(QUIC) Listener for HTTP3 traffic xdsListenerOnSameAddressPortExists bool // Whether a listener already exists on the same address + port combination @@ -267,8 +285,11 @@ func (t *Translator) processHTTPListenerXdsTranslation( err error ) + http3Settings, http3Enabled = http3EnabledListeners[listenerKey{Address: httpListener.Address, Port: httpListener.Port}] + // Search for an existing TCP listener on the same address + port combination. tcpXDSListener = findXdsListenerByHostPort(tCtx, httpListener.Address, httpListener.Port, corev3.SocketAddress_TCP) + quicXDSListener = findXdsListenerByHostPort(tCtx, httpListener.Address, httpListener.Port, corev3.SocketAddress_UDP) xdsListenerOnSameAddressPortExists = tcpXDSListener != nil tlsEnabled = httpListener.TLS != nil @@ -316,19 +337,19 @@ func (t *Translator) processHTTPListenerXdsTranslation( // route HTTP traffic to the correct virtual host for all the domains // specified in the Gateway HTTP Listener's routes. var ( - routeName string + routeConfigName string hasHCMInDefaultFilterChain bool ) // Find the route config associated with this listener that // maps to the default filter chain for http traffic // Routes for this listener will be added to this route config - routeName = findXdsHTTPRouteConfigName(tcpXDSListener) - hasHCMInDefaultFilterChain = routeName != "" + routeConfigName = findXdsHTTPRouteConfigName(tcpXDSListener) + hasHCMInDefaultFilterChain = routeConfigName != "" addHCM = !hasHCMInDefaultFilterChain - if routeName != "" { - xdsRouteCfg = findXdsRouteConfig(tCtx, routeName) + if routeConfigName != "" { + xdsRouteCfg = findXdsRouteConfig(tCtx, routeConfigName) if xdsRouteCfg == nil { // skip this listener if failed to find xds route config errs = errors.Join(errs, errors.New("unable to find xds route config")) @@ -423,7 +444,7 @@ func (t *Translator) processHTTPListenerXdsTranslation( // Generate xDS virtual hosts and routes for the given HTTPListener, // and add them to the xDS route config. - if err = t.addRouteToRouteConfig(tCtx, xdsRouteCfg, httpListener, metrics, http3Enabled); err != nil { + if err = t.addRouteToRouteConfig(tCtx, xdsRouteCfg, httpListener, metrics, http3Settings); err != nil { errs = errors.Join(errs, err) } @@ -444,7 +465,7 @@ func (t *Translator) addRouteToRouteConfig( xdsRouteCfg *routev3.RouteConfiguration, httpListener *ir.HTTPListener, metrics *ir.Metrics, - http3Enabled bool, + http3Settings *ir.HTTP3Settings, ) error { var ( vHosts = map[string]*routev3.VirtualHost{} // store virtual hosts by domain @@ -511,8 +532,8 @@ func (t *Translator) addRouteToRouteConfig( } } - if http3Enabled { - http3AltSvcHeader := buildHTTP3AltSvcHeader(int(httpListener.HTTP3.QUICPort)) + if http3Settings != nil { + http3AltSvcHeader := buildHTTP3AltSvcHeader(int(http3Settings.QUICPort)) if xdsRoute.ResponseHeadersToAdd == nil { xdsRoute.ResponseHeadersToAdd = make([]*corev3.HeaderValueOption, 0) }