diff options
| author | Emīls Piņķis <emils@mullvad.net> | 2019-01-11 14:34:31 +0000 |
|---|---|---|
| committer | Emīls Piņķis <emils@mullvad.net> | 2019-01-30 13:41:31 +0000 |
| commit | 4e2b2ff81704fdab21b269948c3ebf2a9f65b07c (patch) | |
| tree | 627e9940ef8af578f8356c6997e2b01cd68faa41 /talpid-core | |
| parent | 8c43e0cd550b84c8688270edad525c022d49cd78 (diff) | |
| download | mullvadvpn-4e2b2ff81704fdab21b269948c3ebf2a9f65b07c.tar.xz mullvadvpn-4e2b2ff81704fdab21b269948c3ebf2a9f65b07c.zip | |
Refactor talpid-core
Diffstat (limited to 'talpid-core')
| -rw-r--r-- | talpid-core/src/process/openvpn.rs | 10 | ||||
| -rw-r--r-- | talpid-core/src/security/macos/mod.rs | 5 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/mod.rs | 67 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/openvpn.rs | 29 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/wireguard/config.rs | 147 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/wireguard/mod.rs | 30 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/wireguard/wireguard_go.rs | 4 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connected_state.rs | 30 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connecting_state.rs | 62 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/mod.rs | 13 |
10 files changed, 183 insertions, 214 deletions
diff --git a/talpid-core/src/process/openvpn.rs b/talpid-core/src/process/openvpn.rs index 104471db2b..a55d5d3453 100644 --- a/talpid-core/src/process/openvpn.rs +++ b/talpid-core/src/process/openvpn.rs @@ -61,7 +61,7 @@ pub struct OpenVpnCommand { iproute_bin: Option<OsString>, plugin: Option<(PathBuf, Vec<String>)>, log: Option<PathBuf>, - tunnel_options: net::OpenVpnTunnelOptions, + tunnel_options: net::openvpn::TunnelOptions, tunnel_alias: Option<OsString>, enable_ipv6: bool, } @@ -81,7 +81,7 @@ impl OpenVpnCommand { iproute_bin: None, plugin: None, log: None, - tunnel_options: net::OpenVpnTunnelOptions::default(), + tunnel_options: net::openvpn::TunnelOptions::default(), tunnel_alias: None, enable_ipv6: true, } @@ -150,7 +150,7 @@ impl OpenVpnCommand { } /// Sets extra options - pub fn tunnel_options(&mut self, tunnel_options: &net::OpenVpnTunnelOptions) -> &mut Self { + pub fn tunnel_options(&mut self, tunnel_options: &net::openvpn::TunnelOptions) -> &mut Self { self.tunnel_options = tunnel_options.clone(); self } @@ -275,7 +275,7 @@ impl OpenVpnCommand { fn proxy_arguments(&self) -> Vec<String> { let mut args = vec![]; match self.tunnel_options.proxy { - Some(net::OpenVpnProxySettings::Local(ref local_proxy)) => { + Some(net::openvpn::ProxySettings::Local(ref local_proxy)) => { args.push("--socks-proxy".to_owned()); args.push("127.0.0.1".to_owned()); args.push(local_proxy.port.to_string()); @@ -284,7 +284,7 @@ impl OpenVpnCommand { args.push("255.255.255.255".to_owned()); args.push("net_gateway".to_owned()); } - Some(net::OpenVpnProxySettings::Remote(ref remote_proxy)) => { + Some(net::openvpn::ProxySettings::Remote(ref remote_proxy)) => { args.push("--socks-proxy".to_owned()); args.push(remote_proxy.address.ip().to_string()); args.push(remote_proxy.address.port().to_string()); diff --git a/talpid-core/src/security/macos/mod.rs b/talpid-core/src/security/macos/mod.rs index b4d300e66f..cc14fbfd6e 100644 --- a/talpid-core/src/security/macos/mod.rs +++ b/talpid-core/src/security/macos/mod.rs @@ -1,6 +1,9 @@ use super::{NetworkSecurityT, SecurityPolicy}; use pfctl::FilterRuleAction; -use std::{env, net::Ipv4Addr}; +use std::{ + env, + net::{Ipv4Addr, SocketAddr}, +}; use talpid_types::net; mod dns; diff --git a/talpid-core/src/tunnel/mod.rs b/talpid-core/src/tunnel/mod.rs index 4011db3e84..c0f1abcde2 100644 --- a/talpid-core/src/tunnel/mod.rs +++ b/talpid-core/src/tunnel/mod.rs @@ -6,7 +6,9 @@ use std::{ path::{Path, PathBuf}, }; -use talpid_types::net::{TunnelEndpoint, TunnelEndpointData, TunnelOptions}; +#[cfg(unix)] +use talpid_types::net::wireguard as wireguard_types; +use talpid_types::net::{openvpn as openvpn_types, GenericTunnelOptions, TunnelParameters}; /// A module for all OpenVPN related tunnel management. pub mod openvpn; @@ -113,10 +115,8 @@ impl TunnelMonitor { /// Creates a new `TunnelMonitor` that connects to the given remote and notifies `on_event` /// on tunnel state changes. pub fn start<L>( - tunnel_endpoint: TunnelEndpoint, - tunnel_options: &TunnelOptions, + tunnel_parameters: &TunnelParameters, tunnel_alias: Option<OsString>, - username: &str, log: Option<PathBuf>, resource_dir: &Path, on_event: L, @@ -124,60 +124,46 @@ impl TunnelMonitor { where L: Fn(TunnelEvent) + Send + Sync + 'static, { - Self::ensure_ipv6_can_be_used_if_enabled(tunnel_options)?; - match &tunnel_endpoint.tunnel { - TunnelEndpointData::OpenVpn(_) => Self::start_openvpn_tunnel( - tunnel_endpoint, - tunnel_options, - tunnel_alias, - username, - log, - resource_dir, - on_event, - ), + Self::ensure_ipv6_can_be_used_if_enabled(&tunnel_parameters.get_generic_options())?; + + match tunnel_parameters { + TunnelParameters::OpenVpn(config) => { + Self::start_openvpn_tunnel(&config, tunnel_alias, log, resource_dir, on_event) + } #[cfg(unix)] - TunnelEndpointData::Wireguard(_) => { - Self::start_wireguard_tunnel(tunnel_endpoint, tunnel_options, log, on_event) + TunnelParameters::Wireguard(config) => { + Self::start_wireguard_tunnel(&config, log, on_event) } #[cfg(windows)] - TunnelEndpointData::Wireguard(_) => bail!(ErrorKind::UnsupportedPlatform), + TunnelParameters::Wireguard(_) => bail!(ErrorKind::UnsupportedPlatform), } } #[cfg(unix)] fn start_wireguard_tunnel<L>( - tunnel_endpoint: TunnelEndpoint, - tunnel_options: &TunnelOptions, + params: &wireguard_types::TunnelParameters, log: Option<PathBuf>, on_event: L, ) -> Result<Self> where L: Fn(TunnelEvent) + Send + Sync + 'static, { - let TunnelEndpoint { address, tunnel } = tunnel_endpoint; - let data = match tunnel { - TunnelEndpointData::Wireguard(data) => data, - _ => unreachable!("expected wireguard endpoint data"), - }; - + let config = wireguard::config::Config::from_parameters(¶ms) + .chain_err(|| ErrorKind::TunnelMonitoringError)?; let monitor = wireguard::WireguardMonitor::start( - address, - data, - tunnel_options, + &config, log.as_ref().map(|p| p.as_path()), on_event, ) - .chain_err(|| ErrorKind::TunnelMonitoringError)?; + .chain_err(|| ErrorKind::TunnelMonitorSetUpError)?; Ok(TunnelMonitor { monitor: InternalTunnelMonitor::Wireguard(monitor), }) } fn start_openvpn_tunnel<L>( - tunnel_endpoint: TunnelEndpoint, - tunnel_options: &TunnelOptions, + config: &openvpn_types::TunnelParameters, tunnel_alias: Option<OsString>, - username: &str, log: Option<PathBuf>, resource_dir: &Path, on_event: L, @@ -185,22 +171,15 @@ impl TunnelMonitor { where L: Fn(TunnelEvent) + Send + Sync + 'static, { - let monitor = openvpn::OpenVpnMonitor::start( - on_event, - tunnel_endpoint.to_endpoint(), - tunnel_options, - tunnel_alias, - log, - resource_dir, - username, - ) - .chain_err(|| ErrorKind::TunnelMonitorSetUpError)?; + let monitor = + openvpn::OpenVpnMonitor::start(on_event, config, tunnel_alias, log, resource_dir) + .chain_err(|| ErrorKind::TunnelMonitorSetUpError)?; Ok(TunnelMonitor { monitor: InternalTunnelMonitor::OpenVpn(monitor), }) } - fn ensure_ipv6_can_be_used_if_enabled(tunnel_options: &TunnelOptions) -> Result<()> { + fn ensure_ipv6_can_be_used_if_enabled(tunnel_options: &GenericTunnelOptions) -> Result<()> { if tunnel_options.enable_ipv6 && !is_ipv6_enabled_in_os() { bail!(ErrorKind::EnableIpv6Error); } else { diff --git a/talpid-core/src/tunnel/openvpn.rs b/talpid-core/src/tunnel/openvpn.rs index fadb035966..38aee11755 100644 --- a/talpid-core/src/tunnel/openvpn.rs +++ b/talpid-core/src/tunnel/openvpn.rs @@ -23,7 +23,7 @@ use std::{ time::Duration, }; use talpid_ipc; -use talpid_types::net::{Endpoint, OpenVpnProxySettings, TunnelOptions}; +use talpid_types::net::openvpn; #[cfg(target_os = "linux")] use which; @@ -107,20 +107,19 @@ impl OpenVpnMonitor<OpenVpnCommand> { /// path. pub fn start<L>( on_event: L, - endpoint: Endpoint, - tunnel_options: &TunnelOptions, + params: &openvpn::TunnelParameters, tunnel_alias: Option<OsString>, log_path: Option<PathBuf>, resource_dir: &Path, - username: &str, ) -> Result<Self> where L: Fn(TunnelEvent) + Send + Sync + 'static, { - let user_pass_file = Self::create_credentials_file(username, "-") - .chain_err(|| ErrorKind::CredentialsWriteError)?; + let user_pass_file = + Self::create_credentials_file(¶ms.config.username, ¶ms.config.password) + .chain_err(|| ErrorKind::CredentialsWriteError)?; - let proxy_auth_file = Self::create_proxy_auth_file(&tunnel_options.openvpn.proxy) + let proxy_auth_file = Self::create_proxy_auth_file(¶ms.options.proxy) .chain_err(|| ErrorKind::CredentialsWriteError)?; @@ -147,9 +146,8 @@ impl OpenVpnMonitor<OpenVpnCommand> { } }; let cmd = Self::create_openvpn_cmd( - endpoint, + params, tunnel_alias, - &tunnel_options, user_pass_file.as_ref(), match proxy_auth_file { Some(ref file) => Some(file.as_ref()), @@ -293,9 +291,9 @@ impl<C: OpenVpnBuilder> OpenVpnMonitor<C> { } fn create_proxy_auth_file( - proxy: &Option<OpenVpnProxySettings>, + proxy: &Option<openvpn::ProxySettings>, ) -> ::std::result::Result<Option<mktemp::TempFile>, io::Error> { - if let Some(OpenVpnProxySettings::Remote(ref remote_proxy)) = proxy { + if let Some(openvpn::ProxySettings::Remote(ref remote_proxy)) = proxy { if let Some(ref proxy_auth) = remote_proxy.auth { return Ok(Some(Self::create_credentials_file( &proxy_auth.username, @@ -339,9 +337,8 @@ impl<C: OpenVpnBuilder> OpenVpnMonitor<C> { } fn create_openvpn_cmd( - remote: Endpoint, + params: &openvpn::TunnelParameters, tunnel_alias: Option<OsString>, - options: &TunnelOptions, user_pass_file: &Path, proxy_auth_file: Option<&Path>, resource_dir: &Path, @@ -356,10 +353,10 @@ impl<C: OpenVpnBuilder> OpenVpnMonitor<C> { .compat() .chain_err(|| ErrorKind::IpRouteNotFound)?, ); - cmd.remote(remote) + cmd.remote(params.config.get_tunnel_endpoint().endpoint) .user_pass(user_pass_file) - .tunnel_options(&options.openvpn) - .enable_ipv6(options.enable_ipv6) + .tunnel_options(¶ms.options) + .enable_ipv6(params.generic_options.enable_ipv6) .tunnel_alias(tunnel_alias) .ca(resource_dir.join("ca.crt")); if let Some(proxy_auth_file) = proxy_auth_file { diff --git a/talpid-core/src/tunnel/wireguard/config.rs b/talpid-core/src/tunnel/wireguard/config.rs index a99e46994f..a15f377165 100644 --- a/talpid-core/src/tunnel/wireguard/config.rs +++ b/talpid-core/src/tunnel/wireguard/config.rs @@ -1,60 +1,83 @@ -use super::{ErrorKind, Result}; -use ipnetwork::IpNetwork; -use std::{ - borrow::Cow, - ffi::CString, - net::{IpAddr, SocketAddr}, -}; -use talpid_types::net::{TunnelOptions, WgPrivateKey, WgPublicKey, WireguardEndpointData}; +use std::{borrow::Cow, ffi::CString, net::IpAddr}; +use talpid_types::net::{wireguard, GenericTunnelOptions}; pub struct Config { - pub interface: TunnelConfig, + pub tunnel: wireguard::TunnelConfig, + pub peers: Vec<wireguard::PeerConfig>, pub gateway: IpAddr, - pub preferred_name: Option<String>, + pub mtu: u16, + #[cfg(target_os = "linux")] + pub fwmark: i32, +} + +/// Smallest MTU that supports IPv6 +const SMALLEST_IPV6_MTU: u16 = 1420; +const DEFAULT_MTU: u16 = SMALLEST_IPV6_MTU; + +error_chain! { + errors { + InvalidTunnelIpError { + description("No valid tunnel IP"), + } + + InvalidPeerIpError { + description("Supplied peer has no valid IPs") + } + + NoPeersSuppliedError{ + description("No peers supplied") + } + } } -// Smallest MTU that supports IPv6 -const MIN_IPV6_MTU: u16 = 1420; -const DEFAULT_MTU: u16 = MIN_IPV6_MTU; impl Config { - pub fn from_data( - ip: IpAddr, - data: WireguardEndpointData, - options: &TunnelOptions, + pub fn from_parameters(params: &wireguard::TunnelParameters) -> Result<Config> { + let tunnel = params.connection.tunnel.clone(); + let peer = vec![params.connection.peer.clone()]; + Self::new( + tunnel, + peer, + params.connection.gateway, + ¶ms.options, + ¶ms.generic_options, + ) + } + + pub fn new( + mut tunnel: wireguard::TunnelConfig, + mut peers: Vec<wireguard::PeerConfig>, + gateway: IpAddr, + wg_options: &wireguard::TunnelOptions, + generic_options: &GenericTunnelOptions, ) -> Result<Config> { - let private_key = match data.client_private_key { - Some(private_key) => private_key, - None => bail!(ErrorKind::NoKeyError), - }; + ensure!(peers.is_empty(), ErrorKind::NoPeersSuppliedError); + let mtu = wg_options.mtu.unwrap_or(DEFAULT_MTU); + let is_ipv6_enabled = mtu >= SMALLEST_IPV6_MTU && generic_options.enable_ipv6; - let mtu = options.wireguard.mtu.unwrap_or(DEFAULT_MTU); - let ipv6_enabled = options.enable_ipv6 && mtu >= MIN_IPV6_MTU; - let peer = PeerConfig { - public_key: data.peer_public_key, - allowed_ips: all_of_the_internet() - .into_iter() - .filter(|ip| ip.is_ipv4() || ipv6_enabled) - .collect(), - endpoint: SocketAddr::new(ip, data.port), - }; + for peer in &mut peers { + peer.allowed_ips = peer + .allowed_ips + .iter() + .cloned() + .filter(|ip| ip.is_ipv4() || is_ipv6_enabled) + .collect(); + ensure!(peer.allowed_ips.is_empty(), ErrorKind::InvalidPeerIpError); + } - let tunnel_config = TunnelConfig { - private_key, - addresses: data - .addresses - .into_iter() - .filter(|ip| ip.is_ipv4() || ipv6_enabled) - .collect(), - mtu, - #[cfg(target_os = "linux")] - fwmark: options.wireguard.fwmark, - peers: vec![peer], - }; + tunnel.addresses = tunnel + .addresses + .into_iter() + .filter(|ip| ip.is_ipv4() || is_ipv6_enabled) + .collect(); + ensure!(tunnel.addresses.is_empty(), ErrorKind::InvalidTunnelIpError); Ok(Config { - interface: tunnel_config, - gateway: data.gateway, - preferred_name: Some("talpid".to_string()), + tunnel, + peers, + gateway, + mtu, + #[cfg(target_os = "linux")] + fwmark: wg_options.fwmark, }) } @@ -63,20 +86,17 @@ impl Config { // the order of insertion matters, public key entry denotes a new peer entry let mut wg_conf = WgConfigBuffer::new(); wg_conf - .add( - "private_key", - self.interface.private_key.as_bytes().as_ref(), - ) + .add("private_key", self.tunnel.private_key.as_bytes().as_ref()) .add("listen_port", "0"); #[cfg(target_os = "linux")] { - wg_conf.add("fwmark", self.interface.fwmark.to_string().as_str()); + wg_conf.add("fwmark", self.fwmark.to_string().as_str()); } wg_conf.add("replace_peers", "true"); - for peer in &self.interface.peers { + for peer in &self.peers { wg_conf .add("public_key", peer.public_key.as_bytes().as_ref()) .add("endpoint", peer.endpoint.to_string().as_str()) @@ -91,29 +111,6 @@ impl Config { } } -pub struct PeerConfig { - pub public_key: WgPublicKey, - pub allowed_ips: Vec<IpNetwork>, - pub endpoint: SocketAddr, -} - -pub struct TunnelConfig { - pub private_key: WgPrivateKey, - pub addresses: Vec<IpAddr>, - #[cfg(target_os = "linux")] - pub fwmark: i32, - pub mtu: u16, - pub peers: Vec<PeerConfig>, -} - - -fn all_of_the_internet() -> Vec<IpNetwork> { - vec![ - "::0/0".parse().expect("Failed to parse ipv6 network"), - "0.0.0.0/0".parse().expect("Failed to parse ipv4 network"), - ] -} - pub enum ConfValue<'a> { String(&'a str), Bytes(&'a [u8]), diff --git a/talpid-core/src/tunnel/wireguard/mod.rs b/talpid-core/src/tunnel/wireguard/mod.rs index c74dc8d41e..cc60f71c38 100644 --- a/talpid-core/src/tunnel/wireguard/mod.rs +++ b/talpid-core/src/tunnel/wireguard/mod.rs @@ -1,8 +1,7 @@ use self::config::Config; use super::{TunnelEvent, TunnelMetadata}; use crate::routing; -use std::{net::IpAddr, path::Path, sync::mpsc}; -use talpid_types::net::{TunnelOptions, WireguardEndpointData}; +use std::{path::Path, sync::mpsc}; pub mod config; mod ping_monitor; @@ -15,6 +14,10 @@ const PING_TIMEOUT: u16 = 5; error_chain! { errors { + /// Config error + ConfigError{ + description("Invalid configuration") + } /// Failed to setup a tunnel device SetupTunnelDeviceError { description("Failed to create tunnel device") @@ -64,13 +67,10 @@ pub struct WireguardMonitor { impl WireguardMonitor { pub fn start<F: Fn(TunnelEvent) + Send + Sync + 'static>( - address: IpAddr, - data: WireguardEndpointData, - options: &TunnelOptions, + config: &Config, log_path: Option<&Path>, on_event: F, ) -> Result<WireguardMonitor> { - let config = Config::from_data(address, data.clone(), options)?; let tunnel = Box::new(WgGoTunnel::start_tunnel(&config, log_path)?); let router = routing::RouteManager::new().chain_err(|| ErrorKind::SetupRoutingError)?; let event_callback = Box::new(on_event); @@ -84,7 +84,7 @@ impl WireguardMonitor { }; monitor.setup_routing(&config)?; monitor.start_pinger(&config); - monitor.tunnel_up(data); + monitor.tunnel_up(&config); Ok(monitor) } @@ -111,7 +111,6 @@ impl WireguardMonitor { fn setup_routing(&mut self, config: &Config) -> Result<()> { let iface_name = self.tunnel.get_interface_name(); let mut routes: Vec<_> = config - .interface .peers .iter() .flat_map(|peer| peer.allowed_ips.iter()) @@ -129,11 +128,12 @@ impl WireguardMonitor { .router .get_default_route_node() .chain_err(|| ErrorKind::SetupRoutingError)?; + // route endpoints with specific routes - for peer in config.interface.peers.iter() { + for peer in config.peers.iter() { let default_route = routing::Route::new( - peer.endpoint.ip().clone().into(), - routing::NetNode::Address(default_node.clone()), + peer.endpoint.ip().into(), + routing::NetNode::Address(default_node), ); routes.push(default_route); } @@ -142,7 +142,7 @@ impl WireguardMonitor { let required_routes = routing::RequiredRoutes { routes, #[cfg(target_os = "linux")] - fwmark: Some(config.interface.fwmark.to_string()), + fwmark: Some(config.fwmark.to_string()), }; self.router .add_routes(required_routes) @@ -162,12 +162,12 @@ impl WireguardMonitor { ) } - fn tunnel_up(&self, data: WireguardEndpointData) { + fn tunnel_up(&self, config: &Config) { let interface_name = self.tunnel.get_interface_name(); let metadata = TunnelMetadata { interface: interface_name.to_string(), - ips: data.addresses, - gateway: data.gateway, + ips: config.tunnel.addresses.clone(), + gateway: config.gateway, }; (self.event_callback)(TunnelEvent::Up(metadata)); } diff --git a/talpid-core/src/tunnel/wireguard/wireguard_go.rs b/talpid-core/src/tunnel/wireguard/wireguard_go.rs index 32d82889cc..e9531e88be 100644 --- a/talpid-core/src/tunnel/wireguard/wireguard_go.rs +++ b/talpid-core/src/tunnel/wireguard/wireguard_go.rs @@ -20,7 +20,7 @@ impl WgGoTunnel { let mut tunnel_device = TunnelDevice::new().chain_err(|| ErrorKind::SetupTunnelDeviceError)?; - for ip in config.interface.addresses.iter() { + for ip in config.tunnel.addresses.iter() { tunnel_device .set_ip(*ip) .chain_err(|| ErrorKind::SetupTunnelDeviceError)?; @@ -40,7 +40,7 @@ impl WgGoTunnel { let handle = unsafe { wgTurnOnWithFd( iface_name.as_ptr(), - config.interface.mtu as i64, + config.mtu as i64, wg_config_str.as_ptr(), tunnel_device.as_raw_fd(), log_file.as_raw_fd(), diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs index 4a65e7fadd..b5a88c7181 100644 --- a/talpid-core/src/tunnel_state_machine/connected_state.rs +++ b/talpid-core/src/tunnel_state_machine/connected_state.rs @@ -4,14 +4,14 @@ use futures::{ Async, Future, Stream, }; use talpid_types::{ - net::{Endpoint, OpenVpnProxySettings, TransportProtocol}, + net::{Endpoint, TunnelParameters}, tunnel::BlockReason, }; use super::{ AfterDisconnect, BlockedState, ConnectingState, DisconnectingState, EventConsequence, Result, - ResultExt, SharedTunnelStateValues, TunnelCommand, TunnelParameters, TunnelState, - TunnelStateTransition, TunnelStateWrapper, + ResultExt, SharedTunnelStateValues, TunnelCommand, TunnelState, TunnelStateTransition, + TunnelStateWrapper, }; use crate::{ security::SecurityPolicy, @@ -48,17 +48,7 @@ impl ConnectedState { fn set_security_policy(&self, shared_values: &mut SharedTunnelStateValues) -> Result<()> { // If a proxy is specified we need to pass it on as the peer endpoint. - let peer_endpoint = match self.tunnel_parameters.options.openvpn.proxy { - Some(OpenVpnProxySettings::Local(ref local_proxy)) => Endpoint { - address: local_proxy.peer, - protocol: TransportProtocol::Tcp, - }, - Some(OpenVpnProxySettings::Remote(ref remote_proxy)) => Endpoint { - address: remote_proxy.address, - protocol: TransportProtocol::Tcp, - }, - _ => self.tunnel_parameters.endpoint.to_endpoint(), - }; + let peer_endpoint = self.get_endpoint_from_params(); let policy = SecurityPolicy::Connected { peer_endpoint, @@ -71,6 +61,16 @@ impl ConnectedState { .chain_err(|| "Failed to apply security policy for connected state") } + fn get_endpoint_from_params(&self) -> Endpoint { + match self.tunnel_parameters { + TunnelParameters::OpenVpn(ref config) => match config.options.proxy { + Some(ref proxy_settings) => proxy_settings.get_endpoint(), + None => self.tunnel_parameters.get_tunnel_endpoint().endpoint, + }, + _ => self.tunnel_parameters.get_tunnel_endpoint().endpoint, + } + } + fn set_dns(&self, shared_values: &mut SharedTunnelStateValues) -> Result<()> { shared_values .dns_monitor @@ -192,8 +192,8 @@ impl TunnelState for ConnectedState { shared_values: &mut SharedTunnelStateValues, bootstrap: Self::Bootstrap, ) -> (TunnelStateWrapper, TunnelStateTransition) { - let tunnel_endpoint = bootstrap.tunnel_parameters.endpoint.clone(); let connected_state = ConnectedState::from(bootstrap); + let tunnel_endpoint = connected_state.tunnel_parameters.get_tunnel_endpoint(); if let Err(error) = connected_state.set_security_policy(shared_values) { log::error!("{}", error.display_chain()); diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs index 3a4ea3d37a..ad3712144a 100644 --- a/talpid-core/src/tunnel_state_machine/connecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs @@ -12,14 +12,14 @@ use futures::{ }; use log::{debug, error, info, trace, warn}; use talpid_types::{ - net::{Endpoint, OpenVpnProxySettings, TransportProtocol, TunnelEndpoint, TunnelEndpointData}, + net::{openvpn, Endpoint, TunnelParameters}, tunnel::BlockReason, }; use super::{ AfterDisconnect, BlockedState, ConnectedState, ConnectedStateBootstrap, DisconnectingState, - EventConsequence, SharedTunnelStateValues, TunnelCommand, TunnelParameters, TunnelState, - TunnelStateTransition, TunnelStateWrapper, + EventConsequence, SharedTunnelStateValues, TunnelCommand, TunnelState, TunnelStateTransition, + TunnelStateWrapper, }; use crate::{ logging, @@ -62,20 +62,13 @@ pub struct ConnectingState { impl ConnectingState { fn set_security_policy( shared_values: &mut SharedTunnelStateValues, - proxy: &Option<OpenVpnProxySettings>, - endpoint: TunnelEndpoint, + proxy: &Option<openvpn::ProxySettings>, + endpoint: Endpoint, ) -> Result<()> { // If a proxy is specified we need to pass it on as the peer endpoint. let peer_endpoint = match proxy { - Some(OpenVpnProxySettings::Local(ref local_proxy)) => Endpoint { - address: local_proxy.peer, - protocol: TransportProtocol::Tcp, - }, - Some(OpenVpnProxySettings::Remote(ref remote_proxy)) => Endpoint { - address: remote_proxy.address, - protocol: TransportProtocol::Tcp, - }, - _ => endpoint.to_endpoint(), + Some(proxy_settings) => proxy_settings.get_endpoint(), + None => endpoint, }; let policy = SecurityPolicy::Connecting { @@ -120,10 +113,8 @@ impl ConnectingState { let log_file = Self::prepare_tunnel_log_file(¶meters, log_dir)?; Ok(TunnelMonitor::start( - parameters.endpoint.clone(), - ¶meters.options, + ¶meters, TUNNEL_INTERFACE_ALIAS.to_owned().map(OsString::from), - ¶meters.username, log_file.clone(), resource_dir, on_tunnel_event, @@ -135,9 +126,9 @@ impl ConnectingState { log_dir: &Option<PathBuf>, ) -> Result<Option<PathBuf>> { if let Some(ref log_dir) = log_dir { - let filename = match parameters.endpoint.tunnel { - TunnelEndpointData::OpenVpn(_) => OPENVPN_LOG_FILENAME, - TunnelEndpointData::Wireguard(_) => WIREGUARD_LOG_FILENAME, + let filename = match parameters { + TunnelParameters::OpenVpn(_) => OPENVPN_LOG_FILENAME, + TunnelParameters::Wireguard(_) => WIREGUARD_LOG_FILENAME, }; let tunnel_log = log_dir.join(filename); logging::rotate_log(&tunnel_log).chain_err(|| ErrorKind::RotateLogError)?; @@ -228,8 +219,8 @@ impl ConnectingState { shared_values.allow_lan = allow_lan; match Self::set_security_policy( shared_values, - &self.tunnel_parameters.options.openvpn.proxy, - self.tunnel_parameters.endpoint.clone(), + &get_openvpn_proxy_settings(&self.tunnel_parameters), + self.tunnel_parameters.get_tunnel_endpoint().endpoint, ) { Ok(()) => SameState(self), Err(error) => { @@ -292,6 +283,7 @@ impl ConnectingState { } } + fn handle_tunnel_events( mut self, shared_values: &mut SharedTunnelStateValues, @@ -351,6 +343,15 @@ impl ConnectingState { } } +fn get_openvpn_proxy_settings( + tunnel_parameters: &TunnelParameters, +) -> &Option<openvpn::ProxySettings> { + match tunnel_parameters { + TunnelParameters::OpenVpn(ref config) => &config.options.proxy, + _ => &None, + } +} + impl TunnelState for ConnectingState { type Bootstrap = u32; @@ -367,11 +368,11 @@ impl TunnelState for ConnectingState { { None => BlockedState::enter(shared_values, BlockReason::NoMatchingRelay), Some(tunnel_parameters) => { - let tunnel_endpoint = tunnel_parameters.endpoint.clone(); + let endpoint = tunnel_parameters.get_tunnel_endpoint().endpoint; if let Err(error) = Self::set_security_policy( shared_values, - &tunnel_parameters.options.openvpn.proxy, - tunnel_endpoint.clone(), + &get_openvpn_proxy_settings(&tunnel_parameters), + endpoint, ) { error!("{}", error.display_chain()); BlockedState::enter(shared_values, BlockReason::StartTunnelError) @@ -382,10 +383,13 @@ impl TunnelState for ConnectingState { &shared_values.resource_dir, retry_attempt, ) { - Ok(connecting_state) => ( - TunnelStateWrapper::from(connecting_state), - TunnelStateTransition::Connecting(tunnel_endpoint), - ), + Ok(connecting_state) => { + let params = connecting_state.tunnel_parameters.clone(); + ( + TunnelStateWrapper::from(connecting_state), + TunnelStateTransition::Connecting(params.get_tunnel_endpoint()), + ) + } Err(error) => { let block_reason = match *error.kind() { ErrorKind::TunnelMonitorError( diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs index 53d58060d3..8e20e3a159 100644 --- a/talpid-core/src/tunnel_state_machine/mod.rs +++ b/talpid-core/src/tunnel_state_machine/mod.rs @@ -18,7 +18,7 @@ use futures::{sync::mpsc, Async, Future, Poll, Stream}; use tokio_core::reactor::Core; use talpid_types::{ - net::{TunnelEndpoint, TunnelOptions}, + net::TunnelParameters, tunnel::{BlockReason, TunnelStateTransition}, }; @@ -162,17 +162,6 @@ pub enum TunnelCommand { Block(BlockReason), } -/// Information necessary to open a tunnel. -#[derive(Debug, PartialEq)] -pub struct TunnelParameters { - /// Tunnel enpoint to connect to. - pub endpoint: TunnelEndpoint, - /// Tunnel connection options. - pub options: TunnelOptions, - /// Username to use for setting up the tunnel. - pub username: String, -} - /// Asynchronous handling of the tunnel state machine. /// /// This type implements `Stream`, and attempts to advance the state machine based on the events |
