Skip to content

Commit

Permalink
Add daita.enabled and daita.use_anywhere rpc calls
Browse files Browse the repository at this point in the history
  • Loading branch information
hulthe committed Aug 19, 2024
1 parent f46767e commit f31112e
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 29 deletions.
15 changes: 6 additions & 9 deletions gui/src/main/daemon-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import {
IAppVersionInfo,
IBridgeConstraints,
ICustomList,
IDaitaSettings,
IDevice,
IDeviceRemoval,
IDnsOptions,
Expand Down Expand Up @@ -573,14 +572,12 @@ export class DaemonRpc {
await this.callBool(this.client.prepareRestartV2, quit);
}

public async setDaitaSettings(daitaSettings: IDaitaSettings): Promise<void> {
const grpcDaitaSettings = new grpcTypes.DaitaSettings();
grpcDaitaSettings.setEnabled(daitaSettings.enabled);
grpcDaitaSettings.setUseAnywhere(daitaSettings.useAnywhere);
await this.call<grpcTypes.DaitaSettings, Empty>(
this.client.setDaitaSettings,
grpcDaitaSettings,
);
public async setEnableDaita(value: boolean): Promise<void> {
await this.callBool(this.client.setEnableDaita, value);
}

public async setDaitaUseAnywhere(value: boolean): Promise<void> {
await this.callBool(this.client.setDaitaUseAnywhere, value);
}

public async listDevices(accountToken: AccountToken): Promise<Array<IDevice>> {
Expand Down
7 changes: 5 additions & 2 deletions gui/src/main/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,11 @@ export default class Settings implements Readonly<ISettings> {
const settings = await fs.readFile(path);
return this.daemonRpc.applyJsonSettings(settings.toString());
});
IpcMainEventChannel.settings.handleSetDaitaSettings((daitaSettings) => {
return this.daemonRpc.setDaitaSettings(daitaSettings);
IpcMainEventChannel.settings.handleSetEnableDaita((value) => {
return this.daemonRpc.setEnableDaita(value);
});
IpcMainEventChannel.settings.handleSetDaitaUseAnywhere((value) => {
return this.daemonRpc.setDaitaUseAnywhere(value);
});

IpcMainEventChannel.guiSettings.handleSetEnableSystemNotifications((flag: boolean) => {
Expand Down
7 changes: 4 additions & 3 deletions gui/src/renderer/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
IAccountData,
IAppVersionInfo,
ICustomList,
IDaitaSettings,
IDevice,
IDeviceRemoval,
IDnsOptions,
Expand Down Expand Up @@ -345,8 +344,10 @@ export default class AppRenderer {
IpcRendererEventChannel.splitTunneling.forgetManuallyAddedApplication(application);
public setObfuscationSettings = (obfuscationSettings: ObfuscationSettings) =>
IpcRendererEventChannel.settings.setObfuscationSettings(obfuscationSettings);
public setDaitaSettings = (daitaSettings: IDaitaSettings) =>
IpcRendererEventChannel.settings.setDaitaSettings(daitaSettings);
public setEnableDaita = (value: boolean) =>
IpcRendererEventChannel.settings.setEnableDaita(value);
public setDaitaUseAnywhere = (value: boolean) =>
IpcRendererEventChannel.settings.setDaitaUseAnywhere(value);
public collectProblemReport = (toRedact: string | undefined) =>
IpcRendererEventChannel.problemReport.collectLogs(toRedact);
public viewLog = (path: string) => IpcRendererEventChannel.problemReport.viewLog(path);
Expand Down
8 changes: 4 additions & 4 deletions gui/src/renderer/components/WireguardSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ function MtuSetting() {
}

function DaitaSettings() {
const { setDaitaSettings } = useAppContext();
const { setEnableDaita, setDaitaUseAnywhere } = useAppContext();
const daita = useSelector((state) => state.settings.wireguard.daita?.enabled ?? false);
const useAnywhere = useSelector((state) => state.settings.wireguard.daita?.useAnywhere ?? false);

Expand All @@ -565,16 +565,16 @@ function DaitaSettings() {
if (value) {
showConfirmationDialog();
} else {
void setDaitaSettings({ enabled: value, useAnywhere: useAnywhere });
void setEnableDaita(value);
}
}, []);

const setUseAnywhere = useCallback((value: boolean) => {
void setDaitaSettings({ enabled: daita, useAnywhere: value });
void setDaitaUseAnywhere(value);
}, []);

const confirmDaita = useCallback(() => {
void setDaitaSettings({ enabled: true, useAnywhere: useAnywhere });
void setEnableDaita(true);
hideConfirmationDialog();
}, []);

Expand Down
4 changes: 2 additions & 2 deletions gui/src/shared/ipc-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
IAccountData,
IAppVersionInfo,
ICustomList,
IDaitaSettings,
IDevice,
IDeviceRemoval,
IDnsOptions,
Expand Down Expand Up @@ -195,7 +194,8 @@ export const ipcSchema = {
testApiAccessMethodById: invoke<string, boolean>(),
testCustomApiAccessMethod: invoke<CustomProxy, boolean>(),
clearAllRelayOverrides: invoke<void, void>(),
setDaitaSettings: invoke<IDaitaSettings, void>(),
setEnableDaita: invoke<boolean, void>(),
setDaitaUseAnywhere: invoke<boolean, void>(),
},
guiSettings: {
'': notifyRenderer<IGuiSettingsState>(),
Expand Down
25 changes: 17 additions & 8 deletions mullvad-cli/src/cmds/tunnel.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use anyhow::Result;
use clap::Subcommand;
use mullvad_management_interface::MullvadProxyClient;
#[cfg(daita)]
use mullvad_types::wireguard::DaitaSettings;
use mullvad_types::{
constraints::Constraint,
wireguard::{QuantumResistantState, RotationInterval, DEFAULT_ROTATION_INTERVAL},
Expand Down Expand Up @@ -44,6 +42,10 @@ pub enum TunnelOptions {
#[cfg(daita)]
#[arg(long)]
daita: Option<BooleanOption>,
/// Configure whether to enable DAITA "use anywhere"
#[cfg(daita)]
#[arg(long)]
daita_use_anywhere: Option<BooleanOption>,
/// The key rotation interval. Number of hours, or 'any'
#[arg(long)]
rotation_interval: Option<Constraint<RotationInterval>>,
Expand Down Expand Up @@ -140,6 +142,8 @@ impl Tunnel {
quantum_resistant,
#[cfg(daita)]
daita,
#[cfg(daita)]
daita_use_anywhere,
rotation_interval,
rotate_key,
} => {
Expand All @@ -148,6 +152,8 @@ impl Tunnel {
quantum_resistant,
#[cfg(daita)]
daita,
#[cfg(daita)]
daita_use_anywhere,
rotation_interval,
rotate_key,
)
Expand Down Expand Up @@ -179,6 +185,7 @@ impl Tunnel {
mtu: Option<Constraint<u16>>,
quantum_resistant: Option<QuantumResistantState>,
#[cfg(daita)] daita: Option<BooleanOption>,
#[cfg(daita)] daita_use_anywhere: Option<BooleanOption>,
rotation_interval: Option<Constraint<RotationInterval>>,
rotate_key: Option<RotateKey>,
) -> Result<()> {
Expand All @@ -195,12 +202,14 @@ impl Tunnel {
}

#[cfg(daita)]
if let Some(daita) = daita {
rpc.set_daita_settings(DaitaSettings {
enabled: *daita,
use_anywhere: true, /* TODO */
})
.await?;
if let Some(enable_daita) = daita {
rpc.set_enable_daita(*enable_daita).await?;
println!("DAITA setting has been updated");
}

#[cfg(daita)]
if let Some(daita_use_anywhere) = daita_use_anywhere {
rpc.set_daita_use_anywhere(*daita_use_anywhere).await?;
println!("DAITA setting has been updated");
}

Expand Down
56 changes: 56 additions & 0 deletions mullvad-daemon/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ pub enum DaemonCommand {
SetQuantumResistantTunnel(ResponseTx<(), settings::Error>, QuantumResistantState),
/// Set DAITA settings for the tunnel
#[cfg(daita)]
SetEnableDaita(ResponseTx<(), settings::Error>, bool),
#[cfg(daita)]
SetDaitaUseAnywhere(ResponseTx<(), settings::Error>, bool),
#[cfg(daita)]
SetDaitaSettings(ResponseTx<(), settings::Error>, DaitaSettings),
/// Set DNS options or servers to use
SetDnsOptions(ResponseTx<(), settings::Error>, DnsOptions),
Expand Down Expand Up @@ -1219,6 +1223,10 @@ impl Daemon {
.await
}
#[cfg(daita)]
SetEnableDaita(tx, value) => self.on_set_daita_enabled(tx, value).await,
#[cfg(daita)]
SetDaitaUseAnywhere(tx, value) => self.on_set_daita_use_anywhere(tx, value).await,
#[cfg(daita)]
SetDaitaSettings(tx, daita_settings) => {
self.on_set_daita_settings(tx, daita_settings).await
}
Expand Down Expand Up @@ -2291,6 +2299,54 @@ impl Daemon {
}
}

#[cfg(daita)]
async fn on_set_daita_enabled(&mut self, tx: ResponseTx<(), settings::Error>, value: bool) {
match self
.settings
.update(|settings| settings.tunnel_options.wireguard.daita.enabled = value)
.await
{
Ok(settings_changed) => {
Self::oneshot_send(tx, Ok(()), "set_daita_enabled response");
if settings_changed && self.get_target_tunnel_type() != Some(TunnelType::OpenVpn) {
log::info!("Reconnecting because DAITA settings changed");
self.reconnect_tunnel();
}
}
Err(e) => {
log::error!("{}", e.display_chain_with_msg("Unable to save settings"));
Self::oneshot_send(tx, Err(e), "set_daita_enabled response");
}
}
}

#[cfg(daita)]
async fn on_set_daita_use_anywhere(
&mut self,
tx: ResponseTx<(), settings::Error>,
value: bool,
) {
match self
.settings
.update(|settings| settings.tunnel_options.wireguard.daita.use_anywhere = value)
.await
{
Ok(settings_changed) => {
Self::oneshot_send(tx, Ok(()), "set_daita_use_anywhere response");

// TODO: don't reconnect if multihop is enabled
if settings_changed && self.get_target_tunnel_type() != Some(TunnelType::OpenVpn) {
log::info!("Reconnecting because DAITA settings changed");
self.reconnect_tunnel();
}
}
Err(e) => {
log::error!("{}", e.display_chain_with_msg("Unable to save settings"));
Self::oneshot_send(tx, Err(e), "set_daita_use_anywhere response");
}
}
}

#[cfg(daita)]
async fn on_set_daita_settings(
&mut self,
Expand Down
30 changes: 30 additions & 0 deletions mullvad-daemon/src/management_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,26 @@ impl ManagementService for ManagementServiceImpl {
Ok(Response::new(()))
}

#[cfg(daita)]
async fn set_enable_daita(&self, request: Request<bool>) -> ServiceResult<()> {
let value = request.into_inner();
log::debug!("set_enable_daita({value})");
let (tx, rx) = oneshot::channel();
self.send_command_to_daemon(DaemonCommand::SetEnableDaita(tx, value))?;
self.wait_for_result(rx).await?.map(Response::new)?;
Ok(Response::new(()))
}

#[cfg(daita)]
async fn set_daita_use_anywhere(&self, request: Request<bool>) -> ServiceResult<()> {
let value = request.into_inner();
log::debug!("set_daita_use_anywhere({value})");
let (tx, rx) = oneshot::channel();
self.send_command_to_daemon(DaemonCommand::SetDaitaUseAnywhere(tx, value))?;
self.wait_for_result(rx).await?.map(Response::new)?;
Ok(Response::new(()))
}

#[cfg(daita)]
async fn set_daita_settings(
&self,
Expand All @@ -355,6 +375,16 @@ impl ManagementService for ManagementServiceImpl {
Ok(Response::new(()))
}

#[cfg(not(daita))]
async fn set_enable_daita(&self, _: Request<bool>) -> ServiceResult<()> {
Ok(Response::new(()))
}

#[cfg(not(daita))]
async fn set_daita_use_anywhere(&self, _: Request<bool>) -> ServiceResult<()> {
Ok(Response::new(()))
}

#[cfg(not(daita))]
async fn set_daita_settings(&self, _: Request<types::DaitaSettings>) -> ServiceResult<()> {
Ok(Response::new(()))
Expand Down
2 changes: 2 additions & 0 deletions mullvad-management-interface/proto/management_interface.proto
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ service ManagementService {
rpc SetWireguardMtu(google.protobuf.UInt32Value) returns (google.protobuf.Empty) {}
rpc SetEnableIpv6(google.protobuf.BoolValue) returns (google.protobuf.Empty) {}
rpc SetQuantumResistantTunnel(QuantumResistantState) returns (google.protobuf.Empty) {}
rpc SetEnableDaita(google.protobuf.BoolValue) returns (google.protobuf.Empty) {}
rpc SetDaitaUseAnywhere(google.protobuf.BoolValue) returns (google.protobuf.Empty) {}
rpc SetDaitaSettings(DaitaSettings) returns (google.protobuf.Empty) {}
rpc SetDnsOptions(DnsOptions) returns (google.protobuf.Empty) {}
rpc SetRelayOverride(RelayOverride) returns (google.protobuf.Empty) {}
Expand Down
15 changes: 15 additions & 0 deletions mullvad-management-interface/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,21 @@ impl MullvadProxyClient {
Ok(())
}

#[cfg(daita)]
pub async fn set_enable_daita(&mut self, value: bool) -> Result<()> {
self.0.set_enable_daita(value).await.map_err(Error::Rpc)?;
Ok(())
}

#[cfg(daita)]
pub async fn set_daita_use_anywhere(&mut self, value: bool) -> Result<()> {
self.0
.set_daita_use_anywhere(value)
.await
.map_err(Error::Rpc)?;
Ok(())
}

#[cfg(daita)]
pub async fn set_daita_settings(&mut self, settings: DaitaSettings) -> Result<()> {
let settings = types::DaitaSettings::from(settings);
Expand Down
2 changes: 1 addition & 1 deletion mullvad-relay-selector/src/relay_selector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ impl RelaySelector {
.take_while(|relay| relay.distance <= smallest_distance)
.map(|relay_with_distance| relay_with_distance.relay)
.collect_vec();
let entry = pick_random_excluding(&entry_candidates, &exit).ok_or(Error::NoRelay)?;
let entry = pick_random_excluding(&entry_candidates, exit).ok_or(Error::NoRelay)?;

Ok(WireguardConfig::multihop(exit.clone(), entry.clone()))
}
Expand Down

0 comments on commit f31112e

Please sign in to comment.