mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 21:27:31 +00:00
control/controlclient, tailcfg: add Node.Expired field, set for expired nodes
Nodes that are expired, taking into account the time delta calculated from MapResponse.ControlTime have the newly-added Expired boolean set. For additional defense-in-depth, also replicate what control does and clear the Endpoints and DERP fields, and additionally set the node key to a bogus value. Updates #6932 Signed-off-by: Andrew Dunham <andrew@du.nham.ca> Change-Id: Ia2bd6b56064416feee28aef5699ca7090940662a
This commit is contained in:
@@ -255,6 +255,12 @@ type Node struct {
|
||||
|
||||
// DataPlaneAuditLogID is the per-node logtail ID used for data plane audit logging.
|
||||
DataPlaneAuditLogID string `json:",omitempty"`
|
||||
|
||||
// Expired is whether this node's key has expired. Control may send
|
||||
// this; clients are only allowed to set this from false to true. On
|
||||
// the client, this is calculated client-side based on a timestamp sent
|
||||
// from control, to avoid clock skew issues.
|
||||
Expired bool `json:",omitempty"`
|
||||
}
|
||||
|
||||
// DisplayName returns the user-facing name for a node which should
|
||||
@@ -1628,7 +1634,8 @@ func (n *Node) Equal(n2 *Node) bool {
|
||||
n.ComputedName == n2.ComputedName &&
|
||||
n.computedHostIfDifferent == n2.computedHostIfDifferent &&
|
||||
n.ComputedNameWithHost == n2.ComputedNameWithHost &&
|
||||
eqStrings(n.Tags, n2.Tags)
|
||||
eqStrings(n.Tags, n2.Tags) &&
|
||||
n.Expired == n2.Expired
|
||||
}
|
||||
|
||||
func eqBoolPtr(a, b *bool) bool {
|
||||
|
@@ -97,6 +97,7 @@ var _NodeCloneNeedsRegeneration = Node(struct {
|
||||
computedHostIfDifferent string
|
||||
ComputedNameWithHost string
|
||||
DataPlaneAuditLogID string
|
||||
Expired bool
|
||||
}{})
|
||||
|
||||
// Clone makes a deep copy of Hostinfo.
|
||||
|
@@ -334,7 +334,7 @@ func TestNodeEqual(t *testing.T) {
|
||||
"Capabilities",
|
||||
"UnsignedPeerAPIOnly",
|
||||
"ComputedName", "computedHostIfDifferent", "ComputedNameWithHost",
|
||||
"DataPlaneAuditLogID",
|
||||
"DataPlaneAuditLogID", "Expired",
|
||||
}
|
||||
if have := fieldsOf(reflect.TypeOf(Node{})); !reflect.DeepEqual(have, nodeHandles) {
|
||||
t.Errorf("Node.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
|
||||
@@ -514,6 +514,11 @@ func TestNodeEqual(t *testing.T) {
|
||||
&Node{},
|
||||
false,
|
||||
},
|
||||
{
|
||||
&Node{Expired: true},
|
||||
&Node{},
|
||||
false,
|
||||
},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
got := tt.a.Equal(tt.b)
|
||||
|
@@ -175,6 +175,7 @@ func (v NodeView) UnsignedPeerAPIOnly() bool { return v.ж.UnsignedPeerA
|
||||
func (v NodeView) ComputedName() string { return v.ж.ComputedName }
|
||||
func (v NodeView) ComputedNameWithHost() string { return v.ж.ComputedNameWithHost }
|
||||
func (v NodeView) DataPlaneAuditLogID() string { return v.ж.DataPlaneAuditLogID }
|
||||
func (v NodeView) Expired() bool { return v.ж.Expired }
|
||||
func (v NodeView) Equal(v2 NodeView) bool { return v.ж.Equal(v2.ж) }
|
||||
|
||||
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
|
||||
@@ -207,6 +208,7 @@ var _NodeViewNeedsRegeneration = Node(struct {
|
||||
computedHostIfDifferent string
|
||||
ComputedNameWithHost string
|
||||
DataPlaneAuditLogID string
|
||||
Expired bool
|
||||
}{})
|
||||
|
||||
// View returns a readonly view of Hostinfo.
|
||||
|
Reference in New Issue
Block a user