Skip to content

Commit

Permalink
Fix MTU detection below min IPv6 value for windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Serock3 committed Feb 12, 2024
1 parent 66f4b14 commit 93493d1
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 20 deletions.
21 changes: 4 additions & 17 deletions talpid-windows/src/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,25 +333,12 @@ pub fn add_ip_address_for_interface(luid: NET_LUID_LH, address: IpAddr) -> Resul
}

/// Sets MTU on the specified network interface identified by `luid`.
pub fn set_mtu(luid: NET_LUID_LH, mtu: u32, use_ipv6: bool) -> io::Result<()> {
let ip_families: &[AddressFamily] = if use_ipv6 {
&[AddressFamily::Ipv4, AddressFamily::Ipv6]
} else {
&[AddressFamily::Ipv4]
};
for family in ip_families {
let mut row = match get_ip_interface_entry(*family, &luid) {
Ok(row) => row,
Err(error) if error.raw_os_error() == Some(ERROR_NOT_FOUND as i32) => continue,
Err(error) => return Err(error),
};

row.NlMtu = mtu;
pub fn set_mtu(mtu: u32, luid: NET_LUID_LH, ip_family: AddressFamily) -> io::Result<()> {
let mut row = get_ip_interface_entry(ip_family, &luid)?;

set_ip_interface_entry(&mut row)?;
}
row.NlMtu = mtu;

Ok(())
set_ip_interface_entry(&mut row)
}

/// Returns the unicast IP address table. If `family` is `None`, then addresses for all families are
Expand Down
22 changes: 19 additions & 3 deletions talpid-wireguard/src/mtu_detection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,31 @@ pub async fn automatic_mtu_correction(
#[cfg(any(target_os = "linux", target_os = "macos"))]
crate::unix::set_mtu(&iface_name, verified_mtu).map_err(Error::SetMtu)?;
#[cfg(windows)]
talpid_windows::net::luid_from_alias(iface_name)
.and_then(|luid| talpid_windows::net::set_mtu(luid, verified_mtu as u32, ipv6))
.map_err(Error::SetMtu)?;
set_mtu_windows(verified_mtu, iface_name, ipv6).map_err(Error::SetMtu)?;
} else {
log::debug!("MTU {verified_mtu} verified to not drop packets");
};
Ok(())
}

#[cfg(windows)]
fn set_mtu_windows(verified_mtu: u16, iface_name: String, ipv6: bool) -> io::Result<()> {
use talpid_windows::net::{set_mtu, AddressFamily};

let luid = talpid_windows::net::luid_from_alias(iface_name)?;
set_mtu(u32::from(verified_mtu), luid, AddressFamily::Ipv4)?;
if ipv6 {
let clamped_mtu = if verified_mtu < talpid_tunnel::MIN_IPV6_MTU {
log::warn!("Cannot set MTU to {verified_mtu} for IPv6, setting to the minimum value 1280 instead");
talpid_tunnel::MIN_IPV6_MTU
} else {
verified_mtu
};
set_mtu(u32::from(clamped_mtu), luid, AddressFamily::Ipv6)?;
}
Ok(())
}

/// Detects the maximum MTU that does not cause dropped packets.
///
/// The detection works by sending evenly spread out range of pings between 576 and the given
Expand Down

0 comments on commit 93493d1

Please sign in to comment.