Skip to content

Commit

Permalink
Remove recreateTunIfOpen
Browse files Browse the repository at this point in the history
  • Loading branch information
dlon committed Aug 9, 2024
1 parent c14bc32 commit aedf04c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,6 @@ open class TalpidVpnService : LifecycleVpnService() {
}
}

fun recreateTunIfOpen(config: TunConfig) {
synchronized(this) {
if (tunIsOpen) {
currentTunConfig = config
activeTunStatus = createTun(config)
}
}
}

fun closeTun() {
synchronized(this) { activeTunStatus = null }
}
Expand Down
109 changes: 41 additions & 68 deletions talpid-tunnel/src/tun_provider/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub struct AndroidTunProvider {
jvm: Arc<JavaVM>,
class: GlobalRef,
object: GlobalRef,
last_tun_config: (TunConfig, bool),
last_tun_config: Option<(TunConfig, bool)>,
allow_lan: bool,
custom_dns_servers: Option<Vec<IpAddr>>,
allowed_lan_networks: Vec<IpNetwork>,
Expand Down Expand Up @@ -82,7 +82,7 @@ impl AndroidTunProvider {
jvm: context.jvm,
class: talpid_vpn_service_class,
object: context.vpn_service,
last_tun_config: (TunConfig::default(), false),
last_tun_config: None,
allow_lan,
custom_dns_servers,
allowed_lan_networks,
Expand Down Expand Up @@ -122,22 +122,27 @@ impl AndroidTunProvider {
/// Retrieve a tunnel device with the provided configuration. Custom DNS and LAN routes are
/// appended to the provided config.
pub fn get_tun(&mut self, config: TunConfig) -> Result<VpnServiceTun, Error> {
let original_config = config;
let config = VpnServiceConfig::new(
original_config.clone(),
self.get_tun_inner(config, false)
}

/// Retrieve a tunnel device with the provided configuration.
fn get_tun_inner(&mut self, config: TunConfig, blocking: bool) -> Result<VpnServiceTun, Error> {
let service_config = VpnServiceConfig::new(
config.clone(),
&self.allowed_lan_networks,
self.allow_lan,
self.custom_dns_servers.clone(),
if !blocking {
self.custom_dns_servers.clone()
} else {
// Disable DNS
Some(vec![])
},
self.excluded_packages.clone(),
);
let tun = self.get_tun_inner(config)?;
self.last_tun_config = (original_config, false);
Ok(tun)
}

/// Retrieve a tunnel device with the provided configuration.
fn get_tun_inner(&self, config: VpnServiceConfig) -> Result<VpnServiceTun, Error> {
let tun_fd = self.get_tun_fd(config.clone())?;
let tun_fd = self.get_tun_fd(service_config)?;

self.last_tun_config = Some((config, blocking));

let jvm = unsafe { JavaVM::from_raw(self.jvm.get_java_vm_pointer()) }
.map_err(Error::CloneJavaVm)?;
Expand All @@ -150,23 +155,30 @@ impl AndroidTunProvider {
})
}

fn get_tun_fd(&self, config: VpnServiceConfig) -> Result<RawFd, Error> {
let env = self.env()?;
let java_config = config.into_java(&env);

let result = self.call_method(
"getTun",
"(Lnet/mullvad/talpid/model/TunConfig;)Lnet/mullvad/talpid/model/CreateTunResult;",
JavaType::Object("net/mullvad/talpid/model/CreateTunResult".to_owned()),
&[JValue::Object(java_config.as_obj())],
)?;

match result {
JValue::Object(result) => CreateTunResult::from_java(&env, result).into(),
value => Err(Error::InvalidMethodResult("getTun", format!("{:?}", value))),
}
}

/// Open a tunnel device that routes everything but (potentially) LAN routes via the tunnel
/// device. Excluded apps will also be kept.
///
/// Will open a new tunnel if there is already an active tunnel. The previous tunnel will be
/// closed.
pub fn create_blocking_tun(&mut self) -> Result<(), Error> {
let original_config = TunConfig::default();
let config = VpnServiceConfig::new(
original_config.clone(),
&self.allowed_lan_networks,
self.allow_lan,
// Disable DNS
Some(vec![]),
self.excluded_packages.clone(),
);
let _ = self.get_tun_inner(config)?;
self.last_tun_config = (original_config, true);
let _ = self.get_tun_inner(TunConfig::default(), true)?;
Ok(())
}

Expand All @@ -183,6 +195,8 @@ impl AndroidTunProvider {
Err(error) => Some(error),
};

self.last_tun_config = None;

if let Some(error) = error {
log::error!(
"{}",
Expand All @@ -191,52 +205,11 @@ impl AndroidTunProvider {
}
}

fn get_tun_fd(&self, config: VpnServiceConfig) -> Result<RawFd, Error> {
let env = self.env()?;
let java_config = config.into_java(&env);

let result = self.call_method(
"getTun",
"(Lnet/mullvad/talpid/model/TunConfig;)Lnet/mullvad/talpid/model/CreateTunResult;",
JavaType::Object("net/mullvad/talpid/model/CreateTunResult".to_owned()),
&[JValue::Object(java_config.as_obj())],
)?;

match result {
JValue::Object(result) => CreateTunResult::from_java(&env, result).into(),
value => Err(Error::InvalidMethodResult("getTun", format!("{:?}", value))),
}
}

fn recreate_tun_if_open(&mut self) -> Result<(), Error> {
let (last_tun_config, blocking) = self.last_tun_config.clone();

let config = VpnServiceConfig::new(
last_tun_config,
&self.allowed_lan_networks,
self.allow_lan,
if !blocking {
self.custom_dns_servers.clone()
} else {
Some(vec![])
},
self.excluded_packages.clone(),
);

let env = self.env()?;
let java_config = config.into_java(&env);

let result = self.call_method(
"recreateTunIfOpen",
"(Lnet/mullvad/talpid/model/TunConfig;)V",
JavaType::Primitive(Primitive::Void),
&[JValue::Object(java_config.as_obj())],
)?;

match result {
JValue::Void => Ok(()),
value => Err(Error::InvalidMethodResult("getTun", format!("{:?}", value))),
if let Some((config, blocking)) = self.last_tun_config.clone() {
let _ = self.get_tun_inner(config, blocking)?;
}
Ok(())
}

/// Allow a socket to bypass the tunnel.
Expand Down

0 comments on commit aedf04c

Please sign in to comment.