Preserve unreachable state and ping failures across node merges

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ian Gulliver
2026-02-04 12:45:09 -08:00
parent c328e737d0
commit 41f3602696
2 changed files with 23 additions and 22 deletions

View File

@@ -388,9 +388,6 @@ func (n *Nodes) mergeNodes(keep, merge *Node) {
return return
} }
keepWasUnreachable := keep.Unreachable
mergeWasUnreachable := merge.Unreachable
for name := range merge.Names { for name := range merge.Names {
if keep.Names == nil { if keep.Names == nil {
keep.Names = NameSet{} keep.Names = NameSet{}
@@ -428,28 +425,20 @@ func (n *Nodes) mergeNodes(keep, merge *Node) {
n.mergeMulticast(keep, merge) n.mergeMulticast(keep, merge)
n.mergeDante(keep, merge) n.mergeDante(keep, merge)
if merge.cancelFunc != nil { if merge.InConfig {
merge.cancelFunc() keep.InConfig = true
} }
hasIPs := false if merge.Unreachable {
for _, iface := range keep.Interfaces { keep.Unreachable = true
if len(iface.IPs) > 0 {
hasIPs = true
break
}
} }
if hasIPs && (keepWasUnreachable || mergeWasUnreachable) {
keep.Unreachable = false if n.t != nil && n.t.ping != nil {
if n.t != nil && n.t.errors != nil { n.t.ping.TransferFailures(merge.ID, keep.ID)
n.t.errors.RemoveUnreachable(keep) }
}
if keepWasUnreachable { if merge.cancelFunc != nil {
log.Printf("[merge] %s is now reachable (merged with node that has IPs)", keep.DisplayName()) merge.cancelFunc()
}
if mergeWasUnreachable {
log.Printf("[merge] %s is now reachable (merged into %s)", merge.DisplayName(), keep.DisplayName())
}
} }
n.removeNode(merge) n.removeNode(merge)

12
ping.go
View File

@@ -138,6 +138,18 @@ func (pm *PingManager) Ping(ipStr string, timeout time.Duration) bool {
} }
} }
func (pm *PingManager) TransferFailures(fromID, toID string) {
pm.mu.Lock()
defer pm.mu.Unlock()
fromFailures := pm.failures[fromID]
toFailures := pm.failures[toID]
if fromFailures > toFailures {
pm.failures[toID] = fromFailures
}
delete(pm.failures, fromID)
}
func (t *Tendrils) pingNode(node *Node) { func (t *Tendrils) pingNode(node *Node) {
t.nodes.mu.RLock() t.nodes.mu.RLock()
if node.Avoid { if node.Avoid {