diff options
| author | David Lönnhager <david.l@mullvad.net> | 2020-09-18 13:45:10 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2020-09-22 13:12:18 +0200 |
| commit | aa040282b4c4b608a8f6e75d304a8f97af02833a (patch) | |
| tree | d1e6b78d257a76598737cb3ee3d6bf75c21b81af | |
| parent | 76ad0fdf0b9ba3141d9c1029158352e073047dc5 (diff) | |
| download | mullvadvpn-aa040282b4c4b608a8f6e75d304a8f97af02833a.tar.xz mullvadvpn-aa040282b4c4b608a8f6e75d304a8f97af02833a.zip | |
Don't use rt_tables for mullvad_exclusions
| -rw-r--r-- | talpid-core/src/routing/linux.rs | 93 |
1 files changed, 8 insertions, 85 deletions
diff --git a/talpid-core/src/routing/linux.rs b/talpid-core/src/routing/linux.rs index 404bda606f..bea318aacf 100644 --- a/talpid-core/src/routing/linux.rs +++ b/talpid-core/src/routing/linux.rs @@ -6,11 +6,9 @@ use crate::{ use talpid_types::ErrorExt; use ipnetwork::IpNetwork; -use regex::Regex; use std::{ collections::{BTreeMap, HashSet}, - fs, - io::{self, BufRead, BufReader, Read, Seek, Write}, + io, net::{IpAddr, Ipv4Addr}, }; @@ -35,9 +33,6 @@ use rtnetlink::{ use libc::{AF_INET, AF_INET6}; -const ROUTING_TABLE_NAME: &str = "mullvad_exclusions"; -const RT_TABLES_PATH: &str = "/etc/iproute2/rt_tables"; - pub type Result<T> = std::result::Result<T, Error>; @@ -70,11 +65,7 @@ pub enum Error { UnknownDeviceIndex(u32), /// Unable to create routing table for tagged connections and packets. - #[error(display = "Unable to create routing table for split tunneling")] - ExclusionsRoutingTableSetup(#[error(source)] io::Error), - - /// Unable to create routing table for tagged connections and packets. - #[error(display = "Cannot find a free routing table ID in rt_tables")] + #[error(display = "Cannot find a free routing table ID")] NoFreeRoutingTableId, #[error(display = "Shutting down route manager")] @@ -109,7 +100,7 @@ pub struct RouteManagerImpl { best_default_node_v4: Option<Node>, best_default_node_v6: Option<Node>, - split_table_id: i32, + split_table_id: u32, } impl RouteManagerImpl { @@ -127,7 +118,9 @@ impl RouteManagerImpl { tokio::spawn(connection); let iface_map = Self::initialize_link_map(&handle).await?; - let split_table_id = Self::initialize_exclusions_table().await?; + let split_table_id = Self::find_free_table_id(&handle).await?; + + log::trace!("Using table id {} for excluded apps", split_table_id); let mut monitor = Self { iface_map, @@ -155,8 +148,8 @@ impl RouteManagerImpl { Ok(monitor) } - async fn find_free_table_id(&self) -> Result<u32> { - let mut request = self.handle.route().get(IpVersion::V4).execute(); + async fn find_free_table_id(handle: &rtnetlink::Handle) -> Result<u32> { + let mut request = handle.route().get(IpVersion::V4).execute(); let mut used_ids = HashSet::new(); while let Some(route) = request.try_next().await.map_err(Error::NetlinkError)? { @@ -190,76 +183,6 @@ impl RouteManagerImpl { Err(Error::NoFreeRoutingTableId) } - /// Set up policy-based routing table for marked packets. - /// Returns the routing table id. - async fn initialize_exclusions_table() -> Result<i32> { - // Add routing table to /etc/iproute2/rt_tables, if it does not exist - - let file = fs::OpenOptions::new() - .read(true) - .open(RT_TABLES_PATH) - .map_err(Error::ExclusionsRoutingTableSetup)?; - let buf_reader = BufReader::new(file); - let expression = Regex::new(r"^\s*(\d+)\s+(\w+)").unwrap(); - - let mut used_ids = Vec::<i32>::new(); - - for line in buf_reader.lines() { - let line = line.map_err(Error::ExclusionsRoutingTableSetup)?; - if let Some(captures) = expression.captures(&line) { - let table_id = captures - .get(1) - .unwrap() - .as_str() - .parse::<i32>() - .expect("Table ID does not fit i32"); - let table_name = captures.get(2).unwrap().as_str(); - - if table_name == ROUTING_TABLE_NAME { - // The table has already been added - return Ok(table_id); - } - - used_ids.push(table_id); - } - } - - used_ids.sort_unstable(); - - // Assign a free id to the table - let mut table_id = 1; - loop { - if used_ids.binary_search(&table_id).is_err() { - break; - } - - table_id += 1; - - if table_id >= 256 { - return Err(Error::NoFreeRoutingTableId); - } - } - - let mut file = fs::OpenOptions::new() - .read(true) - .append(true) - .open(RT_TABLES_PATH) - .map_err(Error::ExclusionsRoutingTableSetup)?; - - if let Ok(_) = file.seek(io::SeekFrom::End(-1)) { - // Append newline if necessary - let mut buffer = [0u8]; - let _ = file.read_exact(&mut buffer); - if buffer[0] != b'\n' { - writeln!(file).map_err(Error::ExclusionsRoutingTableSetup)?; - } - } - - writeln!(file, "{} {}", table_id, ROUTING_TABLE_NAME) - .map_err(Error::ExclusionsRoutingTableSetup)?; - Ok(table_id) - } - /// Route PID-associated packets through the physical interface. async fn enable_exclusions_routes(&mut self) -> Result<()> { // TODO: IPv6 |
