summaryrefslogtreecommitdiffhomepage
path: root/ios/PacketTunnelCore/Actor/Protocols/SettingsReaderProtocol.swift
blob: 49f501ee9046b2672edf58fa86bcb58c666076e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//
//  SettingsReaderProtocol.swift
//  PacketTunnel
//
//  Created by pronebird on 25/08/2023.
//  Copyright © 2023 Mullvad VPN AB. All rights reserved.
//

import Foundation
import MullvadSettings
import MullvadTypes
import Network
@preconcurrency import WireGuardKitTypes

/// A type that implements a reader that can return settings required by `PacketTunnelActor` in order to configure the tunnel.
public protocol SettingsReaderProtocol {
    /**
     Read settings from storage.

     - Throws: an error thrown by this method is passed down to the implementation of `BlockedStateErrorMapperProtocol`.
     - Returns: `Settings` used to configure packet tunnel adapter.
     */
    func read() throws -> Settings
}

/// Struct holding settings necessary to configure packet tunnel adapter.
public struct Settings: Equatable, Sendable {
    /// Private key used by device.
    public var privateKey: PrivateKey

    /// IP addresses assigned for tunnel interface.
    public var interfaceAddresses: [IPAddressRange]

    public var tunnelSettings: LatestTunnelSettings

    public init(
        privateKey: PrivateKey,
        interfaceAddresses: [IPAddressRange],
        tunnelSettings: LatestTunnelSettings
    ) {
        self.privateKey = privateKey
        self.interfaceAddresses = interfaceAddresses
        self.tunnelSettings = tunnelSettings
    }
}

extension Settings {
    /// Relay constraints.
    public var relayConstraints: RelayConstraints {
        tunnelSettings.relayConstraints
    }

    /// DNS servers selected by user.
    public var dnsServers: SelectedDNSServers {
        /**
         Converts `DNSSettings` to `SelectedDNSServers` structure.
         */
        if tunnelSettings.dnsSettings.effectiveEnableCustomDNS {
            let addresses = Array(
                tunnelSettings.dnsSettings.customDNSDomains
                    .prefix(DNSSettings.maxAllowedCustomDNSDomains)
            )
            return .custom(addresses)
        } else if let serverAddress = tunnelSettings.dnsSettings.blockingOptions.serverAddress {
            return .blocking(serverAddress)
        } else {
            return .gateway
        }
    }

    /// Obfuscation settings
    public var obfuscation: WireGuardObfuscationSettings {
        tunnelSettings.wireGuardObfuscation
    }

    public var quantumResistance: TunnelQuantumResistance {
        tunnelSettings.tunnelQuantumResistance
    }

    /// Whether multi-hop is enabled.
    public var multihopState: MultihopState {
        tunnelSettings.tunnelMultihopState
    }

    /// DAITA settings.
    public var daita: DAITASettings {
        tunnelSettings.daita
    }
}

/// Enum describing selected DNS servers option.
public enum SelectedDNSServers: Equatable, Sendable {
    /// Custom DNS servers.
    case custom([IPAddress])
    /// Mullvad server acting as a blocking DNS proxy.
    case blocking(IPAddress)
    /// Gateway IP will be used as DNS automatically.
    case gateway

    public static func == (lhs: SelectedDNSServers, rhs: SelectedDNSServers) -> Bool {
        return switch (lhs, rhs) {
        case let (.custom(lhsAddresss), .custom(rhsAddresses)):
            lhsAddresss.map { $0.rawValue } == rhsAddresses.map { $0.rawValue }
        case let (.blocking(lhsAddress), .blocking(rhsAddress)):
            lhsAddress.rawValue == rhsAddress.rawValue
        case (.gateway, .gateway):
            true
        default: false
        }
    }
}