diff --git a/nym-vpn-android/nym-vpn-client/src/main/java/net/nymtech/vpn/backend/NymBackend.kt b/nym-vpn-android/nym-vpn-client/src/main/java/net/nymtech/vpn/backend/NymBackend.kt index 3e337881aa..a0b2f81725 100644 --- a/nym-vpn-android/nym-vpn-client/src/main/java/net/nymtech/vpn/backend/NymBackend.kt +++ b/nym-vpn-android/nym-vpn-client/src/main/java/net/nymtech/vpn/backend/NymBackend.kt @@ -46,6 +46,7 @@ import nym_vpn_lib.waitForRegisterDevice import nym_vpn_lib.waitForUpdateAccount import nym_vpn_lib.waitForUpdateDevice import timber.log.Timber +import java.net.InetAddress import java.util.concurrent.atomic.AtomicBoolean import kotlin.properties.Delegates diff --git a/nym-vpn-android/nym-vpn-client/src/main/java/net/nymtech/vpn/util/extensions/TunnelExtensions.kt b/nym-vpn-android/nym-vpn-client/src/main/java/net/nymtech/vpn/util/extensions/TunnelExtensions.kt index fa4a8727c1..c935fd21fd 100644 --- a/nym-vpn-android/nym-vpn-client/src/main/java/net/nymtech/vpn/util/extensions/TunnelExtensions.kt +++ b/nym-vpn-android/nym-vpn-client/src/main/java/net/nymtech/vpn/util/extensions/TunnelExtensions.kt @@ -6,10 +6,11 @@ import nym_vpn_lib.Ipv4Route import nym_vpn_lib.Ipv6Route import nym_vpn_lib.TunnelNetworkSettings import timber.log.Timber +import java.net.InetAddress fun VpnService.Builder.addRoutes(config: TunnelNetworkSettings, calculator: IpCalculator) { - val includedRoutes = mutableListOf() - val excludedRoutes = mutableListOf() + val includedRoutes = mutableSetOf() + val excludedRoutes = mutableSetOf() with(config.ipv4Settings) { this?.includedRoutes?.forEach { when (it) { @@ -38,6 +39,16 @@ fun VpnService.Builder.addRoutes(config: TunnelNetworkSettings, calculator: IpCa } } } + config.entryGatewayHostname?.let { + runCatching { + val address: InetAddress = InetAddress.getByName(it) + Timber.d("Entry gateway host name: ${address.hostName}") + Timber.d("Host name address: ${address.hostAddress}") + address.hostAddress?.let { + excludedRoutes.add(it) + } + } + } with(config.ipv6Settings) { this?.includedRoutes?.forEach { when (it) { @@ -67,7 +78,7 @@ fun VpnService.Builder.addRoutes(config: TunnelNetworkSettings, calculator: IpCa Timber.d("Excluded routes: $excludedRoutes") // Add all ipv6 to included to block ipv6 leaks if (!includedRoutes.contains(IpCalculator.ALL_IPV6_ADDRESS)) includedRoutes.add(IpCalculator.ALL_IPV6_ADDRESS) - val allowedIps = calculator.calculateAllowedIps(includedRoutes, excludedRoutes) + val allowedIps = calculator.calculateAllowedIps(includedRoutes.toList(), excludedRoutes.toList()) allowedIps.forEach { Timber.d("Adding allowed route: ${it.first}/${it.second}") addRoute(it.first, it.second) diff --git a/nym-vpn-core/crates/nym-vpn-lib/src/platform/error.rs b/nym-vpn-core/crates/nym-vpn-lib/src/platform/error.rs index 1e9db3d22d..18b7a40807 100644 --- a/nym-vpn-core/crates/nym-vpn-lib/src/platform/error.rs +++ b/nym-vpn-core/crates/nym-vpn-lib/src/platform/error.rs @@ -151,6 +151,7 @@ impl From for VpnError { code_reference_id: e.code_reference_id, } } + AccountCommandError::RegisterDeviceEndpointFailure(e) => { VpnError::DeviceRegistrationFailed { details: e.message, diff --git a/nym-vpn-core/crates/nym-vpn-lib/src/tunnel_provider/tunnel_settings.rs b/nym-vpn-core/crates/nym-vpn-lib/src/tunnel_provider/tunnel_settings.rs index c7c51d3f86..a13dee9912 100644 --- a/nym-vpn-core/crates/nym-vpn-lib/src/tunnel_provider/tunnel_settings.rs +++ b/nym-vpn-core/crates/nym-vpn-lib/src/tunnel_provider/tunnel_settings.rs @@ -13,6 +13,9 @@ pub struct TunnelSettings { /// Tunnel interface addresses. pub interface_addresses: Vec, + #[cfg(any(target_os = "ios", target_os = "android"))] + pub entry_gateway_hostname: Option, + /// DNS servers to set on tunnel interface. pub dns_servers: Vec, @@ -47,6 +50,7 @@ impl TunnelSettings { TunnelNetworkSettings { tunnel_remote_address: "127.0.0.1".to_owned(), + entry_gateway_hostname: self.entry_gateway_hostname, ipv4_settings, ipv6_settings, dns_settings: Some(DnsSettings { @@ -226,6 +230,9 @@ pub struct TunnelNetworkSettings { /// Tunnel remote address, which is mostly of decorative value. pub tunnel_remote_address: String, + /// host name of the entry gateway + pub entry_gateway_hostname: Option, + /// IPv4 interface settings. pub ipv4_settings: Option, diff --git a/nym-vpn-core/crates/nym-vpn-lib/src/tunnel_state_machine/tunnel_monitor.rs b/nym-vpn-core/crates/nym-vpn-lib/src/tunnel_state_machine/tunnel_monitor.rs index 458c299c22..ece7e7fae7 100644 --- a/nym-vpn-core/crates/nym-vpn-lib/src/tunnel_state_machine/tunnel_monitor.rs +++ b/nym-vpn-core/crates/nym-vpn-lib/src/tunnel_state_machine/tunnel_monitor.rs @@ -20,9 +20,6 @@ use tun::AsyncDevice; #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] use tun::Device; -#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] -use nym_ip_packet_requests::IpPair; - #[cfg(target_os = "linux")] use super::default_interface::DefaultInterface; #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] @@ -36,6 +33,9 @@ use super::{ ConnectionData, Error, ErrorStateReason, MixnetConnectionData, MixnetEvent, NymConfig, Result, TunnelConnectionData, TunnelSettings, TunnelType, WireguardConnectionData, WireguardNode, }; +#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] +use nym_ip_packet_requests::IpPair; +use nym_topology::NetworkAddress; #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] use super::tunnel::wireguard::connected_tunnel::{ @@ -282,7 +282,7 @@ impl TunnelMonitor { #[cfg(target_os = "android")] match connected_mixnet.websocket_fd().await { Some(fd) => { - self.tun_provider.bypass(fd); + //self.tun_provider.bypass(fd); } None => { tracing::error!("Failed to obtain websocket for bypass"); @@ -294,8 +294,25 @@ impl TunnelMonitor { .await; let selected_gateways = connected_mixnet.selected_gateways().clone(); + + #[cfg(any(target_os = "ios", target_os = "android"))] + let entry_hostname = match selected_gateways.clone().entry.host { + Some(address) => match address { + NetworkAddress::IpAddr(ip) => Some(ip.to_string()), + NetworkAddress::Hostname(host) => Some(host), + }, + None => None, + }; + let (tunnel_conn_data, mut tunnel_handle) = match self.tunnel_settings.tunnel_type { - TunnelType::Mixnet => self.start_mixnet_tunnel(connected_mixnet).await?, + TunnelType::Mixnet => { + self.start_mixnet_tunnel( + connected_mixnet, + #[cfg(any(target_os = "ios", target_os = "android"))] + entry_hostname, + ) + .await? + } TunnelType::Wireguard => { match self.tunnel_settings.wireguard_tunnel_options.multihop_mode { #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] @@ -303,8 +320,12 @@ impl TunnelMonitor { self.start_wireguard_tunnel(connected_mixnet).await? } WireguardMultihopMode::Netstack => { - self.start_wireguard_netstack_tunnel(connected_mixnet) - .await? + self.start_wireguard_netstack_tunnel( + connected_mixnet, + #[cfg(any(target_os = "ios", target_os = "android"))] + entry_hostname, + ) + .await? } } } @@ -365,6 +386,7 @@ impl TunnelMonitor { async fn start_mixnet_tunnel( &mut self, connected_mixnet: ConnectedMixnet, + #[cfg(any(target_os = "ios", target_os = "android"))] entry_hostname: Option, ) -> Result<(TunnelConnectionData, AnyTunnelHandle)> { let interface_addrs = self.tunnel_settings.mixnet_tunnel_options.interface_addrs; @@ -386,6 +408,7 @@ impl TunnelMonitor { let tun_device = { let packet_tunnel_settings = tunnel_provider::tunnel_settings::TunnelSettings { dns_servers: self.tunnel_settings.dns.ip_addresses().to_vec(), + entry_gateway_hostname: entry_hostname, interface_addresses: vec![ IpNetwork::V4(Ipv4Network::from( assigned_addresses.interface_addresses.ipv4, @@ -690,6 +713,7 @@ impl TunnelMonitor { async fn start_wireguard_netstack_tunnel( &self, connected_mixnet: ConnectedMixnet, + entry_hostname: Option, ) -> Result<(TunnelConnectionData, AnyTunnelHandle)> { let connected_tunnel = connected_mixnet .connect_wireguard_tunnel(self.tunnel_settings.enable_credentials_mode) @@ -699,6 +723,7 @@ impl TunnelMonitor { let packet_tunnel_settings = tunnel_provider::tunnel_settings::TunnelSettings { dns_servers: self.tunnel_settings.dns.ip_addresses().to_vec(), + entry_gateway_hostname: entry_hostname, interface_addresses: vec![ IpNetwork::V4(Ipv4Network::from(conn_data.exit.private_ipv4)), IpNetwork::V6(Ipv6Network::from(conn_data.exit.private_ipv6)),