diff options
| author | Cubxity <contact@cubxity.dev> | 2022-10-19 18:27:58 +0200 |
|---|---|---|
| committer | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2023-05-09 16:18:13 +0200 |
| commit | 411fbd4a5470e95ca0048d5ac959350190c199e8 (patch) | |
| tree | f0765756110779cc78aa4370c02ed644b57966cc | |
| parent | a3299ad74fcd58f9c4b435ea57cf2c7350f1dd9f (diff) | |
| download | mullvadvpn-411fbd4a5470e95ca0048d5ac959350190c199e8.tar.xz mullvadvpn-411fbd4a5470e95ca0048d5ac959350190c199e8.zip | |
Propagate udp2tcp settings between app and daemon
Co-authored-by: Albin <albin@mullvad.net>
Co-authored-by: David Lönnhager <david.l@mullvad.net>
Co-authored-by: Odd Stranne <odd@mullvad.net>
16 files changed, 160 insertions, 8 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt index 56900e4440..189dc27087 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt @@ -6,6 +6,7 @@ import java.net.InetAddress import kotlinx.parcelize.Parcelize import net.mullvad.mullvadvpn.model.DnsOptions import net.mullvad.mullvadvpn.model.LocationConstraint +import net.mullvad.mullvadvpn.model.ObfuscationSettings // Requests that the service can handle sealed class Request : Message.RequestMessage() { @@ -82,6 +83,8 @@ sealed class Request : Message.RequestMessage() { @Parcelize data class SetDnsOptions(val dnsOptions: DnsOptions) : Request() + @Parcelize data class SetObfuscationSettings(val settings: ObfuscationSettings) : Request() + companion object { private const val MESSAGE_KEY = "request" diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ObfuscationSettings.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ObfuscationSettings.kt new file mode 100644 index 0000000000..19b5c0e5f2 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ObfuscationSettings.kt @@ -0,0 +1,10 @@ +package net.mullvad.mullvadvpn.model + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class ObfuscationSettings( + val selectedObfuscation: SelectedObfuscation, + val udp2tcp: Udp2TcpObfuscationSettings +) : Parcelable diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/SelectedObfuscation.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/SelectedObfuscation.kt new file mode 100644 index 0000000000..8124bcc6a6 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/SelectedObfuscation.kt @@ -0,0 +1,11 @@ +package net.mullvad.mullvadvpn.model + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +enum class SelectedObfuscation : Parcelable { + Auto, + Off, + Udp2Tcp +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt index 2fcae9f4ea..0d45b38179 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Settings.kt @@ -6,6 +6,7 @@ import kotlinx.parcelize.Parcelize @Parcelize data class Settings( val relaySettings: RelaySettings, + val obfuscationSettings: ObfuscationSettings, val allowLan: Boolean, val autoConnect: Boolean, val tunnelOptions: TunnelOptions, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Udp2TcpObfuscationSettings.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Udp2TcpObfuscationSettings.kt new file mode 100644 index 0000000000..49f466a147 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Udp2TcpObfuscationSettings.kt @@ -0,0 +1,9 @@ +package net.mullvad.mullvadvpn.model + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class Udp2TcpObfuscationSettings( + val port: Constraint<Int> +) : Parcelable diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt index 6d82ee617c..86291f8c30 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt @@ -13,6 +13,7 @@ import net.mullvad.mullvadvpn.model.DnsOptions import net.mullvad.mullvadvpn.model.GeoIpLocation import net.mullvad.mullvadvpn.model.GetAccountDataResult import net.mullvad.mullvadvpn.model.LoginResult +import net.mullvad.mullvadvpn.model.ObfuscationSettings import net.mullvad.mullvadvpn.model.RelayList import net.mullvad.mullvadvpn.model.RelaySettingsUpdate import net.mullvad.mullvadvpn.model.RemoveDeviceEvent @@ -173,6 +174,10 @@ class MullvadDaemon( updateRelaySettings(daemonInterfaceAddress, update) } + fun setObfuscationSettings(settings: ObfuscationSettings) { + setObfuscationSettings(daemonInterfaceAddress, settings) + } + fun onDestroy() { onSettingsChange.unsubscribeAll() onTunnelStateChange.unsubscribeAll() @@ -245,6 +250,11 @@ class MullvadDaemon( update: RelaySettingsUpdate ) + private external fun setObfuscationSettings( + daemonInterfaceAddress: Long, + settings: ObfuscationSettings + ) + private fun notifyAppVersionInfoEvent(appVersionInfo: AppVersionInfo) { onAppVersionInfoChange?.invoke(appVersionInfo) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt index 772e3127b9..2e688cda56 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt @@ -8,9 +8,7 @@ import kotlinx.coroutines.channels.actor import kotlinx.coroutines.channels.trySendBlocking import net.mullvad.mullvadvpn.ipc.Event import net.mullvad.mullvadvpn.ipc.Request -import net.mullvad.mullvadvpn.model.DnsOptions -import net.mullvad.mullvadvpn.model.RelaySettings -import net.mullvad.mullvadvpn.model.Settings +import net.mullvad.mullvadvpn.model.* import net.mullvad.mullvadvpn.service.MullvadDaemon import net.mullvad.talpid.util.EventNotifier @@ -19,6 +17,7 @@ class SettingsListener(endpoint: ServiceEndpoint) { class SetAllowLan(val allow: Boolean) : Command() class SetAutoConnect(val autoConnect: Boolean) : Command() class SetWireGuardMtu(val mtu: Int?) : Command() + class SetObfuscationSettings(val settings: ObfuscationSettings) : Command() } private val commandChannel = spawnActor() @@ -26,6 +25,7 @@ class SettingsListener(endpoint: ServiceEndpoint) { val dnsOptionsNotifier = EventNotifier<DnsOptions?>(null) val relaySettingsNotifier = EventNotifier<RelaySettings?>(null) + val obfuscationSettingsNotifier = EventNotifier<ObfuscationSettings?>(null) val settingsNotifier = EventNotifier<Settings?>(null) var settings by settingsNotifier.notifiable() @@ -55,6 +55,10 @@ class SettingsListener(endpoint: ServiceEndpoint) { registerHandler(Request.SetWireGuardMtu::class) { request -> commandChannel.trySendBlocking(Command.SetWireGuardMtu(request.mtu)) } + + registerHandler(Request.SetObfuscationSettings::class) { request -> + commandChannel.trySendBlocking(Command.SetObfuscationSettings(request.settings)) + } } } @@ -64,6 +68,7 @@ class SettingsListener(endpoint: ServiceEndpoint) { dnsOptionsNotifier.unsubscribeAll() relaySettingsNotifier.unsubscribeAll() + obfuscationSettingsNotifier.unsubscribeAll() settingsNotifier.unsubscribeAll() } @@ -96,6 +101,10 @@ class SettingsListener(endpoint: ServiceEndpoint) { relaySettingsNotifier.notify(newSettings.relaySettings) } + if (settings?.obfuscationSettings != newSettings.obfuscationSettings) { + obfuscationSettingsNotifier.notify(newSettings.obfuscationSettings) + } + settings = newSettings } } @@ -110,6 +119,8 @@ class SettingsListener(endpoint: ServiceEndpoint) { is Command.SetAutoConnect -> daemon.await().setAutoConnect(command.autoConnect) is Command.SetWireGuardMtu -> daemon.await().setWireguardMtu(command.mtu) + is Command.SetObfuscationSettings -> + daemon.await().setObfuscationSettings(command.settings) } } } catch (exception: ClosedReceiveChannelException) { diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/net/ObfuscationEndpoint.kt b/android/app/src/main/kotlin/net/mullvad/talpid/net/ObfuscationEndpoint.kt new file mode 100644 index 0000000000..9ec96b1494 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/talpid/net/ObfuscationEndpoint.kt @@ -0,0 +1,8 @@ +package net.mullvad.talpid.net + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class ObfuscationEndpoint(val endpoint: Endpoint, val obfuscationType: ObfuscationType) : + Parcelable diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/net/ObfuscationType.kt b/android/app/src/main/kotlin/net/mullvad/talpid/net/ObfuscationType.kt new file mode 100644 index 0000000000..72409d9026 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/talpid/net/ObfuscationType.kt @@ -0,0 +1,9 @@ +package net.mullvad.talpid.net + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +enum class ObfuscationType : Parcelable { + Udp2Tcp +} diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/net/TunnelEndpoint.kt b/android/app/src/main/kotlin/net/mullvad/talpid/net/TunnelEndpoint.kt index 7bb9eb2530..9c45833eb2 100644 --- a/android/app/src/main/kotlin/net/mullvad/talpid/net/TunnelEndpoint.kt +++ b/android/app/src/main/kotlin/net/mullvad/talpid/net/TunnelEndpoint.kt @@ -4,4 +4,8 @@ import android.os.Parcelable import kotlinx.parcelize.Parcelize @Parcelize -data class TunnelEndpoint(val endpoint: Endpoint, val quantumResistant: Boolean) : Parcelable +data class TunnelEndpoint( + val endpoint: Endpoint, + val quantumResistant: Boolean, + val obfuscation: ObfuscationEndpoint? +) : Parcelable diff --git a/mullvad-jni/src/classes.rs b/mullvad-jni/src/classes.rs index 32123ebb07..eea0dd6544 100644 --- a/mullvad-jni/src/classes.rs +++ b/mullvad-jni/src/classes.rs @@ -28,6 +28,7 @@ pub const CLASSES: &[&str] = &[ "net/mullvad/mullvadvpn/model/LocationConstraint$City", "net/mullvad/mullvadvpn/model/LocationConstraint$Country", "net/mullvad/mullvadvpn/model/LocationConstraint$Hostname", + "net/mullvad/mullvadvpn/model/ObfuscationSettings", "net/mullvad/mullvadvpn/model/PublicKey", "net/mullvad/mullvadvpn/model/Relay", "net/mullvad/mullvadvpn/model/RelayConstraints", @@ -42,12 +43,14 @@ pub const CLASSES: &[&str] = &[ "net/mullvad/mullvadvpn/model/RelaySettingsUpdate$CustomTunnelEndpoint", "net/mullvad/mullvadvpn/model/RelaySettingsUpdate$Normal", "net/mullvad/mullvadvpn/model/RelayConstraintsUpdate", + "net/mullvad/mullvadvpn/model/SelectedObfuscation", "net/mullvad/mullvadvpn/model/Settings", "net/mullvad/mullvadvpn/model/TunnelState$Error", "net/mullvad/mullvadvpn/model/TunnelState$Connected", "net/mullvad/mullvadvpn/model/TunnelState$Connecting", "net/mullvad/mullvadvpn/model/TunnelState$Disconnected", "net/mullvad/mullvadvpn/model/TunnelState$Disconnecting", + "net/mullvad/mullvadvpn/model/Udp2TcpObfuscationSettings", "net/mullvad/mullvadvpn/model/VoucherSubmission", "net/mullvad/mullvadvpn/model/VoucherSubmissionResult", "net/mullvad/mullvadvpn/model/LoginResult", @@ -57,6 +60,8 @@ pub const CLASSES: &[&str] = &[ "net/mullvad/talpid/net/Endpoint", "net/mullvad/talpid/net/TransportProtocol", "net/mullvad/talpid/net/TunnelEndpoint", + "net/mullvad/talpid/net/ObfuscationEndpoint", + "net/mullvad/talpid/net/ObfuscationType", "net/mullvad/talpid/tun_provider/InetNetwork", "net/mullvad/talpid/tun_provider/TunConfig", "net/mullvad/talpid/tunnel/ActionAfterDisconnect", diff --git a/mullvad-jni/src/daemon_interface.rs b/mullvad-jni/src/daemon_interface.rs index a9406a5507..ca4c27fb25 100644 --- a/mullvad-jni/src/daemon_interface.rs +++ b/mullvad-jni/src/daemon_interface.rs @@ -4,7 +4,7 @@ use mullvad_types::{ account::{AccountData, AccountToken, VoucherSubmission}, device::{Device, DeviceState}, location::GeoIpLocation, - relay_constraints::RelaySettingsUpdate, + relay_constraints::{ObfuscationSettings, RelaySettingsUpdate}, relay_list::RelayList, settings::{DnsOptions, Settings}, states::{TargetState, TunnelState}, @@ -316,6 +316,16 @@ impl DaemonInterface { .map_err(|_| Error::SettingsError) } + pub fn set_obfuscation_settings(&self, settings: ObfuscationSettings) -> Result<()> { + let (tx, rx) = oneshot::channel(); + + self.send_command(DaemonCommand::SetObfuscationSettings(tx, settings))?; + + block_on(rx) + .map_err(|_| Error::NoResponse)? + .map_err(|_| Error::SettingsError) + } + fn send_command(&self, command: DaemonCommand) -> Result<()> { self.command_sender.send(command).map_err(Error::NoDaemon) } diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs index 370959c4e5..35db9a6766 100644 --- a/mullvad-jni/src/lib.rs +++ b/mullvad-jni/src/lib.rs @@ -1182,6 +1182,28 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_updateR } } +#[no_mangle] +#[allow(non_snake_case)] +pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_setObfuscationSettings( + env: JNIEnv<'_>, + _: JObject<'_>, + daemon_interface_address: jlong, + obfuscationSettings: JObject<'_>, +) { + let env = JnixEnv::from(env); + + if let Some(daemon_interface) = get_daemon_interface(daemon_interface_address) { + let settings = FromJava::from_java(&env, obfuscationSettings); + + if let Err(error) = daemon_interface.set_obfuscation_settings(settings) { + log::error!( + "{}", + error.display_chain_with_msg("Failed to update obfuscation settings") + ); + } + } +} + fn log_request_error(request: &str, error: &daemon_interface::Error) { match error { daemon_interface::Error::RpcError(RestError::Aborted) => { diff --git a/mullvad-types/src/relay_constraints.rs b/mullvad-types/src/relay_constraints.rs index 9d896a46c7..8f91ffab52 100644 --- a/mullvad-types/src/relay_constraints.rs +++ b/mullvad-types/src/relay_constraints.rs @@ -7,7 +7,7 @@ use crate::{ CustomTunnelEndpoint, }; #[cfg(target_os = "android")] -use jnix::{FromJava, IntoJava}; +use jnix::{jni::objects::JObject, FromJava, IntoJava, JnixEnv}; use serde::{Deserialize, Serialize}; use std::{collections::HashSet, fmt, str::FromStr}; use talpid_types::net::{openvpn::ProxySettings, IpVersion, TransportProtocol, TunnelType}; @@ -580,6 +580,8 @@ pub enum BridgeSettings { } #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Deserialize, Serialize)] +#[cfg_attr(target_os = "android", derive(FromJava, IntoJava))] +#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))] #[serde(rename_all = "snake_case")] #[cfg_attr(feature = "clap", derive(clap::ValueEnum))] pub enum SelectedObfuscation { @@ -600,11 +602,44 @@ impl fmt::Display for SelectedObfuscation { } #[derive(Default, Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] +#[cfg_attr(target_os = "android", derive(IntoJava))] +#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))] #[serde(rename_all = "snake_case")] pub struct Udp2TcpObfuscationSettings { + #[cfg_attr( + target_os = "android", + jnix(map = "|constraint| constraint.map(|v| v as i32)") + )] pub port: Constraint<u16>, } +#[cfg(target_os = "android")] +impl<'env, 'sub_env> FromJava<'env, JObject<'sub_env>> for Udp2TcpObfuscationSettings +where + 'env: 'sub_env, +{ + const JNI_SIGNATURE: &'static str = "Lnet/mullvad/mullvadvpn/model/Udp2TcpObfuscationSettings;"; + + fn from_java(env: &JnixEnv<'env>, object: JObject<'sub_env>) -> Self { + let object = env + .call_method( + object, + "component1", + "()Lnet/mullvad/mullvadvpn/model/Constraint;", + &[], + ) + .expect("missing Udp2TcpObfuscationSettings.port") + .l() + .expect("Udp2TcpObfuscationSettings.port did not return an object"); + + let port: Constraint<i32> = Constraint::from_java(env, object); + + Udp2TcpObfuscationSettings { + port: port.map(|port| port as u16), + } + } +} + impl fmt::Display for Udp2TcpObfuscationSettings { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.port { @@ -616,6 +651,8 @@ impl fmt::Display for Udp2TcpObfuscationSettings { /// Contains obfuscation settings #[derive(Default, Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] +#[cfg_attr(target_os = "android", derive(FromJava, IntoJava))] +#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))] #[serde(rename_all = "snake_case")] #[serde(default)] pub struct ObfuscationSettings { diff --git a/mullvad-types/src/settings/mod.rs b/mullvad-types/src/settings/mod.rs index 80891ea970..ec4adb109a 100644 --- a/mullvad-types/src/settings/mod.rs +++ b/mullvad-types/src/settings/mod.rs @@ -68,7 +68,6 @@ pub struct Settings { pub relay_settings: RelaySettings, #[cfg_attr(target_os = "android", jnix(skip))] pub bridge_settings: BridgeSettings, - #[cfg_attr(target_os = "android", jnix(skip))] pub obfuscation_settings: ObfuscationSettings, #[cfg_attr(target_os = "android", jnix(skip))] pub bridge_state: BridgeState, diff --git a/talpid-types/src/net/mod.rs b/talpid-types/src/net/mod.rs index 910c1f168e..3daff6bae2 100644 --- a/talpid-types/src/net/mod.rs +++ b/talpid-types/src/net/mod.rs @@ -156,7 +156,6 @@ pub struct TunnelEndpoint { pub quantum_resistant: bool, #[cfg_attr(target_os = "android", jnix(skip))] pub proxy: Option<proxy::ProxyEndpoint>, - #[cfg_attr(target_os = "android", jnix(skip))] pub obfuscation: Option<ObfuscationEndpoint>, #[cfg_attr(target_os = "android", jnix(skip))] pub entry_endpoint: Option<Endpoint>, @@ -190,6 +189,8 @@ impl fmt::Display for TunnelEndpoint { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename = "obfuscation_type")] +#[cfg_attr(target_os = "android", derive(IntoJava))] +#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.talpid.net"))] pub enum ObfuscationType { #[serde(rename = "udp2tcp")] Udp2Tcp, @@ -205,6 +206,8 @@ impl fmt::Display for ObfuscationType { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename = "obfuscation_endpoint")] +#[cfg_attr(target_os = "android", derive(IntoJava))] +#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.talpid.net"))] pub struct ObfuscationEndpoint { pub endpoint: Endpoint, pub obfuscation_type: ObfuscationType, |
