Skip to content

Commit

Permalink
Get value of data directory value at app startup
Browse files Browse the repository at this point in the history
Remove `APP_PATH` from `mullvad-paths` on Android since it should
not be a constant value. Instead, it is passed down from the Android app
startup. As it turns out, it is really ever used for pointing to the RPC
socket in use.
  • Loading branch information
MarkusPettersson98 committed Jun 17, 2024
1 parent 9cba0d8 commit 5c16eff
Show file tree
Hide file tree
Showing 23 changed files with 181 additions and 154 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ The settings directory can be changed by setting the `MULLVAD_SETTINGS_DIR` envi
| Linux | `/etc/mullvad-vpn/` |
| macOS | `/etc/mullvad-vpn/` |
| Windows | `%LOCALAPPDATA%\Mullvad VPN\` |
| Android | `/data/data/net.mullvad.mullvadvpn/` |
| Android | [`getFilesDir()`](https://developer.android.com/reference/android/content/Context#getFilesDir()) |

#### Logs

Expand All @@ -343,7 +343,7 @@ The log directory can be changed by setting the `MULLVAD_LOG_DIR` environment va
| Linux | `/var/log/mullvad-vpn/` + systemd |
| macOS | `/var/log/mullvad-vpn/` |
| Windows | `C:\ProgramData\Mullvad VPN\` |
| Android | `/data/data/net.mullvad.mullvadvpn/` |
| Android | [`getFilesDir()`](https://developer.android.com/reference/android/content/Context#getFilesDir()) |

#### Cache

Expand All @@ -354,7 +354,7 @@ The cache directory can be changed by setting the `MULLVAD_CACHE_DIR` environmen
| Linux | `/var/cache/mullvad-vpn/` |
| macOS | `/Library/Caches/mullvad-vpn/` |
| Windows | `C:\ProgramData\Mullvad VPN\cache` |
| Android | `/data/data/net.mullvad.mullvadvpn/cache` |
| Android | [`getCacheDir()`](https://developer.android.com/reference/android/content/Context#getCacheDir()) |

#### RPC address file

Expand All @@ -366,7 +366,7 @@ environment variable.
| Linux | `/var/run/mullvad-vpn` |
| macOS | `/var/run/mullvad-vpn` |
| Windows | `//./pipe/Mullvad VPN` |
| Android | `/data/data/net.mullvad.mullvadvpn/rpc-socket` |
| Android | [`getNoBackupFilesDir()`](https://developer.android.com/reference/android/content/ContextWrapper#getNoBackupFilesDir()) |

### GUI

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package net.mullvad.mullvadvpn.di

import java.io.File
import kotlinx.coroutines.MainScope
import net.mullvad.mullvadvpn.BuildConfig
import net.mullvad.mullvadvpn.constant.GRPC_SOCKET_FILE_NAME
import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAME
import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAMED_ARGUMENT
import net.mullvad.mullvadvpn.lib.daemon.grpc.ManagementService
import net.mullvad.mullvadvpn.lib.intent.IntentProvider
import net.mullvad.mullvadvpn.lib.model.BuildVersion
Expand All @@ -15,10 +17,12 @@ import org.koin.core.qualifier.named
import org.koin.dsl.module

val appModule = module {
single(named(RPC_SOCKET_PATH)) { "${androidContext().dataDir.path}/$GRPC_SOCKET_FILE_NAME" }
single(named(GRPC_SOCKET_FILE_NAMED_ARGUMENT)) {
File(androidContext().noBackupFilesDir, GRPC_SOCKET_FILE_NAME)
}
single {
ManagementService(
rpcSocketPath = get(named(RPC_SOCKET_PATH)),
rpcSocketFile = get(named(GRPC_SOCKET_FILE_NAMED_ARGUMENT)),
extensiveLogging = BuildConfig.DEBUG,
scope = MainScope(),
)
Expand All @@ -30,5 +34,3 @@ val appModule = module {
single { VpnPermissionRepository(androidContext()) }
single { ConnectionProxy(get(), get()) }
}

const val RPC_SOCKET_PATH = "RPC_SOCKET"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package net.mullvad.mullvadvpn.lib.common.constant

const val GRPC_SOCKET_FILE_NAMED_ARGUMENT = "RPC_SOCKET"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package net.mullvad.mullvadvpn.lib.common.constant

const val GRPC_SOCKET_FILE_NAME = "rpc-socket"
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import io.grpc.ConnectivityState
import io.grpc.Status
import io.grpc.StatusException
import io.grpc.android.UdsChannelBuilder
import java.io.File
import java.net.InetAddress
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -127,14 +128,19 @@ import net.mullvad.mullvadvpn.lib.model.wireguardConstraints

@Suppress("TooManyFunctions")
class ManagementService(
rpcSocketPath: String,
rpcSocketFile: File,
private val extensiveLogging: Boolean,
private val scope: CoroutineScope,
) {
private var job: Job? = null

// We expect daemon to create the rpc socket file on the path provided on initialisation
private val channel =
UdsChannelBuilder.forPath(rpcSocketPath, LocalSocketAddress.Namespace.FILESYSTEM).build()
UdsChannelBuilder.forPath(
rpcSocketFile.absolutePath,
LocalSocketAddress.Namespace.FILESYSTEM
)
.build()

val connectionState: StateFlow<GrpcConnectivityState> =
channel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ private const val RELAYS_FILE = "relays.json"
@SuppressLint("SdCardPath")
class MullvadDaemon(
vpnService: MullvadVpnService,
rpcSocketFile: File,
apiEndpointConfiguration: ApiEndpointConfiguration,
migrateSplitTunneling: MigrateSplitTunneling
) {
Expand All @@ -34,8 +35,9 @@ class MullvadDaemon(

initialize(
vpnService = vpnService,
rpcSocketPath = rpcSocketFile.absolutePath,
filesDirectory = vpnService.filesDir.absolutePath,
cacheDirectory = vpnService.cacheDir.absolutePath,
resourceDirectory = vpnService.filesDir.absolutePath,
apiEndpoint = apiEndpointConfiguration.apiEndpoint()
)
}
Expand Down Expand Up @@ -69,8 +71,9 @@ class MullvadDaemon(

private external fun initialize(
vpnService: MullvadVpnService,
rpcSocketPath: String,
filesDirectory: String,
cacheDirectory: String,
resourceDirectory: String,
apiEndpoint: ApiEndpoint?
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.util.Log
import androidx.core.content.getSystemService
import androidx.lifecycle.lifecycleScope
import arrow.atomic.AtomicInt
import java.io.File
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
Expand All @@ -17,6 +18,7 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAMED_ARGUMENT
import net.mullvad.mullvadvpn.lib.common.constant.KEY_CONNECT_ACTION
import net.mullvad.mullvadvpn.lib.common.constant.KEY_DISCONNECT_ACTION
import net.mullvad.mullvadvpn.lib.common.constant.TAG
Expand All @@ -36,6 +38,7 @@ import net.mullvad.mullvadvpn.service.notifications.ShouldBeOnForegroundProvider
import net.mullvad.talpid.TalpidVpnService
import org.koin.android.ext.android.getKoin
import org.koin.core.context.loadKoinModules
import org.koin.core.qualifier.named

class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
private val _shouldBeOnForeground = MutableStateFlow(false)
Expand All @@ -49,6 +52,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
private lateinit var migrateSplitTunneling: MigrateSplitTunneling
private lateinit var intentProvider: IntentProvider
private lateinit var connectionProxy: ConnectionProxy
private lateinit var rpcSocketFile: File

private lateinit var foregroundNotificationHandler: ForegroundNotificationManager

Expand All @@ -75,6 +79,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
migrateSplitTunneling = get()
intentProvider = get()
connectionProxy = get()
rpcSocketFile = get(named(GRPC_SOCKET_FILE_NAMED_ARGUMENT))
}

keyguardManager = getSystemService<KeyguardManager>()!!
Expand All @@ -88,6 +93,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
daemonInstance =
MullvadDaemon(
vpnService = this@MullvadVpnService,
rpcSocketFile = rpcSocketFile,
apiEndpointConfiguration =
intentProvider.getLatestIntent()?.getApiEndpointConfigurationExtras()
?: apiEndpointConfiguration,
Expand Down
4 changes: 2 additions & 2 deletions mullvad-daemon/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2894,8 +2894,8 @@ fn oneshot_map<T1: Send + 'static, T2: Send + 'static>(

/// Remove any old RPC socket (if it exists).
#[cfg(not(windows))]
pub async fn cleanup_old_rpc_socket() {
if let Err(err) = tokio::fs::remove_file(mullvad_paths::get_rpc_socket_path()).await {
pub async fn cleanup_old_rpc_socket(rpc_socket_path: impl AsRef<std::path::Path>) {
if let Err(err) = tokio::fs::remove_file(rpc_socket_path).await {
if err.kind() != std::io::ErrorKind::NotFound {
log::error!("Failed to remove old RPC socket: {}", err);
}
Expand Down
19 changes: 14 additions & 5 deletions mullvad-daemon/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ use mullvad_daemon::{
management_interface::{ManagementInterfaceEventBroadcaster, ManagementInterfaceServer},
rpc_uniqueness_check, runtime, version, Daemon, DaemonCommandChannel, DaemonCommandSender,
};
use std::{path::PathBuf, thread, time::Duration};
use std::{
path::{Path, PathBuf},
thread,
time::Duration,
};
use talpid_types::ErrorExt;

mod cli;
Expand Down Expand Up @@ -163,7 +167,7 @@ fn get_log_dir(config: &cli::Config) -> Result<Option<PathBuf>, String> {

async fn run_standalone(log_dir: Option<PathBuf>) -> Result<(), String> {
#[cfg(not(windows))]
cleanup_old_rpc_socket().await;
cleanup_old_rpc_socket(mullvad_paths::get_rpc_socket_path()).await;

if !running_as_admin() {
log::warn!("Running daemon as a non-administrator user, clients might refuse to connect");
Expand Down Expand Up @@ -192,14 +196,15 @@ async fn run_standalone(log_dir: Option<PathBuf>) -> Result<(), String> {
async fn create_daemon(
log_dir: Option<PathBuf>,
) -> Result<Daemon<ManagementInterfaceEventBroadcaster>, String> {
let rpc_socket_path = mullvad_paths::get_rpc_socket_path();
let resource_dir = mullvad_paths::get_resource_dir();
let settings_dir = mullvad_paths::settings_dir()
.map_err(|e| e.display_chain_with_msg("Unable to get settings dir"))?;
let cache_dir = mullvad_paths::cache_dir()
.map_err(|e| e.display_chain_with_msg("Unable to get cache dir"))?;

let command_channel = DaemonCommandChannel::new();
let event_listener = spawn_management_interface(command_channel.sender())?;
let event_listener = spawn_management_interface(command_channel.sender(), rpc_socket_path)?;

Daemon::start(
log_dir,
Expand All @@ -215,13 +220,17 @@ async fn create_daemon(

fn spawn_management_interface(
command_sender: DaemonCommandSender,
rpc_socket_path: impl AsRef<Path>,
) -> Result<ManagementInterfaceEventBroadcaster, String> {
let (socket_path, event_broadcaster) = ManagementInterfaceServer::start(command_sender)
let event_broadcaster = ManagementInterfaceServer::start(command_sender, &rpc_socket_path)
.map_err(|error| {
error.display_chain_with_msg("Unable to start management interface server")
})?;

log::info!("Management interface listening on {}", socket_path);
log::info!(
"Management interface listening on {}",
rpc_socket_path.as_ref().display()
);

Ok(event_broadcaster)
}
Expand Down
29 changes: 14 additions & 15 deletions mullvad-daemon/src/management_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use mullvad_types::{
wireguard::{RotationInterval, RotationIntervalError},
};
use std::{
path::Path,
str::FromStr,
sync::{Arc, Mutex},
time::Duration,
Expand Down Expand Up @@ -1024,21 +1025,22 @@ pub struct ManagementInterfaceServer(());
impl ManagementInterfaceServer {
pub fn start(
tunnel_tx: DaemonCommandSender,
) -> Result<(String, ManagementInterfaceEventBroadcaster), Error> {
rpc_socket_path: impl AsRef<Path>,
) -> Result<ManagementInterfaceEventBroadcaster, Error> {
let subscriptions = Arc::<Mutex<Vec<EventsListenerSender>>>::default();

let socket_path = mullvad_paths::get_rpc_socket_path()
.to_string_lossy()
.to_string();

let (server_abort_tx, server_abort_rx) = mpsc::channel(0);
let server = ManagementServiceImpl {
daemon_tx: tunnel_tx,
subscriptions: subscriptions.clone(),
};
let join_handle = mullvad_management_interface::spawn_rpc_server(server, async move {
server_abort_rx.into_future().await;
})
let join_handle = mullvad_management_interface::spawn_rpc_server(
server,
async move {
server_abort_rx.into_future().await;
},
rpc_socket_path,
)
.map_err(Error::SetupError)?;

tokio::spawn(async move {
Expand All @@ -1048,13 +1050,10 @@ impl ManagementInterfaceServer {
log::info!("Management interface shut down");
});

Ok((
socket_path,
ManagementInterfaceEventBroadcaster {
subscriptions,
_close_handle: server_abort_tx,
},
))
Ok(ManagementInterfaceEventBroadcaster {
subscriptions,
_close_handle: server_abort_tx,
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion mullvad-jni/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ log-panics = "2"
nix = "0.23"
rand = "0.8.5"

mullvad-api = { path = "../mullvad-api" }
mullvad-daemon = { path = "../mullvad-daemon" }
mullvad-problem-report = { path = "../mullvad-problem-report" }
mullvad-types = { path = "../mullvad-types" }
mullvad-api = { path = "../mullvad-api" }
talpid-tunnel = { path = "../talpid-tunnel" }
talpid-types = { path = "../talpid-types" }
Loading

0 comments on commit 5c16eff

Please sign in to comment.