From f547d5e0dd07a09e53e99ee3660c1ed5ead80c74 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 21 Oct 2024 18:10:42 +1100 Subject: [PATCH] Introduce `UdpSocketState:try_send` API for windows --- quinn-udp/src/windows.rs | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/quinn-udp/src/windows.rs b/quinn-udp/src/windows.rs index 0776906062..8a8709a6d6 100644 --- a/quinn-udp/src/windows.rs +++ b/quinn-udp/src/windows.rs @@ -124,23 +124,25 @@ impl UdpSocketState { } pub fn send(&self, socket: UdpSockRef<'_>, transmit: &Transmit<'_>) -> io::Result<()> { - let rc = send(socket, transmit); + match send(socket, transmit) { + Ok(()) => Ok(()), + Err(e) if e.kind() == io::ErrorKind::WouldBlock => Err(e), + Err(e) => { + // Other errors are ignored, since they will usually be handled + // by higher level retransmits and timeouts. + // - PermissionDenied errors have been observed due to iptable rules. + // Those are not fatal errors, since the + // configuration can be dynamically changed. + // - Destination unreachable errors have been observed for other + log_sendmsg_error(&self.last_send_error, e, transmit); - if rc != 0 { - let e = io::Error::last_os_error(); - if e.kind() == io::ErrorKind::WouldBlock { - return Err(e); + Ok(()) } - - // Other errors are ignored, since they will usually be handled - // by higher level retransmits and timeouts. - // - PermissionDenied errors have been observed due to iptable rules. - // Those are not fatal errors, since the - // configuration can be dynamically changed. - // - Destination unreachable errors have been observed for other - log_sendmsg_error(&self.last_send_error, e, transmit); } - Ok(()) + } + + pub fn try_send(&self, socket: UdpSockRef<'_>, transmit: &Transmit<'_>) -> io::Result<()> { + send(socket, transmit) } pub fn recv( @@ -272,7 +274,7 @@ impl UdpSocketState { } } -fn send(socket: UdpSockRef<'_>, transmit: &Transmit<'_>) -> i32 { +fn send(socket: UdpSockRef<'_>, transmit: &Transmit<'_>) -> io::Result<()> { // we cannot use [`socket2::sendmsg()`] and [`socket2::MsgHdr`] as we do not have access // to the inner field which holds the WSAMSG let mut ctrl_buf = cmsg::Aligned([0; CMSG_LEN]); @@ -349,7 +351,7 @@ fn send(socket: UdpSockRef<'_>, transmit: &Transmit<'_>) -> i32 { encoder.finish(); let mut len = 0; - unsafe { + let rc = unsafe { WinSock::WSASendMsg( socket.0.as_raw_socket() as usize, &wsa_msg, @@ -358,7 +360,13 @@ fn send(socket: UdpSockRef<'_>, transmit: &Transmit<'_>) -> i32 { ptr::null_mut(), None, ) + }; + + if rc != 0 { + return Err(io::Error::last_os_error()); } + + Ok(()) } fn set_socket_option(