diff --git a/NucleicRemote/NucleicRemote/Models/HostConnection.swift b/NucleicRemote/NucleicRemote/Models/HostConnection.swift index a6c9358..654ab5f 100644 --- a/NucleicRemote/NucleicRemote/Models/HostConnection.swift +++ b/NucleicRemote/NucleicRemote/Models/HostConnection.swift @@ -478,8 +478,18 @@ final class HostConnection { else { continue } let fingerprint = member.staticPublicKey.fingerprintHex guard fingerprint != self.hostID else { continue } // that's the Mac we're on - if IdentityStore.pairedHost(id: fingerprint) == nil { changed = true } - IdentityStore.mergePairedHost(Self.pairedHost(from: member)) + let incoming = Self.pairedHost(from: member) + let existing = IdentityStore.pairedHost(id: fingerprint) + // Re-dial not only when a Mac is brand-new, but also when a known Mac's dialable + // address changed — a Mac's LAN port is OS-assigned (`.any`), so it lands on a + // fresh one every relaunch and re-gossips it. `mergePairedHost` updates the + // registry in place, but a connection already retrying the dead old address won't + // pick that up on its own (its retry loop reuses the address it was last handed), + // so without forcing a fresh reconnect here the phone never reconnects to it. + if existing == nil || Self.dialableAddressChanged(from: existing!, to: incoming) { + changed = true + } + IdentityStore.mergePairedHost(incoming) } for tombstone in push.tombstones { // fingerprint = first 16 hex of the hostID (sha256 prefix), the registry key.