diff --git a/Cargo.lock b/Cargo.lock index 73cf4ca..75334ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -258,7 +258,7 @@ dependencies = [ "gobject-sys", "libc", "system-deps", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] @@ -673,16 +673,6 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "socket2" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "syn" version = "2.0.93" @@ -758,12 +748,12 @@ dependencies = [ "glob", "gtk4", "libadwaita", + "libc", "log", "macaddr", "semver", "serde", "serde_json", - "socket2", ] [[package]] @@ -778,15 +768,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.59.0" diff --git a/Cargo.toml b/Cargo.toml index ca688ed..83bb0d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,9 +31,9 @@ log = "0.4.22" macaddr = { version = "1.0.1", default-features = false } serde = { version = "1.0.210", features = ["derive"] } serde_json = "1.0.128" -socket2 = "0.5.7" bitflags = "2.6.0" semver = "1.0.24" +libc = "0.2.161" [build-dependencies] glob = "0.3.1" diff --git a/src/net/ping.rs b/src/net/ping.rs index 1e832b2..496a813 100644 --- a/src/net/ping.rs +++ b/src/net/ping.rs @@ -9,7 +9,7 @@ use std::fmt::Display; use std::future::Future; use std::net::{IpAddr, SocketAddr}; -use std::os::fd::{AsRawFd, OwnedFd}; +use std::os::fd::{AsRawFd, FromRawFd, OwnedFd}; use std::time::{Duration, Instant}; use futures_util::stream::FuturesUnordered; @@ -18,7 +18,7 @@ use glib::IOCondition; use gtk::gio::prelude::{ResolverExt, SocketExtManual}; use gtk::gio::Cancellable; use gtk::gio::{self, IOErrorEnum}; -use socket2::{Domain, Protocol, Type}; +use gtk::prelude::SocketExt; use crate::config::G_LOG_DOMAIN; @@ -33,24 +33,34 @@ fn to_glib_error(error: std::io::Error) -> glib::Error { glib::Error::new(io_error, &error.to_string()) } -fn create_dgram_socket(domain: Domain, protocol: Protocol) -> Result { - let socket = - socket2::Socket::new_raw(domain, Type::DGRAM, Some(protocol)).map_err(to_glib_error)?; - socket.set_nonblocking(true).map_err(to_glib_error)?; - socket - .set_read_timeout(Some(Duration::from_secs(10))) - .map_err(to_glib_error)?; - let fd = OwnedFd::from(socket); - // SAFETY: from_fd has unfortunate ownership semantics: It claims the fd on - // success, but on error the caller retains ownership of the fd. Hence, we - // do _not_ move out of `fd` here, but instead pass the raw fd. In case of - // error Rust will then just drop our owned fd as usual. In case of success - // the fd now belongs to the GIO socket, so we explicitly forget the - // borrowed fd. - let gio_socket = unsafe { gio::Socket::from_fd(fd.as_raw_fd()) }?; - // Do not drop our fd because it is now owned by gio_socket - std::mem::forget(fd); - Ok(gio_socket) +fn icmp_socket_for_address(address: IpAddr) -> Result { + let (domain, proto) = match address { + IpAddr::V4(_) => (libc::AF_INET, libc::IPPROTO_ICMP), + IpAddr::V6(_) => (libc::AF_INET6, libc::IPPROTO_ICMPV6), + }; + // SAFETY: We only pass integer constants here, and check for error return immediately. + let socket = unsafe { libc::socket(domain, libc::SOCK_DGRAM, proto) }; + if socket < 0 { + Err(to_glib_error(std::io::Error::last_os_error())) + } else { + // SAFETY: socket returns a new FD on success which the caller now owns. + let socket = unsafe { OwnedFd::from_raw_fd(socket) }; + // SAFETY: from_fd has unfortunate ownership semantics: It claims the fd on + // success, but on error the caller retains ownership of the fd. Hence, we + // do _not_ move out of `fd` here, but instead pass the raw fd. In case of + // error Rust will then just drop our owned fd as usual. In case of success + // the fd now belongs to the GIO socket, so we explicitly forget the + // borrowed fd. + let gio_socket = unsafe { gio::Socket::from_fd(socket.as_raw_fd()) }?; + // Do not drop our fd because it is now owned by gio_socket. + std::mem::forget(socket); + // Make the socket non-blocking and add a reasonable timeout. + // set_timeout takes a timeout in seconds; we go through a Duration value + // to make this explicit. + gio_socket.set_blocking(false); + gio_socket.set_timeout(u32::try_from(Duration::from_secs(10).as_secs()).unwrap()); + Ok(gio_socket) + } } /// Send a single ping to `ip_address`. @@ -66,12 +76,8 @@ pub async fn ping_address( sequence_number: u16, ) -> Result { glib::trace!("Sending ICMP echo request to {ip_address}"); - let (domain, protocol) = match ip_address { - IpAddr::V4(_) => (Domain::IPV4, Protocol::ICMPV4), - IpAddr::V6(_) => (Domain::IPV6, Protocol::ICMPV6), - }; let start = Instant::now(); - let socket = create_dgram_socket(domain, protocol)?; + let socket = icmp_socket_for_address(ip_address)?; let condition = socket .create_source_future(IOCondition::OUT, Cancellable::NONE, glib::Priority::DEFAULT) .await; diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock index 0286e08..69dc7c2 100644 --- a/supply-chain/imports.lock +++ b/supply-chain/imports.lock @@ -273,13 +273,6 @@ user-id = 6743 user-login = "epage" user-name = "Ed Page" -[[publisher.windows-sys]] -version = "0.52.0" -when = "2023-11-15" -user-id = 64539 -user-login = "kennykerr" -user-name = "Kenny Kerr" - [[publisher.windows-sys]] version = "0.59.0" when = "2024-07-30" @@ -380,11 +373,6 @@ criteria = "safe-to-deploy" delta = "0.8.0 -> 0.9.0" notes = "No major changes in the crate, mostly updates to use new nightly Rust features." -[[audits.bytecode-alliance.audits.socket2]] -who = "Alex Crichton " -criteria = "safe-to-deploy" -delta = "0.4.9 -> 0.4.4" - [[audits.embark-studios.wildcard-audits.cfg-expr]] who = "Jake Shadle " criteria = "safe-to-deploy" @@ -837,19 +825,6 @@ criteria = "safe-to-run" delta = "1.0.133 -> 1.0.134" aggregated-from = "https://chromium.googlesource.com/chromium/src/+/main/third_party/rust/chromium_crates_io/supply-chain/audits.toml?format=TEXT" -[[audits.google.audits.socket2]] -who = "Vovo Yang " -criteria = "safe-to-run" -version = "0.4.9" -aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT" - -[[audits.google.audits.socket2]] -who = "David Koloski " -criteria = "safe-to-deploy" -delta = "0.4.4 -> 0.5.5" -notes = "Reviewed at https://fxrev.dev/946307" -aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT" - [[audits.google.audits.toml]] who = "George Burgess IV " criteria = "safe-to-run" @@ -910,12 +885,6 @@ criteria = "safe-to-deploy" delta = "0.2.13 -> 0.2.14" aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" -[[audits.mozilla.audits.socket2]] -who = "Kershaw Chang " -criteria = "safe-to-deploy" -delta = "0.5.5 -> 0.5.7" -aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml" - [[audits.swsnr.audits.cfg-expr]] who = "Sebastian Wiesner " criteria = "safe-to-run"