summaryrefslogtreecommitdiffhomepage
path: root/ios/MullvadRustRuntime
diff options
context:
space:
mode:
authorBug Magnet <marco.nikic@mullvad.net>2025-05-16 13:35:30 +0200
committerBug Magnet <marco.nikic@mullvad.net>2025-05-23 09:23:28 +0200
commit8e997549c3af645992e80f6356d71425b4a784d6 (patch)
tree854bc8db0b04d649922cfb3c559b362acb57d6d5 /ios/MullvadRustRuntime
parenta9d8ce8abf4073f72fb94fb6a05fb6c1b43069c3 (diff)
downloadmullvadvpn-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.swift31
-rw-r--r--ios/MullvadRustRuntime/MullvadApiContext.swift15
-rw-r--r--ios/MullvadRustRuntime/include/mullvad_rust_runtime.h36
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