diff options
| author | Bug Magnet <marco.nikic@mullvad.net> | 2025-05-16 13:35:30 +0200 |
|---|---|---|
| committer | Bug Magnet <marco.nikic@mullvad.net> | 2025-05-23 09:23:28 +0200 |
| commit | 8e997549c3af645992e80f6356d71425b4a784d6 (patch) | |
| tree | 854bc8db0b04d649922cfb3c559b362acb57d6d5 /ios/MullvadRustRuntime | |
| parent | a9d8ce8abf4073f72fb94fb6a05fb6c1b43069c3 (diff) | |
| download | mullvadvpn-8e997549c3af645992e80f6356d71425b4a784d6.tar.xz mullvadvpn-8e997549c3af645992e80f6356d71425b4a784d6.zip | |
Fix API breaking down when used without connectivity
Diffstat (limited to 'ios/MullvadRustRuntime')
| -rw-r--r-- | ios/MullvadRustRuntime/MullvadAddressCacheProvider.swift | 31 | ||||
| -rw-r--r-- | ios/MullvadRustRuntime/MullvadApiContext.swift | 15 | ||||
| -rw-r--r-- | ios/MullvadRustRuntime/include/mullvad_rust_runtime.h | 36 |
3 files changed, 76 insertions, 6 deletions
diff --git a/ios/MullvadRustRuntime/MullvadAddressCacheProvider.swift b/ios/MullvadRustRuntime/MullvadAddressCacheProvider.swift new file mode 100644 index 0000000000..4c731eaf3a --- /dev/null +++ b/ios/MullvadRustRuntime/MullvadAddressCacheProvider.swift @@ -0,0 +1,31 @@ +// +// MullvadAddressCacheProvider.swift +// MullvadRustRuntime +// +// Created by Marco Nikic on 2025-05-15. +// Copyright © 2025 Mullvad VPN AB. All rights reserved. +// + +import Foundation +import MullvadTypes + +public func iniSwiftAddressCacheWrapper(provider: DefaultAddressCacheProvider) -> SwiftAddressCacheWrapper { + let rawProvider = Unmanaged.passUnretained(provider).toOpaque() + return init_swift_address_cache_wrapper(rawProvider) +} + +@_cdecl("swift_get_cached_endpoint") +func getCacheEndpoint(rawAddressCacheProvider: UnsafeMutableRawPointer) -> UnsafePointer<CChar>! { + let addressCacheProvider = Unmanaged<DefaultAddressCacheProvider>.fromOpaque(rawAddressCacheProvider) + .takeUnretainedValue() + let cStr = addressCacheProvider.getCurrentEndpoint().description.toCStringPointer() + /** + `cStr` needs to shortly outlive the return of this function in order to get transformed into a `SocketAddr` + This is the simplest way to guarantee that the pointer returned does not get deallocated immediately + Or that no memory is leaked every time this function gets called + **/ + DispatchQueue(label: "com.MullvadRustRuntime.DecallocateQueue").async { + cStr?.deallocate() + } + return cStr +} diff --git a/ios/MullvadRustRuntime/MullvadApiContext.swift b/ios/MullvadRustRuntime/MullvadApiContext.swift index 5517348cc1..bd89ab891f 100644 --- a/ios/MullvadRustRuntime/MullvadApiContext.swift +++ b/ios/MullvadRustRuntime/MullvadApiContext.swift @@ -16,6 +16,8 @@ public struct MullvadApiContext: @unchecked Sendable { public let context: SwiftApiContext private let shadowsocksBridgeProvider: SwiftShadowsocksBridgeProviding! private let shadowsocksBridgeProviderWrapper: SwiftShadowsocksLoaderWrapper! + private let addressCacheWrapper: SwiftAddressCacheWrapper! + private let addressCacheProvider: AddressCacheProviding! public init( host: String, @@ -23,12 +25,17 @@ public struct MullvadApiContext: @unchecked Sendable { domain: String, disableTls: Bool = false, shadowsocksProvider: SwiftShadowsocksBridgeProviding, - accessMethodWrapper: SwiftAccessMethodSettingsWrapper + accessMethodWrapper: SwiftAccessMethodSettingsWrapper, + addressCacheProvider: AddressCacheProviding ) 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) + context = switch disableTls { case true: mullvad_api_init_new_tls_disabled( @@ -36,7 +43,8 @@ public struct MullvadApiContext: @unchecked Sendable { address, domain, shadowsocksBridgeProviderWrapper, - accessMethodWrapper + accessMethodWrapper, + addressCacheWrapper ) case false: mullvad_api_init_new( @@ -44,7 +52,8 @@ public struct MullvadApiContext: @unchecked Sendable { address, domain, shadowsocksBridgeProviderWrapper, - accessMethodWrapper + accessMethodWrapper, + addressCacheWrapper ) } diff --git a/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h b/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h index accd302d53..70c1428098 100644 --- a/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h +++ b/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h @@ -61,6 +61,14 @@ typedef struct SwiftShadowsocksLoaderWrapper { struct SwiftShadowsocksLoaderWrapperContext _0; } SwiftShadowsocksLoaderWrapper; +typedef struct SwiftAddressCacheProviderContext { + const void *address_cache; +} SwiftAddressCacheProviderContext; + +typedef struct SwiftAddressCacheWrapper { + struct SwiftAddressCacheProviderContext _0; +} SwiftAddressCacheWrapper; + typedef struct SwiftCancelHandle { struct RequestCancelHandle *ptr; } SwiftCancelHandle; @@ -161,7 +169,8 @@ struct SwiftApiContext mullvad_api_init_new_tls_disabled(const char *host, const char *address, const char *domain, struct SwiftShadowsocksLoaderWrapper bridge_provider, - struct SwiftAccessMethodSettingsWrapper settings_provider); + struct SwiftAccessMethodSettingsWrapper settings_provider, + struct SwiftAddressCacheWrapper address_cache); /** * # Safety @@ -181,7 +190,8 @@ struct SwiftApiContext mullvad_api_init_new(const char *host, const char *address, const char *domain, struct SwiftShadowsocksLoaderWrapper bridge_provider, - struct SwiftAccessMethodSettingsWrapper settings_provider); + struct SwiftAccessMethodSettingsWrapper settings_provider, + struct SwiftAddressCacheWrapper address_cache); /** * # Safety @@ -202,7 +212,8 @@ struct SwiftApiContext mullvad_api_init_inner(const char *host, const char *domain, bool disable_tls, struct SwiftShadowsocksLoaderWrapper bridge_provider, - struct SwiftAccessMethodSettingsWrapper settings_provider); + struct SwiftAccessMethodSettingsWrapper settings_provider, + struct SwiftAddressCacheWrapper address_cache); /** * Converts parameters into a `Box<AccessMethodSetting>` raw representation that @@ -299,6 +310,25 @@ struct SwiftCancelHandle mullvad_ios_delete_account(struct SwiftApiContext api_c const char *account_number); /** + * Return the latest available endpoint, or a default one if none are cached + * + * # SAFETY + * `rawAddressCacheProvider` **must** be provided by a call to `init_swift_address_cache_wrapper` + * It is okay to persist it, and use it accross multiple threads. + */ +extern const char *swift_get_cached_endpoint(const void *rawAddressCacheProvider); + +/** + * Called by the Swift side in order to provide an object to rust that provides API addresses in a UTF-8 string form + * + * # SAFETY + * `address_cache` **must be** pointing to a valid instance of a `DefaultAddressCacheProvider` + * That instance's lifetime has to be equivalent to a `'static` lifetime in Rust + * This function does not take ownership of `address_cache` + */ +struct SwiftAddressCacheWrapper init_swift_address_cache_wrapper(const void *address_cache); + +/** * # Safety * * `api_context` must be pointing to a valid instance of `SwiftApiContext`. A `SwiftApiContext` is created |
