Fixed race in Filter Chain (#4728)

This commit is contained in:
Zach Reyes 2021-09-02 14:43:26 -04:00 committed by GitHub
parent b189f5e1bc
commit c93e472777
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 11 additions and 13 deletions

View File

@ -324,12 +324,13 @@ func (l *listenerWrapper) Accept() (net.Conn, error) {
// can come it at any time), and connections aren't accepted too often,
// so this reinstantation of the Route Configuration is an acceptable
// tradeoff for simplicity.
if err := fc.ConstructUsableRouteConfiguration(rc); err != nil {
vhswi, err := fc.ConstructUsableRouteConfiguration(rc)
if err != nil {
l.logger.Warningf("route configuration construction: %v", err)
conn.Close()
continue
}
return &connWrapper{Conn: conn, filterChain: fc, parent: l, virtualHosts: fc.VirtualHosts}, nil
return &connWrapper{Conn: conn, filterChain: fc, parent: l, virtualHosts: vhswi}, nil
}
}

View File

@ -67,11 +67,6 @@ type FilterChain struct {
//
// Only one of RouteConfigName and InlineRouteConfig is set.
InlineRouteConfig *RouteConfigUpdate
// VirtualHosts are the virtual hosts ready to be used in the xds interceptors.
// It contains a way to match routes using a matcher and also instantiates
// HTTPFilter overrides to simply run incoming RPC's through if they are selected.
VirtualHosts []VirtualHostWithInterceptors
}
// VirtualHostWithInterceptors captures information present in a VirtualHost
@ -98,17 +93,16 @@ type RouteWithInterceptors struct {
// ConstructUsableRouteConfiguration takes Route Configuration and converts it
// into matchable route configuration, with instantiated HTTP Filters per route.
func (f *FilterChain) ConstructUsableRouteConfiguration(config RouteConfigUpdate) error {
func (f *FilterChain) ConstructUsableRouteConfiguration(config RouteConfigUpdate) ([]VirtualHostWithInterceptors, error) {
vhs := make([]VirtualHostWithInterceptors, len(config.VirtualHosts))
for _, vh := range config.VirtualHosts {
vhwi, err := f.convertVirtualHost(vh)
if err != nil {
return fmt.Errorf("virtual host construction: %v", err)
return nil, fmt.Errorf("virtual host construction: %v", err)
}
vhs = append(vhs, vhwi)
}
f.VirtualHosts = vhs
return nil
return vhs, nil
}
func (f *FilterChain) convertVirtualHost(virtualHost *VirtualHost) (VirtualHostWithInterceptors, error) {

View File

@ -2629,11 +2629,14 @@ func TestHTTPFilterInstantiation(t *testing.T) {
fc := FilterChain{
HTTPFilters: test.filters,
}
fc.ConstructUsableRouteConfiguration(test.routeConfig)
vhswi, err := fc.ConstructUsableRouteConfiguration(test.routeConfig)
if err != nil {
t.Fatalf("Error constructing usable route configuration: %v", err)
}
// Build out list of errors by iterating through the virtual hosts and routes,
// and running the filters in route configurations.
var errs []string
for _, vh := range fc.VirtualHosts {
for _, vh := range vhswi {
for _, r := range vh.Routes {
for _, int := range r.Interceptors {
errs = append(errs, int.AllowRPC(context.Background()).Error())