Skip to content

Commit

Permalink
Refactor on_test_api_access_method
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkusPettersson98 committed Dec 21, 2023
1 parent 6223e0c commit 6e1814d
Showing 1 changed file with 59 additions and 60 deletions.
119 changes: 59 additions & 60 deletions mullvad-daemon/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2447,75 +2447,38 @@ where
tx: ResponseTx<bool, Error>,
access_method: mullvad_types::access_method::Id,
) {
let access_method_lookup = self
.get_api_access_method(access_method)
.map_err(Error::AccessMethodError);

match access_method_lookup {
Ok(access_method) => {
let access_method_selector = self.connection_modes_handler.clone();

let api::ResolvedConnectionMode {
connection_mode,
endpoint,
setting,
} = match access_method_selector.resolve(access_method.clone()).await {
Ok(v) => v,
Err(err) => {
Self::oneshot_send(
tx,
Err(Error::ApiConnectionModeError(err)),
"on_test_api_access_method response",
);
return;
}
};
use futures::{future, TryFutureExt};
let access_method_selector = self.connection_modes_handler.clone();
let access_method_lookup = future::ready(
self.get_api_access_method(access_method)
.map_err(Error::AccessMethodError),
)
.and_then(|access_method| {
access_method_selector
.resolve(access_method)
.map_err(Error::ApiConnectionModeError)
});

let proxy_provider = connection_mode.into_repeat();
match access_method_lookup.await {
Ok(test_subject) => {
let proxy_provider = test_subject.connection_mode.clone().into_repeat();
let rest_handle = self.api_runtime.mullvad_rest_handle(proxy_provider).await;
let api_proxy = mullvad_api::ApiProxy::new(rest_handle);
let daemon_event_sender = self.tx.to_specialized_sender();
let access_method_selector = self.connection_modes_handler.clone();

tokio::spawn(async move {
// Send an internal daemon event which will punch a hole in the firewall for the connection mode we are testing.
let (event, update_finished_rx) =
api::NewAccessMethodEvent::new(setting, endpoint, false);

// Wait on the daemon to finish.
let _ = daemon_event_sender.send(event);
let _ = update_finished_rx.await;

// Send a HEAD request to some Mullvad API endpoint. We issue a HEAD
// request because we are *only* concerned with if we get a reply from
// the API, and not with the actual data that the endpoint returns.
let result = api_proxy
.api_addrs_available()
.await
.map_err(Error::RestError);

// Tell the daemon to reset the hole we just punched to whatever was in place before.
let api::ResolvedConnectionMode {
endpoint, setting, ..
} = match access_method_selector.get_current().await {
Ok(v) => v,
Err(err) => {
Self::oneshot_send(
tx,
Err(Error::ApiConnectionModeError(err)),
"on_test_api_access_method response",
);
return;
}
};
let (event, update_finished_rx) =
api::NewAccessMethodEvent::new(setting, endpoint, false);

let _ = daemon_event_sender.send(event);
let _ = update_finished_rx.await;
let result = Self::test_api_access_method_inner(
test_subject.clone(),
access_method_selector,
api_proxy,
daemon_event_sender,
)
.await;

log::debug!(
"API access method {method} {result}",
method = access_method.name,
method = test_subject.setting.name,
result = if result.as_ref().is_ok_and(|is_true| *is_true) {
"could successfully connect to the Mullvad API".to_string()
} else {
Expand All @@ -2532,6 +2495,42 @@ where
};
}

async fn test_api_access_method_inner(
test_subject: api::ResolvedConnectionMode,
access_method_selector: api::AccessModeSelectorHandle,
api_proxy: mullvad_api::ApiProxy,
daemon_event_sender: DaemonEventSender<NewAccessMethodEvent>,
) -> Result<bool, Error> {
// Send an internal daemon event which will punch a hole in the firewall for the connection mode we are testing.
let (event, update_finished_rx) =
api::NewAccessMethodEvent::new(test_subject.setting, test_subject.endpoint, false);
let _ = daemon_event_sender.send(event);
// Wait for the daemon to finish processing `event`.
let _ = update_finished_rx.await;

// Send a HEAD request to some Mullvad API endpoint. We issue a HEAD
// request because we are *only* concerned with if we get a reply from
// the API, and not with the actual data that the endpoint returns.
let result = api_proxy
.api_addrs_available()
.await
.map_err(Error::RestError);

// Tell the daemon to reset the hole we just punched to whatever was in place before.
let api::ResolvedConnectionMode {
endpoint, setting, ..
} = access_method_selector
.get_current()
.await
.map_err(Error::ApiConnectionModeError)?;

let (event, update_finished_rx) = api::NewAccessMethodEvent::new(setting, endpoint, false);
let _ = daemon_event_sender.send(event);
// Wait for the daemon to finish processing `event`.
let _ = update_finished_rx.await;
result
}

fn on_get_settings(&self, tx: oneshot::Sender<Settings>) {
Self::oneshot_send(tx, self.settings.to_settings(), "get_settings response");
}
Expand Down

0 comments on commit 6e1814d

Please sign in to comment.