diff --git a/CHANGELOG.md b/CHANGELOG.md index b0997dfe..2a23380c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,18 @@ ## [Unreleased] +### Changed + +- Updated `windows-sys` from `0.36.1` to `0.59.0`. + Users of `Capture::get_event()` on Windows platforms should note that + `HANDLE` is a `isize` in `0.36`, but has been made a pointer in `0.59`, + causing types containing it to no longer be autotraited with `Send`. + ### Added - Added `packet_header_size()` for applications that need to know the size of internal type `pcap_pkthdr` (for instance to calculate exact send queue sizes). -want to precalculate exact queue sizes. - ## [2.2.0] - 2024-09-01 ### Added diff --git a/Cargo.toml b/Cargo.toml index 04a3db81..8838c309 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ futures = { version = "0.3", optional = true } gat-std = { version = "0.1.1", optional = true } [target.'cfg(target_os = "windows")'.dependencies] -windows-sys = { version = "0.36.1", features = ["Win32_Foundation", "Win32_Networking_WinSock"] } +windows-sys = { version = "0.59.0", features = ["Win32_Foundation", "Win32_Networking_WinSock"] } [dev-dependencies] etherparse = "0.13.0" @@ -32,7 +32,7 @@ tempfile = "3.10" [target.'cfg(target_os = "windows")'.dev-dependencies] eui48 = { version = "1.1", default-features = false } -windows-sys = { version = "0.36.1", features = ["Win32_System_Threading"] } +windows-sys = { version = "0.59.0", features = ["Win32_System_Threading"] } [target.'cfg(not(target_os = "windows"))'.dev-dependencies] tun-tap = "0.1.3" diff --git a/src/capture/mod.rs b/src/capture/mod.rs index 83f50566..3abc46eb 100644 --- a/src/capture/mod.rs +++ b/src/capture/mod.rs @@ -283,10 +283,10 @@ mod tests { let ctx = raw::pcap_getevent_context(); ctx.expect() .withf_st(move |arg1| *arg1 == pcap) - .return_once(|_| 5); + .return_once(|_| 5 as *mut std::ffi::c_void); let handle = unsafe { capture.get_event() }; - assert_eq!(handle, 5); + assert_eq!(handle, 5 as *mut std::ffi::c_void); } #[test] diff --git a/src/device.rs b/src/device.rs index 561b11fd..60a748b2 100644 --- a/src/device.rs +++ b/src/device.rs @@ -266,7 +266,7 @@ impl Address { return None; } - match (*ptr).sa_family as u32 { + match (*ptr).sa_family { WinSock::AF_INET => { let ptr: *const WinSock::SOCKADDR_IN = std::mem::transmute(ptr); let addr: [u8; 4] = ((*ptr).sin_addr.S_un.S_addr).to_ne_bytes(); @@ -372,7 +372,7 @@ mod tests { fn new() -> Self { let mut addr: Self = unsafe { std::mem::zeroed() }; // The cast is only necessary due to a bug in windows_sys@v0.36.1 - addr.sin_family = WinSock::AF_INET as u16; + addr.sin_family = WinSock::AF_INET; addr } @@ -418,7 +418,7 @@ mod tests { fn new() -> Self { let mut addr: Self = unsafe { std::mem::zeroed() }; // The cast is only necessary due to a bug in windows_sys@v0.36.1 - addr.sin6_family = WinSock::AF_INET6 as u16; + addr.sin6_family = WinSock::AF_INET6; unsafe { addr.sin6_addr.u.Byte[0] = 0xFE; addr.sin6_addr.u.Byte[1] = 0x80; diff --git a/src/stream/windows.rs b/src/stream/windows.rs index 11656c8f..88a57ab8 100644 --- a/src/stream/windows.rs +++ b/src/stream/windows.rs @@ -73,6 +73,17 @@ struct EventHandle { state: EventHandleState, } +// SAFETY: EventHandle needs to be Send because it's passed over a thread boundary. +// It contains a HANDLE that is a raw pointer, so the Send autotrait doesn't apply. +// The capture device owns the original handle; as long as the capture device isn't +// released before the EventHandle, this should be good. +unsafe impl Send for EventHandle {} + +/// Newtype used to wrap `HANDLE` to make it `Send`:able +struct InternalHandle(HANDLE); + +unsafe impl Send for InternalHandle {} + enum EventHandleState { /// We haven't started waiting for an event yet. Init, @@ -98,12 +109,13 @@ impl EventHandle { loop { match self.state { EventHandleState::Init => { - let handle = self.handle; + let handle = InternalHandle(self.handle); self.state = EventHandleState::Polling(tokio::task::spawn_blocking(move || { const INFINITE: u32 = !0; + let handle = handle; // avoid partial closure capture problems unsafe { - WaitForSingleObject(handle, INFINITE); + WaitForSingleObject(handle.0, INFINITE); } })); }