From 14d3539e96890e57c90c7b6ea3b931037c454086 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Wed, 8 Nov 2023 03:52:22 +0000 Subject: [PATCH] [ffx] Only compare TargetAddr on ip and port This patch implements custom `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` that only compare `ip` and `port`, and ignores ipv6 `flowinfo` and `scope_id` fields. The latest rust nightly has [fixed] a longstanding bug where the `PartialEq` implementation for `std::net::SocketAddr6` did not compare the `flowinfo` and `scope_id` fields. This has been fixed, but it broke ffx, which depended on this to deduplicate addresses that had the same ip and port, but different scopes. [fixed]: https://github.com/rust-lang/rust/pull/116714 Change-Id: I64536942fe3ad44c509ffa10bd8e637d2a92ea2c Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/942191 Reviewed-by: Steven Grady Fuchsia-Auto-Submit: Erick Tryzelaar Commit-Queue: Auto-Submit --- src/developer/ffx/lib/addr/src/target_addr.rs | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/developer/ffx/lib/addr/src/target_addr.rs b/src/developer/ffx/lib/addr/src/target_addr.rs index 67cfe4c7785..95216385c52 100644 --- a/src/developer/ffx/lib/addr/src/target_addr.rs +++ b/src/developer/ffx/lib/addr/src/target_addr.rs @@ -12,14 +12,31 @@ use std::{ str::FromStr, }; -#[derive(Hash, Clone, Debug, Copy, Eq, PartialEq)] +#[derive(Clone, Debug, Copy)] pub struct TargetAddr(SocketAddr); +// Only compare `TargetAddr` by ip and port, since we want to deduplicate targets if they are +// addressable over multiple IPv6 interfaces. +impl std::hash::Hash for TargetAddr { + fn hash(&self, state: &mut H) + where + H: std::hash::Hasher, + { + (self.0.ip(), self.0.port()).hash(state) + } +} + +impl PartialEq for TargetAddr { + fn eq(&self, other: &Self) -> bool { + self.0.ip() == other.0.ip() && self.0.port() == other.0.port() + } +} + +impl Eq for TargetAddr {} + impl Ord for TargetAddr { fn cmp(&self, other: &Self) -> Ordering { - let this_socket = SocketAddr::from(self); - let other_socket = SocketAddr::from(other); - this_socket.cmp(&other_socket) + self.0.ip().cmp(&other.0.ip()).then(self.0.port().cmp(&other.0.port())) } }