Skip to content

Commit

Permalink
Refactor wireguard implementation picker
Browse files Browse the repository at this point in the history
  • Loading branch information
Serock3 committed Jan 24, 2025
1 parent e3151f7 commit 72fc231
Showing 1 changed file with 83 additions and 61 deletions.
144 changes: 83 additions & 61 deletions talpid-wireguard/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,9 +643,11 @@ impl WireguardMonitor {
log::debug!("Tunnel MTU: {}", config.mtu);

#[cfg(target_os = "linux")]
if !*FORCE_USERSPACE_WIREGUARD {
// If DAITA is enabled, wireguard-go has to be used.
if config.daita {
{
let userspace_wireguard = *FORCE_USERSPACE_WIREGUARD || config.daita;
if userspace_wireguard {
log::debug!("Using userspace WireGuard implementation");

let tunnel = runtime
.block_on(Self::open_wireguard_go_tunnel(
config,
Expand All @@ -654,81 +656,101 @@ impl WireguardMonitor {
))
.map(Box::new)?;
return Ok(tunnel);
}

if will_nm_manage_dns() {
match wireguard_kernel::NetworkManagerTunnel::new(runtime.clone(), config) {
Ok(tunnel) => {
log::debug!("Using NetworkManager to use kernel WireGuard implementation");
return Ok(Box::new(tunnel));
}
Err(err) => {
log::error!(
"{}",
err.display_chain_with_msg(
"Failed to initialize WireGuard tunnel via NetworkManager"
)
);
}
};
} else {
match wireguard_kernel::NetlinkTunnel::new(runtime.clone(), config) {
Ok(tunnel) => {
log::debug!("Using kernel WireGuard implementation");
return Ok(Box::new(tunnel));
}
Err(error) => {
log::error!(
"{}",
error.display_chain_with_msg(
"Failed to setup kernel WireGuard device, falling back to the userspace implementation"
)
);
}
};
}
}
log::debug!("Using kernel WireGuard implementation");
{
let res: Option<TunnelType> = if will_nm_manage_dns() {
match wireguard_kernel::NetworkManagerTunnel::new(runtime, config) {
Ok(tunnel) => {
log::debug!(
"Using NetworkManager to use kernel WireGuard implementation"
);
Some(Box::new(tunnel))
}
Err(err) => {
log::error!(
"{}",
err.display_chain_with_msg(
"Failed to initialize WireGuard tunnel via NetworkManager"
)
);
None
}
}
} else {
match wireguard_kernel::NetlinkTunnel::new(runtime, config) {
Ok(tunnel) => {
log::debug!("Using kernel WireGuard implementation");
Some(Box::new(tunnel))
}
Err(error) => {
log::error!(
"{}",
error.display_chain_with_msg(
"Failed to setup kernel WireGuard device, falling back to the userspace implementation"
)
);
None
}
}
};

#[cfg(target_os = "windows")]
{
#[cfg(wireguard_go)]
{
let use_userspace_wg = config.daita || *FORCE_USERSPACE_WIREGUARD;
if use_userspace_wg {
log::debug!("Using userspace WireGuard implementation");
let tunnel = runtime
.block_on(Self::open_wireguard_go_tunnel(
config,
log_path,
setup_done_tx,
route_manager,
))
.map(Box::new)?;
return Ok(tunnel);
match res {
Some(tunnel) => Ok(tunnel),
None => {
log::warn!("Falling back to userspace WireGuard implementation");
let tunnel =
Self::open_wireguard_go_tunnel(config, log_path, tun_provider)
.map(Box::new)?;
Ok(tunnel)
}
}
}
}

wireguard_nt::WgNtTunnel::start_tunnel(config, log_path, resource_dir, setup_done_tx)
.map(|tun| Box::new(tun) as Box<dyn Tunnel + 'static>)
.map_err(Error::TunnelError)
}

#[cfg(all(wireguard_go, not(target_os = "windows")))]
#[cfg(target_os = "macos")]
{
#[cfg(target_os = "linux")]
log::debug!("Using userspace WireGuard implementation");

let tunnel = runtime
.block_on(Self::open_wireguard_go_tunnel(
config,
log_path,
tun_provider,
#[cfg(target_os = "android")]
gateway_only,
))
.map(Box::new)?;
Ok(tunnel)
}
#[cfg(target_os = "windows")]
{
let userspace_wireguard = *FORCE_USERSPACE_WIREGUARD || config.daita;

if userspace_wireguard {
log::debug!("Using userspace WireGuard implementation");

log::debug!("Using userspace WireGuard implementation");
let tunnel = runtime
.block_on(Self::open_wireguard_go_tunnel(
config,
log_path,
setup_done_tx,
route_manager,
))
.map(Box::new)?;
Ok(tunnel)
} else {
log::debug!("Using kernel WireGuard implementation");

wireguard_nt::WgNtTunnel::start_tunnel(
config,
log_path,
resource_dir,
setup_done_tx,
)
.map(|tun| Box::new(tun) as Box<dyn Tunnel + 'static>)
.map_err(Error::TunnelError)
}
}
}

/// Configure and start a Wireguard-go tunnel.
Expand Down

0 comments on commit 72fc231

Please sign in to comment.