Skip to content

Commit

Permalink
udp: support GRO on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralith committed Dec 31, 2023
1 parent e721f95 commit 93170e1
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions quinn-udp/src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,17 @@ impl UdpSocketState {
)?;
}

// Opportunistically try to enable GRO
_ = set_socket_option(
&*socket.0,
WinSock::IPPROTO_UDP,
WinSock::UDP_RECV_MAX_COALESCED_SIZE,
// u32 per
// https://learn.microsoft.com/en-us/windows/win32/winsock/ipproto-udp-socket-options.
// Choice of 2^16 - 1 inspired by msquic.
u16::MAX as u32,
);

let now = Instant::now();
Ok(Self {
last_send_error: Mutex::new(now.checked_sub(2 * IO_ERROR_LOG_INTERVAL).unwrap_or(now)),
Expand Down Expand Up @@ -276,9 +287,11 @@ impl UdpSocketState {
// Decode control messages (PKTINFO and ECN)
let mut ecn_bits = 0;
let mut dst_ip = None;
let mut stride = len;

let cmsg_iter = unsafe { cmsg::Iter::new(&wsa_msg) };
for cmsg in cmsg_iter {
const UDP_COALESCED_INFO: i32 = WinSock::UDP_COALESCED_INFO as i32;
// [header (len)][data][padding(len + sizeof(data))] -> [header][data][padding]
match (cmsg.cmsg_level, cmsg.cmsg_type) {
(WinSock::IPPROTO_IP, WinSock::IP_PKTINFO) => {
Expand All @@ -302,13 +315,18 @@ impl UdpSocketState {
// ECN is a C integer https://learn.microsoft.com/en-us/windows/win32/winsock/winsock-ecn
ecn_bits = unsafe { cmsg::decode::<c_int, WinSock::CMSGHDR>(cmsg) };
}
(WinSock::IPPROTO_UDP, UDP_COALESCED_INFO) => {
// Has type u32 (aka DWORD) per
// https://learn.microsoft.com/en-us/windows/win32/winsock/ipproto-udp-socket-options
stride = unsafe { cmsg::decode::<u32, WinSock::CMSGHDR>(cmsg) };
}
_ => {}
}
}

meta[0] = RecvMeta {
len: len as usize,
stride: len as usize,
stride: stride as usize,
addr: addr.unwrap(),
ecn: EcnCodepoint::from_bits(ecn_bits as u8),
dst_ip,
Expand All @@ -332,7 +350,8 @@ impl UdpSocketState {
/// Returns 1 if the platform doesn't support GRO.
#[inline]
pub fn gro_segments(&self) -> usize {
1
// Arbitrary reasonable value inspired by Linux and msquic
64
}

#[inline]
Expand Down

0 comments on commit 93170e1

Please sign in to comment.