summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarkus Pettersson <markus.pettersson@mullvad.net>2024-11-07 09:28:30 +0100
committerMarkus Pettersson <markus.pettersson@mullvad.net>2024-11-22 17:42:38 +0100
commit29a6778daeb1699e725094ae061d9ee81ad2450b (patch)
tree422c5dfe120dd931b88a4d62e62251796b7ed223
parent40a9dc2269d408e5ae819fad44a19eec7aa7965a (diff)
downloadmullvadvpn-29a6778daeb1699e725094ae061d9ee81ad2450b.tar.xz
mullvadvpn-29a6778daeb1699e725094ae061d9ee81ad2450b.zip
Fix a lot of things
- Fix remaining rustc warnings on non-Android platforms - Fix lookup entry peer if it exists in wireguard-go - Fix talpid-wireguard not compiling on windows - Fix entry peer config code - Fix clippy issue - Fix Daita - Remove TODOs
-rw-r--r--talpid-wireguard/src/config.rs84
-rw-r--r--talpid-wireguard/src/connectivity_check.rs4
-rw-r--r--talpid-wireguard/src/ephemeral.rs14
-rw-r--r--talpid-wireguard/src/lib.rs90
-rw-r--r--talpid-wireguard/src/wireguard_go/mod.rs162
-rw-r--r--talpid-wireguard/src/wireguard_kernel/netlink_tunnel.rs1
-rw-r--r--talpid-wireguard/src/wireguard_kernel/nm_tunnel.rs1
-rw-r--r--wireguard-go-rs/libwg/libwg_android.go1
-rw-r--r--wireguard-go-rs/libwg/libwg_daita.go10
-rw-r--r--wireguard-go-rs/libwg/tunnelcontainer/tunnelcontainer.go2
-rw-r--r--wireguard-go-rs/src/lib.rs3
11 files changed, 192 insertions, 180 deletions
diff --git a/talpid-wireguard/src/config.rs b/talpid-wireguard/src/config.rs
index ae5194e200..0469273545 100644
--- a/talpid-wireguard/src/config.rs
+++ b/talpid-wireguard/src/config.rs
@@ -3,6 +3,7 @@ use std::{
ffi::CString,
net::{Ipv4Addr, Ipv6Addr},
};
+use talpid_types::net::wireguard::{PeerConfig, PrivateKey};
use talpid_types::net::{obfuscation::ObfuscatorConfig, wireguard, GenericTunnelOptions};
/// Name to use for the tunnel device
@@ -121,38 +122,12 @@ impl Config {
/// Returns a CString with the appropriate config for WireGuard-go
// TODO: Consider outputting both overriding and additive configs
pub fn to_userspace_format(&self) -> CString {
- // the order of insertion matters, public key entry denotes a new peer entry
- let mut wg_conf = WgConfigBuffer::new();
- wg_conf
- .add::<&[u8]>("private_key", self.tunnel.private_key.to_bytes().as_ref())
- .add("listen_port", "0");
-
- #[cfg(target_os = "linux")]
- if let Some(fwmark) = &self.fwmark {
- wg_conf.add("fwmark", fwmark.to_string().as_str());
- }
-
- wg_conf.add("replace_peers", "true");
-
- for peer in self.peers() {
- wg_conf
- .add::<&[u8]>("public_key", peer.public_key.as_bytes().as_ref())
- .add("endpoint", peer.endpoint.to_string().as_str())
- .add("replace_allowed_ips", "true");
- if let Some(ref psk) = peer.psk {
- wg_conf.add::<&[u8]>("preshared_key", psk.as_bytes().as_ref());
- }
- for addr in &peer.allowed_ips {
- wg_conf.add("allowed_ip", addr.to_string().as_str());
- }
- #[cfg(daita)]
- if peer.constant_packet_size {
- wg_conf.add("constant_packet_size", "true");
- }
- }
-
- let bytes = wg_conf.into_config();
- CString::new(bytes).expect("null bytes inside config")
+ userspace_format(
+ &self.tunnel.private_key,
+ self.peers(),
+ #[cfg(target_os = "linux")]
+ self.fwmark,
+ )
}
/// Return whether the config connects to an exit peer from another remote peer.
@@ -242,3 +217,48 @@ impl WgConfigBuffer {
self.buf
}
}
+
+/// Returns a CString with the appropriate config for WireGuard-go
+#[allow(single_use_lifetimes)]
+pub fn userspace_format<'a>(
+ private_key: &PrivateKey,
+ peers: impl Iterator<Item = &'a PeerConfig>,
+ #[cfg(target_os = "linux")] fwmark: Option<u32>,
+) -> CString {
+ // the order of insertion matters, public key entry denotes a new peer entry
+ let mut wg_conf = WgConfigBuffer::new();
+ wg_conf
+ .add::<&[u8]>("private_key", private_key.to_bytes().as_ref())
+ .add("listen_port", "0");
+
+ #[cfg(target_os = "linux")]
+ if let Some(fwmark) = fwmark {
+ wg_conf.add("fwmark", fwmark.to_string().as_str());
+ }
+
+ wg_conf.add("replace_peers", "true");
+
+ for peer in peers {
+ write_peer_to_config(&mut wg_conf, peer)
+ }
+
+ let bytes = wg_conf.into_config();
+ CString::new(bytes).expect("null bytes inside config")
+}
+
+fn write_peer_to_config(wg_conf: &mut WgConfigBuffer, peer: &PeerConfig) {
+ wg_conf
+ .add::<&[u8]>("public_key", peer.public_key.as_bytes().as_ref())
+ .add("endpoint", peer.endpoint.to_string().as_str())
+ .add("replace_allowed_ips", "true");
+ if let Some(ref psk) = peer.psk {
+ wg_conf.add::<&[u8]>("preshared_key", psk.as_bytes().as_ref());
+ }
+ for addr in &peer.allowed_ips {
+ wg_conf.add("allowed_ip", addr.to_string().as_str());
+ }
+ #[cfg(daita)]
+ if peer.constant_packet_size {
+ wg_conf.add("constant_packet_size", "true");
+ }
+}
diff --git a/talpid-wireguard/src/connectivity_check.rs b/talpid-wireguard/src/connectivity_check.rs
index 35096a0ce2..4b6e0f9810 100644
--- a/talpid-wireguard/src/connectivity_check.rs
+++ b/talpid-wireguard/src/connectivity_check.rs
@@ -11,7 +11,9 @@ use std::{
};
use tokio::sync::Mutex;
-use super::{Tunnel, TunnelError};
+#[cfg(target_os = "android")]
+use super::Tunnel;
+use super::TunnelError;
/// Sleep time used when initially establishing connectivity
const DELAY_ON_INITIAL_SETUP: Duration = Duration::from_millis(50);
diff --git a/talpid-wireguard/src/ephemeral.rs b/talpid-wireguard/src/ephemeral.rs
index 07f611c842..127836863a 100644
--- a/talpid-wireguard/src/ephemeral.rs
+++ b/talpid-wireguard/src/ephemeral.rs
@@ -1,7 +1,10 @@
//! This module takes care of obtaining ephemeral peers, updating the WireGuard configuration and
//! restarting obfuscation and WG tunnels when necessary.
-use super::{config::Config, obfuscation::ObfuscatorHandle, CloseMsg, Error, Tunnel, TunnelType};
+#[cfg(target_os = "android")] // On Android, the Tunnel trait is not imported by default.
+use super::Tunnel;
+use super::{config::Config, obfuscation::ObfuscatorHandle, CloseMsg, Error, TunnelType};
+
#[cfg(target_os = "android")]
use std::sync::Mutex;
use std::{
@@ -64,6 +67,7 @@ fn try_set_ipv4_mtu(alias: &str, mtu: u16) {
}
}
+#[cfg(not(windows))]
pub async fn config_ephemeral_peers(
tunnel: &Arc<AsyncMutex<Option<TunnelType>>>,
config: &mut Config,
@@ -95,7 +99,6 @@ async fn config_ephemeral_peers_inner(
let ephemeral_private_key = PrivateKey::new_from_random();
let close_obfs_sender = close_obfs_sender.clone();
- // NOTE: this might be the entry?
let exit_should_have_daita = config.daita && !config.is_multihop();
let exit_psk = request_ephemeral_peer(
retry_attempt,
@@ -159,8 +162,6 @@ async fn config_ephemeral_peers_inner(
)
.await?;
- log::info!("Config: {config:#?}");
-
#[cfg(daita)]
if config.daita {
// Start local DAITA machines
@@ -203,7 +204,10 @@ async fn reconfigure_tunnel(
let tunnel = lock.take().expect("tunnel was None");
- let new_tunnel = tunnel.better_set_config(&config).unwrap();
+ let new_tunnel = tunnel
+ .better_set_config(&config)
+ .map_err(Error::TunnelError)
+ .map_err(CloseMsg::SetupError)?;
*lock = Some(new_tunnel);
Ok(config)
diff --git a/talpid-wireguard/src/lib.rs b/talpid-wireguard/src/lib.rs
index 948cbc0129..0f05314e72 100644
--- a/talpid-wireguard/src/lib.rs
+++ b/talpid-wireguard/src/lib.rs
@@ -54,7 +54,7 @@ mod mtu_detection;
#[cfg(wireguard_go)]
use self::wireguard_go::WgGoTunnel;
-// TODO: Document why we have a type alias !
+// On android we only have Wireguard Go tunnel
#[cfg(not(target_os = "android"))]
type TunnelType = Box<dyn Tunnel>;
#[cfg(target_os = "android")]
@@ -590,7 +590,6 @@ impl WireguardMonitor {
/// Replace `0.0.0.0/0`/`::/0` with the gateway IPs when `gateway_only` is true.
/// Used to block traffic to other destinations while connecting on Android.
///
- /// TODO: This might need some patchin' now when multihop is a thing.
#[cfg(target_os = "android")]
fn patch_allowed_ips(config: &Config, gateway_only: bool) -> Cow<'_, Config> {
if gateway_only {
@@ -750,50 +749,47 @@ impl WireguardMonitor {
tun_provider: Arc<Mutex<TunProvider>>,
#[cfg(target_os = "android")] gateway_only: bool,
) -> Result<WgGoTunnel> {
- let routes = Self::get_tunnel_destinations(config).flat_map(Self::replace_default_prefixes);
+ let routes = config
+ .get_tunnel_destinations()
+ .flat_map(Self::replace_default_prefixes);
+ #[cfg(not(target_os = "android"))]
+ let tunnel = WgGoTunnel::start_tunnel(
+ #[allow(clippy::needless_borrow)]
+ &config,
+ log_path,
+ tun_provider,
+ routes,
+ #[cfg(daita)]
+ resource_dir,
+ )
+ .map_err(Error::TunnelError)?;
+
+ // Android uses multihop implemented in Mullvad's wireguard-go fork. When negotiating
+ // with an ephemeral peer, this multihop strategy require us to restart the tunnel
+ // every time we want to reconfigure it. As such, we will actually start a multihop
+ // tunnel at a later stage, after we have negotiated with the first ephemeral peer.
+ // At this point, when the tunnel *is first started*, we establish a regular, singlehop
+ // tunnel to where the ephemeral peer resides.
+ //
+ // Refer to `docs/architecture.md` for details on how to use multihop + PQ.
#[cfg(target_os = "android")]
let config = Self::patch_allowed_ips(config, gateway_only);
- let exit_config = wireguard_go::exit_config(&config);
-
- let should_negotiate_with_ephemeral_peer = gateway_only;
#[cfg(target_os = "android")]
- let tunnel = match exit_config {
- // Android uses multihop implemented in Mullvad's wireguard-go fork. When negotiating
- // with an ephemeral peer, this multihop strategy require us to restart the tunnel
- // every time we want to reconfigure it. As such, we will actually start a multihop
- // tunnel at a later stage, after we have negotiated with the first ephemeral peer.
- // At this point, when the tunnel *is first started*, we establish a regular, singlehop
- // tunnel to where the ephemeral peer resides.
- //
- // TODO: Refer to `docs/architecture.md` for details on how to use multihop + PQ.
- Some(_exit_config) if should_negotiate_with_ephemeral_peer => {
- WgGoTunnel::start_multihop_tunnel(
- #[allow(clippy::needless_borrow)]
- // TODO: Check if `entry` should be used instead ??
- &config,
- log_path,
- tun_provider,
- routes,
- #[cfg(daita)]
- resource_dir,
- )
- .map_err(Error::TunnelError)?
- }
- // If we don't need to negotiate with an ephemeral peer, we may simply start a multihop
- // tunnel from the get-go.
- Some(_exit_config) => WgGoTunnel::start_multihop_tunnel(
- #[allow(clippy::needless_borrow)]
+ let tunnel = if let Some(exit_peer) = &config.exit_peer {
+ WgGoTunnel::start_multihop_tunnel(
&config,
+ exit_peer,
log_path,
tun_provider,
routes,
#[cfg(daita)]
resource_dir,
)
- .map_err(Error::TunnelError)?,
- None => WgGoTunnel::start_tunnel(
+ .map_err(Error::TunnelError)?
+ } else {
+ WgGoTunnel::start_tunnel(
#[allow(clippy::needless_borrow)]
&config,
log_path,
@@ -802,21 +798,9 @@ impl WireguardMonitor {
#[cfg(daita)]
resource_dir,
)
- .map_err(Error::TunnelError)?,
+ .map_err(Error::TunnelError)?
};
- #[cfg(not(target_os = "android"))]
- let tunnel = WgGoTunnel::start_tunnel(
- #[allow(clippy::needless_borrow)]
- &config,
- log_path,
- tun_provider,
- routes,
- #[cfg(daita)]
- resource_dir,
- )
- .map_err(Error::TunnelError)?;
-
Ok(tunnel)
}
@@ -922,7 +906,8 @@ impl WireguardMonitor {
gateway_routes.map(|route| Self::apply_route_mtu_for_multihop(route, config));
let routes = gateway_routes.chain(
- Self::get_tunnel_destinations(config)
+ config
+ .get_tunnel_destinations()
.filter(|allowed_ip| allowed_ip.prefix() != 0)
.map(move |allowed_ip| {
if allowed_ip.is_ipv4() {
@@ -943,7 +928,8 @@ impl WireguardMonitor {
config: &'a Config,
) -> impl Iterator<Item = RequiredRoute> + 'a {
let (node_v4, node_v6) = Self::get_tunnel_nodes(iface_name, config);
- let iter = Self::get_tunnel_destinations(config)
+ let iter = config
+ .get_tunnel_destinations()
.filter(|allowed_ip| allowed_ip.prefix() == 0)
.flat_map(Self::replace_default_prefixes)
.map(move |allowed_ip| {
@@ -985,12 +971,6 @@ impl WireguardMonitor {
}
}
- // TODO: Remove?
- /// Return routes for all allowed IPs.
- fn get_tunnel_destinations(config: &Config) -> impl Iterator<Item = ipnetwork::IpNetwork> + '_ {
- config.get_tunnel_destinations()
- }
-
/// Replace default (0-prefix) routes with more specific routes.
fn replace_default_prefixes(network: ipnetwork::IpNetwork) -> Vec<ipnetwork::IpNetwork> {
#[cfg(windows)]
diff --git a/talpid-wireguard/src/wireguard_go/mod.rs b/talpid-wireguard/src/wireguard_go/mod.rs
index c2543ed917..6734475c4b 100644
--- a/talpid-wireguard/src/wireguard_go/mod.rs
+++ b/talpid-wireguard/src/wireguard_go/mod.rs
@@ -1,3 +1,12 @@
+#[cfg(target_os = "android")]
+use super::config;
+use super::{
+ stats::{Stats, StatsMap},
+ Config, Tunnel, TunnelError,
+};
+#[cfg(target_os = "linux")]
+use crate::config::MULLVAD_INTERFACE_NAME;
+use crate::logging::{clean_up_logging, initialize_logging};
use ipnetwork::IpNetwork;
#[cfg(daita)]
use once_cell::sync::OnceCell;
@@ -5,7 +14,6 @@ use once_cell::sync::OnceCell;
use std::{ffi::CString, fs, path::PathBuf};
use std::{
future::Future,
- net::IpAddr,
os::unix::io::{AsRawFd, RawFd},
path::Path,
pin::Pin,
@@ -14,16 +22,10 @@ use std::{
#[cfg(target_os = "android")]
use talpid_tunnel::tun_provider::Error as TunProviderError;
use talpid_tunnel::tun_provider::{Tun, TunProvider};
+#[cfg(target_os = "android")]
+use talpid_types::net::wireguard::PeerConfig;
use talpid_types::BoxedError;
-use super::{
- stats::{Stats, StatsMap},
- Config, Tunnel, TunnelError,
-};
-#[cfg(target_os = "linux")]
-use crate::config::MULLVAD_INTERFACE_NAME;
-use crate::logging::{clean_up_logging, initialize_logging};
-
const MAX_PREPARE_TUN_ATTEMPTS: usize = 4;
/// Maximum number of events that can be stored in the underlying buffer
@@ -36,19 +38,49 @@ const DAITA_ACTIONS_CAPACITY: u32 = 1000;
type Result<T> = std::result::Result<T, TunnelError>;
-struct LoggingContext(u64);
+struct LoggingContext {
+ ordinal: u64,
+ #[allow(dead_code)]
+ path: Option<PathBuf>,
+}
+
+impl LoggingContext {
+ fn new(ordinal: u64, path: Option<PathBuf>) -> Self {
+ LoggingContext { ordinal, path }
+ }
+}
impl Drop for LoggingContext {
fn drop(&mut self) {
- clean_up_logging(self.0);
+ clean_up_logging(self.ordinal);
}
}
+#[cfg(not(target_os = "android"))]
+pub struct WgGoTunnel(WgGoTunnelState);
+
+#[cfg(target_os = "android")]
pub enum WgGoTunnel {
Multihop(WgGoTunnelState),
Singlehop(WgGoTunnelState),
}
+#[cfg(not(target_os = "android"))]
+impl WgGoTunnel {
+ fn into_state(self) -> WgGoTunnelState {
+ self.0
+ }
+
+ fn as_state(&self) -> &WgGoTunnelState {
+ &self.0
+ }
+
+ fn to_state_mut(&mut self) -> &mut WgGoTunnelState {
+ &mut self.0
+ }
+}
+
+#[cfg(target_os = "android")]
impl WgGoTunnel {
fn into_state(self) -> WgGoTunnelState {
match self {
@@ -73,7 +105,7 @@ impl WgGoTunnel {
pub fn better_set_config(self, config: &Config) -> Result<Self> {
let state = self.as_state();
- let log_path = state._log_path.clone();
+ let log_path = state._logging_context.path.clone();
let tun_provider = Arc::clone(&state.tun_provider);
let routes = config.get_tunnel_destinations();
#[cfg(daita)]
@@ -81,8 +113,7 @@ impl WgGoTunnel {
match self {
WgGoTunnel::Multihop(state) if !config.is_multihop() => {
- // Important!
- state.stop().unwrap();
+ state.stop()?;
Self::start_tunnel(
config,
log_path.as_deref(),
@@ -92,9 +123,10 @@ impl WgGoTunnel {
)
}
WgGoTunnel::Singlehop(state) if config.is_multihop() => {
- state.stop().unwrap();
+ state.stop()?;
Self::start_multihop_tunnel(
config,
+ &config.exit_peer.clone().unwrap().clone(),
log_path.as_deref(),
tun_provider,
routes,
@@ -117,16 +149,13 @@ impl WgGoTunnel {
}
}
-// TODO: Does this need to be pub?
-pub struct WgGoTunnelState {
+pub(crate) struct WgGoTunnelState {
interface_name: String,
tunnel_handle: wireguard_go_rs::Tunnel,
// holding on to the tunnel device and the log file ensures that the associated file handles
// live long enough and get closed when the tunnel is stopped
_tunnel_device: Tun,
- // HACK: Don't use this. Only sometimes. ;-)
- _log_path: Option<PathBuf>,
- // context that maps to fs::File instance, used with logging callback
+ // context that maps to fs::File instance and stores the file path, used with logging callback
_logging_context: LoggingContext,
#[cfg(target_os = "android")]
tun_provider: Arc<Mutex<TunProvider>>,
@@ -172,34 +201,6 @@ impl WgGoTunnelState {
}
}
-// TODO: move into impl of Config
-pub(crate) fn exit_config(multihop_config: &Config) -> Option<Config> {
- let mut exit_config = multihop_config.clone();
- exit_config.entry_peer = multihop_config.exit_peer.clone()?;
- Some(exit_config)
-}
-
-// TODO: move into impl of Config
-pub(crate) fn entry_config(multihop_config: &Config) -> Config {
- let mut entry_config = multihop_config.clone();
- entry_config.exit_peer = None;
- entry_config
-}
-
-// TODO: move into impl of Config
-fn private_ip(config: &Config) -> CString {
- if let Some(ip) = config
- .tunnel
- .addresses
- .iter()
- .find(|addr| matches!(addr, IpAddr::V4(_)))
- {
- CString::new(ip.to_string()).unwrap()
- } else {
- CString::default()
- }
-}
-
impl WgGoTunnel {
#[cfg(not(target_os = "android"))]
pub fn start_tunnel(
@@ -214,7 +215,7 @@ impl WgGoTunnel {
let interface_name: String = tunnel_device.interface_name().to_string();
let wg_config_str = config.to_userspace_format();
let logging_context = initialize_logging(log_path)
- .map(LoggingContext)
+ .map(|ordinal| LoggingContext::new(ordinal, log_path.map(Path::to_owned)))
.map_err(TunnelError::LoggingError)?;
let mtu = config.mtu as isize;
@@ -224,11 +225,11 @@ impl WgGoTunnel {
&wg_config_str,
tunnel_fd,
Some(logging::wg_go_logging_callback),
- logging_context.0,
+ logging_context.ordinal,
)
.map_err(|e| TunnelError::FatalStartWireguardError(Box::new(e)))?;
- Ok(WgGoTunnelState {
+ Ok(WgGoTunnel(WgGoTunnelState {
interface_name,
tunnel_handle: handle,
_tunnel_device: tunnel_device,
@@ -237,7 +238,7 @@ impl WgGoTunnel {
resource_dir: resource_dir.to_owned(),
#[cfg(daita)]
config: config.clone(),
- })
+ }))
}
fn get_tunnel(
@@ -288,22 +289,21 @@ impl WgGoTunnel {
routes: impl Iterator<Item = IpNetwork>,
#[cfg(daita)] resource_dir: &Path,
) -> Result<Self> {
- let tun_provider_clone = tun_provider.clone();
-
- let (mut tunnel_device, tunnel_fd) = Self::get_tunnel(tun_provider, config, routes)?;
+ let (mut tunnel_device, tunnel_fd) =
+ Self::get_tunnel(Arc::clone(&tun_provider), config, routes)?;
let interface_name: String = tunnel_device.interface_name().to_string();
- let wg_config_str = config.to_userspace_format();
- let _log_path = log_path;
let logging_context = initialize_logging(log_path)
- .map(LoggingContext)
+ .map(|ordinal| LoggingContext::new(ordinal, log_path.map(Path::to_owned)))
.map_err(TunnelError::LoggingError)?;
+ let wg_config_str = config.to_userspace_format();
+
let handle = wireguard_go_rs::Tunnel::turn_on(
&wg_config_str,
tunnel_fd,
Some(logging::wg_go_logging_callback),
- logging_context.0,
+ logging_context.ordinal,
)
.map_err(|e| TunnelError::FatalStartWireguardError(Box::new(e)))?;
@@ -315,8 +315,7 @@ impl WgGoTunnel {
tunnel_handle: handle,
_tunnel_device: tunnel_device,
_logging_context: logging_context,
- _log_path: _log_path.map(|log_path| log_path.to_owned()),
- tun_provider: tun_provider_clone,
+ tun_provider,
#[cfg(daita)]
resource_dir: resource_dir.to_owned(),
#[cfg(daita)]
@@ -326,29 +325,35 @@ impl WgGoTunnel {
pub fn start_multihop_tunnel(
config: &Config,
+ exit_peer: &PeerConfig,
log_path: Option<&Path>,
tun_provider: Arc<Mutex<TunProvider>>,
routes: impl Iterator<Item = IpNetwork>,
#[cfg(daita)] resource_dir: &Path,
) -> Result<Self> {
- let tun_provider_clone = tun_provider.clone();
-
- let (mut tunnel_device, tunnel_fd) = Self::get_tunnel(tun_provider, config, routes)?;
+ let (mut tunnel_device, tunnel_fd) =
+ Self::get_tunnel(Arc::clone(&tun_provider), config, routes)?;
let interface_name: String = tunnel_device.interface_name().to_string();
- let _log_path = log_path;
let logging_context = initialize_logging(log_path)
- .map(LoggingContext)
+ .map(|ordinal| LoggingContext::new(ordinal, log_path.map(Path::to_owned)))
.map_err(TunnelError::LoggingError)?;
- let entry_config = entry_config(config);
- let exit_config = exit_config(config);
+ let entry_config_str = config::userspace_format(
+ &config.tunnel.private_key,
+ std::iter::once(&config.entry_peer),
+ );
- // multihop
- let exit_config = exit_config.unwrap();
- let entry_config_str = entry_config.to_userspace_format();
- let exit_config_str = exit_config.to_userspace_format();
- let private_ip = private_ip(config);
+ let exit_config_str =
+ config::userspace_format(&config.tunnel.private_key, std::iter::once(exit_peer));
+
+ let private_ip = config
+ .tunnel
+ .addresses
+ .iter()
+ .find(|addr| addr.is_ipv4())
+ .map(|addr| CString::new(addr.to_string()).unwrap())
+ .ok_or(TunnelError::SetConfigError)?;
let handle = wireguard_go_rs::Tunnel::turn_on_multihop(
&exit_config_str,
@@ -356,7 +361,7 @@ impl WgGoTunnel {
&private_ip,
tunnel_fd,
Some(logging::wg_go_logging_callback),
- logging_context.0,
+ logging_context.ordinal,
)
.map_err(|e| TunnelError::FatalStartWireguardError(Box::new(e)))?;
@@ -368,8 +373,7 @@ impl WgGoTunnel {
tunnel_handle: handle,
_tunnel_device: tunnel_device,
_logging_context: logging_context,
- _log_path: _log_path.map(|log_path| log_path.to_owned()),
- tun_provider: tun_provider_clone,
+ tun_provider,
#[cfg(daita)]
resource_dir: resource_dir.to_owned(),
#[cfg(daita)]
@@ -425,11 +429,7 @@ impl Tunnel for WgGoTunnel {
log::info!("Initializing DAITA for wireguard device");
let config = &self.as_state().config;
-
- let peer_public_key = match config.exit_peer.as_ref() {
- Some(exit) => &exit.public_key,
- None => &config.entry_peer.public_key,
- };
+ let peer_public_key = &config.entry_peer.public_key;
self.as_state()
.tunnel_handle
diff --git a/talpid-wireguard/src/wireguard_kernel/netlink_tunnel.rs b/talpid-wireguard/src/wireguard_kernel/netlink_tunnel.rs
index 69b7687579..52d8616c02 100644
--- a/talpid-wireguard/src/wireguard_kernel/netlink_tunnel.rs
+++ b/talpid-wireguard/src/wireguard_kernel/netlink_tunnel.rs
@@ -1,4 +1,3 @@
-use std::any::Any;
use std::pin::Pin;
use futures::Future;
diff --git a/talpid-wireguard/src/wireguard_kernel/nm_tunnel.rs b/talpid-wireguard/src/wireguard_kernel/nm_tunnel.rs
index 84230c22a1..76cfbcaddd 100644
--- a/talpid-wireguard/src/wireguard_kernel/nm_tunnel.rs
+++ b/talpid-wireguard/src/wireguard_kernel/nm_tunnel.rs
@@ -5,7 +5,6 @@ use super::{
Config, Error as WgKernelError, Handle, Tunnel, TunnelError,
};
use futures::Future;
-use std::any::Any;
use std::{collections::HashMap, pin::Pin};
use talpid_dbus::{
dbus,
diff --git a/wireguard-go-rs/libwg/libwg_android.go b/wireguard-go-rs/libwg/libwg_android.go
index 9f488230a9..caca9b04d0 100644
--- a/wireguard-go-rs/libwg/libwg_android.go
+++ b/wireguard-go-rs/libwg/libwg_android.go
@@ -32,7 +32,6 @@ import (
type LogSink = unsafe.Pointer
type LogContext = C.uint64_t
-// TODO: Document
type tunnelHandle struct {
exit *device.Device
entry *device.Device
diff --git a/wireguard-go-rs/libwg/libwg_daita.go b/wireguard-go-rs/libwg/libwg_daita.go
index 3b1fedda4c..fbfceec8f0 100644
--- a/wireguard-go-rs/libwg/libwg_daita.go
+++ b/wireguard-go-rs/libwg/libwg_daita.go
@@ -32,7 +32,15 @@ func wgActivateDaita(tunnelHandle C.int32_t, peerPubkey *C.uint8_t, machines *C.
var publicKey device.NoisePublicKey
copy(publicKey[:], C.GoBytes(unsafe.Pointer(peerPubkey), device.NoisePublicKeySize))
- peer := tunnel.Device.LookupPeer(publicKey)
+
+ var peer *device.Peer
+ if tunnel.EntryDevice != nil {
+ // TODO: Document me
+ peer = tunnel.EntryDevice.LookupPeer(publicKey)
+ } else {
+ // TODO: Document me
+ peer = tunnel.Device.LookupPeer(publicKey)
+ }
if peer == nil {
return ERROR_UNKNOWN_PEER
diff --git a/wireguard-go-rs/libwg/tunnelcontainer/tunnelcontainer.go b/wireguard-go-rs/libwg/tunnelcontainer/tunnelcontainer.go
index bd4003b409..79eacc2a17 100644
--- a/wireguard-go-rs/libwg/tunnelcontainer/tunnelcontainer.go
+++ b/wireguard-go-rs/libwg/tunnelcontainer/tunnelcontainer.go
@@ -16,9 +16,9 @@ import (
type Context struct {
Device *device.Device
+ EntryDevice *device.Device
Uapi net.Listener
Logger *device.Logger
- EntryDevice *device.Device
}
type Container struct {
diff --git a/wireguard-go-rs/src/lib.rs b/wireguard-go-rs/src/lib.rs
index 8049498107..851fd47b9f 100644
--- a/wireguard-go-rs/src/lib.rs
+++ b/wireguard-go-rs/src/lib.rs
@@ -105,7 +105,8 @@ impl Tunnel {
result_from_code(code)
}
- /// TODO: Document
+ /// Special function for android multihop since that behavior is different from desktop
+ /// and android non-multihop.
///
/// The `logging_callback` let's you provide a Rust function that receives any logging output
/// from wireguard-go. `logging_context` is a value that will be passed to each invocation of