diff options
| author | Emīls Piņķis <pinkisemils@gmail.com> | 2018-03-15 14:51:35 +0000 |
|---|---|---|
| committer | Emīls Piņķis <pinkisemils@gmail.com> | 2018-03-22 13:40:13 +0000 |
| commit | 4aa897ce23440b7159436909b64fabeb398cc625 (patch) | |
| tree | 180b650f34acd3364ec03362d915a01f46678285 | |
| parent | e6ab7a128270594d5152f16263000d98a63ca439 (diff) | |
| download | mullvadvpn-4aa897ce23440b7159436909b64fabeb398cc625.tar.xz mullvadvpn-4aa897ce23440b7159436909b64fabeb398cc625.zip | |
Allow passing the `--mssfix` paramter to OpenVPN based on config
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/relay.rs | 2 | ||||
| -rw-r--r-- | mullvad-daemon/src/main.rs | 26 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 36 | ||||
| -rw-r--r-- | mullvad-daemon/src/settings.rs | 18 | ||||
| -rw-r--r-- | talpid-core/src/process/openvpn.rs | 13 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/mod.rs | 7 | ||||
| -rw-r--r-- | talpid-types/src/net.rs | 19 |
8 files changed, 119 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb49a7fe7..533a4a20bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [Unreleased] ### Added +- Add support for passing the `--mssfix` argument to OpenVPN tunnels. - Add `--disable-rpc-auth` flag to daemon to make it accept unauthorized control. - Add colors to terminal output on macOS and Linux. - Add details to mullvad CLI interface error for when it doesn't trust the RPC file. diff --git a/mullvad-cli/src/cmds/relay.rs b/mullvad-cli/src/cmds/relay.rs index e87512e0c2..aea58ae76b 100644 --- a/mullvad-cli/src/cmds/relay.rs +++ b/mullvad-cli/src/cmds/relay.rs @@ -53,7 +53,7 @@ impl Command for Relay { .index(4) .default_value("udp") .possible_values(&["udp", "tcp"]), - ), + ) ) .subcommand( clap::SubCommand::with_name("location") diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs index 231a6ebcf9..6da206a6fb 100644 --- a/mullvad-daemon/src/main.rs +++ b/mullvad-daemon/src/main.rs @@ -78,7 +78,7 @@ use std::time::{Duration, Instant}; use talpid_core::firewall::{Firewall, FirewallProxy, SecurityPolicy}; use talpid_core::mpsc::IntoSender; use talpid_core::tunnel::{self, TunnelEvent, TunnelMetadata, TunnelMonitor}; -use talpid_types::net::TunnelEndpoint; +use talpid_types::net::{TunnelEndpoint, TunnelOptions}; use std::fs; @@ -394,6 +394,8 @@ impl Daemon { UpdateRelaySettings(tx, update) => self.on_update_relay_settings(tx, update), SetAllowLan(tx, allow_lan) => self.on_set_allow_lan(tx, allow_lan), GetAllowLan(tx) => Ok(self.on_get_allow_lan(tx)), + SetOpenVpnMssfix(tx, mssfix_arg) => self.on_set_openvpn_mssfix(tx, mssfix_arg), + GetTunnelOptions(tx) => self.on_get_tunnel_options(tx), GetRelaySettings(tx) => Ok(self.on_get_relay_settings(tx)), Shutdown => self.handle_trigger_shutdown_event(), } @@ -529,6 +531,25 @@ impl Daemon { Self::oneshot_send(tx, self.settings.get_allow_lan(), "allow lan") } + fn on_set_openvpn_mssfix( + &mut self, + tx: OneshotSender<()>, + mssfix_arg: Option<u16>, + ) -> Result<()> { + let save_result = self.settings.set_openvpn_mssfix(mssfix_arg); + match save_result.chain_err(|| "Unable to save settings") { + Ok(_) => Self::oneshot_send(tx, (), "set_openvpn_mssfix response"), + Err(e) => error!("{}", e.display_chain()), + }; + Ok(()) + } + + fn on_get_tunnel_options(&self, tx: OneshotSender<TunnelOptions>) -> Result<()> { + let tunnel_options = self.settings.get_tunnel_options().clone(); + Self::oneshot_send(tx, tunnel_options, "get_tunnel_options response"); + Ok(()) + } + 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); @@ -696,8 +717,11 @@ impl Daemon { .unwrap() .send(DaemonEvent::TunnelEvent(event)); }; + + let tunnel_options = self.settings.get_tunnel_options(); TunnelMonitor::new( tunnel_endpoint, + &tunnel_options, account_token, self.tunnel_log.as_ref().map(PathBuf::as_path), &self.resource_dir, diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index cdc237ef30..5bf7603db5 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -23,6 +23,7 @@ use std::sync::{Arc, Mutex, RwLock}; use std::sync::atomic::{AtomicBool, Ordering}; use talpid_core::mpsc::IntoSender; use talpid_ipc; +use talpid_types::net::TunnelOptions; use uuid; use account_history::AccountHistory; @@ -115,6 +116,14 @@ build_rpc_trait! { #[rpc(meta, name = "remove_account_from_history")] fn remove_account_from_history(&self, Self::Metadata, AccountToken) -> BoxFuture<(), Error>; + /// Sets openvpn's mssfix parameter + #[rpc(meta, name = "set_openvpn_mssfix")] + fn set_openvpn_mssfix(&self, Self::Metadata, Option<u16>) -> BoxFuture<(), Error>; + + /// Gets tunnel specific options + #[rpc(meta, name = "get_tunnel_options")] + fn get_tunnel_options(&self, Self::Metadata) -> BoxFuture<TunnelOptions, Error>; + #[pubsub(name = "new_state")] { /// Subscribes to the `new_state` event notifications. #[rpc(name = "new_state_subscribe")] @@ -165,6 +174,10 @@ pub enum TunnelCommand { SetAllowLan(OneshotSender<()>, bool), /// Request the current allow LAN setting. GetAllowLan(OneshotSender<bool>), + /// Set the mssfix argument for OpenVPN + SetOpenVpnMssfix(OneshotSender<()>, Option<u16>), + /// Get the mssfix argument for OpenVPN + GetTunnelOptions(OneshotSender<TunnelOptions>), /// Makes the daemon exit the main loop and quit. Shutdown, } @@ -555,6 +568,29 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for Managem )) } + fn set_openvpn_mssfix( + &self, + meta: Self::Metadata, + mssfix: Option<u16>, + ) -> BoxFuture<(), Error> { + trace!("set_openvpn_mssfix"); + try_future!(self.check_auth(&meta)); + let (tx, rx) = sync::oneshot::channel(); + let future = self.send_command_to_daemon(TunnelCommand::SetOpenVpnMssfix(tx, mssfix)) + .and_then(|_| rx.map_err(|_| Error::internal_error())); + + Box::new(future) + } + + fn get_tunnel_options(&self, meta: Self::Metadata) -> BoxFuture<TunnelOptions, Error> { + trace!("get_tunnel_options"); + try_future!(self.check_auth(&meta)); + let (tx, rx) = sync::oneshot::channel(); + let future = self.send_command_to_daemon(TunnelCommand::GetTunnelOptions(tx)) + .and_then(|_| rx.map_err(|_| Error::internal_error())); + Box::new(future) + } + fn new_state_subscribe( &self, meta: Self::Metadata, diff --git a/mullvad-daemon/src/settings.rs b/mullvad-daemon/src/settings.rs index 867f461deb..d0023b59c1 100644 --- a/mullvad-daemon/src/settings.rs +++ b/mullvad-daemon/src/settings.rs @@ -4,6 +4,7 @@ use app_dirs; use mullvad_types::relay_constraints::{Constraint, LocationConstraint, RelayConstraints, RelaySettings, RelaySettingsUpdate}; +use talpid_types::net::TunnelOptions; use std::fs::File; use std::io; @@ -37,6 +38,9 @@ pub struct Settings { relay_settings: RelaySettings, /// If the app should allow communication with private (LAN) networks. allow_lan: bool, + /// Options that should be applied to tunnels of a specific type regardless of where the relays + /// might be located. + tunnel_options: TunnelOptions, } impl Default for Settings { @@ -48,6 +52,7 @@ impl Default for Settings { tunnel: Constraint::Any, }), allow_lan: false, + tunnel_options: TunnelOptions::default(), } } } @@ -149,4 +154,17 @@ impl Settings { Ok(false) } } + + pub fn set_openvpn_mssfix(&mut self, openvpn_mssfix: Option<u16>) -> Result<bool> { + if self.tunnel_options.openvpn.mssfix != openvpn_mssfix { + self.tunnel_options.openvpn.mssfix = openvpn_mssfix; + self.save().map(|_| true) + } else { + Ok(false) + } + } + + pub fn get_tunnel_options(&self) -> &TunnelOptions { + &self.tunnel_options + } } diff --git a/talpid-core/src/process/openvpn.rs b/talpid-core/src/process/openvpn.rs index ec79795baf..53c72ba413 100644 --- a/talpid-core/src/process/openvpn.rs +++ b/talpid-core/src/process/openvpn.rs @@ -39,6 +39,7 @@ pub struct OpenVpnCommand { crl: Option<PathBuf>, plugin: Option<(PathBuf, Vec<String>)>, log: Option<PathBuf>, + tunnel_options: net::OpenVpnTunnelOptions, } impl OpenVpnCommand { @@ -54,6 +55,7 @@ impl OpenVpnCommand { crl: None, plugin: None, log: None, + tunnel_options: net::OpenVpnTunnelOptions::default(), } } @@ -106,6 +108,12 @@ impl OpenVpnCommand { duct::cmd(&self.openvpn_bin, self.get_arguments()).unchecked() } + /// Sets extra options + pub fn set_tunnel_options(&mut self, tunnel_options: &net::OpenVpnTunnelOptions) -> &mut Self { + self.tunnel_options = *tunnel_options; + self + } + /// Returns all arguments that the subprocess would be spawned with. pub fn get_arguments(&self) -> Vec<OsString> { let mut args: Vec<OsString> = Self::base_arguments().iter().map(OsString::from).collect(); @@ -138,6 +146,11 @@ impl OpenVpnCommand { args.push(OsString::from(path)) } + if let Some(mssfix) = self.tunnel_options.mssfix { + args.push(OsString::from("--mssfix")); + args.push(OsString::from(mssfix.to_string())); + } + args.extend(Self::security_arguments().iter().map(OsString::from)); args diff --git a/talpid-core/src/tunnel/mod.rs b/talpid-core/src/tunnel/mod.rs index 5845212615..ef24aac193 100644 --- a/talpid-core/src/tunnel/mod.rs +++ b/talpid-core/src/tunnel/mod.rs @@ -12,7 +12,8 @@ use std::io::{self, Write}; use std::net::Ipv4Addr; use std::path::{Path, PathBuf}; -use talpid_types::net::{Endpoint, TunnelEndpoint, TunnelEndpointData}; +use talpid_types::net::{Endpoint, OpenVpnTunnelOptions, TunnelEndpoint, TunnelEndpointData, + TunnelOptions}; /// A module for all OpenVPN related tunnel management. pub mod openvpn; @@ -113,6 +114,7 @@ impl TunnelMonitor { /// on tunnel state changes. pub fn new<L>( tunnel_endpoint: TunnelEndpoint, + tunnel_options: &TunnelOptions, account_token: &str, log: Option<&Path>, resource_dir: &Path, @@ -129,6 +131,7 @@ impl TunnelMonitor { .chain_err(|| ErrorKind::CredentialsWriteError)?; let cmd = Self::create_openvpn_cmd( tunnel_endpoint.to_endpoint(), + &tunnel_options.openvpn, user_pass_file.as_ref(), log, resource_dir, @@ -156,6 +159,7 @@ impl TunnelMonitor { fn create_openvpn_cmd( remote: Endpoint, + options: &OpenVpnTunnelOptions, user_pass_file: &Path, log: Option<&Path>, resource_dir: &Path, @@ -166,6 +170,7 @@ impl TunnelMonitor { } cmd.remote(remote) .user_pass(user_pass_file) + .set_tunnel_options(&options) .ca(resource_dir.join("ca.crt")) .crl(resource_dir.join("crl.pem")); if let Some(log) = log { diff --git a/talpid-types/src/net.rs b/talpid-types/src/net.rs index 9b9630419c..fff70094d0 100644 --- a/talpid-types/src/net.rs +++ b/talpid-types/src/net.rs @@ -125,3 +125,22 @@ impl Error for TransportProtocolParseError { "Not a valid transport protocol" } } + +/// TunnelOptions holds optional settings for tunnels, that are to be applied to any tunnel of the +/// appropriate type. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] +pub struct TunnelOptions { + /// openvpn holds OpenVPN specific tunnel options. + pub openvpn: OpenVpnTunnelOptions, +} + + +/// OpenVpnTunnelOptions contains options for an openvpn tunnel that should be applied irrespective +/// of the relay parameters - i.e. have nothing to do with the particular OpenVPN server, but do +/// affect the connection. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +pub struct OpenVpnTunnelOptions { + /// Optional argument for openvpn to try and limit TCP packet size, + /// as discussed [here](https://openvpn.net/archive/openvpn-users/2003-11/msg00154.html) + pub mssfix: Option<u16>, +} |
