summaryrefslogtreecommitdiffhomepage
path: root/ios/MullvadRustRuntime/MullvadApiContext.swift
blob: f938968b974561e718378e7514d9b5cc031488fc (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
//
//  MullvadApiContext.swift
//  MullvadVPN
//
//  Created by Jon Petersson on 2025-01-24.
//  Copyright © 2025 Mullvad VPN AB. All rights reserved.
//

import MullvadTypes

func onAccessChangeCallback(selfPtr: UnsafeRawPointer?, bytes: UnsafePointer<UInt8>?) {
    guard let selfPtr, let bytes else { return }
    let context = Unmanaged<MullvadApiContext>.fromOpaque(selfPtr).takeUnretainedValue()

    let uuid = NSUUID(uuidBytes: bytes) as UUID
    context.accessMethodChangeListeners.forEach { $0.accessMethodChangedTo(uuid) }
}

public class MullvadApiContext: @unchecked Sendable {
    enum Error: Swift.Error {
        case failedToConstructApiClient
    }

    public private(set) var context: SwiftApiContext!
    private let shadowsocksBridgeProvider: SwiftShadowsocksBridgeProviding!
    private let shadowsocksBridgeProviderWrapper: SwiftShadowsocksLoaderWrapper!
    private let addressCacheWrapper: SwiftAddressCacheWrapper!
    private let addressCacheProvider: AddressCacheProviding!
    public let accessMethodChangeListeners: [MullvadAccessMethodChangeListening]

    public init(
        host: String,
        address: String,
        domain: String,
        disableTls: Bool = false,
        shadowsocksProvider: SwiftShadowsocksBridgeProviding,
        accessMethodWrapper: SwiftAccessMethodSettingsWrapper,
        addressCacheProvider: AddressCacheProviding,
        accessMethodChangeListeners: [MullvadAccessMethodChangeListening]
    ) throws {
        let bridgeProvider = SwiftShadowsocksBridgeProvider(provider: shadowsocksProvider)
        self.shadowsocksBridgeProvider = bridgeProvider
        self.shadowsocksBridgeProviderWrapper = initMullvadShadowsocksBridgeProvider(provider: bridgeProvider)

        let defaultAddressCache = DefaultAddressCacheProvider(provider: addressCacheProvider)
        self.addressCacheProvider = defaultAddressCache
        self.addressCacheWrapper = iniSwiftAddressCacheWrapper(provider: defaultAddressCache)
        self.accessMethodChangeListeners = accessMethodChangeListeners

        let selfPtr = Unmanaged.passUnretained(self).toOpaque()
        context =
            switch disableTls {
            case true:
                mullvad_api_init_new_tls_disabled(
                    host,
                    address,
                    domain,
                    shadowsocksBridgeProviderWrapper,
                    accessMethodWrapper,
                    addressCacheWrapper,
                    onAccessChangeCallback,
                    selfPtr
                )
            case false:
                mullvad_api_init_new(
                    host,
                    address,
                    domain,
                    shadowsocksBridgeProviderWrapper,
                    accessMethodWrapper,
                    addressCacheWrapper,
                    onAccessChangeCallback,
                    selfPtr
                )
            }

        if context._0 == nil {
            throw Error.failedToConstructApiClient
        }
    }
}

extension SwiftApiContext: @unchecked @retroactive Sendable {}