diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2017-10-18 17:35:00 +0200 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2017-10-18 17:35:00 +0200 |
| commit | b92ef2951393555009fcfe4030a62979bdbcbdac (patch) | |
| tree | 147190e526692251e066baecf5f3a59391b14fd8 | |
| parent | d7a0a68987223f994b6cb30fad79b9454d99def7 (diff) | |
| parent | e1f41bb918aedb3c4af06ad505e80bf28db99462 (diff) | |
| download | mullvadvpn-b92ef2951393555009fcfe4030a62979bdbcbdac.tar.xz mullvadvpn-b92ef2951393555009fcfe4030a62979bdbcbdac.zip | |
Merge branch 'add-shutdown-rpc-method'
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/mod.rs | 4 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/shutdown.rs | 20 | ||||
| -rw-r--r-- | mullvad-cli/src/rpc.rs | 15 | ||||
| -rw-r--r-- | mullvad-daemon/src/main.rs | 2 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 12 | ||||
| -rw-r--r-- | mullvad-daemon/src/rpc_info.rs | 12 |
7 files changed, 55 insertions, 12 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index a710c238a9..0b8d31c2a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Added +- Possibility to shut down the daemon via an RPC call. ## [2017.1-beta2] - 2017-09-27 diff --git a/mullvad-cli/src/cmds/mod.rs b/mullvad-cli/src/cmds/mod.rs index 8061344b96..0104185543 100644 --- a/mullvad-cli/src/cmds/mod.rs +++ b/mullvad-cli/src/cmds/mod.rs @@ -16,6 +16,9 @@ pub use self::disconnect::Disconnect; mod custom_relay; pub use self::custom_relay::CustomRelay; +mod shutdown; +pub use self::shutdown::Shutdown; + /// Returns a map of all available subcommands with their name as key. pub fn get_commands() -> HashMap<&'static str, Box<Command>> { let commands: Vec<Box<Command>> = vec![ @@ -24,6 +27,7 @@ pub fn get_commands() -> HashMap<&'static str, Box<Command>> { Box::new(Connect), Box::new(Disconnect), Box::new(CustomRelay), + Box::new(Shutdown), ]; let mut map = HashMap::new(); for cmd in commands { diff --git a/mullvad-cli/src/cmds/shutdown.rs b/mullvad-cli/src/cmds/shutdown.rs new file mode 100644 index 0000000000..4a334da5a5 --- /dev/null +++ b/mullvad-cli/src/cmds/shutdown.rs @@ -0,0 +1,20 @@ +use {Command, Result}; +use clap; + +use rpc; + +pub struct Shutdown; + +impl Command for Shutdown { + fn name(&self) -> &'static str { + "shutdown" + } + + fn clap_subcommand(&self) -> clap::App<'static, 'static> { + clap::SubCommand::with_name(self.name()).about("Makes the backend daemon quit") + } + + fn run(&self, _matches: &clap::ArgMatches) -> Result<()> { + rpc::call("shutdown", &[] as &[u8; 0]) + } +} diff --git a/mullvad-cli/src/rpc.rs b/mullvad-cli/src/rpc.rs index 16a23bda94..5e14cdf195 100644 --- a/mullvad-cli/src/rpc.rs +++ b/mullvad-cli/src/rpc.rs @@ -2,7 +2,7 @@ use {Result, ResultExt}; use serde; use std::fs::{File, Metadata}; -use std::io::{self, Read}; +use std::io::{self, BufRead, BufReader}; use std::path::{Path, PathBuf}; use talpid_ipc::WsIpcClient; @@ -20,7 +20,7 @@ where T: serde::Serialize, O: for<'de> serde::Deserialize<'de>, { - let address = read_rpc_address().chain_err(|| "Unable to read RPC address")?; + let (address, _shared_secret) = read_rpc_address().chain_err(|| "Unable to read RPC address")?; info!("Using RPC address {}", address); let mut rpc_client = WsIpcClient::new(address).chain_err(|| "Unable to create RPC client")?; rpc_client @@ -41,16 +41,19 @@ lazy_static! { static ref RPC_ADDRESS_FILE_PATH: PathBuf = ::std::env::temp_dir().join(".mullvad_rpc_address"); } -fn read_rpc_address() -> io::Result<String> { +fn read_rpc_address() -> io::Result<(String, String)> { debug!( "Trying to read RPC address at {}", RPC_ADDRESS_FILE_PATH.to_string_lossy() ); - let mut file = File::open(&*RPC_ADDRESS_FILE_PATH)?; + let file = File::open(&*RPC_ADDRESS_FILE_PATH)?; if is_rpc_file_trusted(file.metadata()?) { + let mut buf_file = BufReader::new(file); let mut address = String::new(); - file.read_to_string(&mut address)?; - Ok(address) + buf_file.read_line(&mut address)?; + let mut shared_secret = String::new(); + buf_file.read_line(&mut shared_secret)?; + Ok((address, shared_secret)) } else { Err(io::Error::new( io::ErrorKind::Other, diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs index c427c252bb..e804dcace8 100644 --- a/mullvad-daemon/src/main.rs +++ b/mullvad-daemon/src/main.rs @@ -320,6 +320,7 @@ impl Daemon { SetAccount(tx, account_token) => self.on_set_account(tx, account_token), GetAccount(tx) => Ok(self.on_get_account(tx)), SetCustomRelay(tx, relay_endpoint) => self.on_set_custom_relay(tx, relay_endpoint), + Shutdown => self.handle_trigger_shutdown_event(), } } @@ -635,6 +636,7 @@ fn run() -> Result<()> { daemon.run()?; debug!("Mullvad daemon is quitting"); + thread::sleep(Duration::from_millis(500)); Ok(()) } diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index e2fb6f33f7..829f843fca 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -91,6 +91,10 @@ build_rpc_trait! { #[rpc(name = "get_location")] fn get_location(&self) -> Result<Location, Error>; + /// Makes the daemon exit its main loop and quit. + #[rpc(meta, name = "shutdown")] + fn shutdown(&self, Self::Metadata) -> BoxFuture<(), Error>; + #[pubsub(name = "new_state")] { /// Subscribes to the `new_state` event notifications. #[rpc(name = "new_state_subscribe")] @@ -131,6 +135,8 @@ pub enum TunnelCommand { GetAccount(OneshotSender<Option<AccountToken>>), /// Set a custom relay instead of the default list of relays SetCustomRelay(OneshotSender<()>, Option<RelayEndpoint>), + /// Makes the daemon exit the main loop and quit. + Shutdown, } #[derive(Default)] @@ -441,6 +447,12 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for Managem }) } + fn shutdown(&self, meta: Self::Metadata) -> BoxFuture<(), Error> { + trace!("shutdown"); + try_future!(self.check_auth(&meta)); + self.send_command_to_daemon(TunnelCommand::Shutdown) + } + fn new_state_subscribe( &self, meta: Self::Metadata, diff --git a/mullvad-daemon/src/rpc_info.rs b/mullvad-daemon/src/rpc_info.rs index 7826b736a8..3bd42d9751 100644 --- a/mullvad-daemon/src/rpc_info.rs +++ b/mullvad-daemon/src/rpc_info.rs @@ -5,8 +5,8 @@ use std::path::{Path, PathBuf}; error_chain! { errors { WriteFailed(path: PathBuf) { - description("Failed to write RCP address to file") - display("Failed to write RPC address to {}", path.to_string_lossy()) + description("Failed to write RCP connection info to file") + display("Failed to write RPC connection info to {}", path.to_string_lossy()) } RemoveFailed(path: PathBuf) { description("Failed to remove file") @@ -17,18 +17,18 @@ error_chain! { #[cfg(unix)] lazy_static! { - /// The path to the file where we write the RPC address + /// The path to the file where we write the RPC connection info static ref RPC_ADDRESS_FILE_PATH: PathBuf = Path::new("/tmp").join(".mullvad_rpc_address"); } #[cfg(not(unix))] lazy_static! { - /// The path to the file where we write the RPC address + /// The path to the file where we write the RPC connection info static ref RPC_ADDRESS_FILE_PATH: PathBuf = ::std::env::temp_dir().join(".mullvad_rpc_address"); } -/// Writes down the RPC address to some API to a file. +/// Writes down the RPC connection info to some API to a file. pub fn write(rpc_address: &str, shared_secret: &str) -> Result<()> { open_file(RPC_ADDRESS_FILE_PATH.as_path()) .and_then(|mut file| { @@ -37,7 +37,7 @@ pub fn write(rpc_address: &str, shared_secret: &str) -> Result<()> { .chain_err(|| ErrorKind::WriteFailed(RPC_ADDRESS_FILE_PATH.to_owned()))?; debug!( - "Wrote RPC address to {}", + "Wrote RPC connection info to {}", RPC_ADDRESS_FILE_PATH.to_string_lossy() ); Ok(()) |
