diff --git a/quinn/Cargo.toml b/quinn/Cargo.toml index fe67f2c51..aa19a7ca9 100644 --- a/quinn/Cargo.toml +++ b/quinn/Cargo.toml @@ -31,7 +31,7 @@ azure-devops = { project = "dochtman/Projects", pipeline = "Quinn", build = "1" bytes = "0.5.2" err-derive = "0.2.3" futures = "0.3.1" -libc = "0.2.49" +libc = "0.2.67" mio = "0.6" proto = { package = "quinn-proto", path = "../quinn-proto", version = "0.5.0" } rustls = { version = "0.17", features = ["quic"], optional = true } diff --git a/quinn/src/platform/unix.rs b/quinn/src/platform/unix.rs index 1e4245e04..3955309f2 100644 --- a/quinn/src/platform/unix.rs +++ b/quinn/src/platform/unix.rs @@ -53,6 +53,39 @@ impl super::UdpExt for UdpSocket { return Err(io::Error::last_os_error()); } } + #[cfg(target_os = "linux")] + { + // TODO: Replace with constants from libc > 0.2.67 + const IP_PMTUDISC_PROBE: libc::c_int = 2; + if addr.is_ipv4() { + const IP_MTU_DISCOVER: libc::c_int = 10; + let rc = unsafe { + libc::setsockopt( + self.as_raw_fd(), + libc::IPPROTO_IP, + IP_MTU_DISCOVER, + &IP_PMTUDISC_PROBE as *const _ as _, + mem::size_of_val(&IP_PMTUDISC_PROBE) as _, + ) + }; + if rc == -1 { + return Err(io::Error::last_os_error()); + } + } else if addr.is_ipv6() { + let rc = unsafe { + libc::setsockopt( + self.as_raw_fd(), + libc::IPPROTO_IPV6, + libc::IPV6_MTU_DISCOVER, + &IP_PMTUDISC_PROBE as *const _ as _, + mem::size_of_val(&IP_PMTUDISC_PROBE) as _, + ) + }; + if rc == -1 { + return Err(io::Error::last_os_error()); + } + } + } if addr.is_ipv6() { let on: libc::c_int = 1; let rc = unsafe {