diff options
| author | Markus Pettersson <markus.pettersson@mullvad.net> | 2023-09-20 13:41:43 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2023-10-09 14:40:06 +0200 |
| commit | 7fcaad31643ca324c5dd4a17ddf0f445ac679384 (patch) | |
| tree | 9a913059321b437857863efed43b4d47ed9c0eb4 | |
| parent | fc477f4e4df6db2973ff88fc4b6819d38d64d8cc (diff) | |
| download | mullvadvpn-7fcaad31643ca324c5dd4a17ddf0f445ac679384.tar.xz mullvadvpn-7fcaad31643ca324c5dd4a17ddf0f445ac679384.zip | |
Add `mullvad proxy test`
For quickly assessing whether an api access method can reach the API or not.
| -rw-r--r-- | mullvad-cli/src/cmds/proxy.rs | 34 | ||||
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 10 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 11 | ||||
| -rw-r--r-- | mullvad-management-interface/proto/management_interface.proto | 2 | ||||
| -rw-r--r-- | mullvad-management-interface/src/client.rs | 5 |
5 files changed, 62 insertions, 0 deletions
diff --git a/mullvad-cli/src/cmds/proxy.rs b/mullvad-cli/src/cmds/proxy.rs index c876a25d2e..fa05081f89 100644 --- a/mullvad-cli/src/cmds/proxy.rs +++ b/mullvad-cli/src/cmds/proxy.rs @@ -24,6 +24,8 @@ pub enum Proxy { Enable(SelectItem), /// Disable an API proxy Disable(SelectItem), + /// Test an API proxy + Test(SelectItem), /// Force the use of a specific API proxy. Use(SelectItem), } @@ -59,6 +61,10 @@ impl Proxy { let enabled = false; Self::toggle(index, enabled).await?; } + Proxy::Test(cmd) => { + let index = Self::zero_to_one_based_index(cmd.index)?; + Self::test(index).await?; + } Proxy::Use(cmd) => { let index = Self::zero_to_one_based_index(cmd.index)?; Self::set(index).await?; @@ -199,6 +205,34 @@ impl Proxy { Ok(()) } + /// Test an access method to see if it successfully reaches the Mullvad API. + async fn test(index: usize) -> Result<()> { + let mut rpc = MullvadProxyClient::new().await?; + // TODO: Refactor this into some helper function. This code has been copy-pastead a lot already .. + // Step 1. + let access_method = rpc + .get_api_access_methods() + .await? + .get(index) + .ok_or(anyhow!(format!( + "Access method {} does not exist", + index + 1 + )))? + .clone(); + + // Step 2. + rpc.set_access_method(access_method).await?; + // Step 3. + let api_call = rpc.test_api().await; + // Step 4. + match api_call { + Ok(_) => println!("API call succeeded!"), + Err(_) => println!("API call failed :-("), + } + + Ok(()) + } + /// Force the use of a specific access method when trying to reach the /// Mullvad API. If this method fails, the daemon will resume the automatic /// roll-over behavior (which is the default). diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 3c822fdf4e..ed7bafd007 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -275,6 +275,8 @@ pub enum DaemonCommand { ToggleApiAccessMethod(ResponseTx<(), Error>, ApiAccessMethodToggle), /// Set the API access method to use SetApiAccessMethod(ResponseTx<(), Error>, AccessMethod), + /// Get the addresses of all known API endpoints + GetApiAddresses(ResponseTx<Vec<std::net::SocketAddr>, Error>), /// Get information about the currently running and latest app versions GetVersionInfo(oneshot::Sender<Option<AppVersionInfo>>), /// Return whether the daemon is performing post-upgrade tasks @@ -1067,6 +1069,7 @@ where } ToggleApiAccessMethod(tx, method) => self.on_toggle_api_access_method(tx, method).await, SetApiAccessMethod(tx, method) => self.on_set_api_access_method(tx, method).await, + GetApiAddresses(tx) => self.on_get_api_addresses(tx).await, IsPerformingPostUpgrade(tx) => self.on_is_performing_post_upgrade(tx), GetCurrentVersion(tx) => self.on_get_current_version(tx), #[cfg(not(target_os = "android"))] @@ -2298,6 +2301,13 @@ where Self::oneshot_send(tx, result, "set_api_access_method response"); } + async fn on_get_api_addresses(&mut self, tx: ResponseTx<Vec<std::net::SocketAddr>, Error>) { + let api_proxy = mullvad_api::ApiProxy::new(self.api_handle.clone()); + let result = api_proxy.get_api_addrs().await.map_err(Error::RestError); + + Self::oneshot_send(tx, result, "on_get_api_adressess response"); + } + fn on_get_settings(&self, tx: oneshot::Sender<Settings>) { Self::oneshot_send(tx, self.settings.to_settings(), "get_settings response"); } diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index 2b6481207a..88ea87056c 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -654,6 +654,17 @@ impl ManagementService for ManagementServiceImpl { .map_err(map_daemon_error) } + async fn get_api_addressess(&self, _: Request<()>) -> ServiceResult<()> { + log::debug!("test_api"); + let (tx, rx) = oneshot::channel(); + self.send_command_to_daemon(DaemonCommand::GetApiAddresses(tx))?; + self.wait_for_result(rx) + .await? + .map(drop) + .map(Response::new) + .map_err(map_daemon_error) + } + // Split tunneling // diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto index a062e0b642..018906cdaf 100644 --- a/mullvad-management-interface/proto/management_interface.proto +++ b/mullvad-management-interface/proto/management_interface.proto @@ -91,6 +91,8 @@ service ManagementService { // Can I return something useful here instead of Empty? } + rpc GetApiAddressess(google.protobuf.Empty) returns (google.protobuf.Empty) {} + // Split tunneling (Linux) rpc GetSplitTunnelProcesses(google.protobuf.Empty) returns (stream google.protobuf.Int32Value) {} rpc AddSplitTunnelProcess(google.protobuf.Int32Value) returns (google.protobuf.Empty) {} diff --git a/mullvad-management-interface/src/client.rs b/mullvad-management-interface/src/client.rs index 900775b10a..049f8a2fe3 100644 --- a/mullvad-management-interface/src/client.rs +++ b/mullvad-management-interface/src/client.rs @@ -181,6 +181,11 @@ impl MullvadProxyClient { .collect() } + pub async fn test_api(&mut self) -> Result<()> { + self.0.get_api_addressess(()).await.map_err(Error::Rpc)?; + Ok(()) + } + pub async fn update_relay_locations(&mut self) -> Result<()> { self.0 .update_relay_locations(()) |
