Skip to content

Commit

Permalink
Minor changes to Ipv4Addr
Browse files Browse the repository at this point in the history
* Impl IntoInner rather than AsInner for Ipv4Addr
* Add some comments
* Add test to show endiannes of Ipv4Addr display
  • Loading branch information
tesuji committed Aug 19, 2020
1 parent 2c3dc04 commit 768509f
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 11 deletions.
6 changes: 4 additions & 2 deletions library/std/src/net/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() }
},
}
Expand All @@ -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) }
}

Expand All @@ -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.
Expand Down
15 changes: 10 additions & 5 deletions library/std/src/net/ip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -909,7 +909,10 @@ impl Eq for Ipv4Addr {}
#[stable(feature = "rust1", since = "1.0.0")]
impl hash::Hash for Ipv4Addr {
fn hash<H: hash::Hasher>(&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)
}
}
Expand Down Expand Up @@ -944,13 +947,14 @@ impl PartialOrd<IpAddr> 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<c::in_addr> for Ipv4Addr {
fn as_inner(&self) -> &c::in_addr {
&self.inner
impl IntoInner<c::in_addr> for Ipv4Addr {
fn into_inner(self) -> c::in_addr {
self.inner
}
}

Expand Down Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions library/std/src/sys_common/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down

0 comments on commit 768509f

Please sign in to comment.