diff --git a/nodes.go b/nodes.go index a5f4f57..78ef8e9 100644 --- a/nodes.go +++ b/nodes.go @@ -388,9 +388,6 @@ func (n *Nodes) mergeNodes(keep, merge *Node) { return } - keepWasUnreachable := keep.Unreachable - mergeWasUnreachable := merge.Unreachable - for name := range merge.Names { if keep.Names == nil { keep.Names = NameSet{} @@ -428,28 +425,20 @@ func (n *Nodes) mergeNodes(keep, merge *Node) { n.mergeMulticast(keep, merge) n.mergeDante(keep, merge) - if merge.cancelFunc != nil { - merge.cancelFunc() + if merge.InConfig { + keep.InConfig = true } - hasIPs := false - for _, iface := range keep.Interfaces { - if len(iface.IPs) > 0 { - hasIPs = true - break - } + if merge.Unreachable { + keep.Unreachable = true } - if hasIPs && (keepWasUnreachable || mergeWasUnreachable) { - keep.Unreachable = false - if n.t != nil && n.t.errors != nil { - n.t.errors.RemoveUnreachable(keep) - } - if keepWasUnreachable { - log.Printf("[merge] %s is now reachable (merged with node that has IPs)", keep.DisplayName()) - } - if mergeWasUnreachable { - log.Printf("[merge] %s is now reachable (merged into %s)", merge.DisplayName(), keep.DisplayName()) - } + + if n.t != nil && n.t.ping != nil { + n.t.ping.TransferFailures(merge.ID, keep.ID) + } + + if merge.cancelFunc != nil { + merge.cancelFunc() } n.removeNode(merge) diff --git a/ping.go b/ping.go index d382c3c..2d13aad 100644 --- a/ping.go +++ b/ping.go @@ -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) { t.nodes.mu.RLock() if node.Avoid {