diff options
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/mod.rs | 20 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/reconnect.rs | 22 | ||||
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 9 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 16 | ||||
| -rw-r--r-- | mullvad-ipc-client/src/lib.rs | 4 | ||||
| -rw-r--r-- | mullvad-jni/src/daemon_interface.rs | 7 |
7 files changed, 69 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a3f84f6cb..afb065c704 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ Line wrap the file at 100 chars. Th ### Added - Add `mullvad relay set tunnel-protocol` subcommand to the CLI to specify what tunnel protocol to use +- Add `mullvad reconnect` subcommand to the CLI to make the app pick a new server and reconnect. #### Windows - Full WireGuard support, GUI and CLI. diff --git a/mullvad-cli/src/cmds/mod.rs b/mullvad-cli/src/cmds/mod.rs index 8caf26eac5..a26b64be74 100644 --- a/mullvad-cli/src/cmds/mod.rs +++ b/mullvad-cli/src/cmds/mod.rs @@ -7,30 +7,33 @@ pub use self::account::Account; mod auto_connect; pub use self::auto_connect::AutoConnect; +mod block_when_disconnected; +pub use self::block_when_disconnected::BlockWhenDisconnected; + mod bridge; pub use self::bridge::Bridge; -mod status; -pub use self::status::Status; - mod connect; pub use self::connect::Connect; mod disconnect; pub use self::disconnect::Disconnect; -mod block_when_disconnected; -pub use self::block_when_disconnected::BlockWhenDisconnected; +mod lan; +pub use self::lan::Lan; + +mod reconnect; +pub use self::reconnect::Reconnect; mod relay; pub use self::relay::Relay; -mod lan; -pub use self::lan::Lan; - mod reset; pub use self::reset::Reset; +mod status; +pub use self::status::Status; + mod tunnel; pub use self::tunnel::Tunnel; @@ -46,6 +49,7 @@ pub fn get_commands() -> HashMap<&'static str, Box<dyn Command>> { Box::new(Bridge), Box::new(Connect), Box::new(Disconnect), + Box::new(Reconnect), Box::new(Lan), Box::new(Relay), Box::new(Reset), diff --git a/mullvad-cli/src/cmds/reconnect.rs b/mullvad-cli/src/cmds/reconnect.rs new file mode 100644 index 0000000000..0cc7f6bfea --- /dev/null +++ b/mullvad-cli/src/cmds/reconnect.rs @@ -0,0 +1,22 @@ +use crate::{new_rpc_client, Command, Result}; +use talpid_types::ErrorExt; + +pub struct Reconnect; + +impl Command for Reconnect { + fn name(&self) -> &'static str { + "reconnect" + } + + fn clap_subcommand(&self) -> clap::App<'static, 'static> { + clap::SubCommand::with_name(self.name()).about("Command the client to reconnect") + } + + fn run(&self, _matches: &clap::ArgMatches<'_>) -> Result<()> { + let mut rpc = new_rpc_client()?; + if let Err(e) = rpc.reconnect() { + eprintln!("{}", e.display_chain()); + } + Ok(()) + } +} diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 35839d47f2..bae58b2f12 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -782,6 +782,7 @@ where } match event { SetTargetState(tx, state) => self.on_set_target_state(tx, state), + Reconnect => self.on_reconnect(), GetState(tx) => self.on_get_state(tx), GetCurrentLocation(tx) => self.on_get_current_location(tx), CreateNewAccount(tx) => self.on_create_new_account(tx), @@ -918,6 +919,14 @@ where Self::oneshot_send(tx, Ok(()), "target state"); } + fn on_reconnect(&mut self) { + if self.target_state == TargetState::Secured || self.tunnel_state.is_blocked() { + self.connect_tunnel(); + } else { + debug!("Ignoring reconnect command. Currently not in secured state"); + } + } + fn on_get_state(&self, tx: oneshot::Sender<TunnelState>) { Self::oneshot_send(tx, self.tunnel_state.clone(), "current state"); } diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index ad31150e9a..4ddeda473c 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -96,6 +96,10 @@ build_rpc_trait! { #[rpc(meta, name = "disconnect")] fn disconnect(&self, Self::Metadata) -> BoxFuture<(), Error>; + /// Reconnect if connecting/connected, or do nothing if disconnected. + #[rpc(meta, name = "reconnect")] + fn reconnect(&self, Self::Metadata) -> BoxFuture<(), Error>; + /// Returns the current state of the Mullvad client. Changes to this state will /// be announced to subscribers of `new_state`. #[rpc(meta, name = "get_state")] @@ -185,8 +189,10 @@ build_rpc_trait! { /// Enum representing commands coming in on the management interface. pub enum ManagementCommand { - /// Change target state. + /// Set target state. Does nothing if the daemon already has the state that is being set. SetTargetState(OneshotSender<Result<(), ()>>, TargetState), + /// Reconnect the tunnel, if one is connecting/connected. + Reconnect, /// Request the current state. GetState(OneshotSender<TunnelState>), /// Get the current geographical location. @@ -245,8 +251,8 @@ pub enum ManagementCommand { GetVersionInfo(OneshotSender<version::AppVersionInfo>), /// Get current version of the app GetCurrentVersion(OneshotSender<version::AppVersion>), - #[cfg(not(target_os = "android"))] /// Remove settings and clear the cache + #[cfg(not(target_os = "android"))] FactoryReset(OneshotSender<()>), /// Makes the daemon exit the main loop and quit. Shutdown, @@ -568,6 +574,12 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } + fn reconnect(&self, _: Self::Metadata) -> BoxFuture<(), Error> { + log::debug!("reconnect"); + let future = self.send_command_to_daemon(ManagementCommand::Reconnect); + Box::new(future) + } + fn get_state(&self, _: Self::Metadata) -> BoxFuture<TunnelState, Error> { log::debug!("get_state"); let (state_tx, state_rx) = sync::oneshot::channel(); diff --git a/mullvad-ipc-client/src/lib.rs b/mullvad-ipc-client/src/lib.rs index 84eacb5dd7..dad3be309d 100644 --- a/mullvad-ipc-client/src/lib.rs +++ b/mullvad-ipc-client/src/lib.rs @@ -99,6 +99,10 @@ impl DaemonRpcClient { self.call("disconnect", &NO_ARGS) } + pub fn reconnect(&mut self) -> Result<()> { + self.call("reconnect", &NO_ARGS) + } + pub fn create_new_account(&mut self) -> Result<()> { self.call("create_new_account", &NO_ARGS) } diff --git a/mullvad-jni/src/daemon_interface.rs b/mullvad-jni/src/daemon_interface.rs index 97580c22d4..2b37a16d21 100644 --- a/mullvad-jni/src/daemon_interface.rs +++ b/mullvad-jni/src/daemon_interface.rs @@ -69,6 +69,13 @@ impl DaemonInterface { Ok(()) } + // TODO: Implement this all the way on Android. This method is currently unused. + #[allow(dead_code)] + pub fn reconnect(&self) -> Result<()> { + self.send_command(ManagementCommand::Reconnect)?; + Ok(()) + } + pub fn generate_wireguard_key(&self) -> Result<KeygenEvent> { let (tx, rx) = oneshot::channel(); |
