summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarwan Sulaiman <marwan@tailscale.com>2023-08-31 17:43:54 +0100
committerMarwan Sulaiman <marwan.sameer@gmail.com>2023-09-05 13:30:04 -0400
commita4aa6507fa3afa586dc3cbbf85f2cae852622b9e (patch)
treee8248de61962873639aad97a86da9d9fe240e868
parent7175f06e626a0d3494c7e583a105a0f0b66738f3 (diff)
downloadtailscale-a4aa6507fa3afa586dc3cbbf85f2cae852622b9e.tar.xz
tailscale-a4aa6507fa3afa586dc3cbbf85f2cae852622b9e.zip
ipn, ipn/ipnlocal: add session identifier for WatchIPNBus
This PR adds a SessionID field to the ipn.Notify struct so that ipn buses can identify a session and register deferred clean up code in the future. The first use case this is for is to be able to tie foreground serve configs to a specific watch session and ensure its clean up when a connection is closed. Updates #8489 Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
-rw-r--r--cmd/tailscaled/depaware.txt2
-rw-r--r--ipn/backend.go8
-rw-r--r--ipn/ipnlocal/local.go5
3 files changed, 13 insertions, 2 deletions
diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt
index 1367bbebc..4e49741a5 100644
--- a/cmd/tailscaled/depaware.txt
+++ b/cmd/tailscaled/depaware.txt
@@ -343,7 +343,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
tailscale.com/util/osshare from tailscale.com/ipn/ipnlocal+
W tailscale.com/util/pidowner from tailscale.com/ipn/ipnauth
tailscale.com/util/racebuild from tailscale.com/logpolicy
- tailscale.com/util/rands from tailscale.com/ipn/localapi
+ tailscale.com/util/rands from tailscale.com/ipn/localapi+
tailscale.com/util/ringbuffer from tailscale.com/wgengine/magicsock
tailscale.com/util/set from tailscale.com/health+
tailscale.com/util/singleflight from tailscale.com/control/controlclient+
diff --git a/ipn/backend.go b/ipn/backend.go
index 806598aa2..8da7e6a5c 100644
--- a/ipn/backend.go
+++ b/ipn/backend.go
@@ -61,7 +61,7 @@ const (
// each one via RequestEngineStatus.
NotifyWatchEngineUpdates NotifyWatchOpt = 1 << iota
- NotifyInitialState // if set, the first Notify message (sent immediately) will contain the current State + BrowseToURL
+ NotifyInitialState // if set, the first Notify message (sent immediately) will contain the current State + BrowseToURL + SessionID
NotifyInitialPrefs // if set, the first Notify message (sent immediately) will contain the current Prefs
NotifyInitialNetMap // if set, the first Notify message (sent immediately) will contain the current NetMap
@@ -77,6 +77,12 @@ type Notify struct {
_ structs.Incomparable
Version string // version number of IPN backend
+ // SessionID identifies the unique WatchIPNBus session.
+ // This field is only set in the first message when requesting
+ // NotifyInitialState. Clients must store it on their side as
+ // following notifications will not include this field.
+ SessionID string `json:",omitempty"`
+
// ErrMessage, if non-nil, contains a critical error message.
// For State InUseOtherUser, ErrMessage is not critical and just contains the details.
ErrMessage *string
diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go
index 69bba760f..b516b12c0 100644
--- a/ipn/ipnlocal/local.go
+++ b/ipn/ipnlocal/local.go
@@ -78,6 +78,7 @@ import (
"tailscale.com/util/mak"
"tailscale.com/util/multierr"
"tailscale.com/util/osshare"
+ "tailscale.com/util/rands"
"tailscale.com/util/set"
"tailscale.com/util/systemd"
"tailscale.com/util/testenv"
@@ -1935,6 +1936,8 @@ func (b *LocalBackend) ResendHostinfoIfNeeded() {
func (b *LocalBackend) WatchNotifications(ctx context.Context, mask ipn.NotifyWatchOpt, onWatchAdded func(), fn func(roNotify *ipn.Notify) (keepGoing bool)) {
ch := make(chan *ipn.Notify, 128)
+ sessionID := rands.HexString(16)
+
origFn := fn
if mask&ipn.NotifyNoPrivateKeys != 0 {
fn = func(n *ipn.Notify) bool {
@@ -1956,10 +1959,12 @@ func (b *LocalBackend) WatchNotifications(ctx context.Context, mask ipn.NotifyWa
var ini *ipn.Notify
b.mu.Lock()
+
const initialBits = ipn.NotifyInitialState | ipn.NotifyInitialPrefs | ipn.NotifyInitialNetMap
if mask&initialBits != 0 {
ini = &ipn.Notify{Version: version.Long()}
if mask&ipn.NotifyInitialState != 0 {
+ ini.SessionID = sessionID
ini.State = ptr.To(b.state)
if b.state == ipn.NeedsLogin {
ini.BrowseToURL = ptr.To(b.authURLSticky)