diff options
| -rw-r--r-- | talpid-wireguard/src/lib.rs | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/talpid-wireguard/src/lib.rs b/talpid-wireguard/src/lib.rs index 71331c2edf..a2d4d496c0 100644 --- a/talpid-wireguard/src/lib.rs +++ b/talpid-wireguard/src/lib.rs @@ -81,6 +81,11 @@ pub enum Error { #[error(display = "Failed to detect MTU because of unexpected ping error.")] MtuDetectionPingError(#[error(source)] surge_ping::SurgeError), + /// Failed to set MTU + #[cfg(target_os = "macos")] + #[error(display = "Failed to set buffer size")] + MtuSetBufferSize(#[error(source)] nix::Error), + /// Tunnel timed out #[error(display = "Tunnel timed out")] TimeoutError, @@ -1025,13 +1030,25 @@ async fn auto_mtu_detection( /// dropped, so we return the largest collected packet size. const PING_OFFSET_TIMEOUT: Duration = Duration::from_secs(2); + let step_size = 20; + let linspace = mtu_spacing(MIN_IPV4_MTU, current_mtu, step_size); + let config_builder = Config::builder().kind(surge_ping::ICMP::V4); #[cfg(any(target_os = "macos", target_os = "linux"))] let config_builder = config_builder.interface(&iface_name); let client = Client::new(&config_builder.build()).unwrap(); - - let step_size = 20; - let linspace = mtu_spacing(MIN_IPV4_MTU, current_mtu, step_size); + // For macos, the default socket receive buffer size seems to be too small to handle the data we + // are sending here. The consequence will be dropped packets causing the MTU detection to set a + // low value. Here we manually increase this value, which fixes the problem. + // TODO: Make sure this fix is not needed for any other target OS + #[cfg(target_os = "macos")] + { + use nix::sys::socket::{setsockopt, sockopt}; + let fd = client.get_socket().get_native_sock(); + let buf_size = linspace.iter().map(|sz| usize::from(*sz)).sum(); + setsockopt(fd, sockopt::SndBuf, &buf_size).map_err(Error::MtuSetBufferSize)?; + setsockopt(fd, sockopt::RcvBuf, &buf_size).map_err(Error::MtuSetBufferSize)?; + } let payload_buf = vec![0; current_mtu as usize]; |
