diff --git a/Cargo.toml b/Cargo.toml index e09f758a25..dc854c5ff4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ libc = { git = "https://github.com/rust-lang/libc", rev = "cc19b6f0801", feature bitflags = "1.1" cfg-if = "1.0" pin-utils = { version = "0.1.0", optional = true } +static_assertions = "1" [target.'cfg(not(target_os = "redox"))'.dependencies] memoffset = { version = "0.6.3", optional = true } diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs index 4a16eea94e..c7b5f29eb6 100644 --- a/src/sys/socket/addr.rs +++ b/src/sys/socket/addr.rs @@ -40,23 +40,22 @@ use std::{fmt, mem, net, ptr, slice}; /// Convert a std::net::Ipv4Addr into the libc form. #[cfg(feature = "net")] -pub(crate) fn ipv4addr_to_libc(addr: net::Ipv4Addr) -> libc::in_addr { - let octets = addr.octets(); - libc::in_addr { - s_addr: u32::to_be( - ((octets[0] as u32) << 24) - | ((octets[1] as u32) << 16) - | ((octets[2] as u32) << 8) - | (octets[3] as u32), - ), +pub(crate) const fn ipv4addr_to_libc(addr: net::Ipv4Addr) -> libc::in_addr { + static_assertions::assert_eq_size!(net::Ipv4Addr, libc::in_addr); + // Safe because both types have the same memory layout, and no fancy Drop + // impls. + unsafe { + mem::transmute(addr) } } /// Convert a std::net::Ipv6Addr into the libc form. #[cfg(feature = "net")] pub(crate) const fn ipv6addr_to_libc(addr: &net::Ipv6Addr) -> libc::in6_addr { - libc::in6_addr { - s6_addr: addr.octets(), + static_assertions::assert_eq_size!(net::Ipv6Addr, libc::in6_addr); + // Safe because both are Newtype wrappers around the same libc type + unsafe { + mem::transmute(*addr) } }