mirror of
https://github.com/juanfont/headscale.git
synced 2026-10-26 16:26:50 +09:00
change: drop untargeted pings when collapsing to a full
The ping ID in the URL is the only authentication on the answer, so rescuing an untargeted ping for every node would let any node answer for another. Rescue a ping only for the node it targets.
This commit is contained in:
1 parent
d4948da301
commit
85587e2e29
2 files changed
+8
-6
No files matched your search
@@ -232,14 +232,15 @@ func HasFull(rs []Change) bool {
|
|||||||
|
|
||||||
// CollapseToFull returns what nodeID receives when a full update supersedes
|
// CollapseToFull returns what nodeID receives when a full update supersedes
|
||||||
// changes: one [FullUpdate], then a ping-only [PingNode] for every
|
// changes: one [FullUpdate], then a ping-only [PingNode] for every
|
||||||
// [Change.PingRequest] addressed to nodeID, in order. A full renders state at
|
// [Change.PingRequest] targeted at nodeID, in order. A full renders state at
|
||||||
// drain time, so it covers every state change; a ping is a one-shot command
|
// drain time, so it covers every state change; a ping is a one-shot command
|
||||||
// the full cannot carry.
|
// the full cannot carry. An untargeted ping is dropped: the ID in its URL is
|
||||||
|
// all that authenticates the answer, so any node could answer for another.
|
||||||
func CollapseToFull(nodeID types.NodeID, changes []Change) []Change {
|
func CollapseToFull(nodeID types.NodeID, changes []Change) []Change {
|
||||||
out := []Change{FullUpdate()}
|
out := []Change{FullUpdate()}
|
||||||
|
|
||||||
for _, c := range changes {
|
for _, c := range changes {
|
||||||
if c.PingRequest != nil && c.ShouldSendToNode(nodeID) {
|
if c.PingRequest != nil && c.TargetNode == nodeID {
|
||||||
out = append(out, PingNode(nodeID, c.PingRequest))
|
out = append(out, PingNode(nodeID, c.PingRequest))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ func TestChange_FullUpdateSubsumesAllButPing(t *testing.T) {
|
|||||||
isCarried, ok := carried[field.Name]
|
isCarried, ok := carried[field.Name]
|
||||||
require.True(t, ok, "field %s is not classified", field.Name)
|
require.True(t, ok, "field %s is not classified", field.Name)
|
||||||
|
|
||||||
var c Change
|
// Addressed to self, so only the field under test decides.
|
||||||
|
c := Change{TargetNode: self}
|
||||||
|
|
||||||
v := reflect.ValueOf(&c).Elem().FieldByIndex(field.Index)
|
v := reflect.ValueOf(&c).Elem().FieldByIndex(field.Index)
|
||||||
setNonZero(t, v, self)
|
setNonZero(t, v, self)
|
||||||
@@ -701,9 +702,9 @@ func TestCollapseToFullKeepsPings(t *testing.T) {
|
|||||||
want: []Change{FullUpdate(), PingNode(self, prA)},
|
want: []Change{FullUpdate(), PingNode(self, prA)},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "untargeted ping is addressed to every node",
|
name: "untargeted ping is dropped",
|
||||||
changes: []Change{{Reason: "broadcast ping", PingRequest: prA}},
|
changes: []Change{{Reason: "broadcast ping", PingRequest: prA}},
|
||||||
want: []Change{FullUpdate(), PingNode(self, prA)},
|
want: []Change{FullUpdate()},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "fulls never stack",
|
name: "fulls never stack",
|
||||||
|
|||||||
Reference in new issue
Block a user