mirror of
https://github.com/n0-computer/noq.git
synced 2026-09-16 16:25:08 +00:00
fix: evaluate max_gso_segments for every socket on Windows
This follows the behaviour we have for UNIX-based systems. Support for GSO varies depending on the network driver which may change at runtime when e.g. a device switches between Ethernet and WiFi or gets plugged into a docking station. Resolves: #2491
This commit is contained in:
committed by
Dirkjan Ochtman
parent
c67e9d8930
commit
41bf1db60d
+10
-11
@@ -4,7 +4,10 @@ use std::{
|
||||
net::{IpAddr, Ipv4Addr},
|
||||
os::windows::io::AsRawSocket,
|
||||
ptr,
|
||||
sync::{LazyLock, Mutex},
|
||||
sync::{
|
||||
LazyLock, Mutex,
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
},
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
@@ -24,6 +27,7 @@ use crate::{
|
||||
#[derive(Debug)]
|
||||
pub struct UdpSocketState {
|
||||
last_send_error: Mutex<Instant>,
|
||||
max_gso_segments: AtomicUsize,
|
||||
|
||||
/// Whether the underlying Winsock provider supports IPv4 ECN socket options/control messages.
|
||||
///
|
||||
@@ -153,6 +157,7 @@ impl UdpSocketState {
|
||||
let now = Instant::now();
|
||||
Ok(Self {
|
||||
last_send_error: Mutex::new(now.checked_sub(2 * IO_ERROR_LOG_INTERVAL).unwrap_or(now)),
|
||||
max_gso_segments: AtomicUsize::new(max_gso_segments(&*socket.0)),
|
||||
ecn_v4_supported,
|
||||
ecn_v6_supported,
|
||||
})
|
||||
@@ -332,7 +337,7 @@ impl UdpSocketState {
|
||||
/// while using GSO.
|
||||
#[inline]
|
||||
pub fn max_gso_segments(&self) -> usize {
|
||||
*MAX_GSO_SEGMENTS
|
||||
self.max_gso_segments.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// The number of segments to read when GRO is enabled. Used as a factor to
|
||||
@@ -552,16 +557,10 @@ static WSARECVMSG_PTR: LazyLock<WinSock::LPFN_WSARECVMSG> = LazyLock::new(|| {
|
||||
wsa_recvmsg_ptr
|
||||
});
|
||||
|
||||
static MAX_GSO_SEGMENTS: LazyLock<usize> = LazyLock::new(|| {
|
||||
let socket = match std::net::UdpSocket::bind("[::]:0")
|
||||
.or_else(|_| std::net::UdpSocket::bind((Ipv4Addr::LOCALHOST, 0)))
|
||||
{
|
||||
Ok(socket) => socket,
|
||||
Err(_) => return 1,
|
||||
};
|
||||
fn max_gso_segments(socket: &impl AsRawSocket) -> usize {
|
||||
const GSO_SIZE: c_uint = 1500;
|
||||
match set_socket_option(
|
||||
&socket,
|
||||
socket,
|
||||
WinSock::IPPROTO_UDP,
|
||||
WinSock::UDP_SEND_MSG_SIZE,
|
||||
GSO_SIZE,
|
||||
@@ -570,4 +569,4 @@ static MAX_GSO_SEGMENTS: LazyLock<usize> = LazyLock::new(|| {
|
||||
Ok(()) => 512,
|
||||
Err(_) => 1,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user