From 206259a00793eb90fb6a10a814c290ee26ba99cc Mon Sep 17 00:00:00 2001 From: Michael Uray <25169478+MichaelUray@users.noreply.github.com> Date: Mon, 6 Apr 2026 15:15:47 +0000 Subject: [PATCH 1/3] fix: change ForceRelay default from true to false The default was set to true in #108 as a workaround for P2P stability issues on Android. Now that the underlying ICE issues are fixed (netbirdio/netbird: guard loop, candidate buffering, anet for Android), P2P connections work reliably and should be enabled by default. --- netbird | 2 +- tool/src/main/java/io/netbird/client/tool/Preferences.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/netbird b/netbird index 332c624..3e020e7 160000 --- a/netbird +++ b/netbird @@ -1 +1 @@ -Subproject commit 332c624c55a486c0ab7b981a26cf8e00a6fa0774 +Subproject commit 3e020e77d7a96fdeaaed701429a9cde6f1da9dcf diff --git a/tool/src/main/java/io/netbird/client/tool/Preferences.java b/tool/src/main/java/io/netbird/client/tool/Preferences.java index ddf57ca..db1acec 100644 --- a/tool/src/main/java/io/netbird/client/tool/Preferences.java +++ b/tool/src/main/java/io/netbird/client/tool/Preferences.java @@ -27,7 +27,7 @@ public void disableTraceLog() { } public boolean isConnectionForceRelayed() { - return sharedPref.getBoolean(keyForceRelayConnection, true); + return sharedPref.getBoolean(keyForceRelayConnection, false); } public void enableForcedRelayConnection() { From 8987fd852a51321199fff65aa8fedc5d1fac9228 Mon Sep 17 00:00:00 2001 From: Michael Uray <25169478+MichaelUray@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:46:14 +0000 Subject: [PATCH 2/3] fix: trigger engine restart on any network type change, not just WiFi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous implementation only notified the listener in two cases: - onNetworkAvailable: only when WiFi became available - onNetworkLost: only when WiFi was lost AND mobile was available This missed the case where WiFi is disabled and mobile data takes over as the active connection. The onAvailable(MOBILE) callback was ignored, and if mobile wasn't yet registered when onLost(WIFI) fired, the notification was skipped entirely. This left the Go engine with stale NetworkAddresses (containing the old WiFi subnet), causing posture checks like peer_network_range_check to incorrectly block the peer. The fix notifies the listener on any network type transition: - onNetworkAvailable: notify when a new network type appears - onNetworkLost: notify when a network is lost but others remain This ensures the engine restarts and sends fresh NetworkAddresses to the management server after every WiFi ↔ Mobile switch. --- .../ConcreteNetworkAvailabilityListener.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/tool/src/main/java/io/netbird/client/tool/networks/ConcreteNetworkAvailabilityListener.java b/tool/src/main/java/io/netbird/client/tool/networks/ConcreteNetworkAvailabilityListener.java index 8c8cdbc..708edcc 100644 --- a/tool/src/main/java/io/netbird/client/tool/networks/ConcreteNetworkAvailabilityListener.java +++ b/tool/src/main/java/io/netbird/client/tool/networks/ConcreteNetworkAvailabilityListener.java @@ -13,26 +13,27 @@ public ConcreteNetworkAvailabilityListener() { @Override public void onNetworkAvailable(@Constants.NetworkType int networkType) { - boolean isWifiAvailable = Boolean.TRUE.equals(availableNetworkTypes.get(Constants.NetworkType.WIFI)); + boolean hadNetwork = !availableNetworkTypes.isEmpty(); + boolean hadSameType = Boolean.TRUE.equals(availableNetworkTypes.get(networkType)); availableNetworkTypes.put(networkType, true); - // if wifi is available and wasn't before, notifies listener. - // Android prioritizes wifi over mobile data network by default. - if (!isWifiAvailable && networkType == Constants.NetworkType.WIFI) { + // Notify on any network type change: + // - new WiFi connection (Mobile → WiFi switch) + // - new Mobile connection when WiFi was lost (WiFi → Mobile switch) + // - first network connection + if (!hadSameType) { notifyListener(); } } @Override public void onNetworkLost(@Constants.NetworkType int networkType) { - boolean isMobileAvailable = Boolean.TRUE.equals(availableNetworkTypes.get(Constants.NetworkType.MOBILE)); - availableNetworkTypes.remove(networkType); - // if wifi is lost and mobile data is available, notifies listener. - // No use to notify it if there's no other type of network available. - if (isMobileAvailable && networkType == Constants.NetworkType.WIFI) { + // Notify when a network is lost and another type is still available. + // This covers WiFi lost with Mobile still active. + if (!availableNetworkTypes.isEmpty()) { notifyListener(); } } From 2bb01dd71f39b7c214cef28722c27a23c477697b Mon Sep 17 00:00:00 2001 From: Michael Uray <25169478+MichaelUray@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:56:21 +0000 Subject: [PATCH 3/3] fix: guard onNetworkLost against duplicate/out-of-order callbacks Only notify the listener when the lost network type was actually tracked, preventing avoidable engine restart churn from spurious or duplicate onLost events. --- .../networks/ConcreteNetworkAvailabilityListener.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tool/src/main/java/io/netbird/client/tool/networks/ConcreteNetworkAvailabilityListener.java b/tool/src/main/java/io/netbird/client/tool/networks/ConcreteNetworkAvailabilityListener.java index 708edcc..e15cdd3 100644 --- a/tool/src/main/java/io/netbird/client/tool/networks/ConcreteNetworkAvailabilityListener.java +++ b/tool/src/main/java/io/netbird/client/tool/networks/ConcreteNetworkAvailabilityListener.java @@ -29,11 +29,11 @@ public void onNetworkAvailable(@Constants.NetworkType int networkType) { @Override public void onNetworkLost(@Constants.NetworkType int networkType) { - availableNetworkTypes.remove(networkType); + boolean wasPresent = availableNetworkTypes.remove(networkType) != null; - // Notify when a network is lost and another type is still available. - // This covers WiFi lost with Mobile still active. - if (!availableNetworkTypes.isEmpty()) { + // Notify when a tracked network is lost and another type is still available. + // Guards against duplicate/out-of-order onLost callbacks. + if (wasPresent && !availableNetworkTypes.isEmpty()) { notifyListener(); } }