Skip to content

Commit 54f67bd

Browse files
committed
Merge branch 'android-refactor-tun-config'
2 parents bf9d513 + 68d699b commit 54f67bd

File tree

24 files changed

+506
-584
lines changed

24 files changed

+506
-584
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ Line wrap the file at 100 chars. Th
4040
#### macOS
4141
- Fix intermittent failures to connect with PQ enabled.
4242

43+
#### Android
44+
- Fix VPN service being recreated multiple times when toggling certain options.
45+
4346

4447
## [2024.4] - 2024-07-23
4548
This release is identical to 2024.4-beta1.

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt

+16-24
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ open class TalpidVpnService : LifecycleVpnService() {
2626
}
2727
}
2828

29-
private val tunIsOpen
30-
get() = activeTunStatus?.isOpen ?: false
31-
32-
private var currentTunConfig = defaultTunConfig()
29+
private var currentTunConfig: TunConfig? = null
3330

3431
// Used by JNI
3532
val connectivityListener = ConnectivityListener()
@@ -46,36 +43,33 @@ open class TalpidVpnService : LifecycleVpnService() {
4643
connectivityListener.unregister()
4744
}
4845

49-
fun getTun(config: TunConfig): CreateTunResult {
46+
fun openTun(config: TunConfig): CreateTunResult {
5047
synchronized(this) {
5148
val tunStatus = activeTunStatus
5249

53-
if (config == currentTunConfig && tunIsOpen) {
54-
return tunStatus!!
50+
if (config == currentTunConfig && tunStatus != null && tunStatus.isOpen) {
51+
return tunStatus
5552
} else {
56-
val newTunStatus = createTun(config)
57-
58-
currentTunConfig = config
59-
activeTunStatus = newTunStatus
60-
61-
return newTunStatus
53+
return openTunImpl(config)
6254
}
6355
}
6456
}
6557

66-
fun createTun() {
67-
synchronized(this) { activeTunStatus = createTun(currentTunConfig) }
68-
}
69-
70-
fun recreateTunIfOpen(config: TunConfig) {
58+
fun openTunForced(config: TunConfig): CreateTunResult {
7159
synchronized(this) {
72-
if (tunIsOpen) {
73-
currentTunConfig = config
74-
activeTunStatus = createTun(config)
75-
}
60+
return openTunImpl(config)
7661
}
7762
}
7863

64+
private fun openTunImpl(config: TunConfig): CreateTunResult {
65+
val newTunStatus = createTun(config)
66+
67+
currentTunConfig = config
68+
activeTunStatus = newTunStatus
69+
70+
return newTunStatus
71+
}
72+
7973
fun closeTun() {
8074
synchronized(this) { activeTunStatus = null }
8175
}
@@ -151,8 +145,6 @@ open class TalpidVpnService : LifecycleVpnService() {
151145
}
152146
}
153147

154-
private external fun defaultTunConfig(): TunConfig
155-
156148
private external fun waitForTunnelUp(tunFd: Int, isIpv6Enabled: Boolean)
157149

158150
companion object {

mullvad-jni/src/talpid_vpn_service.rs

+4-19
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
use ipnetwork::IpNetwork;
2-
use jnix::{
3-
jni::{
4-
objects::JObject,
5-
sys::{jboolean, jint, JNI_FALSE},
6-
JNIEnv,
7-
},
8-
IntoJava, JnixEnv,
2+
use jnix::jni::{
3+
objects::JObject,
4+
sys::{jboolean, jint, JNI_FALSE},
5+
JNIEnv,
96
};
107
use nix::sys::{
118
select::{pselect, FdSet},
@@ -18,7 +15,6 @@ use std::{
1815
os::unix::io::RawFd,
1916
time::{Duration, Instant},
2017
};
21-
use talpid_tunnel::tun_provider::TunConfig;
2218
use talpid_types::ErrorExt;
2319

2420
#[derive(Debug, thiserror::Error)]
@@ -33,17 +29,6 @@ enum Error {
3329
TunnelDeviceTimeout,
3430
}
3531

36-
#[no_mangle]
37-
#[allow(non_snake_case)]
38-
pub extern "system" fn Java_net_mullvad_talpid_TalpidVpnService_defaultTunConfig<'env>(
39-
env: JNIEnv<'env>,
40-
_this: JObject<'_>,
41-
) -> JObject<'env> {
42-
let env = JnixEnv::from(env);
43-
44-
TunConfig::default().into_java(&env).forget()
45-
}
46-
4732
#[no_mangle]
4833
#[allow(non_snake_case)]
4934
pub extern "system" fn Java_net_mullvad_talpid_TalpidVpnService_waitForTunnelUp(

talpid-core/src/firewall/linux.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ use std::{
1212
fs, io,
1313
net::{IpAddr, Ipv4Addr},
1414
};
15-
use talpid_types::net::{AllowedEndpoint, AllowedTunnelTraffic, Endpoint, TransportProtocol};
15+
use talpid_types::net::{
16+
AllowedEndpoint, AllowedTunnelTraffic, Endpoint, TransportProtocol, ALLOWED_LAN_MULTICAST_NETS,
17+
ALLOWED_LAN_NETS,
18+
};
1619

1720
/// Priority for rules that tag split tunneling packets. Equals NF_IP_PRI_MANGLE.
1821
const MANGLE_CHAIN_PRIORITY: i32 = libc::NF_IP_PRI_MANGLE;
@@ -840,15 +843,15 @@ impl<'a> PolicyBatch<'a> {
840843
// Output and forward chains
841844
for chain in &[&self.out_chain, &self.forward_chain] {
842845
// LAN -> LAN
843-
for net in &*super::ALLOWED_LAN_NETS {
846+
for net in &*ALLOWED_LAN_NETS {
844847
let mut out_rule = Rule::new(chain);
845848
check_net(&mut out_rule, End::Dst, *net);
846849
add_verdict(&mut out_rule, &Verdict::Accept);
847850
self.batch.add(&out_rule, nftnl::MsgType::Add);
848851
}
849852

850853
// LAN -> Multicast
851-
for net in &*super::ALLOWED_LAN_MULTICAST_NETS {
854+
for net in &*ALLOWED_LAN_MULTICAST_NETS {
852855
let mut rule = Rule::new(chain);
853856
check_net(&mut rule, End::Dst, *net);
854857
add_verdict(&mut rule, &Verdict::Accept);
@@ -858,7 +861,7 @@ impl<'a> PolicyBatch<'a> {
858861

859862
// Input chain
860863
// LAN -> LAN
861-
for net in &*super::ALLOWED_LAN_NETS {
864+
for net in &*ALLOWED_LAN_NETS {
862865
let mut in_rule = Rule::new(&self.in_chain);
863866
check_net(&mut in_rule, End::Src, *net);
864867
add_verdict(&mut in_rule, &Verdict::Accept);

talpid-core/src/firewall/macos.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use std::{
88
ptr,
99
};
1010
use subslice::SubsliceExt;
11-
use talpid_types::net::{self, AllowedEndpoint, AllowedTunnelTraffic};
11+
use talpid_types::net::{
12+
self, AllowedEndpoint, AllowedTunnelTraffic, ALLOWED_LAN_MULTICAST_NETS, ALLOWED_LAN_NETS,
13+
};
1214

1315
pub use pfctl::Error;
1416

@@ -494,7 +496,7 @@ impl Firewall {
494496

495497
fn get_allow_lan_rules(&self) -> Result<Vec<pfctl::FilterRule>> {
496498
let mut rules = vec![];
497-
for net in &*super::ALLOWED_LAN_NETS {
499+
for net in &*ALLOWED_LAN_NETS {
498500
let mut rule_builder = self.create_rule_builder(FilterRuleAction::Pass);
499501
rule_builder.quick(true);
500502
let allow_out = rule_builder
@@ -510,7 +512,7 @@ impl Firewall {
510512
rules.push(allow_out);
511513
rules.push(allow_in);
512514
}
513-
for multicast_net in &*super::ALLOWED_LAN_MULTICAST_NETS {
515+
for multicast_net in &*ALLOWED_LAN_MULTICAST_NETS {
514516
let allow_multicast_out = self
515517
.create_rule_builder(FilterRuleAction::Pass)
516518
.quick(true)

talpid-core/src/firewall/mod.rs

+3-38
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
fmt,
55
net::{IpAddr, Ipv4Addr, Ipv6Addr},
66
};
7-
use talpid_types::net::{AllowedEndpoint, AllowedTunnelTraffic};
7+
use talpid_types::net::{AllowedEndpoint, AllowedTunnelTraffic, ALLOWED_LAN_NETS};
88

99
#[cfg(target_os = "macos")]
1010
#[path = "macos.rs"]
@@ -24,39 +24,6 @@ mod imp;
2424

2525
pub use self::imp::Error;
2626

27-
/// When "allow local network" is enabled the app will allow traffic to and from these networks.
28-
pub(crate) static ALLOWED_LAN_NETS: Lazy<[IpNetwork; 6]> = Lazy::new(|| {
29-
[
30-
IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(10, 0, 0, 0), 8).unwrap()),
31-
IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(172, 16, 0, 0), 12).unwrap()),
32-
IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(192, 168, 0, 0), 16).unwrap()),
33-
IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(169, 254, 0, 0), 16).unwrap()),
34-
IpNetwork::V6(Ipv6Network::new(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0), 10).unwrap()),
35-
IpNetwork::V6(Ipv6Network::new(Ipv6Addr::new(0xfc00, 0, 0, 0, 0, 0, 0, 0), 7).unwrap()),
36-
]
37-
});
38-
/// When "allow local network" is enabled the app will allow traffic to these networks.
39-
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "android"))]
40-
pub(crate) static ALLOWED_LAN_MULTICAST_NETS: Lazy<[IpNetwork; 8]> = Lazy::new(|| {
41-
[
42-
// Local network broadcast. Not routable
43-
IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(255, 255, 255, 255), 32).unwrap()),
44-
// Local subnetwork multicast. Not routable
45-
IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(224, 0, 0, 0), 24).unwrap()),
46-
// Admin-local IPv4 multicast.
47-
IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(239, 0, 0, 0), 8).unwrap()),
48-
// Interface-local IPv6 multicast.
49-
IpNetwork::V6(Ipv6Network::new(Ipv6Addr::new(0xff01, 0, 0, 0, 0, 0, 0, 0), 16).unwrap()),
50-
// Link-local IPv6 multicast. IPv6 equivalent of 224.0.0.0/24
51-
IpNetwork::V6(Ipv6Network::new(Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0), 16).unwrap()),
52-
// Realm-local IPv6 multicast.
53-
IpNetwork::V6(Ipv6Network::new(Ipv6Addr::new(0xff03, 0, 0, 0, 0, 0, 0, 0), 16).unwrap()),
54-
// Admin-local IPv6 multicast.
55-
IpNetwork::V6(Ipv6Network::new(Ipv6Addr::new(0xff04, 0, 0, 0, 0, 0, 0, 0), 16).unwrap()),
56-
// Site-local IPv6 multicast.
57-
IpNetwork::V6(Ipv6Network::new(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 0), 16).unwrap()),
58-
]
59-
});
6027
#[cfg(any(target_os = "linux", target_os = "macos"))]
6128
static IPV6_LINK_LOCAL: Lazy<Ipv6Network> =
6229
Lazy::new(|| Ipv6Network::new(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0), 10).unwrap());
@@ -76,10 +43,8 @@ static SOLICITED_NODE_MULTICAST: Lazy<Ipv6Network> =
7643
Lazy::new(|| Ipv6Network::new(Ipv6Addr::new(0xff02, 0, 0, 0, 0, 1, 0xFF00, 0), 104).unwrap());
7744
static LOOPBACK_NETS: Lazy<[IpNetwork; 2]> = Lazy::new(|| {
7845
[
79-
IpNetwork::V4(ipnetwork::Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 0), 8).unwrap()),
80-
IpNetwork::V6(
81-
ipnetwork::Ipv6Network::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 128).unwrap(),
82-
),
46+
IpNetwork::V4(Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 0), 8).unwrap()),
47+
IpNetwork::V6(Ipv6Network::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 128).unwrap()),
8348
]
8449
});
8550

0 commit comments

Comments
 (0)