From 3b2c0a9ae9f7ea32a60fc7d7c638ea0a6cf0946f Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Fri, 14 Aug 2020 04:17:55 +0000 Subject: [PATCH] Minor changes to Ipv4Addr * Impl IntoInner rather than AsInner for Ipv4Addr * Add some comments * Add test to show endiannes of Ipv4Addr display --- library/std/src/net/addr.rs | 6 ++++-- library/std/src/net/ip.rs | 14 ++++++++------ library/std/src/sys_common/net.rs | 8 ++++---- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/library/std/src/net/addr.rs b/library/std/src/net/addr.rs index c11049fb98152..d7d96862b2116 100644 --- a/library/std/src/net/addr.rs +++ b/library/std/src/net/addr.rs @@ -268,7 +268,7 @@ impl SocketAddrV4 { inner: c::sockaddr_in { sin_family: c::AF_INET as c::sa_family_t, sin_port: htons(port), - sin_addr: *ip.as_inner(), + sin_addr: ip.into_inner(), ..unsafe { mem::zeroed() } }, } @@ -286,6 +286,8 @@ impl SocketAddrV4 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn ip(&self) -> &Ipv4Addr { + // SAFETY: `Ipv4Addr` is `#[repr(C)] struct { _: in_addr; }`. + // It is safe to cast from `&in_addr` to `&Ipv4Addr`. unsafe { &*(&self.inner.sin_addr as *const c::in_addr as *const Ipv4Addr) } } @@ -302,7 +304,7 @@ impl SocketAddrV4 { /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] pub fn set_ip(&mut self, new_ip: Ipv4Addr) { - self.inner.sin_addr = *new_ip.as_inner() + self.inner.sin_addr = new_ip.into_inner() } /// Returns the port number associated with this socket address. diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index de28268ea3682..a9393e9f62ef0 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -12,7 +12,7 @@ use crate::hash; use crate::io::Write as IoWrite; use crate::mem::transmute; use crate::sys::net::netc as c; -use crate::sys_common::{AsInner, FromInner}; +use crate::sys_common::{AsInner, FromInner, IntoInner}; /// An IP address, either IPv4 or IPv6. /// @@ -909,8 +909,8 @@ impl Eq for Ipv4Addr {} #[stable(feature = "rust1", since = "1.0.0")] impl hash::Hash for Ipv4Addr { fn hash(&self, s: &mut H) { - // `inner` is #[repr(packed)], so we need to copy `s_addr`. - { self.inner.s_addr }.hash(s) + // hashing in big endian + self.inner.s_addr.hash(s) } } @@ -944,13 +944,14 @@ impl PartialOrd for Ipv4Addr { #[stable(feature = "rust1", since = "1.0.0")] impl Ord for Ipv4Addr { fn cmp(&self, other: &Ipv4Addr) -> Ordering { + // Compare as native endian u32::from_be(self.inner.s_addr).cmp(&u32::from_be(other.inner.s_addr)) } } -impl AsInner for Ipv4Addr { - fn as_inner(&self) -> &c::in_addr { - &self.inner +impl IntoInner for Ipv4Addr { + fn into_inner(self) -> c::in_addr { + self.inner } } @@ -2019,6 +2020,7 @@ mod tests { #[test] fn ipv4_addr_to_string() { + assert_eq!(Ipv4Addr::new(127, 0, 0, 1).to_string(), "127.0.0.1"); // Short address assert_eq!(Ipv4Addr::new(1, 1, 1, 1).to_string(), "1.1.1.1"); // Long address diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index 81a5ef95e82dc..0bb136078bc95 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -585,8 +585,8 @@ impl UdpSocket { pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> { let mreq = c::ip_mreq { - imr_multiaddr: *multiaddr.as_inner(), - imr_interface: *interface.as_inner(), + imr_multiaddr: multiaddr.into_inner(), + imr_interface: interface.into_inner(), }; setsockopt(&self.inner, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) } @@ -601,8 +601,8 @@ impl UdpSocket { pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> { let mreq = c::ip_mreq { - imr_multiaddr: *multiaddr.as_inner(), - imr_interface: *interface.as_inner(), + imr_multiaddr: multiaddr.into_inner(), + imr_interface: interface.into_inner(), }; setsockopt(&self.inner, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) }