-
Notifications
You must be signed in to change notification settings - Fork 0
fix(windows): use WSASendMsg for GSO detection instead of setsockopt #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,7 +8,7 @@ use std::{ | |||||||||||||||||||||||
| time::Instant, | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| use libc::{c_int, c_uint}; | ||||||||||||||||||||||||
| use libc::c_int; | ||||||||||||||||||||||||
| use windows_sys::Win32::Networking::WinSock; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| use crate::{ | ||||||||||||||||||||||||
|
|
@@ -495,21 +495,67 @@ static WSARECVMSG_PTR: LazyLock<WinSock::LPFN_WSARECVMSG> = LazyLock::new(|| { | |||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| 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))) | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| let socket = match std::net::UdpSocket::bind((Ipv4Addr::LOCALHOST, 0)) { | ||||||||||||||||||||||||
| Ok(socket) => socket, | ||||||||||||||||||||||||
| Err(_) => return 1, | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| const GSO_SIZE: c_uint = 1500; | ||||||||||||||||||||||||
| match set_socket_option( | ||||||||||||||||||||||||
| &socket, | ||||||||||||||||||||||||
| WinSock::IPPROTO_UDP, | ||||||||||||||||||||||||
| WinSock::UDP_SEND_MSG_SIZE, | ||||||||||||||||||||||||
| GSO_SIZE, | ||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||
| // Empirically found on Windows 11 x64 | ||||||||||||||||||||||||
| Ok(()) => 512, | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| socket.set_nonblocking(true).ok(); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| socket.set_nonblocking(true).ok(); | |
| if let Err(e) = socket.set_nonblocking(true) { | |
| debug!( | |
| "failed to set nonblocking mode for GSO detection socket: {}", | |
| e | |
| ); | |
| return 1; | |
| } |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the socket is in nonblocking mode and the send operation cannot complete immediately, WSASendMsg returns a non-zero value with the error WSAEWOULDBLOCK (error code 10035). This error should not be interpreted as GSO being unsupported. Consider distinguishing between WSAEWOULDBLOCK (which should be treated as success for detection purposes) and actual GSO-related errors like WSAEINVAL.
| _ => Err(io::Error::last_os_error()), | |
| _ => { | |
| let err = io::Error::last_os_error(); | |
| // When the socket is nonblocking, WSAEWOULDBLOCK means the send cannot | |
| // complete immediately, not that GSO is unsupported. Treat this as | |
| // success for detection purposes. | |
| match err.raw_os_error() { | |
| Some(code) if code == WinSock::WSAEWOULDBLOCK as i32 => Ok(()), | |
| _ => Err(err), | |
| } | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The socket binding was changed from attempting IPv6 first with IPv4 fallback to only IPv4. This change could miss detecting IPv6-specific GSO support or fail on systems where IPv4 binding is unavailable. Consider restoring the original fallback pattern to maintain broader compatibility and more comprehensive GSO detection.