mirror of
https://github.com/tailscale/tailscale.git
synced 2026-01-05 01:11:39 +00:00
appc,*: publish events for route updates and storage (#17392)
Add and wire up event publishers for these two event types in the AppConnector. Nothing currently subscribes to them, so this is harmless. Subscribers for these events will be added in a near-future commit. As part of this, move the appc.RouteInfo type to the types/appctype package. It does not contain any package-specific details from appc. Beside it, add appctype.RouteUpdate to carry route update event state, likewise not specific to appc. Update all usage of the appc.* types throughout to use appctype.* instead, and update depaware files to reflect these changes. Add a Close method to the AppConnector to make sure the client gets cleaned up when the connector is dropped (we re-create connectors). Update the unit tests in the appc package to also check the events published alongside calls to the RouteAdvertiser. For now the tests still rely on the RouteAdvertiser for correctness; this is OK for now as the two methods are always performed together. In the near future, we need to rework the tests so not require that, but that will require building some more test fixtures that we can handle separately. Updates #15160 Updates #17192 Change-Id: I184670ba2fb920e0d2cb2be7c6816259bca77afe Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This commit is contained in:
@@ -1108,6 +1108,7 @@ func (b *LocalBackend) Shutdown() {
|
||||
if b.notifyCancel != nil {
|
||||
b.notifyCancel()
|
||||
}
|
||||
b.appConnector.Close()
|
||||
b.mu.Unlock()
|
||||
b.webClientShutdown()
|
||||
|
||||
@@ -4783,25 +4784,28 @@ func (b *LocalBackend) reconfigAppConnectorLocked(nm *netmap.NetworkMap, prefs i
|
||||
}()
|
||||
|
||||
if !prefs.AppConnector().Advertise {
|
||||
b.appConnector.Close() // clean up a previous connector (safe on nil)
|
||||
b.appConnector = nil
|
||||
return
|
||||
}
|
||||
|
||||
shouldAppCStoreRoutes := b.ControlKnobs().AppCStoreRoutes.Load()
|
||||
if b.appConnector == nil || b.appConnector.ShouldStoreRoutes() != shouldAppCStoreRoutes {
|
||||
var ri *appc.RouteInfo
|
||||
var storeFunc func(*appc.RouteInfo) error
|
||||
var ri *appctype.RouteInfo
|
||||
var storeFunc func(*appctype.RouteInfo) error
|
||||
if shouldAppCStoreRoutes {
|
||||
var err error
|
||||
ri, err = b.readRouteInfoLocked()
|
||||
if err != nil {
|
||||
ri = &appc.RouteInfo{}
|
||||
ri = &appctype.RouteInfo{}
|
||||
if err != ipn.ErrStateNotExist {
|
||||
b.logf("Unsuccessful Read RouteInfo: ", err)
|
||||
}
|
||||
}
|
||||
storeFunc = b.storeRouteInfo
|
||||
}
|
||||
|
||||
b.appConnector.Close() // clean up a previous connector (safe on nil)
|
||||
b.appConnector = appc.NewAppConnector(appc.Config{
|
||||
Logf: b.logf,
|
||||
EventBus: b.sys.Bus.Get(),
|
||||
@@ -6988,7 +6992,7 @@ func namespaceKeyForCurrentProfile(pm *profileManager, key ipn.StateKey) ipn.Sta
|
||||
|
||||
const routeInfoStateStoreKey ipn.StateKey = "_routeInfo"
|
||||
|
||||
func (b *LocalBackend) storeRouteInfo(ri *appc.RouteInfo) error {
|
||||
func (b *LocalBackend) storeRouteInfo(ri *appctype.RouteInfo) error {
|
||||
if !buildfeatures.HasAppConnectors {
|
||||
return feature.ErrUnavailable
|
||||
}
|
||||
@@ -7005,16 +7009,16 @@ func (b *LocalBackend) storeRouteInfo(ri *appc.RouteInfo) error {
|
||||
return b.pm.WriteState(key, bs)
|
||||
}
|
||||
|
||||
func (b *LocalBackend) readRouteInfoLocked() (*appc.RouteInfo, error) {
|
||||
func (b *LocalBackend) readRouteInfoLocked() (*appctype.RouteInfo, error) {
|
||||
if !buildfeatures.HasAppConnectors {
|
||||
return nil, feature.ErrUnavailable
|
||||
}
|
||||
if b.pm.CurrentProfile().ID() == "" {
|
||||
return &appc.RouteInfo{}, nil
|
||||
return &appctype.RouteInfo{}, nil
|
||||
}
|
||||
key := namespaceKeyForCurrentProfile(b.pm, routeInfoStateStoreKey)
|
||||
bs, err := b.pm.Store().ReadState(key)
|
||||
ri := &appc.RouteInfo{}
|
||||
ri := &appctype.RouteInfo{}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -7027,7 +7031,7 @@ func (b *LocalBackend) readRouteInfoLocked() (*appc.RouteInfo, error) {
|
||||
// ReadRouteInfo returns the app connector route information that is
|
||||
// stored in prefs to be consistent across restarts. It should be up
|
||||
// to date with the RouteInfo in memory being used by appc.
|
||||
func (b *LocalBackend) ReadRouteInfo() (*appc.RouteInfo, error) {
|
||||
func (b *LocalBackend) ReadRouteInfo() (*appctype.RouteInfo, error) {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
return b.readRouteInfoLocked()
|
||||
|
||||
@@ -49,6 +49,7 @@ import (
|
||||
"tailscale.com/tsd"
|
||||
"tailscale.com/tstest"
|
||||
"tailscale.com/tstest/deptest"
|
||||
"tailscale.com/types/appctype"
|
||||
"tailscale.com/types/dnstype"
|
||||
"tailscale.com/types/ipproto"
|
||||
"tailscale.com/types/key"
|
||||
@@ -74,7 +75,7 @@ import (
|
||||
"tailscale.com/wgengine/wgcfg"
|
||||
)
|
||||
|
||||
func fakeStoreRoutes(*appc.RouteInfo) error { return nil }
|
||||
func fakeStoreRoutes(*appctype.RouteInfo) error { return nil }
|
||||
|
||||
func inRemove(ip netip.Addr) bool {
|
||||
for _, pfx := range removeFromDefaultRoute {
|
||||
@@ -2314,7 +2315,7 @@ func TestOfferingAppConnector(t *testing.T) {
|
||||
rc := &appctest.RouteCollector{}
|
||||
if shouldStore {
|
||||
b.appConnector = appc.NewAppConnector(appc.Config{
|
||||
Logf: t.Logf, EventBus: bus, RouteAdvertiser: rc, RouteInfo: &appc.RouteInfo{}, StoreRoutesFunc: fakeStoreRoutes,
|
||||
Logf: t.Logf, EventBus: bus, RouteAdvertiser: rc, RouteInfo: &appctype.RouteInfo{}, StoreRoutesFunc: fakeStoreRoutes,
|
||||
})
|
||||
} else {
|
||||
b.appConnector = appc.NewAppConnector(appc.Config{Logf: t.Logf, EventBus: bus, RouteAdvertiser: rc})
|
||||
@@ -2381,7 +2382,7 @@ func TestObserveDNSResponse(t *testing.T) {
|
||||
Logf: t.Logf,
|
||||
EventBus: bus,
|
||||
RouteAdvertiser: rc,
|
||||
RouteInfo: &appc.RouteInfo{},
|
||||
RouteInfo: &appctype.RouteInfo{},
|
||||
StoreRoutesFunc: fakeStoreRoutes,
|
||||
})
|
||||
} else {
|
||||
@@ -2548,7 +2549,7 @@ func TestBackfillAppConnectorRoutes(t *testing.T) {
|
||||
|
||||
// Store the test IP in profile data, but not in Prefs.AdvertiseRoutes.
|
||||
b.ControlKnobs().AppCStoreRoutes.Store(true)
|
||||
if err := b.storeRouteInfo(&appc.RouteInfo{
|
||||
if err := b.storeRouteInfo(&appctype.RouteInfo{
|
||||
Domains: map[string][]netip.Addr{
|
||||
"example.com": {ip},
|
||||
},
|
||||
@@ -5501,10 +5502,10 @@ func TestReadWriteRouteInfo(t *testing.T) {
|
||||
b.pm.currentProfile = prof1.View()
|
||||
|
||||
// set up routeInfo
|
||||
ri1 := &appc.RouteInfo{}
|
||||
ri1 := &appctype.RouteInfo{}
|
||||
ri1.Wildcards = []string{"1"}
|
||||
|
||||
ri2 := &appc.RouteInfo{}
|
||||
ri2 := &appctype.RouteInfo{}
|
||||
ri2.Wildcards = []string{"2"}
|
||||
|
||||
// read before write
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/tsd"
|
||||
"tailscale.com/tstest"
|
||||
"tailscale.com/types/appctype"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/netmap"
|
||||
"tailscale.com/util/eventbus/eventbustest"
|
||||
@@ -261,7 +262,7 @@ func TestPeerAPIPrettyReplyCNAME(t *testing.T) {
|
||||
Logf: t.Logf,
|
||||
EventBus: sys.Bus.Get(),
|
||||
RouteAdvertiser: &appctest.RouteCollector{},
|
||||
RouteInfo: &appc.RouteInfo{},
|
||||
RouteInfo: &appctype.RouteInfo{},
|
||||
StoreRoutesFunc: fakeStoreRoutes,
|
||||
})
|
||||
} else {
|
||||
@@ -346,7 +347,7 @@ func TestPeerAPIReplyToDNSQueriesAreObserved(t *testing.T) {
|
||||
Logf: t.Logf,
|
||||
EventBus: sys.Bus.Get(),
|
||||
RouteAdvertiser: rc,
|
||||
RouteInfo: &appc.RouteInfo{},
|
||||
RouteInfo: &appctype.RouteInfo{},
|
||||
StoreRoutesFunc: fakeStoreRoutes,
|
||||
})
|
||||
} else {
|
||||
@@ -419,7 +420,7 @@ func TestPeerAPIReplyToDNSQueriesAreObservedWithCNAMEFlattening(t *testing.T) {
|
||||
Logf: t.Logf,
|
||||
EventBus: sys.Bus.Get(),
|
||||
RouteAdvertiser: rc,
|
||||
RouteInfo: &appc.RouteInfo{},
|
||||
RouteInfo: &appctype.RouteInfo{},
|
||||
StoreRoutesFunc: fakeStoreRoutes,
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
"tailscale.com/appc"
|
||||
"tailscale.com/client/tailscale/apitype"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/feature"
|
||||
@@ -38,6 +37,7 @@ import (
|
||||
"tailscale.com/net/netutil"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/tstime"
|
||||
"tailscale.com/types/appctype"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/logid"
|
||||
@@ -1684,7 +1684,7 @@ func (h *Handler) serveGetAppcRouteInfo(w http.ResponseWriter, r *http.Request)
|
||||
res, err := h.b.ReadRouteInfo()
|
||||
if err != nil {
|
||||
if errors.Is(err, ipn.ErrStateNotExist) {
|
||||
res = &appc.RouteInfo{}
|
||||
res = &appctype.RouteInfo{}
|
||||
} else {
|
||||
WriteErrorJSON(w, err)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user