summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--talpid-wireguard/src/lib.rs23
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];