summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls Piņķis <pinkisemils@gmail.com>2018-03-15 14:51:35 +0000
committerEmīls Piņķis <pinkisemils@gmail.com>2018-03-22 13:40:13 +0000
commit4aa897ce23440b7159436909b64fabeb398cc625 (patch)
tree180b650f34acd3364ec03362d915a01f46678285
parente6ab7a128270594d5152f16263000d98a63ca439 (diff)
downloadmullvadvpn-4aa897ce23440b7159436909b64fabeb398cc625.tar.xz
mullvadvpn-4aa897ce23440b7159436909b64fabeb398cc625.zip
Allow passing the `--mssfix` paramter to OpenVPN based on config
-rw-r--r--CHANGELOG.md1
-rw-r--r--mullvad-cli/src/cmds/relay.rs2
-rw-r--r--mullvad-daemon/src/main.rs26
-rw-r--r--mullvad-daemon/src/management_interface.rs36
-rw-r--r--mullvad-daemon/src/settings.rs18
-rw-r--r--talpid-core/src/process/openvpn.rs13
-rw-r--r--talpid-core/src/tunnel/mod.rs7
-rw-r--r--talpid-types/src/net.rs19
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>,
+}