WIP: rebase for 2026-05-18 #7
@@ -118,6 +118,17 @@ type Notify struct {
|
||||
Prefs *PrefsView // if non-nil && Valid, the new or current preferences
|
||||
NetMap *netmap.NetworkMap // if non-nil, the new or current netmap
|
||||
|
||||
// SelfChange, if non-nil, indicates that this node's own [tailcfg.Node]
|
||||
// has changed: addresses, name, key expiry, capabilities, etc. It carries
|
||||
// the new self node so reactive consumers (containerboot, kube agents,
|
||||
// sniproxy, etc.) can read the current self state without watching the
|
||||
// full netmap.
|
||||
//
|
||||
// Consumers that need additional state (peers, DNS config, packet
|
||||
// filter) should react to SelfChange by fetching the relevant bits on
|
||||
// demand via [LocalClient].
|
||||
SelfChange *tailcfg.Node `json:",omitzero"`
|
||||
|
||||
// PeerChanges, if non-nil, is a list of [tailcfg.PeerChange] that have occurred since the last
|
||||
// full netmap update. This is sent in lieu of a full NetMap when [NotifyPeerChanges] is set in
|
||||
// the session's mask and a netmap update is derived from an incremental MapResponse.
|
||||
@@ -196,6 +207,9 @@ func (n Notify) String() string {
|
||||
if n.NetMap != nil {
|
||||
sb.WriteString("NetMap{...} ")
|
||||
}
|
||||
if n.SelfChange != nil {
|
||||
fmt.Fprintf(&sb, "SelfChange(%v) ", n.SelfChange.StableID)
|
||||
}
|
||||
if n.PeerChanges != nil {
|
||||
fmt.Fprintf(&sb, "PeerChanges(%d) ", len(n.PeerChanges))
|
||||
}
|
||||
|
||||
@@ -205,6 +205,7 @@ func isNotableNotify(n *ipn.Notify) bool {
|
||||
n.Prefs != nil ||
|
||||
n.ErrMessage != nil ||
|
||||
n.LoginFinished != nil ||
|
||||
n.SelfChange != nil ||
|
||||
!n.DriveShares.IsNil() ||
|
||||
n.Health != nil ||
|
||||
len(n.IncomingFiles) > 0 ||
|
||||
|
||||
@@ -32,6 +32,7 @@ func TestIsNotableNotify(t *testing.T) {
|
||||
{"netmap", &ipn.Notify{NetMap: new(netmap.NetworkMap)}, false},
|
||||
{"peerchanges", &ipn.Notify{PeerChanges: []*tailcfg.PeerChange{{}}}, false},
|
||||
{"engine", &ipn.Notify{Engine: new(ipn.EngineStatus)}, false},
|
||||
{"selfchange", &ipn.Notify{SelfChange: &tailcfg.Node{}}, true},
|
||||
}
|
||||
|
||||
// Then for all other fields, assume they're notable.
|
||||
@@ -41,7 +42,7 @@ func TestIsNotableNotify(t *testing.T) {
|
||||
for sf := range rt.Fields() {
|
||||
n := &ipn.Notify{}
|
||||
switch sf.Name {
|
||||
case "_", "NetMap", "PeerChanges", "Engine", "Version":
|
||||
case "_", "NetMap", "PeerChanges", "SelfChange", "Engine", "Version":
|
||||
// Already covered above or not applicable.
|
||||
continue
|
||||
case "DriveShares":
|
||||
|
||||
@@ -1897,7 +1897,15 @@ func (b *LocalBackend) setControlClientStatusLocked(c controlclient.Client, st c
|
||||
// Update the DERP map in the health package, which uses it for health notifications
|
||||
b.health.SetDERPMap(st.NetMap.DERPMap)
|
||||
|
||||
b.sendLocked(ipn.Notify{NetMap: st.NetMap})
|
||||
// Notify watchers that the self node may have changed. Reactive
|
||||
// consumers (containerboot, kube agents, sniproxy, etc.) listen on
|
||||
// this signal and re-fetch peers/DNS via the LocalAPI if they need
|
||||
// more than self info.
|
||||
var selfChange *tailcfg.Node
|
||||
if st.NetMap.SelfNode.Valid() {
|
||||
selfChange = st.NetMap.SelfNode.AsStruct()
|
||||
}
|
||||
b.sendLocked(ipn.Notify{NetMap: st.NetMap, SelfChange: selfChange})
|
||||
|
||||
// The error here is unimportant as is the result. This will recalculate the suggested exit node
|
||||
// cache the value and push any changes to the IPN bus.
|
||||
|
||||
Reference in New Issue
Block a user