From da008485497c62ddf50ad58bffe10a864019e2b3 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 18 Aug 2025 15:04:55 +1000 Subject: [PATCH] build(deps): bump to Rust 1.89 (#10208) Rust 1.89 comes with a new lint that wants us to use explicitly refer to lifetimes, even if they are elided. --- rust/connlib/ip-packet/src/lib.rs | 62 +++++++++---------- rust/connlib/snownet/src/allocation.rs | 30 ++++----- rust/connlib/snownet/src/channel_data.rs | 2 +- rust/connlib/snownet/src/node.rs | 8 +-- rust/connlib/tunnel/src/client.rs | 8 +-- rust/connlib/tunnel/src/dns.rs | 8 +-- rust/connlib/tunnel/src/io.rs | 24 +++---- rust/connlib/tunnel/src/tests/sut.rs | 8 +-- rust/connlib/tunnel/src/tests/tcp.rs | 18 +++--- .../src-tauri/src/gui/os_windows.rs | 14 ++--- rust/gui-client/src-tauri/src/service.rs | 14 ++--- rust/logging/src/file.rs | 12 ++-- rust/logging/src/format.rs | 8 +-- rust/relay/server/src/server.rs | 9 ++- .../relay/server/src/server/client_message.rs | 2 +- rust/relay/server/src/sockets.rs | 6 +- rust/rust-toolchain.toml | 2 +- 17 files changed, 115 insertions(+), 120 deletions(-) diff --git a/rust/connlib/ip-packet/src/lib.rs b/rust/connlib/ip-packet/src/lib.rs index a2d8cd1fe..9bbd33f51 100644 --- a/rust/connlib/ip-packet/src/lib.rs +++ b/rust/connlib/ip-packet/src/lib.rs @@ -360,26 +360,26 @@ impl IpPacket { } fn set_icmp_identifier(&mut self, v: u16) { - if let Some(icmpv4) = self.as_icmpv4() { - if matches!( + if let Some(icmpv4) = self.as_icmpv4() + && matches!( icmpv4.icmp_type(), Icmpv4Type::EchoRequest(_) | Icmpv4Type::EchoReply(_) - ) { - self.as_icmpv4_mut() - .expect("Not an ICMPv4 packet") - .set_identifier(v); - } + ) + { + self.as_icmpv4_mut() + .expect("Not an ICMPv4 packet") + .set_identifier(v); } - if let Some(icmpv6) = self.as_icmpv6() { - if matches!( + if let Some(icmpv6) = self.as_icmpv6() + && matches!( icmpv6.icmp_type(), Icmpv6Type::EchoRequest(_) | Icmpv6Type::EchoReply(_) - ) { - self.as_icmpv6_mut() - .expect("Not an ICMPv6 packet") - .set_identifier(v); - } + ) + { + self.as_icmpv6_mut() + .expect("Not an ICMPv6 packet") + .set_identifier(v); } } @@ -395,39 +395,39 @@ impl IpPacket { self.set_ipv4_checksum(); } - fn as_ipv4(&self) -> Option { + fn as_ipv4(&self) -> Option> { Ipv4Slice::from_slice(&self.buf[..self.len]).ok() } - fn as_ipv4_header_mut(&mut self) -> Option { + fn as_ipv4_header_mut(&mut self) -> Option> { Ipv4HeaderSliceMut::from_slice(&mut self.buf[..self.len]).ok() } #[expect(clippy::unwrap_used, reason = "The function is marked as `unchecked`.")] - fn as_ipv4_unchecked(&self) -> Ipv4Slice { + fn as_ipv4_unchecked(&self) -> Ipv4Slice<'_> { self.as_ipv4().unwrap() } #[expect(clippy::unwrap_used, reason = "The function is marked as `unchecked`.")] - fn as_ipv4_header_mut_unchecked(&mut self) -> Ipv4HeaderSliceMut { + fn as_ipv4_header_mut_unchecked(&mut self) -> Ipv4HeaderSliceMut<'_> { self.as_ipv4_header_mut().unwrap() } - fn as_ipv6(&self) -> Option { + fn as_ipv6(&self) -> Option> { Ipv6Slice::from_slice(&self.buf[..self.len]).ok() } - fn as_ipv6_header_mut(&mut self) -> Option { + fn as_ipv6_header_mut(&mut self) -> Option> { Ipv6HeaderSliceMut::from_slice(&mut self.buf[..self.len]).ok() } #[expect(clippy::unwrap_used, reason = "The function is marked as `unchecked`.")] - fn as_ipv6_unchecked(&self) -> Ipv6Slice { + fn as_ipv6_unchecked(&self) -> Ipv6Slice<'_> { self.as_ipv6().unwrap() } #[expect(clippy::unwrap_used, reason = "The function is marked as `unchecked`.")] - fn as_ipv6_header_mut_unchecked(&mut self) -> Ipv6HeaderSliceMut { + fn as_ipv6_header_mut_unchecked(&mut self) -> Ipv6HeaderSliceMut<'_> { self.as_ipv6_header_mut().unwrap() } @@ -498,7 +498,7 @@ impl IpPacket { .set_checksum(checksum); } - pub fn as_udp(&self) -> Option { + pub fn as_udp(&self) -> Option> { if !self.is_udp() { return None; } @@ -506,7 +506,7 @@ impl IpPacket { UdpSlice::from_slice(self.payload()).ok() } - pub fn as_udp_mut(&mut self) -> Option { + pub fn as_udp_mut(&mut self) -> Option> { if !self.is_udp() { return None; } @@ -514,7 +514,7 @@ impl IpPacket { UdpHeaderSliceMut::from_slice(self.payload_mut()).ok() } - pub fn as_tcp(&self) -> Option { + pub fn as_tcp(&self) -> Option> { if !self.is_tcp() { return None; } @@ -522,7 +522,7 @@ impl IpPacket { TcpSlice::from_slice(self.payload()).ok() } - pub fn as_tcp_mut(&mut self) -> Option { + pub fn as_tcp_mut(&mut self) -> Option> { if !self.is_tcp() { return None; } @@ -567,7 +567,7 @@ impl IpPacket { i.set_checksum(checksum); } - pub fn as_icmpv4(&self) -> Option { + pub fn as_icmpv4(&self) -> Option> { if !self.is_icmp() { return None; } @@ -577,7 +577,7 @@ impl IpPacket { .ok() } - pub fn as_icmpv4_mut(&mut self) -> Option { + pub fn as_icmpv4_mut(&mut self) -> Option> { if !self.is_icmp() { return None; } @@ -675,7 +675,7 @@ impl IpPacket { Ok(None) } - pub fn as_icmpv6(&self) -> Option { + pub fn as_icmpv6(&self) -> Option> { if !self.is_icmpv6() { return None; } @@ -683,7 +683,7 @@ impl IpPacket { Icmpv6Slice::from_slice(self.payload()).ok() } - pub fn as_icmpv6_mut(&mut self) -> Option { + pub fn as_icmpv6_mut(&mut self) -> Option> { if !self.is_icmpv6() { return None; } @@ -691,7 +691,7 @@ impl IpPacket { Icmpv6EchoHeaderSliceMut::from_slice(self.payload_mut()).ok() } - pub fn as_fz_p2p_control(&self) -> Option { + pub fn as_fz_p2p_control(&self) -> Option> { if !self.is_fz_p2p_control() { return None; } diff --git a/rust/connlib/snownet/src/allocation.rs b/rust/connlib/snownet/src/allocation.rs index e36018d01..52b91bcf2 100644 --- a/rust/connlib/snownet/src/allocation.rs +++ b/rust/connlib/snownet/src/allocation.rs @@ -394,11 +394,11 @@ impl Allocation { let _ = nonce.insert(new_nonce.clone()); }; - if let Some(offered_realm) = message.get_attribute::() { - if offered_realm != realm { - tracing::warn!(allowed_realm = %realm.text(), server_realm = %offered_realm.text(), "Refusing to authenticate with server"); - return true; // We still handled our message correctly. - } + if let Some(offered_realm) = message.get_attribute::() + && offered_realm != realm + { + tracing::warn!(allowed_realm = %realm.text(), server_realm = %offered_realm.text(), "Refusing to authenticate with server"); + return true; // We still handled our message correctly. }; tracing::debug!( @@ -702,14 +702,13 @@ impl Allocation { self.invalidate_allocation(); } - if self.has_allocation() { - if let Some(addr) = self + if self.has_allocation() + && let Some(addr) = self .active_socket .as_mut() .and_then(|a| a.handle_timeout(now)) - { - self.queue(addr, make_binding_request(self.software.clone()), None, now); - } + { + self.queue(addr, make_binding_request(self.software.clone()), None, now); } while let Some(timed_out_request) = self @@ -753,11 +752,12 @@ impl Allocation { backoff.handle_timeout(now); } - if let Some(refresh_at) = self.refresh_allocation_at() { - if (now >= refresh_at) && !self.refresh_in_flight() { - tracing::debug!("Allocation is due for a refresh"); - self.authenticate_and_queue(make_refresh_request(self.software.clone()), None, now); - } + if let Some(refresh_at) = self.refresh_allocation_at() + && (now >= refresh_at) + && !self.refresh_in_flight() + { + tracing::debug!("Allocation is due for a refresh"); + self.authenticate_and_queue(make_refresh_request(self.software.clone()), None, now); } let channel_refresh_messages = self diff --git a/rust/connlib/snownet/src/channel_data.rs b/rust/connlib/snownet/src/channel_data.rs index 86e3b23f0..0e1468cc1 100644 --- a/rust/connlib/snownet/src/channel_data.rs +++ b/rust/connlib/snownet/src/channel_data.rs @@ -18,7 +18,7 @@ impl<'a> Packet<'a> { } } -pub fn decode(data: &[u8]) -> Result { +pub fn decode(data: &[u8]) -> Result, io::Error> { if data.len() < HEADER_LEN { return Err(io::Error::new( io::ErrorKind::UnexpectedEof, diff --git a/rust/connlib/snownet/src/node.rs b/rust/connlib/snownet/src/node.rs index a159ae5df..102bfc651 100644 --- a/rust/connlib/snownet/src/node.rs +++ b/rust/connlib/snownet/src/node.rs @@ -2019,10 +2019,10 @@ where } // If `boringtun` wants to be called earlier than the scheduled interval, move it forward. - if let Some(next_update) = self.tunnel.next_timer_update() { - if next_update < self.next_wg_timer_update { - self.next_wg_timer_update = next_update; - } + if let Some(next_update) = self.tunnel.next_timer_update() + && next_update < self.next_wg_timer_update + { + self.next_wg_timer_update = next_update; } while let Some(event) = self.agent.poll_event() { diff --git a/rust/connlib/tunnel/src/client.rs b/rust/connlib/tunnel/src/client.rs index 56ee2b7d2..9391817f6 100644 --- a/rust/connlib/tunnel/src/client.rs +++ b/rust/connlib/tunnel/src/client.rs @@ -1395,10 +1395,10 @@ impl ClientState { continue; } - if let Some(active_resource) = active_cidr_resources.exact_match(resource.address) { - if self.is_cidr_resource_connected(&active_resource.id) { - continue; - } + if let Some(active_resource) = active_cidr_resources.exact_match(resource.address) + && self.is_cidr_resource_connected(&active_resource.id) + { + continue; } active_cidr_resources.insert(resource.address, resource.clone()); diff --git a/rust/connlib/tunnel/src/dns.rs b/rust/connlib/tunnel/src/dns.rs index 851ceefef..1e6d6d55b 100644 --- a/rust/connlib/tunnel/src/dns.rs +++ b/rust/connlib/tunnel/src/dns.rs @@ -479,10 +479,10 @@ mod pattern { pub fn matches(&self, domain: &Candidate) -> bool { let domain = domain.0.as_str(); - if let Some(rem) = self.inner.as_str().strip_prefix("*/") { - if domain == rem { - return true; - } + if let Some(rem) = self.inner.as_str().strip_prefix("*/") + && domain == rem + { + return true; } self.inner.matches_with( diff --git a/rust/connlib/tunnel/src/io.rs b/rust/connlib/tunnel/src/io.rs index 5baf1d656..75d86ec68 100644 --- a/rust/connlib/tunnel/src/io.rs +++ b/rust/connlib/tunnel/src/io.rs @@ -243,20 +243,20 @@ impl Io { Poll::Pending => {} } - if let Some(timeout) = self.timeout.as_mut() { - if timeout.poll_unpin(cx).is_ready() { - // Always emit `now` as the timeout value. - // This ensures that time within our state machine is always monotonic. - // If we were to use the `deadline` of the timer instead, time may go backwards. - // That is because it is valid to set a `Sleep` to a timestamp in the past. - // It will resolve immediately but it will still report the old timestamp as its deadline. - // To guard against this case, specifically call `Instant::now` here. - let now = Instant::now(); + if let Some(timeout) = self.timeout.as_mut() + && timeout.poll_unpin(cx).is_ready() + { + // Always emit `now` as the timeout value. + // This ensures that time within our state machine is always monotonic. + // If we were to use the `deadline` of the timer instead, time may go backwards. + // That is because it is valid to set a `Sleep` to a timestamp in the past. + // It will resolve immediately but it will still report the old timestamp as its deadline. + // To guard against this case, specifically call `Instant::now` here. + let now = Instant::now(); - self.timeout = None; // Clear the timeout. + self.timeout = None; // Clear the timeout. - return Poll::Ready(Ok(Input::Timeout(now))); - } + return Poll::Ready(Ok(Input::Timeout(now))); } Poll::Pending diff --git a/rust/connlib/tunnel/src/tests/sut.rs b/rust/connlib/tunnel/src/tests/sut.rs index b7ddcd9bb..13e188d06 100644 --- a/rust/connlib/tunnel/src/tests/sut.rs +++ b/rust/connlib/tunnel/src/tests/sut.rs @@ -420,10 +420,10 @@ impl TunnelTest { now, ); - if let Some((next, reason)) = self.poll_timeout() { - if next < now { - tracing::error!(?next, ?now, %reason, "State machine requested time in the past"); - } + if let Some((next, reason)) = self.poll_timeout() + && next < now + { + tracing::error!(?next, ?now, %reason, "State machine requested time in the past"); } for (id, gateway) in self.gateways.iter_mut() { diff --git a/rust/connlib/tunnel/src/tests/tcp.rs b/rust/connlib/tunnel/src/tests/tcp.rs index f4624f288..1fa461d72 100644 --- a/rust/connlib/tunnel/src/tests/tcp.rs +++ b/rust/connlib/tunnel/src/tests/tcp.rs @@ -75,15 +75,13 @@ impl Client { pub fn handle_inbound(&mut self, packet: IpPacket) { // TODO: Upstream ICMP error handling to `smoltcp`. - if let Ok(Some((failed_packet, _))) = packet.icmp_error() { - if let Layer4Protocol::Tcp { dst, .. } = failed_packet.layer4_protocol() { - if let Some(handle) = self - .sockets_by_remote - .get(&SocketAddr::new(failed_packet.dst(), dst)) - { - self.sockets.get_mut::(*handle).abort(); - } - } + if let Ok(Some((failed_packet, _))) = packet.icmp_error() + && let Layer4Protocol::Tcp { dst, .. } = failed_packet.layer4_protocol() + && let Some(handle) = self + .sockets_by_remote + .get(&SocketAddr::new(failed_packet.dst(), dst)) + { + self.sockets.get_mut::(*handle).abort(); } self.device.receive(packet); @@ -111,7 +109,7 @@ impl Client { Some(self.last_now + Duration::from(poll_in)) } - pub fn iter_sockets(&self) -> impl Iterator { + pub fn iter_sockets(&self) -> impl Iterator> { self.sockets.iter().map(|(_, s)| match s { l3_tcp::AnySocket::Tcp(socket) => socket, }) diff --git a/rust/gui-client/src-tauri/src/gui/os_windows.rs b/rust/gui-client/src-tauri/src/gui/os_windows.rs index c5c379fd9..4367cc287 100644 --- a/rust/gui-client/src-tauri/src/gui/os_windows.rs +++ b/rust/gui-client/src-tauri/src/gui/os_windows.rs @@ -108,13 +108,13 @@ pub(crate) fn show_clickable_notification( .text1(body) .scenario(tauri_winrt_notification::Scenario::Reminder) .on_activated(move |_| { - if let Some(req) = req.take() { - if let Err(error) = tx.blocking_send(req) { - tracing::error!( - "User clicked on notification, but we couldn't tell `Controller`: {}", - err_with_src(&error) - ); - } + if let Some(req) = req.take() + && let Err(error) = tx.blocking_send(req) + { + tracing::error!( + "User clicked on notification, but we couldn't tell `Controller`: {}", + err_with_src(&error) + ); } Ok(()) }) diff --git a/rust/gui-client/src-tauri/src/service.rs b/rust/gui-client/src-tauri/src/service.rs index 2af1bf535..dbac551b5 100644 --- a/rust/gui-client/src-tauri/src/service.rs +++ b/rust/gui-client/src-tauri/src/service.rs @@ -447,13 +447,13 @@ impl<'a> Handler<'a> { }); } - if let Some(event_stream) = self.session.as_event_stream() { - if let Poll::Ready(option) = event_stream.poll_next(cx) { - return Poll::Ready(match option { - Some(x) => Event::Connlib(x), - None => Event::CallbackChannelClosed, - }); - } + if let Some(event_stream) = self.session.as_event_stream() + && let Poll::Ready(option) = event_stream.poll_next(cx) + { + return Poll::Ready(match option { + Some(x) => Event::Connlib(x), + None => Event::CallbackChannelClosed, + }); } Poll::Pending diff --git a/rust/logging/src/file.rs b/rust/logging/src/file.rs index 196dc11c2..7f894d410 100644 --- a/rust/logging/src/file.rs +++ b/rust/logging/src/file.rs @@ -149,13 +149,13 @@ impl Appender { open_options.append(true).create(true); let new_file = open_options.open(path.as_path()); - if new_file.is_err() { - if let Some(parent) = path.parent() { - fs::create_dir_all(parent)?; - let file = open_options.open(path)?; + if new_file.is_err() + && let Some(parent) = path.parent() + { + fs::create_dir_all(parent)?; + let file = open_options.open(path)?; - return Ok((file, filename)); - } + return Ok((file, filename)); } let file = new_file?; diff --git a/rust/logging/src/format.rs b/rust/logging/src/format.rs index 3d8bd76d3..73667c165 100644 --- a/rust/logging/src/format.rs +++ b/rust/logging/src/format.rs @@ -134,10 +134,10 @@ where .flat_map(tracing_subscriber::registry::Scope::from_root) { let exts = span.extensions(); - if let Some(fields) = exts.get::>() { - if !fields.is_empty() { - write!(writer, " {}", fields.fields)?; - } + if let Some(fields) = exts.get::>() + && !fields.is_empty() + { + write!(writer, " {}", fields.fields)?; } } writeln!(writer) diff --git a/rust/relay/server/src/server.rs b/rust/relay/server/src/server.rs index f5fa198e0..36608b0d6 100644 --- a/rust/relay/server/src/server.rs +++ b/rust/relay/server/src/server.rs @@ -676,14 +676,13 @@ where if let Some(number) = self .channel_numbers_by_client_and_peer .get(&(sender, peer_address)) + && number != &requested_channel { - if number != &requested_channel { - let (error_response, msg) = make_error_response(BadRequest, request); + let (error_response, msg) = make_error_response(BadRequest, request); - tracing::warn!(target: "relay", existing_channel = %number.value(), allocation = %allocation.port, peer = %peer_address, channel = %requested_channel.value(), "{msg}: Peer is already bound to another channel"); + tracing::warn!(target: "relay", existing_channel = %number.value(), allocation = %allocation.port, peer = %peer_address, channel = %requested_channel.value(), "{msg}: Peer is already bound to another channel"); - return Err(error_response); - } + return Err(error_response); } // Ensure the channel is not already bound to a different address. diff --git a/rust/relay/server/src/server/client_message.rs b/rust/relay/server/src/server/client_message.rs index 971a254e9..ecc6c239c 100644 --- a/rust/relay/server/src/server/client_message.rs +++ b/rust/relay/server/src/server/client_message.rs @@ -28,7 +28,7 @@ const MAX_ALLOCATION_LIFETIME: Duration = Duration::from_secs(3600); /// See . const DEFAULT_ALLOCATION_LIFETIME: Duration = Duration::from_secs(600); -pub fn decode(input: &[u8]) -> Result>, Error> { +pub fn decode(input: &[u8]) -> Result, Message>, Error> { let mut decoder = stun_codec::MessageDecoder::default(); // De-multiplex as per . diff --git a/rust/relay/server/src/sockets.rs b/rust/relay/server/src/sockets.rs index 27f9427c2..da48478fa 100644 --- a/rust/relay/server/src/sockets.rs +++ b/rust/relay/server/src/sockets.rs @@ -175,10 +175,8 @@ impl Sockets { self.current_ready_sockets.insert((0, token)); } - if writeable { - if let Some(waker) = self.flush_waker.take() { - waker.wake(); - } + if writeable && let Some(waker) = self.flush_waker.take() { + waker.wake(); } continue; diff --git a/rust/rust-toolchain.toml b/rust/rust-toolchain.toml index 6a0e04e65..2101cc0d6 100644 --- a/rust/rust-toolchain.toml +++ b/rust/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.88.0" +channel = "1.89.0" components = ["rust-src", "rust-analyzer", "clippy"] targets = ["x86_64-unknown-linux-musl"]