diff --git a/appc/appconnector.go b/appc/appconnector.go index 63e1946e7..91641a294 100644 --- a/appc/appconnector.go +++ b/appc/appconnector.go @@ -116,6 +116,16 @@ func (e *AppConnector) storeRoutesLocked() error { }) } +// ClearRoutes removes all route state from the AppConnector. +func (e *AppConnector) ClearRoutes() error { + e.mu.Lock() + defer e.mu.Unlock() + e.controlRoutes = nil + e.domains = nil + e.wildcards = nil + return e.storeRoutesLocked() +} + // UpdateDomainsAndRoutes starts an asynchronous update of the configuration // given the new domains and routes. func (e *AppConnector) UpdateDomainsAndRoutes(domains []string, routes []netip.Prefix) { diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index c3e92cdad..c67c87c20 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -3138,6 +3138,19 @@ func (b *LocalBackend) SetUseExitNodeEnabled(v bool) (ipn.PrefsView, error) { return b.editPrefsLockedOnEntry(mp, unlock) } +// MaybeClearAppConnector clears the routes from any AppConnector if +// AdvertiseRoutes has been set in the MaskedPrefs. +func (b *LocalBackend) MaybeClearAppConnector(mp *ipn.MaskedPrefs) error { + var err error + if b.appConnector != nil && mp.AdvertiseRoutesSet { + err = b.appConnector.ClearRoutes() + if err != nil { + b.logf("appc: clear routes error: %v", err) + } + } + return err +} + func (b *LocalBackend) EditPrefs(mp *ipn.MaskedPrefs) (ipn.PrefsView, error) { if mp.SetsInternal() { return ipn.PrefsView{}, errors.New("can't set Internal fields") diff --git a/ipn/localapi/localapi.go b/ipn/localapi/localapi.go index 9a31dd304..a822aad69 100644 --- a/ipn/localapi/localapi.go +++ b/ipn/localapi/localapi.go @@ -1366,6 +1366,12 @@ func (h *Handler) servePrefs(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } + if err := h.b.MaybeClearAppConnector(mp); err != nil { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusInternalServerError) + json.NewEncoder(w).Encode(resJSON{Error: err.Error()}) + return + } var err error prefs, err = h.b.EditPrefs(mp) if err != nil {