diff options
| author | Steffen Ernst <steffen.ernst@mullvad.net> | 2025-02-11 15:38:23 +0100 |
|---|---|---|
| committer | Bug Magnet <marco.nikic@mullvad.net> | 2025-02-18 11:52:06 +0100 |
| commit | 9d4b78da2d8312075d93702050f9787eb6998255 (patch) | |
| tree | 71f9b94850253a8c6a292335ca9327c332b5e739 | |
| parent | 63d9f6fc8814c5bbe9e07a26ad6487ec32e5fcab (diff) | |
| download | mullvadvpn-9d4b78da2d8312075d93702050f9787eb6998255.tar.xz mullvadvpn-9d4b78da2d8312075d93702050f9787eb6998255.zip | |
Add debug toggle for include all networks and make it false by default
11 files changed, 87 insertions, 15 deletions
diff --git a/ios/MullvadSettings/TunnelSettingsStrategy.swift b/ios/MullvadSettings/TunnelSettingsStrategy.swift index 05db9132a4..6c8ff01955 100644 --- a/ios/MullvadSettings/TunnelSettingsStrategy.swift +++ b/ios/MullvadSettings/TunnelSettingsStrategy.swift @@ -29,7 +29,8 @@ public struct TunnelSettingsStrategy: TunnelSettingsStrategyProtocol, Sendable { oldSettings: LatestTunnelSettings, newSettings: LatestTunnelSettings ) -> TunnelSettingsReconnectionStrategy { - if oldSettings.localNetworkSharing != newSettings.localNetworkSharing { + if oldSettings.localNetworkSharing != newSettings.localNetworkSharing || + oldSettings.includeAllNetworks != newSettings.includeAllNetworks { return .hardReconnect } switch (oldSettings, newSettings) { diff --git a/ios/MullvadSettings/TunnelSettingsUpdate.swift b/ios/MullvadSettings/TunnelSettingsUpdate.swift index 237e914617..987c664a1e 100644 --- a/ios/MullvadSettings/TunnelSettingsUpdate.swift +++ b/ios/MullvadSettings/TunnelSettingsUpdate.swift @@ -11,6 +11,7 @@ import MullvadTypes public enum TunnelSettingsUpdate: Sendable { case localNetworkSharing(Bool) + case includeAllNetworks(Bool) case dnsSettings(DNSSettings) case obfuscation(WireGuardObfuscationSettings) case relayConstraints(RelayConstraints) @@ -24,6 +25,8 @@ extension TunnelSettingsUpdate { switch self { case let .localNetworkSharing(enabled): settings.localNetworkSharing = enabled + case let .includeAllNetworks(enabled): + settings.includeAllNetworks = enabled case let .dnsSettings(newDNSSettings): settings.dnsSettings = newDNSSettings case let .obfuscation(newObfuscationSettings): @@ -42,6 +45,7 @@ extension TunnelSettingsUpdate { public var subjectName: String { switch self { case .localNetworkSharing: "Local network sharing" + case .includeAllNetworks: "Include all networks" case .dnsSettings: "DNS settings" case .obfuscation: "obfuscation settings" case .relayConstraints: "relay constraints" diff --git a/ios/MullvadSettings/TunnelSettingsV6.swift b/ios/MullvadSettings/TunnelSettingsV6.swift index 3ec50d5658..89d805b1b2 100644 --- a/ios/MullvadSettings/TunnelSettingsV6.swift +++ b/ios/MullvadSettings/TunnelSettingsV6.swift @@ -52,7 +52,8 @@ public struct TunnelSettingsV6: Codable, Equatable, TunnelSettings, Sendable { tunnelQuantumResistance: tunnelQuantumResistance, tunnelMultihopState: tunnelMultihopState, daita: daita, - localNetworkSharing: false + localNetworkSharing: false, + includeAllNetworks: false ) } } diff --git a/ios/MullvadSettings/TunnelSettingsV7.swift b/ios/MullvadSettings/TunnelSettingsV7.swift index bdd23f707b..d44cbd560c 100644 --- a/ios/MullvadSettings/TunnelSettingsV7.swift +++ b/ios/MullvadSettings/TunnelSettingsV7.swift @@ -27,10 +27,13 @@ public struct TunnelSettingsV7: Codable, Equatable, TunnelSettings, Sendable { /// DAITA settings. public var daita: DAITASettings - + /// Local networks sharing. public var localNetworkSharing: Bool + /// Forces the system to route most traffic through the tunnel + public var includeAllNetworks: Bool + public init( relayConstraints: RelayConstraints = RelayConstraints(), dnsSettings: DNSSettings = DNSSettings(), @@ -38,7 +41,8 @@ public struct TunnelSettingsV7: Codable, Equatable, TunnelSettings, Sendable { tunnelQuantumResistance: TunnelQuantumResistance = .automatic, tunnelMultihopState: MultihopState = .off, daita: DAITASettings = DAITASettings(), - localNetworkSharing: Bool = false + localNetworkSharing: Bool = false, + includeAllNetworks: Bool = false ) { self.relayConstraints = relayConstraints self.dnsSettings = dnsSettings @@ -47,6 +51,7 @@ public struct TunnelSettingsV7: Codable, Equatable, TunnelSettings, Sendable { self.tunnelMultihopState = tunnelMultihopState self.daita = daita self.localNetworkSharing = localNetworkSharing + self.includeAllNetworks = includeAllNetworks } public func upgradeToNextVersion() -> any TunnelSettings { diff --git a/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift b/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift index b93a406a84..820c2cabdb 100644 --- a/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift +++ b/ios/MullvadVPN/Classes/AccessbilityIdentifier.swift @@ -176,6 +176,7 @@ public enum AccessibilityIdentifier: Equatable { case statusImageView // DNS settings + case includeAllNetworks case localNetworkSharing case dnsSettings case ipOverrides diff --git a/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift b/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift index d3c88eb0a3..a301a459ce 100644 --- a/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift +++ b/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift @@ -107,7 +107,10 @@ class StartTunnelOperation: ResultOperation<Void>, @unchecked Sendable { ) { let persistentTunnels = interactor.getPersistentTunnels() let tunnel = persistentTunnels.first ?? interactor.createNewTunnel() - let configuration = TunnelConfiguration(excludeLocalNetworks: interactor.settings.localNetworkSharing) + let configuration = TunnelConfiguration( + includeAllNetworks: interactor.settings.includeAllNetworks, + excludeLocalNetworks: interactor.settings.localNetworkSharing + ) tunnel.setConfiguration(configuration) tunnel.saveToPreferences { error in diff --git a/ios/MullvadVPN/TunnelManager/TunnelConfiguration.swift b/ios/MullvadVPN/TunnelManager/TunnelConfiguration.swift index 274e9439be..ba36c4dcf0 100644 --- a/ios/MullvadVPN/TunnelManager/TunnelConfiguration.swift +++ b/ios/MullvadVPN/TunnelManager/TunnelConfiguration.swift @@ -16,11 +16,13 @@ struct TunnelConfiguration { var onDemandRules: [NEOnDemandRule] var isOnDemandEnabled: Bool - init(excludeLocalNetworks: Bool, isOnDemandEnabled: Bool = true) { + init(includeAllNetworks: Bool, excludeLocalNetworks: Bool, isOnDemandEnabled: Bool = true) { let protocolConfig = NETunnelProviderProtocol() protocolConfig.providerBundleIdentifier = ApplicationTarget.packetTunnel.bundleIdentifier protocolConfig.serverAddress = "" - protocolConfig.includeAllNetworks = true + #if DEBUG + protocolConfig.includeAllNetworks = includeAllNetworks + #endif protocolConfig.excludeLocalNetworks = excludeLocalNetworks let alwaysOnRule = NEOnDemandRuleConnect() diff --git a/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsCellFactory.swift b/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsCellFactory.swift index faed3382ac..f86242b756 100644 --- a/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsCellFactory.swift +++ b/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsCellFactory.swift @@ -16,7 +16,8 @@ protocol VPNSettingsCellEventHandler { func selectCustomPortEntry(_ port: UInt16) -> Bool func selectObfuscationState(_ state: WireGuardObfuscationState) func switchMultihop(_ state: MultihopState) - func setLocalNetworkSettings(_ enabled: Bool, onCancel: @escaping () -> Void) + func setLocalNetworkSharing(_ enabled: Bool, onCancel: @escaping () -> Void) + func setIncludeAllNetworks(_ enabled: Bool, onCancel: @escaping () -> Void) } @MainActor @@ -42,11 +43,27 @@ final class VPNSettingsCellFactory: @preconcurrency CellFactoryProtocol { func configureCell(_ cell: UITableViewCell, item: VPNSettingsDataSource.Item, indexPath: IndexPath) { (cell as? SettingsCell)?.detailTitleLabel.accessibilityIdentifier = nil switch item { + case .includeAllNetworks: + guard let cell = cell as? SettingsSwitchCell else { return } + cell.action = { enable in + self.delegate?.setIncludeAllNetworks(enable) { + cell.setOn(self.viewModel.includeAllNetworks, animated: true) + } + } + + cell.titleLabel.text = NSLocalizedString( + "LOCAL_NETWORK_SHARING_CELL_LABEL", + tableName: "VPNSettings", + value: "Include all networks", + comment: "" + ) + cell.setAccessibilityIdentifier(item.accessibilityIdentifier) + cell.setOn(viewModel.includeAllNetworks, animated: true) case .localNetworkSharing: guard let cell = cell as? SettingsSwitchCell else { return } cell.infoButtonHandler = { self.delegate?.showInfo(for: .localNetworkSharing) } cell.action = { enable in - self.delegate?.setLocalNetworkSettings(enable) { + self.delegate?.setLocalNetworkSharing(enable) { cell.setOn(self.viewModel.localNetworkSharing, animated: true) } } @@ -59,6 +76,7 @@ final class VPNSettingsCellFactory: @preconcurrency CellFactoryProtocol { ) cell.setAccessibilityIdentifier(item.accessibilityIdentifier) cell.setOn(viewModel.localNetworkSharing, animated: true) + cell.setSwitchEnabled(viewModel.includeAllNetworks) case .dnsSettings: guard let cell = cell as? SettingsCell else { return } diff --git a/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsDataSource.swift b/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsDataSource.swift index 50b7aeb558..98e443e3a0 100644 --- a/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsDataSource.swift +++ b/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsDataSource.swift @@ -25,6 +25,7 @@ final class VPNSettingsDataSource: UITableViewDiffableDataSource< case wireGuardObfuscationOption case wireGuardObfuscationPort case quantumResistance + case includeAllNetworks var reusableViewClass: AnyClass { switch self { @@ -46,6 +47,8 @@ final class VPNSettingsDataSource: UITableViewDiffableDataSource< return SelectableSettingsCell.self case .quantumResistance: return SelectableSettingsCell.self + case .includeAllNetworks: + return SettingsSwitchCell.self } } } @@ -59,7 +62,9 @@ final class VPNSettingsDataSource: UITableViewDiffableDataSource< } enum Section: String, Hashable, CaseIterable { + #if DEBUG case localNetworkSharing + #endif case dnsSettings case ipOverrides case wireGuardPorts @@ -69,6 +74,7 @@ final class VPNSettingsDataSource: UITableViewDiffableDataSource< } enum Item: Hashable { + case includeAllNetworks(_ enabled: Bool) case localNetworkSharing(_ enabled: Bool) case dnsSettings case ipOverrides @@ -113,6 +119,8 @@ final class VPNSettingsDataSource: UITableViewDiffableDataSource< var accessibilityIdentifier: AccessibilityIdentifier { switch self { + case .includeAllNetworks: + return .includeAllNetworks case .localNetworkSharing: return .localNetworkSharing case .dnsSettings: @@ -144,6 +152,8 @@ final class VPNSettingsDataSource: UITableViewDiffableDataSource< var reuseIdentifier: CellReuseIdentifiers { switch self { + case .includeAllNetworks: + return .includeAllNetworks case .localNetworkSharing: return .localNetworkSharing case .dnsSettings: @@ -371,7 +381,6 @@ final class VPNSettingsDataSource: UITableViewDiffableDataSource< case .quantumResistance: configureQuantumResistanceHeader(view) return view - default: return nil } @@ -387,8 +396,11 @@ final class VPNSettingsDataSource: UITableViewDiffableDataSource< let sectionIdentifier = snapshot().sectionIdentifiers[section] switch sectionIdentifier { - case .dnsSettings, .ipOverrides, .privacyAndSecurity, .localNetworkSharing: + case .dnsSettings, .ipOverrides, .privacyAndSecurity: return .leastNonzeroMagnitude + #if DEBUG + case .localNetworkSharing: return .leastNonzeroMagnitude + #endif default: return tableView.estimatedRowHeight } @@ -400,7 +412,10 @@ final class VPNSettingsDataSource: UITableViewDiffableDataSource< return switch sectionIdentifier { // 0 due to there already being a separator between .dnsSettings and .ipOverrides. case .dnsSettings: 0 - case .ipOverrides, .quantumResistance, .localNetworkSharing: UITableView.automaticDimension + case .ipOverrides, .quantumResistance: UITableView.automaticDimension + #if DEBUG + case .localNetworkSharing: UITableView.automaticDimension + #endif default: 0.5 } } @@ -454,7 +469,17 @@ final class VPNSettingsDataSource: UITableViewDiffableDataSource< snapshot.appendSections(Section.allCases) snapshot.appendItems([.dnsSettings], toSection: .dnsSettings) snapshot.appendItems([.ipOverrides], toSection: .ipOverrides) - snapshot.appendItems([.localNetworkSharing(viewModel.localNetworkSharing)], toSection: .localNetworkSharing) + #if DEBUG + snapshot.appendItems( + [.localNetworkSharing(viewModel.localNetworkSharing)], + toSection: .localNetworkSharing + ) + snapshot + .appendItems( + [.includeAllNetworks(viewModel.includeAllNetworks)], + toSection: .localNetworkSharing + ) + #endif applySnapshot(snapshot, animated: animated, completion: completion) } @@ -611,7 +636,12 @@ final class VPNSettingsDataSource: UITableViewDiffableDataSource< } extension VPNSettingsDataSource: @preconcurrency VPNSettingsCellEventHandler { - func setLocalNetworkSettings(_ enabled: Bool, onCancel: @escaping () -> Void) { + func setIncludeAllNetworks(_ enabled: Bool, onCancel: @escaping () -> Void) { + self.viewModel.setIncludeAllNetworks(enabled) + self.delegate?.didUpdateTunnelSettings(.includeAllNetworks(enabled)) + } + + func setLocalNetworkSharing(_ enabled: Bool, onCancel: @escaping () -> Void) { delegate?.showLocalNetworkSharingWarning(enabled) { accepted in if accepted { self.delegate?.didUpdateTunnelSettings(.localNetworkSharing(enabled)) diff --git a/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsViewController.swift b/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsViewController.swift index 398830365e..46263b99db 100644 --- a/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsViewController.swift +++ b/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsViewController.swift @@ -161,7 +161,8 @@ extension VPNSettingsViewController: @preconcurrency VPNSettingsDataSourceDelega } func showLocalNetworkSharingWarning(_ enable: Bool, completion: @escaping (Bool) -> Void) { - if interactor.tunnelManager.tunnelStatus.state.isSecured && interactor.tunnelManager.tunnelStatus.observedState.connectionState?.isNetworkReachable ?? false { + if interactor.tunnelManager.tunnelStatus.state.isSecured && interactor.tunnelManager.tunnelStatus.observedState + .connectionState?.isNetworkReachable ?? false { let description = NSLocalizedString( "VPN_SETTINGS_LOCAL_NETWORK_SHARING_WARNING", tableName: "LocalNetworkSharing", diff --git a/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsViewModel.swift b/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsViewModel.swift index cf791e0e29..8e731419a4 100644 --- a/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsViewModel.swift +++ b/ios/MullvadVPN/View controllers/VPNSettings/VPNSettingsViewModel.swift @@ -103,6 +103,7 @@ struct VPNSettingsViewModel: Equatable { private(set) var quantumResistance: TunnelQuantumResistance private(set) var multihopState: MultihopState + private(set) var includeAllNetworks: Bool private(set) var localNetworkSharing: Bool static let defaultWireGuardPorts: [UInt16] = [51820, 53] @@ -197,6 +198,10 @@ struct VPNSettingsViewModel: Equatable { multihopState = newState } + mutating func setIncludeAllNetworks(_ newState: Bool) { + includeAllNetworks = newState + } + mutating func setLocalNetworkSharing(_ newState: Bool) { localNetworkSharing = newState } @@ -259,6 +264,7 @@ struct VPNSettingsViewModel: Equatable { quantumResistance = tunnelSettings.tunnelQuantumResistance multihopState = tunnelSettings.tunnelMultihopState + includeAllNetworks = tunnelSettings.includeAllNetworks localNetworkSharing = tunnelSettings.localNetworkSharing } |
