Skip to content

Commit

Permalink
Force WireGuard handshake before PQ handshake
Browse files Browse the repository at this point in the history
  • Loading branch information
dlon committed Dec 16, 2024
1 parent 3911c21 commit a122a93
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 3 deletions.
1 change: 0 additions & 1 deletion talpid-wireguard/src/connectivity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ mod mock;
mod monitor;
mod pinger;

#[cfg(target_os = "android")]
pub use check::Cancellable;
pub use check::Check;
pub use error::Error;
Expand Down
59 changes: 57 additions & 2 deletions talpid-wireguard/src/ephemeral.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! This module takes care of obtaining ephemeral peers, updating the WireGuard configuration and
//! restarting obfuscation and WG tunnels when necessary.
#[cfg(not(target_os = "android"))]
use super::connectivity;
#[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};
Expand Down Expand Up @@ -31,6 +33,7 @@ pub async fn config_ephemeral_peers(
retry_attempt: u32,
obfuscator: Arc<AsyncMutex<Option<ObfuscatorHandle>>>,
close_obfs_sender: sync_mpsc::Sender<CloseMsg>,
connectivity: &mut connectivity::Check<connectivity::Cancellable>,
) -> std::result::Result<(), CloseMsg> {
let iface_name = {
let tunnel = tunnel.lock().await;
Expand All @@ -44,8 +47,15 @@ pub async fn config_ephemeral_peers(
log::trace!("Temporarily lowering tunnel MTU before ephemeral peer config");
try_set_ipv4_mtu(&iface_name, talpid_tunnel::MIN_IPV4_MTU);

config_ephemeral_peers_inner(tunnel, config, retry_attempt, obfuscator, close_obfs_sender)
.await?;
config_ephemeral_peers_inner(
tunnel,
config,
retry_attempt,
obfuscator,
close_obfs_sender,
connectivity,
)
.await?;

log::trace!("Resetting tunnel MTU");
try_set_ipv4_mtu(&iface_name, config.mtu);
Expand Down Expand Up @@ -75,6 +85,9 @@ pub async fn config_ephemeral_peers(
retry_attempt: u32,
obfuscator: Arc<AsyncMutex<Option<ObfuscatorHandle>>>,
close_obfs_sender: sync_mpsc::Sender<CloseMsg>,
#[cfg(not(target_os = "android"))] connectivity: &mut connectivity::Check<
connectivity::Cancellable,
>,
#[cfg(target_os = "android")] tun_provider: Arc<Mutex<TunProvider>>,
) -> Result<(), CloseMsg> {
config_ephemeral_peers_inner(
Expand All @@ -95,8 +108,14 @@ async fn config_ephemeral_peers_inner(
retry_attempt: u32,
obfuscator: Arc<AsyncMutex<Option<ObfuscatorHandle>>>,
close_obfs_sender: sync_mpsc::Sender<CloseMsg>,
#[cfg(not(target_os = "android"))] connectivity: &mut connectivity::Check<
connectivity::Cancellable,
>,
#[cfg(target_os = "android")] tun_provider: Arc<Mutex<TunProvider>>,
) -> Result<(), CloseMsg> {
#[cfg(not(target_os = "android"))]
reestablish_tunnel_connection(tunnel, connectivity).await?;

let ephemeral_private_key = PrivateKey::new_from_random();
let close_obfs_sender = close_obfs_sender.clone();

Expand Down Expand Up @@ -134,6 +153,10 @@ async fn config_ephemeral_peers_inner(
&tun_provider,
)
.await?;

#[cfg(not(target_os = "android"))]
reestablish_tunnel_connection(tunnel, connectivity).await?;

let entry_ephemeral_peer = request_ephemeral_peer(
retry_attempt,
&entry_config,
Expand Down Expand Up @@ -268,6 +291,38 @@ async fn reconfigure_tunnel(
Ok(config)
}

/// Ensure that the WireGuard tunnel works. This is useful after updating the WireGuard config, to
/// force a WireGuard handshake.
/// This should reduce the number of PQ timeouts.
#[cfg(not(target_os = "android"))]
async fn reestablish_tunnel_connection(
tunnel: &Arc<AsyncMutex<Option<TunnelType>>>,
connectivity: &mut connectivity::Check<connectivity::Cancellable>,
) -> Result<(), CloseMsg> {
use talpid_types::ErrorExt;

let mut shared_tunnel = tunnel.lock().await;
let tunnel = shared_tunnel.take().expect("tunnel was None");
let ping_result = connectivity.establish_connectivity(&tunnel);
*shared_tunnel = Some(tunnel);
drop(shared_tunnel);

match ping_result {
Ok(true) => Ok(()),
Ok(false) => {
log::warn!("Timeout while checking tunnel connection");
Err(CloseMsg::PingErr)
}
Err(error) => {
log::error!(
"{}",
error.display_chain_with_msg("Failed to check tunnel connection")
);
Err(CloseMsg::PingErr)
}
}
}

async fn request_ephemeral_peer(
retry_attempt: u32,
config: &Config,
Expand Down
1 change: 1 addition & 0 deletions talpid-wireguard/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ impl WireguardMonitor {
args.retry_attempt,
obfuscator.clone(),
ephemeral_obfs_sender,
&mut connectivity_monitor,
)
.await?;

Expand Down

0 comments on commit a122a93

Please sign in to comment.