summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--mullvad-cli/src/cmds/mod.rs20
-rw-r--r--mullvad-cli/src/cmds/reconnect.rs22
-rw-r--r--mullvad-daemon/src/lib.rs9
-rw-r--r--mullvad-daemon/src/management_interface.rs16
-rw-r--r--mullvad-ipc-client/src/lib.rs4
-rw-r--r--mullvad-jni/src/daemon_interface.rs7
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();