diff options
| author | David Lönnhager <david.l@mullvad.net> | 2020-11-23 15:58:18 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2020-11-24 12:29:47 +0100 |
| commit | 720b7031b3c1eade961d81391f50753f74fa65cb (patch) | |
| tree | 293cfe8d1a016829b50b61f99ba49c4d723107c0 | |
| parent | cba2460cabf9951e706de45024ff08f4511b0421 (diff) | |
| download | mullvadvpn-720b7031b3c1eade961d81391f50753f74fa65cb.tar.xz mullvadvpn-720b7031b3c1eade961d81391f50753f74fa65cb.zip | |
Use single /0 prefix routes, and remove handling of OpenVPN routes for non-Linux OSes
| -rw-r--r-- | talpid-core/src/tunnel/openvpn.rs | 142 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/wireguard/mod.rs | 13 |
2 files changed, 12 insertions, 143 deletions
diff --git a/talpid-core/src/tunnel/openvpn.rs b/talpid-core/src/tunnel/openvpn.rs index 1d6ed9e743..54591565fb 100644 --- a/talpid-core/src/tunnel/openvpn.rs +++ b/talpid-core/src/tunnel/openvpn.rs @@ -311,151 +311,13 @@ pub enum RouteParseError { } #[cfg(target_os = "linux")] -fn parse_openvpn_dict_routes( - env: &HashMap<String, String>, -) -> std::result::Result<Vec<OpenVpnRoute>, RouteParseError> { - let mut routes4 = HashMap::<u32, HashMap<&str, &str>>::new(); - let mut routes6 = HashMap::new(); - - const NUM_EXPECTED_CAPTURES: usize = 4; - - for (key, value) in env.iter() { - if let Some(captures) = ENV_ROUTE_ENTRY.captures(key) { - if captures.len() != NUM_EXPECTED_CAPTURES { - log::error!("Bug: unexpected number of captures"); - continue; - } - - let route_index: u32 = captures[3].parse().unwrap(); - let property = captures.get(2).unwrap().as_str(); - - let is_ipv6 = captures.get(1).is_some(); - let properties = if is_ipv6 { - routes6.entry(route_index).or_default() - } else { - routes4.entry(route_index).or_default() - }; - (*properties).insert(property, value); - } - } - - let parse_dict = |routes: HashMap<u32, HashMap<&str, &str>>, - is_ipv4| - -> std::result::Result<Vec<OpenVpnRoute>, RouteParseError> { - let mut routes = routes.into_iter().collect::<Vec<_>>(); - routes.sort_by(|(idx0, _), (idx1, _)| idx0.cmp(idx1)); - - let mut parsed_list = Vec::with_capacity(routes.len()); - - for (_, route) in routes { - let network = route - .get("network") - .ok_or(RouteParseError::MissingNetwork)?; - - let network = if is_ipv4 { - let network = network - .parse() - .map_err(RouteParseError::ParseNetworkAddress)?; - - let mask: IpAddr = if let Some(mask) = route.get("netmask") { - mask.parse().map_err(RouteParseError::ParseMaskAddress)? - } else { - "255.255.255.255".parse().unwrap() - }; - - IpNetwork::with_netmask(network, mask).map_err(RouteParseError::ParseNetwork)? - } else { - network.parse().map_err(RouteParseError::ParseNetwork)? - }; - - let gateway = route - .get("gateway") - .ok_or(RouteParseError::MissingGateway)? - .parse() - .map_err(RouteParseError::ParseGatewayAddress)?; - - parsed_list.push(OpenVpnRoute { network, gateway }); - } - Ok(parsed_list) - }; - - let mut routes = parse_dict(routes4, true)?; - routes.extend(parse_dict(routes6, false)?); - - Ok(routes) -} - -#[cfg(target_os = "linux")] fn extract_routes(env: &HashMap<String, String>) -> Result<HashSet<RequiredRoute>> { - let mut routes = HashSet::new(); - - let default_node_ip: IpAddr = env - .get("route_net_gateway") - .ok_or(Error::ParseRouteError(RouteParseError::MissingGateway))? - .parse() - .map_err(RouteParseError::ParseGatewayAddress) - .map_err(Error::ParseRouteError)?; - let tun_gateway_ip: IpAddr = env - .get("route_vpn_gateway") - .ok_or(Error::ParseRouteError(RouteParseError::MissingGateway))? - .parse() - .map_err(RouteParseError::ParseGatewayAddress) - .map_err(Error::ParseRouteError)?; - let tun_gateway_ip6: Option<IpAddr> = if let Some(gateway) = env.get("ifconfig_ipv6_remote") { - Some( - gateway - .parse() - .map_err(RouteParseError::ParseGatewayAddress) - .map_err(Error::ParseRouteError)?, - ) - } else { - None - }; - let tun_interface = env.get("dev").ok_or(Error::MissingTunnelInterface)?; - let tun_node = routing::NetNode::from(routing::Node::new( - tun_gateway_ip, - tun_interface.to_string(), - )); - #[cfg(windows)] - let tun_node6 = if tun_gateway_ip6.is_some() { - // The tapdrvr expects a special address here rather than a real gateway. - // See https://github.com/OpenVPN/openvpn/blob/23e11e591347080efa3b933beca7f620dd059d5c/src/openvpn/route.c#L2013 - routing::NetNode::from(routing::Node::new( - "fe80::8" - .parse() - .map_err(RouteParseError::ParseGatewayAddress) - .map_err(Error::ParseRouteError)?, - tun_interface.to_string(), - )) - } else { - routing::NetNode::from(routing::Node::device(tun_interface.to_string())) - }; - #[cfg(not(windows))] - let tun_node6 = routing::NetNode::from(routing::Node::device(tun_interface.to_string())); - - let ovpn_routes = parse_openvpn_dict_routes(env).map_err(Error::ParseRouteError)?; - - for route in ovpn_routes { - let node = if route.gateway == default_node_ip { - log::trace!("Ignoring route to physical interface: {:?}", route); - continue; - } else if route.gateway == tun_gateway_ip { - tun_node.clone() - } else if Some(route.gateway) == tun_gateway_ip6 { - tun_node6.clone() - } else { - routing::NetNode::from(routing::Node::address(route.gateway)) - }; - routes.insert(RequiredRoute::new(route.network, node)); - } - - #[cfg(target_os = "linux")] let tun_node = routing::Node::device(tun_interface.to_string()); - for network in &["0.0.0.0/1".parse().unwrap(), "128.0.0.0/1".parse().unwrap()] { + let mut routes = HashSet::new(); + for network in &["0.0.0.0/0".parse().unwrap(), "::/0".parse().unwrap()] { routes.insert(RequiredRoute::new(*network, tun_node.clone())); } - Ok(routes) } diff --git a/talpid-core/src/tunnel/wireguard/mod.rs b/talpid-core/src/tunnel/wireguard/mod.rs index dd18048dbb..9b2633725c 100644 --- a/talpid-core/src/tunnel/wireguard/mod.rs +++ b/talpid-core/src/tunnel/wireguard/mod.rs @@ -233,12 +233,18 @@ impl WireguardMonitor { } fn get_tunnel_routes(config: &Config) -> impl Iterator<Item = ipnetwork::IpNetwork> + '_ { - config + let routes = config .peers .iter() .flat_map(|peer| peer.allowed_ips.iter()) - .cloned() - .flat_map(|allowed_ip| { + .cloned(); + #[cfg(target_os = "linux")] + { + routes + } + #[cfg(not(target_os = "linux"))] + { + routes.flat_map(|allowed_ip| { if allowed_ip.prefix() == 0 { if allowed_ip.is_ipv4() { vec!["0.0.0.0/1".parse().unwrap(), "128.0.0.0/1".parse().unwrap()] @@ -249,6 +255,7 @@ impl WireguardMonitor { vec![allowed_ip] } }) + } } fn get_routes(iface_name: &str, config: &Config) -> HashSet<RequiredRoute> { |
