From 50330787d2bfffe466114abf01c9f584ecd8a516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Mon, 16 Dec 2024 12:29:50 +0100 Subject: [PATCH] refactor: Move `net`-dependent code in `quinn-udp` into submodule --- quinn-udp/src/lib.rs | 182 ++++++++++++------------ quinn-udp/src/{ => net}/cmsg/mod.rs | 0 quinn-udp/src/{ => net}/cmsg/unix.rs | 0 quinn-udp/src/{ => net}/cmsg/windows.rs | 0 quinn-udp/src/{ => net}/fallback.rs | 0 quinn-udp/src/{ => net}/unix.rs | 5 +- quinn-udp/src/{ => net}/windows.rs | 7 +- 7 files changed, 101 insertions(+), 93 deletions(-) rename quinn-udp/src/{ => net}/cmsg/mod.rs (100%) rename quinn-udp/src/{ => net}/cmsg/unix.rs (100%) rename quinn-udp/src/{ => net}/cmsg/windows.rs (100%) rename quinn-udp/src/{ => net}/fallback.rs (100%) rename quinn-udp/src/{ => net}/unix.rs (99%) rename quinn-udp/src/{ => net}/windows.rs (99%) diff --git a/quinn-udp/src/lib.rs b/quinn-udp/src/lib.rs index 42c80e2ab5..de88c46c5a 100644 --- a/quinn-udp/src/lib.rs +++ b/quinn-udp/src/lib.rs @@ -28,36 +28,99 @@ #![warn(clippy::use_self)] use std::net::{IpAddr, Ipv6Addr, SocketAddr}; -#[cfg(all(feature = "net", unix))] -use std::os::unix::io::AsFd; -#[cfg(all(feature = "net", windows))] -use std::os::windows::io::AsSocket; + +#[cfg(feature = "net")] +pub use net::*; + +/// All UDP APIs that are behind the "net" feature. #[cfg(feature = "net")] -use std::sync::Mutex; -// Allowing unused, otherwise the cfg condition complexity gets -// out of control only to skip an unused `Duration` import. -#[allow(unused)] -#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] -use std::time::{Duration, Instant}; -#[allow(unused)] -#[cfg(all(target_family = "wasm", target_os = "unknown"))] -use web_time::{Duration, Instant}; - -#[cfg(all(feature = "net", any(unix, windows)))] -mod cmsg; - -#[cfg(all(feature = "net", unix))] -#[path = "unix.rs"] -mod imp; - -#[cfg(all(feature = "net", windows))] -#[path = "windows.rs"] -mod imp; - -// No ECN support -#[cfg(all(feature = "net", not(any(unix, windows))))] -#[path = "fallback.rs"] -mod imp; +pub(crate) mod net { + #[cfg(unix)] + use std::os::unix::io::AsFd; + #[cfg(windows)] + use std::os::windows::io::AsSocket; + use std::sync::Mutex; + // Allowing unused, otherwise the cfg condition complexity gets + // out of control only to skip an unused `Duration` import. + #[allow(unused)] + #[cfg(not(all(target_family = "wasm", target_os = "unknown")))] + use std::time::{Duration, Instant}; + #[allow(unused)] + #[cfg(all(target_family = "wasm", target_os = "unknown"))] + use web_time::{Duration, Instant}; + + #[cfg(any(unix, windows))] + mod cmsg; + + #[cfg(unix)] + #[path = "unix.rs"] + pub(crate) mod imp; + + #[cfg(windows)] + #[path = "windows.rs"] + pub(crate) mod imp; + + // No ECN support + #[cfg(not(any(unix, windows)))] + #[path = "fallback.rs"] + pub(crate) mod imp; + + pub use imp::UdpSocketState; + + /// Log at most 1 IO error per minute + const IO_ERROR_LOG_INTERVAL: Duration = std::time::Duration::from_secs(60); + + /// Logs a warning message when sendmsg fails + /// + /// Logging will only be performed if at least [`IO_ERROR_LOG_INTERVAL`] + /// has elapsed since the last error was logged. + #[cfg(any(feature = "tracing", feature = "direct-log"))] + fn log_sendmsg_error( + last_send_error: &Mutex, + err: impl core::fmt::Debug, + transmit: &crate::Transmit, + ) { + let now = Instant::now(); + let last_send_error = &mut *last_send_error.lock().expect("poisend lock"); + if now.saturating_duration_since(*last_send_error) > IO_ERROR_LOG_INTERVAL { + *last_send_error = now; + crate::log::warn!( + "sendmsg error: {:?}, Transmit: {{ destination: {:?}, src_ip: {:?}, ecn: {:?}, len: {:?}, segment_size: {:?} }}", + err, transmit.destination, transmit.src_ip, transmit.ecn, transmit.contents.len(), transmit.segment_size); + } + } + + // No-op + #[cfg(not(any(feature = "tracing", feature = "direct-log")))] + fn log_sendmsg_error(_: &Mutex, _: impl core::fmt::Debug, _: &Transmit) {} + + /// A borrowed UDP socket + /// + /// On Unix, constructible via `From`. On Windows, constructible via `From`. + // Wrapper around socket2 to avoid making it a public dependency and incurring stability risk + pub struct UdpSockRef<'a>(socket2::SockRef<'a>); + + #[cfg(unix)] + impl<'s, S> From<&'s S> for UdpSockRef<'s> + where + S: AsFd, + { + fn from(socket: &'s S) -> Self { + Self(socket.into()) + } + } + + #[cfg(windows)] + impl<'s, S> From<&'s S> for UdpSockRef<'s> + where + S: AsSocket, + { + fn from(socket: &'s S) -> Self { + Self(socket.into()) + } + } +} #[allow(unused_imports, unused_macros)] mod log { @@ -82,12 +145,9 @@ mod log { pub(crate) use no_op::*; } -#[cfg(feature = "net")] -pub use imp::UdpSocketState; - /// Number of UDP packets to send/receive at a time #[cfg(feature = "net")] -pub const BATCH_SIZE: usize = imp::BATCH_SIZE; +pub const BATCH_SIZE: usize = net::imp::BATCH_SIZE; /// Number of UDP packets to send/receive at a time #[cfg(not(feature = "net"))] pub const BATCH_SIZE: usize = 1; @@ -151,62 +211,6 @@ pub struct Transmit<'a> { pub src_ip: Option, } -/// Log at most 1 IO error per minute -#[cfg(feature = "net")] -const IO_ERROR_LOG_INTERVAL: Duration = std::time::Duration::from_secs(60); - -/// Logs a warning message when sendmsg fails -/// -/// Logging will only be performed if at least [`IO_ERROR_LOG_INTERVAL`] -/// has elapsed since the last error was logged. -#[cfg(all(feature = "net", any(feature = "tracing", feature = "direct-log")))] -fn log_sendmsg_error( - last_send_error: &Mutex, - err: impl core::fmt::Debug, - transmit: &Transmit, -) { - let now = Instant::now(); - let last_send_error = &mut *last_send_error.lock().expect("poisend lock"); - if now.saturating_duration_since(*last_send_error) > IO_ERROR_LOG_INTERVAL { - *last_send_error = now; - log::warn!( - "sendmsg error: {:?}, Transmit: {{ destination: {:?}, src_ip: {:?}, ecn: {:?}, len: {:?}, segment_size: {:?} }}", - err, transmit.destination, transmit.src_ip, transmit.ecn, transmit.contents.len(), transmit.segment_size); - } -} - -// No-op -#[cfg(all(feature = "net", not(any(feature = "tracing", feature = "direct-log"))))] -fn log_sendmsg_error(_: &Mutex, _: impl core::fmt::Debug, _: &Transmit) {} - -/// A borrowed UDP socket -/// -/// On Unix, constructible via `From`. On Windows, constructible via `From`. -// Wrapper around socket2 to avoid making it a public dependency and incurring stability risk -#[cfg(feature = "net")] -pub struct UdpSockRef<'a>(socket2::SockRef<'a>); - -#[cfg(all(feature = "net", unix))] -impl<'s, S> From<&'s S> for UdpSockRef<'s> -where - S: AsFd, -{ - fn from(socket: &'s S) -> Self { - Self(socket.into()) - } -} - -#[cfg(all(feature = "net", windows))] -impl<'s, S> From<&'s S> for UdpSockRef<'s> -where - S: AsSocket, -{ - fn from(socket: &'s S) -> Self { - Self(socket.into()) - } -} - /// Explicit congestion notification codepoint #[repr(u8)] #[derive(Debug, Copy, Clone, Eq, PartialEq)] diff --git a/quinn-udp/src/cmsg/mod.rs b/quinn-udp/src/net/cmsg/mod.rs similarity index 100% rename from quinn-udp/src/cmsg/mod.rs rename to quinn-udp/src/net/cmsg/mod.rs diff --git a/quinn-udp/src/cmsg/unix.rs b/quinn-udp/src/net/cmsg/unix.rs similarity index 100% rename from quinn-udp/src/cmsg/unix.rs rename to quinn-udp/src/net/cmsg/unix.rs diff --git a/quinn-udp/src/cmsg/windows.rs b/quinn-udp/src/net/cmsg/windows.rs similarity index 100% rename from quinn-udp/src/cmsg/windows.rs rename to quinn-udp/src/net/cmsg/windows.rs diff --git a/quinn-udp/src/fallback.rs b/quinn-udp/src/net/fallback.rs similarity index 100% rename from quinn-udp/src/fallback.rs rename to quinn-udp/src/net/fallback.rs diff --git a/quinn-udp/src/unix.rs b/quinn-udp/src/net/unix.rs similarity index 99% rename from quinn-udp/src/unix.rs rename to quinn-udp/src/net/unix.rs index 55bd210596..ce361e50cd 100644 --- a/quinn-udp/src/unix.rs +++ b/quinn-udp/src/net/unix.rs @@ -14,8 +14,9 @@ use std::{ use socket2::SockRef; -use super::{ - cmsg, log_sendmsg_error, EcnCodepoint, RecvMeta, Transmit, UdpSockRef, IO_ERROR_LOG_INTERVAL, +use crate::{ + net::{cmsg, log_sendmsg_error, UdpSockRef, IO_ERROR_LOG_INTERVAL}, + EcnCodepoint, RecvMeta, Transmit, }; // Adapted from https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/bsd/sys/socket_private.h diff --git a/quinn-udp/src/windows.rs b/quinn-udp/src/net/windows.rs similarity index 99% rename from quinn-udp/src/windows.rs rename to quinn-udp/src/net/windows.rs index 02717b7713..260875a814 100644 --- a/quinn-udp/src/windows.rs +++ b/quinn-udp/src/net/windows.rs @@ -19,9 +19,12 @@ use windows_sys::Win32::{ }; use crate::{ - cmsg::{self, CMsgHdr}, log::debug, - log_sendmsg_error, EcnCodepoint, RecvMeta, Transmit, UdpSockRef, IO_ERROR_LOG_INTERVAL, + net::{ + cmsg::{self, CMsgHdr}, + log_sendmsg_error, IO_ERROR_LOG_INTERVAL, + }, + EcnCodepoint, RecvMeta, Transmit, UdpSockRef, }; /// QUIC-friendly UDP socket for Windows