ipn,wgengine/magicsock: allow setting static node endpoints via tailscaled configfile (#12882)

wgengine/magicsock,ipn: allow setting static node endpoints via tailscaled config file.

Adds a new StaticEndpoints field to tailscaled config
that can be used to statically configure the endpoints
that the node advertizes. This field will replace
TS_DEBUG_PRETENDPOINTS env var that can be used to achieve the same.

Additionally adds some functionality that ensures that endpoints
are updated when configfile is reloaded.

Also, refactor configuring/reconfiguring components to use the
same functionality when configfile is parsed the first time or
subsequent times (after reload). Previously a configfile reload
did not result in resetting of prefs. Now it does- but does not yet
tell the relevant components to consume the new prefs. This is to
be done in a follow-up.

Updates tailscale/tailscale#12578


Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This commit is contained in:
Irbe Krumina
2024-07-23 18:50:55 +03:00
committed by GitHub
parent 9904421853
commit 57856fc0d5
3 changed files with 85 additions and 17 deletions

View File

@@ -25,6 +25,7 @@ import (
"os"
"os/exec"
"path/filepath"
"reflect"
"runtime"
"slices"
"sort"
@@ -391,18 +392,6 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo
sds.SetDialer(dialer.SystemDial)
}
if sys.InitialConfig != nil {
p := pm.CurrentPrefs().AsStruct()
mp, err := sys.InitialConfig.Parsed.ToPrefs()
if err != nil {
return nil, err
}
p.ApplyEdits(&mp)
if err := pm.SetPrefs(p.View(), ipn.NetworkProfile{}); err != nil {
return nil, err
}
}
envknob.LogCurrent(logf)
osshare.SetFileSharingEnabled(false, logf)
@@ -417,7 +406,6 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo
statsLogf: logger.LogOnChange(logf, 5*time.Minute, clock.Now),
sys: sys,
health: sys.HealthTracker(),
conf: sys.InitialConfig,
e: e,
dialer: dialer,
store: store,
@@ -434,6 +422,12 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo
}
mConn.SetNetInfoCallback(b.setNetInfo)
if sys.InitialConfig != nil {
if err := b.setConfigLocked(sys.InitialConfig); err != nil {
return nil, err
}
}
netMon := sys.NetMon.Get()
b.sockstatLogger, err = sockstatlog.NewLogger(logpolicy.LogsDir(logf), logf, logID, netMon, sys.HealthTracker())
if err != nil {
@@ -616,11 +610,50 @@ func (b *LocalBackend) ReloadConfig() (ok bool, err error) {
if err != nil {
return false, err
}
b.conf = conf
// TODO(bradfitz): apply things
if err := b.setConfigLocked(conf); err != nil {
return false, fmt.Errorf("error setting config: %w", err)
}
return true, nil
}
func (b *LocalBackend) setConfigLocked(conf *conffile.Config) error {
// TODO(irbekrm): notify the relevant components to consume any prefs
// updates. Currently only initial configfile settings are applied
// immediately.
p := b.pm.CurrentPrefs().AsStruct()
mp, err := conf.Parsed.ToPrefs()
if err != nil {
return fmt.Errorf("error parsing config to prefs: %w", err)
}
p.ApplyEdits(&mp)
if err := b.pm.SetPrefs(p.View(), ipn.NetworkProfile{}); err != nil {
return err
}
defer func() {
b.conf = conf
}()
if conf.Parsed.StaticEndpoints == nil && (b.conf == nil || b.conf.Parsed.StaticEndpoints == nil) {
return nil
}
// Ensure that magicsock conn has the up to date static wireguard
// endpoints. Setting the endpoints here triggers an asynchronous update
// of the node's advertised endpoints.
if b.conf == nil && len(conf.Parsed.StaticEndpoints) != 0 || !reflect.DeepEqual(conf.Parsed.StaticEndpoints, b.conf.Parsed.StaticEndpoints) {
ms, ok := b.sys.MagicSock.GetOK()
if !ok {
b.logf("[unexpected] ReloadConfig: MagicSock not set")
} else {
ms.SetStaticEndpoints(views.SliceOf(conf.Parsed.StaticEndpoints))
}
}
return nil
}
var assumeNetworkUpdateForTest = envknob.RegisterBool("TS_ASSUME_NETWORK_UP_FOR_TEST")
// pauseOrResumeControlClientLocked pauses b.cc if there is no network available