From 97c18b18fdccb88a5eec124beb6225e56e7f472d Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Tue, 20 Oct 2026 12:30:31 +0000 Subject: [PATCH] android, ios: ignore link-local addresses in network changes --- apps/ios/Shared/Model/NetworkObserver.swift | 6 ++++-- .../kotlin/chat/simplex/common/helpers/NetworkObserver.kt | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/ios/Shared/Model/NetworkObserver.swift b/apps/ios/Shared/Model/NetworkObserver.swift index 86c4646828..eecbf9f360 100644 --- a/apps/ios/Shared/Model/NetworkObserver.swift +++ b/apps/ios/Shared/Model/NetworkObserver.swift @@ -69,7 +69,8 @@ class NetworkObserver { } // NWPath has no addresses, and a changed address with the same interface and gateway - // (e.g. the lease was renewed after internet loss) also means the connections via it are dead + // (e.g. a new lease after internet loss) also means the connections via it are dead; + // link-local addresses are not used for the connections to the servers private func localAddresses(_ interface: String?) -> Set { var ifap: UnsafeMutablePointer? guard let interface = interface, getifaddrs(&ifap) == 0, let first = ifap else { return [] } @@ -80,7 +81,8 @@ class NetworkObserver { String(cString: ifa.pointee.ifa_name) == interface else { return nil } var host = [CChar](repeating: 0, count: Int(NI_MAXHOST)) guard getnameinfo(sa, socklen_t(sa.pointee.sa_len), &host, socklen_t(host.count), nil, 0, NI_NUMERICHOST) == 0 else { return nil } - return String(cString: host) + let address = String(cString: host) + return address.hasPrefix("fe80:") || address.hasPrefix("169.254.") ? nil : address }) } diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/NetworkObserver.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/NetworkObserver.kt index 13e16787e8..5e137df9e9 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/NetworkObserver.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/NetworkObserver.kt @@ -134,7 +134,7 @@ class NetworkObserver { sendMutex.withLock { val removals = addressRemovals // the core has the same network info for the network its connections were made via, e.g. the network - // was reported offline less than 3 seconds ago and it was not sent - the connections are not affected + // was reported offline less than 3 seconds ago and it was not sent - the connections are assumed not affected if ((removals != sentAddressRemovals || sentInfo != info || network != sentNetwork) && sendNetworkInfo(info, network, removals, ctrlGen)) sent.set(true) } @@ -188,8 +188,10 @@ class NetworkObserver { private fun lost(prev: Set?, addresses: Set?): Boolean = prev != null && (addresses == null || !addresses.containsAll(prev) || (prev.isEmpty() && addresses.isNotEmpty())) - // LinkAddress equality includes address lifetimes that change with every router advertisement - private fun addresses(linkProperties: LinkProperties): Set = linkProperties.linkAddresses.map { it.address }.toSet() + // LinkAddress equality includes address lifetimes that change with every router advertisement; + // link-local addresses are not used for the connections to the servers + private fun addresses(linkProperties: LinkProperties): Set = + linkProperties.linkAddresses.map { it.address }.filterNot { it.isLinkLocalAddress }.toSet() private fun networkInfo(capabilities: NetworkCapabilities) = UserNetworkInfo( networkType = networkTypeFromCapabilities(capabilities),