From 963131e99ccd3a85e6df6676dc2d3ac7cf6ae7e3 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sat, 14 Oct 2023 00:40:18 +0000 Subject: [PATCH 1/2] Derive `Ord`, `PartialOrd` and `Hash` for `SocketAddr*` ...instead of hand rolling impls, since 1. It's nicer 2. It fixes a buggy `Ord` impl of `SocketAddrV6`, which ignored half of the fields --- library/core/src/net/socket_addr.rs | 51 ++--------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) diff --git a/library/core/src/net/socket_addr.rs b/library/core/src/net/socket_addr.rs index 8396aecf947..55116285842 100644 --- a/library/core/src/net/socket_addr.rs +++ b/library/core/src/net/socket_addr.rs @@ -1,6 +1,4 @@ -use crate::cmp::Ordering; use crate::fmt::{self, Write}; -use crate::hash; use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use super::display_buffer::DisplayBuffer; @@ -63,7 +61,7 @@ pub enum SocketAddr { /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1)); /// assert_eq!(socket.port(), 8080); /// ``` -#[derive(Copy, Clone, Eq, PartialEq)] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct SocketAddrV4 { ip: Ipv4Addr, @@ -96,7 +94,7 @@ pub struct SocketAddrV4 { /// assert_eq!(socket.ip(), &Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)); /// assert_eq!(socket.port(), 8080); /// ``` -#[derive(Copy, Clone, Eq, PartialEq)] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub struct SocketAddrV6 { ip: Ipv6Addr, @@ -644,48 +642,3 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(self, fmt) } } - -#[stable(feature = "socketaddr_ordering", since = "1.45.0")] -impl PartialOrd for SocketAddrV4 { - #[inline] - fn partial_cmp(&self, other: &SocketAddrV4) -> Option { - Some(self.cmp(other)) - } -} - -#[stable(feature = "socketaddr_ordering", since = "1.45.0")] -impl PartialOrd for SocketAddrV6 { - #[inline] - fn partial_cmp(&self, other: &SocketAddrV6) -> Option { - Some(self.cmp(other)) - } -} - -#[stable(feature = "socketaddr_ordering", since = "1.45.0")] -impl Ord for SocketAddrV4 { - #[inline] - fn cmp(&self, other: &SocketAddrV4) -> Ordering { - self.ip().cmp(other.ip()).then(self.port().cmp(&other.port())) - } -} - -#[stable(feature = "socketaddr_ordering", since = "1.45.0")] -impl Ord for SocketAddrV6 { - #[inline] - fn cmp(&self, other: &SocketAddrV6) -> Ordering { - self.ip().cmp(other.ip()).then(self.port().cmp(&other.port())) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl hash::Hash for SocketAddrV4 { - fn hash(&self, s: &mut H) { - (self.port, self.ip).hash(s) - } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl hash::Hash for SocketAddrV6 { - fn hash(&self, s: &mut H) { - (self.port, &self.ip, self.flowinfo, self.scope_id).hash(s) - } -} From 5c13c69f63dccdc637d28b403ae1fb687e0a5143 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 15 Oct 2023 12:25:58 +0000 Subject: [PATCH 2/2] Add tests for `SocketAddrV6` ordering with scope_id and flowinfo --- library/core/tests/net/socket_addr.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/library/core/tests/net/socket_addr.rs b/library/core/tests/net/socket_addr.rs index 35a69cead48..3d013d37e04 100644 --- a/library/core/tests/net/socket_addr.rs +++ b/library/core/tests/net/socket_addr.rs @@ -199,6 +199,9 @@ fn compare() { let v6_1 = "[2001:db8:f00::1002]:23456".parse::().unwrap(); let v6_2 = "[2001:db8:f00::2001]:12345".parse::().unwrap(); let v6_3 = "[2001:db8:f00::2001]:23456".parse::().unwrap(); + let v6_4 = "[2001:db8:f00::2001%42]:23456".parse::().unwrap(); + let mut v6_5 = "[2001:db8:f00::2001]:23456".parse::().unwrap(); + v6_5.set_flowinfo(17); // equality assert_eq!(v4_1, v4_1); @@ -207,6 +210,8 @@ fn compare() { assert_eq!(SocketAddr::V6(v6_1), SocketAddr::V6(v6_1)); assert!(v4_1 != v4_2); assert!(v6_1 != v6_2); + assert!(v6_3 != v6_4); + assert!(v6_3 != v6_5); // compare different addresses assert!(v4_1 < v4_2); @@ -226,6 +231,12 @@ fn compare() { assert!(v4_3 > v4_1); assert!(v6_3 > v6_1); + // compare the same address with different scope_id + assert!(v6_3 < v6_4); + + // compare the same address with different flowinfo + assert!(v6_3 < v6_5); + // compare with an inferred right-hand side assert_eq!(v4_1, "224.120.45.1:23456".parse().unwrap()); assert_eq!(v6_1, "[2001:db8:f00::1002]:23456".parse().unwrap());