Skip to content

Commit

Permalink
Cleanup daemon code related to access methods
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkusPettersson98 committed Dec 22, 2023
1 parent 999218d commit cda55e6
Showing 1 changed file with 32 additions and 41 deletions.
73 changes: 32 additions & 41 deletions mullvad-daemon/src/access_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,6 @@ pub enum Error {
Settings(#[error(source)] settings::Error),
}

/// A tiny datastructure used for signaling whether the daemon should force a
/// rotation of the currently used [`AccessMethodSetting`] or not, and if so:
/// how it should do it.
pub enum Command {
/// There is no need to force a rotation of [`AccessMethodSetting`]
Nothing,
/// Select the next available [`AccessMethodSetting`], whichever that is
Rotate,
/// Select the [`AccessMethodSetting`] with a certain [`access_method::Id`]
Set(access_method::Id),
}

impl<L> Daemon<L>
where
L: EventListener + Clone + Send + 'static,
Expand Down Expand Up @@ -79,30 +67,29 @@ where
&mut self,
access_method: access_method::Id,
) -> Result<(), Error> {
// Make sure that we are not trying to remove a built-in API access
// method
let command = match self.settings.api_access_methods.find_by_id(&access_method) {
Some(api_access_method) => {
if api_access_method.is_builtin() {
Err(Error::RemoveBuiltIn)
} else if api_access_method.get_id()
== self.get_current_access_method().await?.get_id()
{
Ok(Command::Rotate)
} else {
Ok(Command::Nothing)
}
match self.settings.api_access_methods.find_by_id(&access_method) {
// Make sure that we are not trying to remove a built-in API access
// method
Some(api_access_method) if api_access_method.is_builtin() => {
return Err(Error::RemoveBuiltIn)
}
None => Ok(Command::Nothing),
}?;
// If the currently active access method is removed, a new access
// method should trigger
Some(api_access_method)
if api_access_method.get_id()
== self.get_current_access_method().await?.get_id() =>
{
self.force_api_endpoint_rotation().await?;
}
_ => (),
}

self.settings
.update(|settings| settings.api_access_methods.remove(&access_method))
.await
.map(|did_change| self.notify_on_change(did_change))
.map_err(Error::Settings)?
.process_command(command)
.await
.map(|_| ())
.map_err(Error::Settings)
}

/// Set a [`AccessMethodSetting`] as the current API access method.
Expand All @@ -119,9 +106,6 @@ where
.set_access_method(access_method)
.await?;
// Force a rotation of Access Methods.
//
// This is not a call to `process_command` due to the restrictions on
// recursively calling async functions.
self.force_api_endpoint_rotation().await
}

Expand Down Expand Up @@ -150,15 +134,16 @@ where
// If the currently active access method is updated, we need to re-set
// it after updating the settings.
let current = self.get_current_access_method().await?;
let mut command = Command::Nothing;
// If the currently active access method is updated, we need to re-set it.
let mut refresh = None;
let settings_update = |settings: &mut Settings| {
let access_methods = &mut settings.api_access_methods;
if let Some(access_method) =
access_methods.find_by_id_mut(&access_method_update.get_id())
{
*access_method = access_method_update;
if access_method.get_id() == current.get_id() {
command = Command::Set(access_method.get_id())
refresh = Some(access_method.get_id())
}
// We have to be a bit careful. If we are about to disable the last
// remaining enabled access method, we would cause an inconsistent state
Expand All @@ -185,19 +170,25 @@ where
.update(settings_update)
.await
.map(|did_change| self.notify_on_change(did_change))
.map_err(Error::Settings)?
.process_command(command)
.await
.map_err(Error::Settings)?;
if let Some(id) = refresh {
self.set_api_access_method(id).await?;
}
Ok(())
}

/// Return the [`AccessMethodSetting`] which is currently used to access the
/// Mullvad API.
pub async fn get_current_access_method(&self) -> Result<AccessMethodSetting, Error> {
Ok(self.connection_modes_handler.get_access_method().await?)
self.connection_modes_handler
.get_current()
.await
.map(|current| current.setting)
.map_err(Error::ConnectionMode)
}

/// Change which [`AccessMethodSetting`] which will be used to figure out
/// the Mullvad API endpoint.
/// Change which [`AccessMethodSetting`] which will be used as the Mullvad
/// API endpoint.
async fn force_api_endpoint_rotation(&self) -> Result<(), Error> {
self.api_handle
.service()
Expand Down

0 comments on commit cda55e6

Please sign in to comment.