1 //! A socket address for any kind of socket. 2 //! 3 //! This is similar to [`std::net::SocketAddr`], but also supports Unix-domain 4 //! socket addresses on Unix. 5 //! 6 //! # Safety 7 //! 8 //! The `read` and `write` functions allow decoding and encoding from and to 9 //! OS-specific socket address representations in memory. 10 #![allow(unsafe_code)] 11 12 #[cfg(target_os = "linux")] 13 use crate::net::xdp::SocketAddrXdp; 14 #[cfg(unix)] 15 use crate::net::SocketAddrUnix; 16 use crate::net::{AddressFamily, SocketAddr, SocketAddrV4, SocketAddrV6}; 17 use crate::{backend, io}; 18 #[cfg(feature = "std")] 19 use core::fmt; 20 21 pub use backend::net::addr::SocketAddrStorage; 22 23 /// `struct sockaddr_storage` as a Rust enum. 24 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] 25 #[doc(alias = "sockaddr")] 26 #[non_exhaustive] 27 pub enum SocketAddrAny { 28 /// `struct sockaddr_in` 29 V4(SocketAddrV4), 30 /// `struct sockaddr_in6` 31 V6(SocketAddrV6), 32 /// `struct sockaddr_un` 33 #[cfg(unix)] 34 Unix(SocketAddrUnix), 35 /// `struct sockaddr_xdp` 36 #[cfg(target_os = "linux")] 37 Xdp(SocketAddrXdp), 38 } 39 40 impl From<SocketAddr> for SocketAddrAny { 41 #[inline] from(from: SocketAddr) -> Self42 fn from(from: SocketAddr) -> Self { 43 match from { 44 SocketAddr::V4(v4) => Self::V4(v4), 45 SocketAddr::V6(v6) => Self::V6(v6), 46 } 47 } 48 } 49 50 impl From<SocketAddrV4> for SocketAddrAny { 51 #[inline] from(from: SocketAddrV4) -> Self52 fn from(from: SocketAddrV4) -> Self { 53 Self::V4(from) 54 } 55 } 56 57 impl From<SocketAddrV6> for SocketAddrAny { 58 #[inline] from(from: SocketAddrV6) -> Self59 fn from(from: SocketAddrV6) -> Self { 60 Self::V6(from) 61 } 62 } 63 64 #[cfg(unix)] 65 impl From<SocketAddrUnix> for SocketAddrAny { 66 #[inline] from(from: SocketAddrUnix) -> Self67 fn from(from: SocketAddrUnix) -> Self { 68 Self::Unix(from) 69 } 70 } 71 72 impl SocketAddrAny { 73 /// Return the address family of this socket address. 74 #[inline] address_family(&self) -> AddressFamily75 pub const fn address_family(&self) -> AddressFamily { 76 match self { 77 Self::V4(_) => AddressFamily::INET, 78 Self::V6(_) => AddressFamily::INET6, 79 #[cfg(unix)] 80 Self::Unix(_) => AddressFamily::UNIX, 81 #[cfg(target_os = "linux")] 82 Self::Xdp(_) => AddressFamily::XDP, 83 } 84 } 85 86 /// Writes a platform-specific encoding of this socket address to 87 /// the memory pointed to by `storage`, and returns the number of 88 /// bytes used. 89 /// 90 /// # Safety 91 /// 92 /// `storage` must point to valid memory for encoding the socket 93 /// address. write(&self, storage: *mut SocketAddrStorage) -> usize94 pub unsafe fn write(&self, storage: *mut SocketAddrStorage) -> usize { 95 backend::net::write_sockaddr::write_sockaddr(self, storage) 96 } 97 98 /// Reads a platform-specific encoding of a socket address from 99 /// the memory pointed to by `storage`, which uses `len` bytes. 100 /// 101 /// # Safety 102 /// 103 /// `storage` must point to valid memory for decoding a socket 104 /// address. read(storage: *const SocketAddrStorage, len: usize) -> io::Result<Self>105 pub unsafe fn read(storage: *const SocketAddrStorage, len: usize) -> io::Result<Self> { 106 backend::net::read_sockaddr::read_sockaddr(storage, len) 107 } 108 } 109 110 #[cfg(feature = "std")] 111 impl fmt::Debug for SocketAddrAny { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result112 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 113 match self { 114 Self::V4(v4) => v4.fmt(fmt), 115 Self::V6(v6) => v6.fmt(fmt), 116 #[cfg(unix)] 117 Self::Unix(unix) => unix.fmt(fmt), 118 #[cfg(target_os = "linux")] 119 Self::Xdp(xdp) => xdp.fmt(fmt), 120 } 121 } 122 } 123