Skip to content

Commit 38ae9e9

Browse files
committed
Merge branch 'investigate-why-testcreateaccount-started-failing-on-main-ios-952'
2 parents 9e98f66 + 732397b commit 38ae9e9

File tree

26 files changed

+413
-246
lines changed

26 files changed

+413
-246
lines changed

Cargo.lock

+52-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

android/app/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt

+19-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import java.io.File
55
import kotlinx.coroutines.CoroutineDispatcher
66
import kotlinx.coroutines.Dispatchers
77
import kotlinx.coroutines.withContext
8+
import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointFromIntentHolder
9+
import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointOverride
10+
import net.mullvad.mullvadvpn.service.BuildConfig
811

912
const val PROBLEM_REPORT_LOGS_FILE = "problem_report.txt"
1013

@@ -21,7 +24,12 @@ sealed interface SendProblemReportResult {
2124

2225
data class UserReport(val email: String?, val description: String)
2326

24-
class MullvadProblemReport(context: Context, val dispatcher: CoroutineDispatcher = Dispatchers.IO) {
27+
class MullvadProblemReport(
28+
context: Context,
29+
private val apiEndpointOverride: ApiEndpointOverride?,
30+
private val apiEndpointFromIntentHolder: ApiEndpointFromIntentHolder,
31+
val dispatcher: CoroutineDispatcher = Dispatchers.IO,
32+
) {
2533

2634
private val cacheDirectory = File(context.cacheDir.toURI())
2735
private val logDirectory = File(context.filesDir.toURI())
@@ -47,11 +55,20 @@ class MullvadProblemReport(context: Context, val dispatcher: CoroutineDispatcher
4755

4856
val sentSuccessfully =
4957
withContext(dispatcher) {
58+
val intentApiOverride = apiEndpointFromIntentHolder.apiEndpointOverride
59+
val apiOverride =
60+
if (BuildConfig.DEBUG && intentApiOverride != null) {
61+
intentApiOverride
62+
} else {
63+
apiEndpointOverride
64+
}
65+
5066
sendProblemReport(
5167
userReport.email ?: "",
5268
userReport.description,
5369
logsPath.absolutePath,
5470
cacheDirectory.absolutePath,
71+
apiOverride,
5572
)
5673
}
5774

@@ -89,5 +106,6 @@ class MullvadProblemReport(context: Context, val dispatcher: CoroutineDispatcher
89106
userMessage: String,
90107
reportPath: String,
91108
cacheDirectory: String,
109+
apiEndpointOverride: ApiEndpointOverride?,
92110
): Boolean
93111
}

android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import net.mullvad.mullvadvpn.repository.UserPreferencesMigration
3333
import net.mullvad.mullvadvpn.repository.UserPreferencesRepository
3434
import net.mullvad.mullvadvpn.repository.UserPreferencesSerializer
3535
import net.mullvad.mullvadvpn.repository.WireguardConstraintsRepository
36+
import net.mullvad.mullvadvpn.service.DaemonConfig
3637
import net.mullvad.mullvadvpn.ui.MainActivity
3738
import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoRepository
3839
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
@@ -129,7 +130,7 @@ val uiModule = module {
129130
single { ChangelogRepository(get()) }
130131
single { UserPreferencesRepository(get()) }
131132
single { SettingsRepository(get()) }
132-
single { MullvadProblemReport(get()) }
133+
single { MullvadProblemReport(get(), get<DaemonConfig>().apiEndpointOverride, get()) }
133134
single { RelayOverridesRepository(get()) }
134135
single { CustomListsRepository(get()) }
135136
single { RelayListRepository(get(), get()) }

android/lib/endpoint/src/main/kotlin/net/mullvad/mullvadvpn/lib/endpoint/ApiEndpointOverride.kt

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import kotlinx.parcelize.Parcelize
77
data class ApiEndpointOverride(
88
val hostname: String,
99
val port: Int = CUSTOM_ENDPOINT_HTTPS_PORT,
10-
val disableAddressCache: Boolean = true,
1110
val disableTls: Boolean = false,
1211
val forceDirectConnection: Boolean = true,
1312
) : Parcelable {

android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiTest.kt

+1-6
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,6 @@ abstract class MockApiTest {
5555
}
5656

5757
private fun createEndpoint(port: Int): ApiEndpointOverride {
58-
return ApiEndpointOverride(
59-
InetAddress.getLocalHost().hostName,
60-
port,
61-
disableAddressCache = true,
62-
disableTls = true,
63-
)
58+
return ApiEndpointOverride(InetAddress.getLocalHost().hostName, port, disableTls = true)
6459
}
6560
}

ios/MullvadVPNUITests/MullvadApi.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ class MullvadApi {
5656
let result = mullvad_api_client_initialize(
5757
&clientContext,
5858
apiAddress,
59-
hostname
59+
hostname,
60+
false
6061
)
6162
try ApiError(result).throwIfErr()
6263
}

mullvad-api/Cargo.toml

+2-3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ tokio = { workspace = true, features = ["macros", "time", "rt-multi-thread", "ne
3333
tokio-rustls = { version = "0.26.0", features = ["logging", "tls12", "ring"], default-features = false}
3434
tokio-socks = "0.5.1"
3535
rustls-pemfile = "2.1.3"
36+
uuid = { version = "1.4.1", features = ["v4"] }
3637

3738
mullvad-encrypted-dns-proxy = { path = "../mullvad-encrypted-dns-proxy" }
3839
mullvad-fs = { path = "../mullvad-fs" }
@@ -45,13 +46,11 @@ shadowsocks = { workspace = true, features = [ "stream-cipher" ] }
4546
[dev-dependencies]
4647
talpid-time = { path = "../talpid-time", features = ["test"] }
4748
tokio = { workspace = true, features = ["test-util", "time"] }
49+
mockito = "1.6.1"
4850

4951
[build-dependencies]
5052
cbindgen = { version = "0.24.3", default-features = false }
5153

52-
[target.'cfg(target_os = "ios")'.dependencies]
53-
uuid = { version = "1.4.1", features = ["v4"] }
54-
5554
[lib]
5655
crate-type = [ "rlib", "staticlib" ]
5756
bench = false

mullvad-api/include/mullvad-api.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,16 @@ typedef struct MullvadApiDevice {
4949
* struct.
5050
*
5151
* * `api_address`: pointer to nul-terminated UTF-8 string containing a socket address
52-
* representation
53-
* ("143.32.4.32:9090"), the port is mandatory.
52+
* representation ("143.32.4.32:9090"), the port is mandatory.
5453
*
5554
* * `hostname`: pointer to a null-terminated UTF-8 string representing the hostname that will be
5655
* used for TLS validation.
56+
* * `disable_tls`: only valid when built for tests, can be ignored when consumed by Swift.
5757
*/
5858
struct MullvadApiError mullvad_api_client_initialize(struct MullvadApiClient *client_ptr,
5959
const char *api_address_ptr,
60-
const char *hostname);
60+
const char *hostname,
61+
bool disable_tls);
6162

6263
/**
6364
* Removes all devices from a given account
@@ -98,8 +99,8 @@ struct MullvadApiError mullvad_api_get_expiry(struct MullvadApiClient client_ptr
9899
* * `account_str_ptr`: pointer to nul-terminated UTF-8 string containing the account number of the
99100
* account that will have all of it's devices removed.
100101
*
101-
* * `device_iter_ptr`: a pointer to a `device::MullvadApiDeviceIterator`. If this function
102-
* doesn't return an error, the pointer will be initialized with a valid instance of
102+
* * `device_iter_ptr`: a pointer to a `device::MullvadApiDeviceIterator`. If this function doesn't
103+
* return an error, the pointer will be initialized with a valid instance of
103104
* `device::MullvadApiDeviceIterator`, which can be used to iterate through the devices.
104105
*/
105106
struct MullvadApiError mullvad_api_list_devices(struct MullvadApiClient client_ptr,

mullvad-api/src/address_cache.rs

+14-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! This module keeps track of the last known good API IP address and reads and stores it on disk.
22
3-
use super::API;
4-
use crate::DnsResolver;
3+
use crate::{ApiEndpoint, DnsResolver};
54
use async_trait::async_trait;
65
use std::{io, net::SocketAddr, path::Path, sync::Arc};
76
use tokio::{
@@ -38,42 +37,42 @@ impl DnsResolver for AddressCache {
3837

3938
#[derive(Clone)]
4039
pub struct AddressCache {
40+
hostname: String,
4141
inner: Arc<Mutex<AddressCacheInner>>,
4242
write_path: Option<Arc<Path>>,
4343
}
4444

4545
impl AddressCache {
4646
/// Initialize cache using the hardcoded address, and write changes to `write_path`.
47-
pub fn new(write_path: Option<Box<Path>>) -> Self {
48-
Self::new_inner(API.address(), write_path)
49-
}
50-
51-
pub fn with_static_addr(address: SocketAddr) -> Self {
52-
Self::new_inner(address, None)
47+
pub fn new(endpoint: &ApiEndpoint, write_path: Option<Box<Path>>) -> Self {
48+
Self::new_inner(endpoint.address(), endpoint.host().to_owned(), write_path)
5349
}
5450

5551
/// Initialize cache using `read_path`, and write changes to `write_path`.
56-
pub async fn from_file(read_path: &Path, write_path: Option<Box<Path>>) -> Result<Self, Error> {
52+
pub async fn from_file(
53+
read_path: &Path,
54+
write_path: Option<Box<Path>>,
55+
hostname: String,
56+
) -> Result<Self, Error> {
5757
log::debug!("Loading API addresses from {}", read_path.display());
58-
Ok(Self::new_inner(
59-
read_address_file(read_path).await?,
60-
write_path,
61-
))
58+
let address = read_address_file(read_path).await?;
59+
Ok(Self::new_inner(address, hostname, write_path))
6260
}
6361

64-
fn new_inner(address: SocketAddr, write_path: Option<Box<Path>>) -> Self {
62+
fn new_inner(address: SocketAddr, hostname: String, write_path: Option<Box<Path>>) -> Self {
6563
let cache = AddressCacheInner::from_address(address);
6664
log::debug!("Using API address: {}", cache.address);
6765

6866
Self {
6967
inner: Arc::new(Mutex::new(cache)),
7068
write_path: write_path.map(Arc::from),
69+
hostname,
7170
}
7271
}
7372

7473
/// Returns the address if the hostname equals `API.host`. Otherwise, returns `None`.
7574
async fn resolve_hostname(&self, hostname: &str) -> Option<SocketAddr> {
76-
if hostname.eq_ignore_ascii_case(API.host()) {
75+
if hostname.eq_ignore_ascii_case(&self.hostname) {
7776
Some(self.get_address().await)
7877
} else {
7978
None

mullvad-api/src/bin/relay_list.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22
//! Used by the installer artifact packer to bundle the latest available
33
//! relay list at the time of creating the installer.
44
5-
use mullvad_api::{proxy::ApiConnectionMode, rest::Error as RestError, RelayListProxy};
5+
use mullvad_api::{
6+
proxy::ApiConnectionMode, rest::Error as RestError, ApiEndpoint, RelayListProxy,
7+
};
68
use std::process;
79
use talpid_types::ErrorExt;
810

911
#[tokio::main]
1012
async fn main() {
11-
let runtime = mullvad_api::Runtime::new(tokio::runtime::Handle::current())
12-
.expect("Failed to load runtime");
13+
let runtime = mullvad_api::Runtime::new(
14+
tokio::runtime::Handle::current(),
15+
&ApiEndpoint::from_env_vars(),
16+
);
1317

1418
let relay_list_request =
1519
RelayListProxy::new(runtime.mullvad_rest_handle(ApiConnectionMode::Direct.into_provider()))

mullvad-api/src/ffi/error.rs

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub enum MullvadApiErrorKind {
1313

1414
/// MullvadApiErrorKind contains a description and an error kind. If the error kind is
1515
/// `MullvadApiErrorKind` is NoError, the pointer will be nil.
16+
#[derive(Debug)]
1617
#[repr(C)]
1718
pub struct MullvadApiError {
1819
description: *mut libc::c_char,
@@ -47,6 +48,13 @@ impl MullvadApiError {
4748
}
4849
}
4950

51+
pub fn unwrap(&self) {
52+
if !matches!(self.kind, MullvadApiErrorKind::NoError) {
53+
let desc = unsafe { std::ffi::CStr::from_ptr(self.description) };
54+
panic!("API ERROR - {:?} - {}", self.kind, desc.to_str().unwrap());
55+
}
56+
}
57+
5058
pub fn drop(self) {
5159
if self.description.is_null() {
5260
return;

0 commit comments

Comments
 (0)