mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-27 18:57:35 +00:00

`routeAdvertiser` is the `iplocal.LocalBackend`. Calls to `Advertise/UnadvertiseRoute` end up calling `EditPrefs` which in turn calls `authReconfig` which finally calls `readvertiseAppConnectorRoutes` which calls `AppConnector.DomainRoutes` and gets stuck on a mutex that was already held when `routeAdvertiser` was called. Make all calls to `routeAdvertiser` in `app.AppConnector` go through the execqueue instead as a short-term fix. Updates tailscale/corp#25965 Signed-off-by: Andrew Lytvynov <awly@tailscale.com> Co-authored-by: Irbe Krumina <irbe@tailscale.com>
64 lines
1.5 KiB
Go
64 lines
1.5 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
// Package appctest contains code to help test App Connectors.
|
|
package appctest
|
|
|
|
import (
|
|
"net/netip"
|
|
"slices"
|
|
)
|
|
|
|
// RouteCollector is a test helper that collects the list of routes advertised
|
|
type RouteCollector struct {
|
|
// AdvertiseCallback (optional) is called synchronously from
|
|
// AdvertiseRoute.
|
|
AdvertiseCallback func()
|
|
// UnadvertiseCallback (optional) is called synchronously from
|
|
// UnadvertiseRoute.
|
|
UnadvertiseCallback func()
|
|
|
|
routes []netip.Prefix
|
|
removedRoutes []netip.Prefix
|
|
}
|
|
|
|
func (rc *RouteCollector) AdvertiseRoute(pfx ...netip.Prefix) error {
|
|
rc.routes = append(rc.routes, pfx...)
|
|
if rc.AdvertiseCallback != nil {
|
|
rc.AdvertiseCallback()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (rc *RouteCollector) UnadvertiseRoute(toRemove ...netip.Prefix) error {
|
|
routes := rc.routes
|
|
rc.routes = rc.routes[:0]
|
|
for _, r := range routes {
|
|
if !slices.Contains(toRemove, r) {
|
|
rc.routes = append(rc.routes, r)
|
|
} else {
|
|
rc.removedRoutes = append(rc.removedRoutes, r)
|
|
}
|
|
}
|
|
if rc.UnadvertiseCallback != nil {
|
|
rc.UnadvertiseCallback()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RemovedRoutes returns the list of routes that were removed.
|
|
func (rc *RouteCollector) RemovedRoutes() []netip.Prefix {
|
|
return rc.removedRoutes
|
|
}
|
|
|
|
// Routes returns the ordered list of routes that were added, including
|
|
// possible duplicates.
|
|
func (rc *RouteCollector) Routes() []netip.Prefix {
|
|
return rc.routes
|
|
}
|
|
|
|
func (rc *RouteCollector) SetRoutes(routes []netip.Prefix) error {
|
|
rc.routes = routes
|
|
return nil
|
|
}
|