@@ -10,13 +10,7 @@ use std::{
10
10
11
11
use libc:: { c_int, c_uint} ;
12
12
use once_cell:: sync:: Lazy ;
13
- use windows_sys:: Win32 :: {
14
- Networking :: WinSock ,
15
- System :: {
16
- SystemInformation :: IMAGE_FILE_MACHINE_ARM64 ,
17
- Threading :: { GetCurrentProcess , IsWow64Process2 } ,
18
- } ,
19
- } ;
13
+ use windows_sys:: Win32 :: Networking :: WinSock ;
20
14
21
15
use crate :: {
22
16
cmsg:: { self , CMsgHdr } ,
@@ -113,40 +107,34 @@ impl UdpSocketState {
113
107
) ?;
114
108
}
115
109
116
- match & * IS_WINDOWS_ON_ARM {
117
- Ok ( true ) => {
118
- // Bug on Windows on ARM, not receiving `UDP_COALESCED_INFO` `CMSG`
119
- // when _Virtual Machine Platform_ feature enabled. See
120
- // <https://github.com/quinn-rs/quinn/issues/2041> for details.
121
- debug ! ( "detected Windows on ARM host thus not enabling URO" )
122
- }
123
- Ok ( false ) => {
124
- // Opportunistically try to enable URO
125
- let result = set_socket_option (
126
- & * socket. 0 ,
127
- WinSock :: IPPROTO_UDP ,
128
- WinSock :: UDP_RECV_MAX_COALESCED_SIZE ,
129
- // u32 per
130
- // https://learn.microsoft.com/en-us/windows/win32/winsock/ipproto-udp-socket-options.
131
- // Choice of 2^16 - 1 inspired by msquic.
132
- u16:: MAX as u32 ,
133
- ) ;
134
-
135
- if let Err ( _e) = result {
136
- debug ! ( "failed to enable URO: {_e}" ) ;
137
- }
138
- }
139
- Err ( _e) => {
140
- debug ! ( "failed to detect host system thus not enabling URO: {_e}" ) ;
141
- }
142
- }
143
-
144
110
let now = Instant :: now ( ) ;
145
111
Ok ( Self {
146
112
last_send_error : Mutex :: new ( now. checked_sub ( 2 * IO_ERROR_LOG_INTERVAL ) . unwrap_or ( now) ) ,
147
113
} )
148
114
}
149
115
116
+ /// Enable or disable receive offloading.
117
+ ///
118
+ /// Also referred to as UDP Receive Segment Coalescing Offload (URO) on Windows.
119
+ ///
120
+ /// <https://learn.microsoft.com/en-us/windows-hardware/drivers/network/udp-rsc-offload>
121
+ ///
122
+ /// Disabled by default on Windows due to <https://github.com/quinn-rs/quinn/issues/2041>.
123
+ pub fn set_gro ( & self , socket : UdpSockRef < ' _ > , enable : bool ) -> io:: Result < ( ) > {
124
+ set_socket_option (
125
+ & * socket. 0 ,
126
+ WinSock :: IPPROTO_UDP ,
127
+ WinSock :: UDP_RECV_MAX_COALESCED_SIZE ,
128
+ match enable {
129
+ // u32 per
130
+ // https://learn.microsoft.com/en-us/windows/win32/winsock/ipproto-udp-socket-options.
131
+ // Choice of 2^16 - 1 inspired by msquic.
132
+ true => u16:: MAX as u32 ,
133
+ false => 0 ,
134
+ } ,
135
+ )
136
+ }
137
+
150
138
/// Sends a [`Transmit`] on the given socket.
151
139
///
152
140
/// This function will only ever return errors of kind [`io::ErrorKind::WouldBlock`].
@@ -493,29 +481,3 @@ static MAX_GSO_SEGMENTS: Lazy<usize> = Lazy::new(|| {
493
481
Err ( _) => 1 ,
494
482
}
495
483
} ) ;
496
-
497
- /// Evaluates to [`Ok(true)`] if executed either directly on Windows on ARM, or
498
- /// on an emulator which itself executes on Windows on ARM.
499
- ///
500
- /// See
501
- /// <https://learn.microsoft.com/en-us/windows/arm/apps-on-arm-x86-emulation#detecting-emulation>
502
- /// for details.
503
- static IS_WINDOWS_ON_ARM : Lazy < io:: Result < bool > > = Lazy :: new ( || {
504
- let mut process_machine: u16 = 0 ;
505
- let mut native_machine: u16 = 0 ;
506
-
507
- let result = unsafe {
508
- IsWow64Process2 (
509
- GetCurrentProcess ( ) ,
510
- & mut process_machine as * mut u16 ,
511
- & mut native_machine as * mut u16 ,
512
- )
513
- } ;
514
-
515
- match result {
516
- // See
517
- // <https://learn.microsoft.com/en-us/windows/win32/api/wow64apiset/nf-wow64apiset-iswow64process2#return-value>.
518
- 0 => Err ( io:: Error :: last_os_error ( ) ) ,
519
- _ => Ok ( native_machine == IMAGE_FILE_MACHINE_ARM64 ) ,
520
- }
521
- } ) ;
0 commit comments