tailcfg, control/controlhttp, control/controlclient: add ControlDialPlan field (#5648)

* tailcfg, control/controlhttp, control/controlclient: add ControlDialPlan field

This field allows the control server to provide explicit information
about how to connect to it; useful if the client's link status can
change after the initial connection, or if the DNS settings pushed by
the control server break future connections.

Change-Id: I720afe6289ec27d40a41b3dcb310ec45bd7e5f3e
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
This commit is contained in:
Andrew Dunham
2022-09-23 13:06:55 -04:00
committed by GitHub
parent acc7baac6d
commit e1bdbfe710
8 changed files with 604 additions and 17 deletions

View File

@@ -189,6 +189,10 @@ type LocalBackend struct {
// statusChanged.Broadcast().
statusLock sync.Mutex
statusChanged *sync.Cond
// dialPlan is any dial plan that we've received from the control
// server during a previous connection; it is cleared on logout.
dialPlan atomic.Pointer[tailcfg.ControlDialPlan]
}
// clientGen is a func that creates a control plane client.
@@ -1087,6 +1091,7 @@ func (b *LocalBackend) Start(opts ipn.Options) error {
Dialer: b.Dialer(),
Status: b.setClientStatus,
C2NHandler: http.HandlerFunc(b.handleC2N),
DialPlan: &b.dialPlan, // pointer because it can't be copied
// Don't warn about broken Linux IP forwarding when
// netstack is being used.
@@ -3112,6 +3117,9 @@ func (b *LocalBackend) logout(ctx context.Context, sync bool) error {
Prefs: ipn.Prefs{WantRunning: false, LoggedOut: true},
})
// Clear any previous dial plan(s), if set.
b.dialPlan.Store(nil)
if cc == nil {
// Double Logout can happen via repeated IPN
// connections to ipnserver making it repeatedly