Просмотр исходного кода

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 <[email protected]>
Marwan Sulaiman 2 лет назад
Родитель
Сommit
a4aa6507fa
3 измененных файлов с 13 добавлено и 2 удалено
  1. 1 1
      cmd/tailscaled/depaware.txt
  2. 7 1
      ipn/backend.go
  3. 5 0
      ipn/ipnlocal/local.go

+ 1 - 1
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+

+ 7 - 1
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

+ 5 - 0
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)