1
0
mirror of https://github.com/juanfont/headscale.git synced 2025-11-10 01:20:58 +01:00

mapper: handle NodeEndpoint and NodeDERP changes

Add batcher cases for NodeEndpoint and NodeDERP that query
NodeStore for current state and send PeerChangedPatch with
both endpoints and DERP region, avoiding full map responses.

Update batcher_test to pass NodeView to change constructors.
This commit is contained in:
Kristoffer Dalby 2025-11-01 22:46:02 +01:00
parent 63986e60f2
commit d045eb237f
No known key found for this signature in database
2 changed files with 33 additions and 2 deletions

View File

@ -128,6 +128,30 @@ func generateMapResponse(nodeID types.NodeID, version tailcfg.CapabilityVersion,
})
}
case change.NodeEndpoint, change.NodeDERP:
// Endpoint or DERP changes can be sent as lightweight patches.
// Query the NodeStore for the current peer state to construct the PeerChange.
// Even if only endpoint or only DERP changed, we include both in the patch
// since they're often updated together and it's minimal overhead.
responseType = "patch"
peer, found := mapper.state.GetNodeByID(c.NodeID)
if !found {
return nil, fmt.Errorf("node not found in NodeStore: %d", c.NodeID)
}
peerChange := &tailcfg.PeerChange{
NodeID: c.NodeID.NodeID(),
Endpoints: peer.Endpoints().AsSlice(),
DERPRegion: 0, // Will be set below if available
}
// Extract DERP region from Hostinfo if available
if hi := peer.AsStruct().Hostinfo; hi != nil && hi.NetInfo != nil {
peerChange.DERPRegion = hi.NetInfo.PreferredDERP
}
mapResp, err = mapper.peerChangedPatchResponse(nodeID, []*tailcfg.PeerChange{peerChange})
default:
// The following will always hit this:
// change.Full, change.Policy

View File

@ -50,7 +50,11 @@ func (t *testBatcherWrapper) AddNode(id types.NodeID, c chan<- *tailcfg.MapRespo
// Send the online notification that poll.go would normally send
// This ensures other nodes get notified about this node coming online
t.AddWork(change.NodeOnline(id))
node, ok := t.state.GetNodeByID(id)
if !ok {
return fmt.Errorf("node not found after adding to batcher: %d", id)
}
t.AddWork(change.NodeOnline(node))
return nil
}
@ -65,7 +69,10 @@ func (t *testBatcherWrapper) RemoveNode(id types.NodeID, c chan<- *tailcfg.MapRe
// Send the offline notification that poll.go would normally send
// Do this BEFORE removing from batcher so the change can be processed
t.AddWork(change.NodeOffline(id))
node, ok := t.state.GetNodeByID(id)
if ok {
t.AddWork(change.NodeOffline(node))
}
// Finally remove from the real batcher
removed := t.Batcher.RemoveNode(id, c)