diff --git a/WireGuard/Shared/NETunnelProviderProtocol+Extension.swift b/WireGuard/Shared/NETunnelProviderProtocol+Extension.swift index 9f4af77..776e03b 100644 --- a/WireGuard/Shared/NETunnelProviderProtocol+Extension.swift +++ b/WireGuard/Shared/NETunnelProviderProtocol+Extension.swift @@ -37,4 +37,10 @@ extension NETunnelProviderProtocol { var isActivateOnDemandEnabled: Bool { return (providerConfiguration?["isActivateOnDemandEnabled"] as? Bool) ?? false } + + func hasTunnelConfiguration(tunnelConfiguration otherTunnelConfiguration: TunnelConfiguration) -> Bool { + guard let serializedThisTunnelConfiguration = providerConfiguration?["tunnelConfiguration"] as? Data else { return false } + guard let serializedOtherTunnelConfiguration = try? JSONEncoder().encode(otherTunnelConfiguration) else { return false } + return serializedThisTunnelConfiguration == serializedOtherTunnelConfiguration + } } diff --git a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift index 10ef1ef..8382361 100644 --- a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift +++ b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift @@ -115,6 +115,9 @@ class TunnelsManager { } tunnel.name = tunnelName } + + let shouldRestartIfActive = !((tunnelProviderManager.protocolConfiguration as? NETunnelProviderProtocol)?.hasTunnelConfiguration(tunnelConfiguration: tunnelConfiguration) ?? false) + tunnelProviderManager.protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration, isActivateOnDemandEnabled: activateOnDemandSetting.isActivateOnDemandEnabled) tunnelProviderManager.localizedDescription = tunnelName tunnelProviderManager.isEnabled = true @@ -137,13 +140,15 @@ class TunnelsManager { self.tunnelsListDelegate?.tunnelMoved(from: oldIndex, to: newIndex) } self.tunnelsListDelegate?.tunnelModified(at: self.tunnels.firstIndex(of: tunnel)!) - - if tunnel.status == .active || tunnel.status == .activating || tunnel.status == .reasserting { - // Turn off the tunnel, and then turn it back on, so the changes are made effective - tunnel.status = .restarting - (tunnel.tunnelProvider.connection as? NETunnelProviderSession)?.stopTunnel() + + if shouldRestartIfActive { + if tunnel.status == .active || tunnel.status == .activating || tunnel.status == .reasserting { + // Turn off the tunnel, and then turn it back on, so the changes are made effective + tunnel.status = .restarting + (tunnel.tunnelProvider.connection as? NETunnelProviderSession)?.stopTunnel() + } } - + if isActivatingOnDemand { // Reload tunnel after saving. // Without this, the tunnel stopes getting updates on the tunnel status from iOS.