From 768509ff84d8527e587df68ecfc4ed962b9f5f2a Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Wed, 19 Aug 2020 03:27:24 +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 | 15 ++++++++++----- library/std/src/sys_common/net.rs | 8 ++++---- 3 files changed, 18 insertions(+), 11 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..85bb6b60e6829 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,7 +909,10 @@ 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`. + // NOTE: + // * hash in big endian order + // * in netbsd, `in_addr` has `repr(packed)`, we need to + // copy `s_addr` to avoid unsafe borrowing { self.inner.s_addr }.hash(s) } } @@ -944,13 +947,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 +2023,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) }