ipn/ipnlocal: pull CapabilityPreviewWebClient into webClientAtomicBool

Now uses webClientAtomicBool as the source of truth for whether the web
client should be running in tailscaled, with it updated when either the
RunWebClient pref or CapabilityPreviewWebClient node capability changes.

This avoids requiring holding the LocalBackend lock on each call to
ShouldRunWebClient to check for the CapabilityPreviewWebClient value.

Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This commit is contained in:
Sonia Appasamy 2023-11-02 12:55:01 -04:00 committed by Sonia Appasamy
parent c6a4612915
commit b370274b29
2 changed files with 12 additions and 9 deletions

View File

@ -170,7 +170,7 @@ type LocalBackend struct {
logFlushFunc func() // or nil if SetLogFlusher wasn't called
em *expiryManager // non-nil
sshAtomicBool atomic.Bool
webclientAtomicBool atomic.Bool
webClientAtomicBool atomic.Bool
shutdownCalled bool // if Shutdown has been called
debugSink *capture.Sink
sockstatLogger *sockstatlog.Logger
@ -1113,6 +1113,7 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control
// Perform all reconfiguration based on the netmap here.
if st.NetMap != nil {
b.capTailnetLock = hasCapability(st.NetMap, tailcfg.CapabilityTailnetLock)
b.setWebClientAtomicBoolLocked(st.NetMap, prefs.View())
b.mu.Unlock() // respect locking rules for tkaSyncIfNeeded
if err := b.tkaSyncIfNeeded(st.NetMap, prefs.View()); err != nil {
@ -2504,7 +2505,7 @@ func (b *LocalBackend) setTCPPortsIntercepted(ports []uint16) {
// and shouldInterceptTCPPortAtomic from the prefs p, which may be !Valid().
func (b *LocalBackend) setAtomicValuesFromPrefsLocked(p ipn.PrefsView) {
b.sshAtomicBool.Store(p.Valid() && p.RunSSH() && envknob.CanSSHD())
b.webclientAtomicBool.Store(p.Valid() && p.RunWebClient())
b.setWebClientAtomicBoolLocked(b.netMap, p)
if !p.Valid() {
b.containsViaIPFuncAtomic.Store(tsaddr.FalseContainsIPFunc())
@ -3018,9 +3019,6 @@ func (b *LocalBackend) setPrefsLockedOnEntry(caller string, newp *ipn.Prefs) ipn
b.sshServer = nil
}
}
if oldp.ShouldWebClientBeRunning() && !newp.ShouldWebClientBeRunning() {
go b.WebClientShutdown()
}
if netMap != nil {
newProfile := netMap.UserProfiles[netMap.User()]
if newLoginName := newProfile.LoginName; newLoginName != "" {
@ -4212,8 +4210,14 @@ func (b *LocalBackend) ResetForClientDisconnect() {
func (b *LocalBackend) ShouldRunSSH() bool { return b.sshAtomicBool.Load() && envknob.CanSSHD() }
func (b *LocalBackend) ShouldRunWebClient() bool {
return b.webclientAtomicBool.Load() && hasCapability(b.netMap, tailcfg.CapabilityPreviewWebClient)
func (b *LocalBackend) ShouldRunWebClient() bool { return b.webClientAtomicBool.Load() }
func (b *LocalBackend) setWebClientAtomicBoolLocked(nm *netmap.NetworkMap, prefs ipn.PrefsView) {
shouldRun := prefs.Valid() && prefs.RunWebClient() && hasCapability(nm, tailcfg.CapabilityPreviewWebClient)
wasRunning := b.webClientAtomicBool.Swap(shouldRun)
if wasRunning && !shouldRun {
go b.WebClientShutdown() // stop web client
}
}
// ShouldHandleViaIP reports whether ip is an IPv6 address in the

View File

@ -14,7 +14,6 @@
"tailscale.com/client/tailscale"
"tailscale.com/client/web"
"tailscale.com/net/netutil"
"tailscale.com/tailcfg"
)
// webClient holds state for the web interface for managing
@ -41,7 +40,7 @@ func (b *LocalBackend) SetWebLocalClient(lc *tailscale.LocalClient) {
// tailscaled instance.
// If the web interface is already running, WebClientInit is a no-op.
func (b *LocalBackend) WebClientInit() (err error) {
if !hasCapability(b.netMap, tailcfg.CapabilityPreviewWebClient) {
if !b.ShouldRunWebClient() {
return errors.New("web client not enabled for this device")
}