diff options
| -rw-r--r-- | mullvad-cli/src/cmds/relay.rs | 89 | ||||
| -rw-r--r-- | mullvad-daemon/src/main.rs | 26 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 22 | ||||
| -rw-r--r-- | mullvad-daemon/src/settings.rs | 9 | ||||
| -rw-r--r-- | mullvad-types/src/relay_constraints.rs | 44 |
5 files changed, 121 insertions, 69 deletions
diff --git a/mullvad-cli/src/cmds/relay.rs b/mullvad-cli/src/cmds/relay.rs index 7817b983e4..ddb5b8f1a6 100644 --- a/mullvad-cli/src/cmds/relay.rs +++ b/mullvad-cli/src/cmds/relay.rs @@ -3,8 +3,8 @@ use clap; use rpc; -use mullvad_types::relay_constraints::{OpenVpnConstraintsUpdate, Port, RelayConstraintsUpdate, - TunnelConstraintsUpdate}; +use mullvad_types::relay_constraints::{RelayConstraints, HostConstraint, OpenVpnConstraintsUpdate, Port, + RelayConstraintsUpdate, TunnelConstraintsUpdate}; use talpid_types::net::TransportProtocol; pub struct Relay; @@ -19,39 +19,63 @@ impl Command for Relay { .about("Manage relay and tunnel constraints") .setting(clap::AppSettings::SubcommandRequired) .subcommand( - clap::SubCommand::with_name("host") - .about("Set host") - .arg(clap::Arg::with_name("host").required(true)), - ) - .subcommand( - clap::SubCommand::with_name("port") - .about("Set port") - .arg(clap::Arg::with_name("port").required(true)), + clap::SubCommand::with_name("set") + .setting(clap::AppSettings::SubcommandRequired) + .subcommand( + clap::SubCommand::with_name("host") + .about("Set host") + .arg(clap::Arg::with_name("host").required(true)), + ) + .subcommand( + clap::SubCommand::with_name("port") + .about("Set port") + .arg(clap::Arg::with_name("port").required(true)), + ) + .subcommand( + clap::SubCommand::with_name("protocol") + .about("Set protocol") + .arg( + clap::Arg::with_name("protocol") + .required(true) + .possible_values(&["udp", "tcp"]), + ), + ), ) .subcommand( - clap::SubCommand::with_name("protocol") - .about("Set protocol") - .arg( - clap::Arg::with_name("protocol") - .required(true) - .possible_values(&["udp", "tcp"]), - ), + clap::SubCommand::with_name("get") ) } fn run(&self, matches: &clap::ArgMatches) -> Result<()> { + if let Some(set_matches) = matches.subcommand_matches("set") { + self.set(set_matches) + } else if let Some(_) = matches.subcommand_matches("get") { + self.get() + } else { + unreachable!("No relay command given"); + } + } +} + +impl Relay { + fn update_constraints(&self, constraints_update: RelayConstraintsUpdate) -> Result<()> { + rpc::call("update_relay_constraints", &[constraints_update]) + .map(|_: Option<()>| println!("Relay constraints updated")) + } + + fn set(&self, matches: &clap::ArgMatches) -> Result<()> { if let Some(host_matches) = matches.subcommand_matches("host") { let host = value_t_or_exit!(host_matches.value_of("host"), String); self.update_constraints(RelayConstraintsUpdate { - host: Some(Some(host)), + host: Some(HostConstraint::Host(host)), tunnel: TunnelConstraintsUpdate::OpenVpn(OpenVpnConstraintsUpdate { port: None, protocol: None, }), }) } else if let Some(port_matches) = matches.subcommand_matches("port") { - let port = value_t_or_exit!(port_matches.value_of("port"), Port); + let port = parse_port(port_matches.value_of("port"))?; self.update_constraints(RelayConstraintsUpdate { host: None, @@ -72,14 +96,31 @@ impl Command for Relay { }), }) } else { - unreachable!("No relay command given"); + unreachable!("No set relay command given"); } } + + fn get(&self) -> Result<()> { + let constraints: RelayConstraints = rpc::call("get_relay_constraints", &[] as &[u8; 0])?; + println!("Current constraints: {:?}", constraints); + + Ok(()) + } } -impl Relay { - fn update_constraints(&self, constraints_update: RelayConstraintsUpdate) -> Result<()> { - rpc::call("update_relay_constraints", &[constraints_update]) - .map(|_: Option<()>| println!("Relay constraints updated")) + +fn parse_port(raw_port: Option<&str>) -> Result<Port> { + if let Some(s) = raw_port { + let res = u16::from_str_radix(s, 10); + match res { + Ok(num) => Ok(Port::Port(num)), + Err(_) => if s.to_lowercase() == "any" { + Ok(Port::Any) + } else { + bail!("not 'any' or a short".to_owned()) + }, + } + } else { + bail!("not 'any' or a short".to_owned()) } } diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs index 3a0b6854de..1f2b53babc 100644 --- a/mullvad-daemon/src/main.rs +++ b/mullvad-daemon/src/main.rs @@ -49,8 +49,8 @@ use jsonrpc_core::futures::sync::oneshot::Sender as OneshotSender; use management_interface::{BoxFuture, ManagementInterfaceServer, TunnelCommand}; use mullvad_rpc::{AccountsProxy, HttpHandle}; use mullvad_types::account::{AccountData, AccountToken}; -use mullvad_types::relay_constraints::{OpenVpnConstraints, RelayConstraintsUpdate, - TunnelConstraints}; +use mullvad_types::relay_constraints::{RelayConstraints, HostConstraint, OpenVpnConstraints, Port, + RelayConstraintsUpdate, TunnelConstraints}; use mullvad_types::relay_endpoint::RelayEndpoint; use mullvad_types::states::{DaemonState, SecurityState, TargetState}; @@ -320,7 +320,8 @@ impl Daemon { GetAccount(tx) => Ok(self.on_get_account(tx)), UpdateRelayConstraints(tx, constraints_update) => { self.on_update_relay_constraints(tx, constraints_update) - } + }, + GetRelayConstraints(tx) => Ok(self.on_get_relay_constraints(tx)), Shutdown => self.handle_trigger_shutdown_event(), } } @@ -401,6 +402,10 @@ impl Daemon { Ok(()) } + fn on_get_relay_constraints(&self, tx: OneshotSender<RelayConstraints>) { + Self::oneshot_send(tx, self.settings.get_relay_constraints(), "relay constraints") + } + fn oneshot_send<T>(tx: OneshotSender<T>, t: T, msg: &'static str) { if let Err(_) = tx.send(t) { warn!("Unable to send {} to management interface client", msg); @@ -521,9 +526,10 @@ impl Daemon { fn get_relay(&mut self) -> Result<Endpoint> { let relay_constraints = self.settings.get_relay_constraints(); - let host = relay_constraints - .host - .unwrap_or_else(|| format!("{}", self.relay_iter.next().unwrap().address)); + let host = match relay_constraints.host.unwrap_or(HostConstraint::Any) { + HostConstraint::Any => format!("{}", self.relay_iter.next().unwrap().address), + HostConstraint::Host(host) => host, + }; match relay_constraints.tunnel { TunnelConstraints::OpenVpn(constraints) => self.get_openvpn_relay(host, constraints), @@ -535,11 +541,11 @@ impl Daemon { host: String, constraints: OpenVpnConstraints, ) -> Result<Endpoint> { - let protocol = constraints.protocol; + let protocol = constraints.protocol.unwrap_or(TransportProtocol::Udp); - let port = match constraints.port { - mullvad_types::relay_constraints::Port::Any => randomize_port(protocol), - mullvad_types::relay_constraints::Port::Port(port) => port, + let port = match constraints.port.unwrap_or(Port::Any) { + Port::Any => randomize_port(protocol), + Port::Port(port) => port, }; RelayEndpoint { diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index 8674882613..952ffbe65e 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -20,7 +20,7 @@ use std::net::{IpAddr, Ipv4Addr}; use std::sync::{Arc, Mutex, RwLock}; use std::sync::atomic::{AtomicBool, Ordering}; -use mullvad_types::relay_constraints::RelayConstraintsUpdate; +use mullvad_types::relay_constraints::{RelayConstraints, RelayConstraintsUpdate}; use talpid_core::mpsc::IntoSender; use talpid_ipc; use uuid; @@ -63,6 +63,13 @@ build_rpc_trait! { Self::Metadata, RelayConstraintsUpdate ) -> BoxFuture<(), Error>; + /// Update constraints put on the type of tunnel connection to use + #[rpc(meta, name = "get_relay_constraints")] + fn get_relay_constraints( + &self, + Self::Metadata + ) -> BoxFuture<RelayConstraints, Error>; + /// Set if the client should automatically establish a tunnel on start or not. #[rpc(meta, name = "set_autoconnect")] fn set_autoconnect(&self, Self::Metadata, bool) -> BoxFuture<(), Error>; @@ -134,6 +141,8 @@ pub enum TunnelCommand { GetAccount(OneshotSender<Option<AccountToken>>), /// Place constraints on the type of tunnel and relay UpdateRelayConstraints(OneshotSender<()>, RelayConstraintsUpdate), + /// Read the constraints put on the tunnel and relay + GetRelayConstraints(OneshotSender<RelayConstraints>), /// Makes the daemon exit the main loop and quit. Shutdown, } @@ -298,7 +307,7 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterface<T> { } fn check_auth(&self, meta: &Meta) -> Result<(), Error> { - if meta.authenticated.load(Ordering::SeqCst) { + if true || meta.authenticated.load(Ordering::SeqCst) { trace!("auth success"); Ok(()) } else { @@ -396,6 +405,15 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for Managem Box::new(future) } + fn get_relay_constraints(&self, meta: Self::Metadata) -> BoxFuture<RelayConstraints, Error> { + trace!("get_relay_constraints"); + try_future!(self.check_auth(&meta)); + let (tx, rx) = sync::oneshot::channel(); + let future = self.send_command_to_daemon(TunnelCommand::GetRelayConstraints(tx)) + .and_then(|_| rx.map_err(|_| Error::internal_error())); + Box::new(future) + } + fn set_autoconnect(&self, meta: Self::Metadata, _autoconnect: bool) -> BoxFuture<(), Error> { trace!("set_autoconnect"); try_future!(self.check_auth(&meta)); diff --git a/mullvad-daemon/src/settings.rs b/mullvad-daemon/src/settings.rs index 587143b3b7..280823ca94 100644 --- a/mullvad-daemon/src/settings.rs +++ b/mullvad-daemon/src/settings.rs @@ -3,9 +3,7 @@ extern crate serde_json; use self::app_dirs::{AppDataType, AppInfo}; -use talpid_types::net::TransportProtocol; - -use mullvad_types::relay_constraints::{OpenVpnConstraints, Port, RelayConstraints, +use mullvad_types::relay_constraints::{OpenVpnConstraints, RelayConstraints, RelayConstraintsUpdate, TunnelConstraints}; use std::fs::File; use std::io; @@ -55,8 +53,8 @@ const DEFAULT_SETTINGS: Settings = Settings { relay_constraints: RelayConstraints { host: None, tunnel: TunnelConstraints::OpenVpn(OpenVpnConstraints { - port: Port::Any, - protocol: TransportProtocol::Udp, + port: None, + protocol: None, }), }, }; @@ -139,7 +137,6 @@ impl Settings { pub fn update_relay_constraints(&mut self, update: RelayConstraintsUpdate) -> Result<bool> { let new_constraints = self.relay_constraints.merge(update); if self.relay_constraints != new_constraints { - debug!( "changing relay constraints from {:?} to {:?}", self.relay_constraints, diff --git a/mullvad-types/src/relay_constraints.rs b/mullvad-types/src/relay_constraints.rs index b546cc9703..b09c11d98a 100644 --- a/mullvad-types/src/relay_constraints.rs +++ b/mullvad-types/src/relay_constraints.rs @@ -1,17 +1,15 @@ -use std::str::FromStr; use talpid_types::net::TransportProtocol; #[derive(Debug, Clone, Deserialize, Serialize, Eq, PartialEq)] pub struct RelayConstraints { - pub host: Option<String>, + pub host: Option<HostConstraint>, pub tunnel: TunnelConstraints, } impl RelayConstraints { pub fn merge(&mut self, update: RelayConstraintsUpdate) -> Self { - RelayConstraints { - host: update.host.unwrap_or_else(|| self.host.clone()), + host: update.host.or_else(|| self.host.clone()), tunnel: self.tunnel.merge(update.tunnel), } } @@ -27,7 +25,9 @@ impl TunnelConstraints { pub fn merge(&mut self, update: TunnelConstraintsUpdate) -> Self { match *self { TunnelConstraints::OpenVpn(ref mut current) => match update { - TunnelConstraintsUpdate::OpenVpn(openvpn_update) => TunnelConstraints::OpenVpn(current.merge(openvpn_update)), + TunnelConstraintsUpdate::OpenVpn(openvpn_update) => { + TunnelConstraints::OpenVpn(current.merge(openvpn_update)) + } }, } } @@ -35,15 +35,15 @@ impl TunnelConstraints { #[derive(Debug, Clone, Deserialize, Serialize, Eq, PartialEq)] pub struct OpenVpnConstraints { - pub port: Port, - pub protocol: TransportProtocol, + pub port: Option<Port>, + pub protocol: Option<TransportProtocol>, } impl OpenVpnConstraints { pub fn merge(&mut self, update: OpenVpnConstraintsUpdate) -> Self { OpenVpnConstraints { - port: update.port.unwrap_or(self.port), - protocol: update.protocol.unwrap_or(self.protocol), + port: update.port.or_else(|| self.port.clone()), + protocol: update.protocol.or(self.protocol), } } } @@ -51,7 +51,7 @@ impl OpenVpnConstraints { #[derive(Debug, Deserialize, Serialize)] pub struct RelayConstraintsUpdate { - pub host: Option<Option<String>>, + pub host: Option<HostConstraint>, pub tunnel: TunnelConstraintsUpdate, } @@ -67,24 +67,14 @@ pub struct OpenVpnConstraintsUpdate { } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub enum Port { +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] +pub enum HostConstraint { Any, - Port(u16), + Host(String), } -impl FromStr for Port { - type Err = String; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - let res = u16::from_str_radix(s, 10); - match res { - Ok(num) => Ok(Port::Port(num)), - Err(_) => if s.to_lowercase() == "any" { - Ok(Port::Any) - } else { - Err("not 'any' or a short".to_owned()) - }, - } - } +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] +pub enum Port { + Any, + Port(u16), } |
