diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 9b4ae310e..e828cdfc8 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -1453,17 +1453,6 @@ dependencies = [ "serde", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "derive_arbitrary" version = "1.3.2" @@ -1506,6 +1495,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.87", + "unicode-xid", ] [[package]] @@ -2206,7 +2196,7 @@ dependencies = [ "bytes", "chrono", "connlib-model", - "derivative", + "derive_more 1.0.0", "divan", "dns-over-tcp", "domain", @@ -7307,6 +7297,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "universal-hash" version = "0.5.1" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 771c10a4c..1002e4c07 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -42,7 +42,6 @@ bytecodec = "0.4.15" bytes = { version = "1.7.1", default-features = false } chrono = { version = "0.4", default-features = false, features = ["std", "clock", "oldtime", "serde"] } clap = "4.5.21" -derivative = "2.2.0" derive_more = "1.0.0" difference = "2.0.0" dirs = "5.0.1" diff --git a/rust/Dockerfile b/rust/Dockerfile index 1f45bdc72..2d3660eac 100644 --- a/rust/Dockerfile +++ b/rust/Dockerfile @@ -1,5 +1,5 @@ # Keep synced with `rust-toolchain.toml` -ARG RUST_VERSION="1.82.0" +ARG RUST_VERSION="1.83.0" ARG ALPINE_VERSION="3.20" ARG CARGO_CHEF_VERSION="0.1.67" diff --git a/rust/bin-shared/src/network_changes/windows.rs b/rust/bin-shared/src/network_changes/windows.rs index 0a40514d8..72e0c7e0b 100644 --- a/rust/bin-shared/src/network_changes/windows.rs +++ b/rust/bin-shared/src/network_changes/windows.rs @@ -253,7 +253,7 @@ struct Callback { tx: NotifySender, } -impl<'a> Drop for Listener<'a> { +impl Drop for Listener<'_> { // Might never be called. Due to the way the scopes ended up, // we crash the GUI process before we can get back to the main thread // and drop the DNS listeners diff --git a/rust/bin-shared/src/tun_device_manager/linux.rs b/rust/bin-shared/src/tun_device_manager/linux.rs index c332c10aa..b686c20e0 100644 --- a/rust/bin-shared/src/tun_device_manager/linux.rs +++ b/rust/bin-shared/src/tun_device_manager/linux.rs @@ -33,8 +33,7 @@ const TUNSETIFF: libc::c_ulong = 0x4004_54ca; const TUN_DEV_MAJOR: u32 = 10; const TUN_DEV_MINOR: u32 = 200; -// Safety: We know that this is a valid C string. -const TUN_FILE: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"/dev/net/tun\0") }; +const TUN_FILE: &CStr = c"/dev/net/tun"; const FIREZONE_TABLE: u32 = 0x2021_fd00; diff --git a/rust/connlib/clients/apple/src/make_writer.rs b/rust/connlib/clients/apple/src/make_writer.rs index 9d04e3d83..2a6ed0266 100644 --- a/rust/connlib/clients/apple/src/make_writer.rs +++ b/rust/connlib/clients/apple/src/make_writer.rs @@ -36,7 +36,7 @@ impl<'l> tracing_subscriber::fmt::MakeWriter<'l> for MakeWriter { } } -impl<'l> io::Write for Writer<'l> { +impl io::Write for Writer<'_> { fn write(&mut self, buf: &[u8]) -> io::Result { let message = std::str::from_utf8(buf).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; diff --git a/rust/connlib/snownet/src/node.rs b/rust/connlib/snownet/src/node.rs index 6eff1a8c3..8825e5e61 100644 --- a/rust/connlib/snownet/src/node.rs +++ b/rust/connlib/snownet/src/node.rs @@ -1534,7 +1534,7 @@ pub struct Transmit<'a> { pub payload: Cow<'a, [u8]>, } -impl<'a> fmt::Debug for Transmit<'a> { +impl fmt::Debug for Transmit<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Transmit") .field("src", &self.src) @@ -1544,7 +1544,7 @@ impl<'a> fmt::Debug for Transmit<'a> { } } -impl<'a> Transmit<'a> { +impl Transmit<'_> { pub fn into_owned(self) -> Transmit<'static> { Transmit { src: self.src, diff --git a/rust/connlib/tunnel/Cargo.toml b/rust/connlib/tunnel/Cargo.toml index b5f9dbedb..49bdbce75 100644 --- a/rust/connlib/tunnel/Cargo.toml +++ b/rust/connlib/tunnel/Cargo.toml @@ -12,7 +12,7 @@ boringtun = { workspace = true } bytes = { workspace = true, features = ["std"] } chrono = { workspace = true } connlib-model = { workspace = true } -derivative = { workspace = true } +derive_more = { workspace = true, features = ["debug"] } divan = { workspace = true, optional = true } dns-over-tcp = { workspace = true } domain = { workspace = true } @@ -44,7 +44,6 @@ tun = { workspace = true } uuid = { workspace = true, features = ["std", "v4"] } [dev-dependencies] -derivative = { workspace = true } firezone-relay = { workspace = true, features = ["proptest"] } ip-packet = { workspace = true, features = ["proptest"] } proptest-state-machine = { workspace = true } diff --git a/rust/connlib/tunnel/src/lib.rs b/rust/connlib/tunnel/src/lib.rs index 6f6f45c4f..620f853d9 100644 --- a/rust/connlib/tunnel/src/lib.rs +++ b/rust/connlib/tunnel/src/lib.rs @@ -339,8 +339,7 @@ pub enum ClientEvent { TunInterfaceUpdated(TunConfig), } -#[derive(Clone, derivative::Derivative, PartialEq, Eq)] -#[derivative(Debug)] +#[derive(Clone, derive_more::Debug, PartialEq, Eq)] pub struct TunConfig { pub ip4: Ipv4Addr, pub ip6: Ipv6Addr, @@ -352,9 +351,9 @@ pub struct TunConfig { /// Otherwise, we will use the DNS servers configured on the system. pub dns_by_sentinel: BiMap, - #[derivative(Debug(format_with = "fmt_routes"))] + #[debug("{}", DisplaySet(ipv4_routes))] pub ipv4_routes: BTreeSet, - #[derivative(Debug(format_with = "fmt_routes"))] + #[debug("{}", DisplaySet(ipv6_routes))] pub ipv6_routes: BTreeSet, } @@ -376,15 +375,21 @@ pub enum GatewayEvent { ResolveDns(ResolveDnsRequest), } -fn fmt_routes(routes: &BTreeSet, f: &mut fmt::Formatter) -> fmt::Result +/// Adapter-struct to [`fmt::Display`] a [`BTreeSet`]. +#[expect(dead_code, reason = "It is used in the `Debug` impl of `TunConfig`")] +struct DisplaySet<'a, T>(&'a BTreeSet); + +impl fmt::Display for DisplaySet<'_, T> where T: fmt::Display, { - let mut list = f.debug_list(); + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut list = f.debug_list(); - for route in routes { - list.entry(&format_args!("{route}")); + for entry in self.0 { + list.entry(&format_args!("{entry}")); + } + + list.finish() } - - list.finish() } diff --git a/rust/connlib/tunnel/src/tests/reference.rs b/rust/connlib/tunnel/src/tests/reference.rs index 03b6df516..25e56d625 100644 --- a/rust/connlib/tunnel/src/tests/reference.rs +++ b/rust/connlib/tunnel/src/tests/reference.rs @@ -20,8 +20,7 @@ use std::{ /// The reference state machine of the tunnel. /// /// This is the "expected" part of our test. -#[derive(Clone, derivative::Derivative)] -#[derivative(Debug)] +#[derive(Clone, Debug)] pub(crate) struct ReferenceState { pub(crate) client: Host, pub(crate) gateways: BTreeMap>, diff --git a/rust/connlib/tunnel/src/tests/sim_client.rs b/rust/connlib/tunnel/src/tests/sim_client.rs index 24291d203..b6dc6d194 100644 --- a/rust/connlib/tunnel/src/tests/sim_client.rs +++ b/rust/connlib/tunnel/src/tests/sim_client.rs @@ -369,8 +369,7 @@ impl SimClient { /// /// The reference state machine is designed to be as abstract as possible over connlib's functionality. /// For example, we try to model connectivity to _resources_ and don't really care, which gateway is being used to route us there. -#[derive(Clone, derivative::Derivative)] -#[derivative(Debug)] +#[derive(Clone, derive_more::Debug)] pub struct RefClient { pub(crate) id: ClientId, pub(crate) key: PrivateKey, @@ -379,10 +378,10 @@ pub struct RefClient { pub(crate) tunnel_ip6: Ipv6Addr, /// The DNS resolvers configured on the client outside of connlib. - #[derivative(Debug = "ignore")] + #[debug(skip)] system_dns_resolvers: Vec, /// The upstream DNS resolvers configured in the portal. - #[derivative(Debug = "ignore")] + #[debug(skip)] upstream_dns_resolvers: Vec, ipv4_routes: BTreeMap, @@ -391,62 +390,62 @@ pub struct RefClient { /// Tracks all resources in the order they have been added in. /// /// When reconnecting to the portal, we simulate them being re-added in the same order. - #[derivative(Debug = "ignore")] + #[debug(skip)] resources: Vec, - #[derivative(Debug = "ignore")] + #[debug(skip)] internet_resource: Option, /// The CIDR resources the client is aware of. - #[derivative(Debug = "ignore")] + #[debug(skip)] cidr_resources: IpNetworkTable, /// The client's DNS records. /// /// The IPs assigned to a domain by connlib are an implementation detail that we don't want to model in these tests. /// Instead, we just remember what _kind_ of records we resolved to be able to sample a matching src IP. - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) dns_records: BTreeMap>, /// Whether we are connected to the gateway serving the Internet resource. - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) connected_internet_resource: bool, /// The CIDR resources the client is connected to. - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) connected_cidr_resources: HashSet, /// The DNS resources the client is connected to. - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) connected_dns_resources: HashSet<(ResourceId, DomainName)>, - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) connected_gateways: BTreeSet, /// Actively disabled resources by the UI - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) disabled_resources: BTreeSet, /// The expected ICMP handshakes. - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) expected_icmp_handshakes: BTreeMap>, /// The expected UDP handshakes. - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) expected_udp_handshakes: BTreeMap>, /// The expected TCP exchanges. - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) expected_tcp_exchanges: BTreeMap>, /// The expected UDP DNS handshakes. - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) expected_udp_dns_handshakes: VecDeque<(SocketAddr, QueryId)>, /// The expected TCP DNS handshakes. - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) expected_tcp_dns_handshakes: VecDeque<(SocketAddr, QueryId)>, } diff --git a/rust/connlib/tunnel/src/tests/sim_net.rs b/rust/connlib/tunnel/src/tests/sim_net.rs index a76296c7e..2e2d96a24 100644 --- a/rust/connlib/tunnel/src/tests/sim_net.rs +++ b/rust/connlib/tunnel/src/tests/sim_net.rs @@ -17,8 +17,7 @@ use std::{ }; use tracing::Span; -#[derive(Clone, derivative::Derivative)] -#[derivative(Debug)] +#[derive(Clone, derive_more::Debug)] pub(crate) struct Host { inner: T, @@ -27,23 +26,23 @@ pub(crate) struct Host { // In production, we always rebind to a new port. // To mimic this, we track the used ports here to not sample an existing one. - #[derivative(Debug = "ignore")] + #[debug(skip)] pub(crate) old_ports: HashSet, default_port: u16, - #[derivative(Debug = "ignore")] + #[debug(skip)] allocated_ports: HashSet<(u16, AddressFamily)>, // The latency of incoming and outgoing packets. latency: Duration, - #[derivative(Debug = "ignore")] + #[debug(skip)] span: Span, /// Messages that have "arrived" and are waiting to be dispatched. /// /// We buffer them here because we need also apply our latency on inbound packets. - #[derivative(Debug = "ignore")] + #[debug(skip)] inbox: BufferedTransmits, } diff --git a/rust/connlib/tunnel/src/tests/stub_portal.rs b/rust/connlib/tunnel/src/tests/stub_portal.rs index bcabe067b..d4825cd25 100644 --- a/rust/connlib/tunnel/src/tests/stub_portal.rs +++ b/rust/connlib/tunnel/src/tests/stub_portal.rs @@ -22,12 +22,11 @@ use std::{ }; /// Stub implementation of the portal. -#[derive(Clone, derivative::Derivative)] -#[derivative(Debug)] +#[derive(Clone, derive_more::Debug)] pub(crate) struct StubPortal { gateways_by_site: BTreeMap>, - #[derivative(Debug = "ignore")] + #[debug(skip)] sites_by_resource: BTreeMap, // TODO: Maybe these should use the `messages` types to cover the conversions and to model that that is what we receive from the portal? @@ -35,7 +34,7 @@ pub(crate) struct StubPortal { dns_resources: BTreeMap, internet_resource: client::InternetResource, - #[derivative(Debug = "ignore")] + #[debug(skip)] gateway_selector: Selector, } diff --git a/rust/connlib/tunnel/src/tests/transition.rs b/rust/connlib/tunnel/src/tests/transition.rs index 806a0b82e..e1f9feda3 100644 --- a/rust/connlib/tunnel/src/tests/transition.rs +++ b/rust/connlib/tunnel/src/tests/transition.rs @@ -114,12 +114,11 @@ pub(crate) struct SPort(pub u16); #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(crate) struct DPort(pub u16); -#[derive(Clone, derivative::Derivative)] -#[derivative(Debug)] +#[derive(Clone, derive_more::Debug)] #[expect(clippy::large_enum_variant)] pub(crate) enum Destination { DomainName { - #[derivative(Debug = "ignore")] + #[debug(skip)] resolved_ip: sample::Selector, name: DomainName, }, diff --git a/rust/deny.toml b/rust/deny.toml index d13bb93af..b8b7e8fe0 100644 --- a/rust/deny.toml +++ b/rust/deny.toml @@ -73,7 +73,6 @@ ignore = [ "RUSTSEC-2020-0095", # `difference` is unmaintained "RUSTSEC-2024-0384", # `instant` is unmaintained "RUSTSEC-2024-0370", # `proc-macro-error` is unmaintained - "RUSTSEC-2024-0388", # `derivative` is unmaintained #"RUSTSEC-0000-0000", #{ id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" }, #"a-crate-that-is-yanked@0.1.1", # you can also ignore yanked crate versions if you wish diff --git a/rust/dns-over-tcp/src/stub_device.rs b/rust/dns-over-tcp/src/stub_device.rs index 294b98b14..766245eed 100644 --- a/rust/dns-over-tcp/src/stub_device.rs +++ b/rust/dns-over-tcp/src/stub_device.rs @@ -57,7 +57,7 @@ pub(crate) struct SmolTxToken<'a> { outbound_packets: &'a mut VecDeque, } -impl<'a> smoltcp::phy::TxToken for SmolTxToken<'a> { +impl smoltcp::phy::TxToken for SmolTxToken<'_> { fn consume(self, len: usize, f: F) -> R where F: FnOnce(&mut [u8]) -> R, diff --git a/rust/gui-client/src-common/src/compositor.rs b/rust/gui-client/src-common/src/compositor.rs index 666e07758..d806ae96e 100644 --- a/rust/gui-client/src-common/src/compositor.rs +++ b/rust/gui-client/src-common/src/compositor.rs @@ -28,7 +28,6 @@ pub struct Image { /// # Returns /// /// An `Image` with the same dimensions as the first layer. - pub fn compose<'a, I: IntoIterator>(layers: I) -> Result { let mut dst = None; diff --git a/rust/headless-client/src/dns_control/windows.rs b/rust/headless-client/src/dns_control/windows.rs index 87c6ee18a..14d021890 100644 --- a/rust/headless-client/src/dns_control/windows.rs +++ b/rust/headless-client/src/dns_control/windows.rs @@ -188,8 +188,6 @@ fn refresh_group_policy() -> Result<()> { Ok(()) } -/// Returns - /// Given the path of a registry key, sets the parameters of an NRPT rule on it. fn set_nrpt_rule(key: &winreg::RegKey, dns_config_string: &str) -> Result<()> { key.set_value("Comment", &FZ_MAGIC)?; diff --git a/rust/headless-client/src/main.rs b/rust/headless-client/src/main.rs index b6b3976b4..327f135cc 100644 --- a/rust/headless-client/src/main.rs +++ b/rust/headless-client/src/main.rs @@ -77,7 +77,6 @@ struct Cli { firezone_name: Option, /// Identifier used by the portal to identify and display the device. - // AKA `device_id` in the Windows and Linux GUI clients // Generated automatically if not provided #[arg(short = 'i', long, env = "FIREZONE_ID")] @@ -94,7 +93,6 @@ struct Cli { token: Option, /// A filesystem path where the token can be found - // Apparently passing secrets through stdin is the most secure method, but // until anyone asks for it, env vars are okay and files on disk are slightly better. // (Since we run as root and the env var on a headless system is probably stored diff --git a/rust/logging/src/err_with_sources.rs b/rust/logging/src/err_with_sources.rs index 88e9a4401..6882448de 100644 --- a/rust/logging/src/err_with_sources.rs +++ b/rust/logging/src/err_with_sources.rs @@ -10,7 +10,7 @@ pub struct ErrorWithSources<'a> { e: &'a (dyn Error + 'static), } -impl<'a> fmt::Display for ErrorWithSources<'a> { +impl fmt::Display for ErrorWithSources<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.e)?; diff --git a/rust/logging/src/format.rs b/rust/logging/src/format.rs index be135826f..711e62fc6 100644 --- a/rust/logging/src/format.rs +++ b/rust/logging/src/format.rs @@ -191,7 +191,7 @@ const INFO_STR: &str = " INFO"; const WARN_STR: &str = " WARN"; const ERROR_STR: &str = "ERROR"; -impl<'a> fmt::Display for FmtLevel<'a> { +impl fmt::Display for FmtLevel<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if self.ansi { match *self.level { diff --git a/rust/rust-toolchain.toml b/rust/rust-toolchain.toml index baaffdc99..672aacb04 100644 --- a/rust/rust-toolchain.toml +++ b/rust/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] # Keep synced with `Dockerfile` -channel = "1.82.0" +channel = "1.83.0" diff --git a/scripts/nix/flake.lock b/scripts/nix/flake.lock index ce6012ad2..fee51bb1e 100644 --- a/scripts/nix/flake.lock +++ b/scripts/nix/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1726560853, - "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1729044727, - "narHash": "sha256-GKJjtPY+SXfLF/yTN7M2cAnQB6RERFKnQhD8UvPSf3M=", + "lastModified": 1732749044, + "narHash": "sha256-T38FQOg0BV5M8FN1712fovzNakSOENEYs+CSkg31C9Y=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "dc2e0028d274394f73653c7c90cc63edbb696be1", + "rev": "0c5b4ecbed5b155b705336aa96d878e55acd8685", "type": "github" }, "original": { @@ -61,11 +61,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1729184663, - "narHash": "sha256-uNyi5vQrzaLkt4jj6ZEOs4+4UqOAwP6jFG2s7LIDwIk=", + "lastModified": 1732802692, + "narHash": "sha256-kFrxb45qj52TT/OFUFyTdmvXkn/KXDUL0/DOtjHEQvs=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "16fb78d443c1970dda9a0bbb93070c9d8598a925", + "rev": "34971069ec33755b2adf2481851f66d8ec9a6bfa", "type": "github" }, "original": { diff --git a/scripts/nix/flake.nix b/scripts/nix/flake.nix index 7a8cebe58..c416ca1cf 100644 --- a/scripts/nix/flake.nix +++ b/scripts/nix/flake.nix @@ -37,8 +37,6 @@ gnome.zenity desktop-file-utils android-tools - erlang_27 - elixir # For Tauri at-spi2-atk