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. 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(unix)] 13 use crate::net::SocketAddrUnix; 14 use crate::net::{AddressFamily, SocketAddrV4, SocketAddrV6}; 15 use crate::{backend, io}; 16 #[cfg(feature = "std")] 17 use core::fmt; 18 19 pub use backend::net::addr::SocketAddrStorage; 20 21 /// `struct sockaddr_storage` as a Rust enum. 22 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] 23 #[doc(alias = "sockaddr")] 24 #[non_exhaustive] 25 pub enum SocketAddrAny { 26 /// `struct sockaddr_in` 27 V4(SocketAddrV4), 28 /// `struct sockaddr_in6` 29 V6(SocketAddrV6), 30 /// `struct sockaddr_un` 31 #[cfg(unix)] 32 Unix(SocketAddrUnix), 33 } 34 35 impl From<SocketAddrV4> for SocketAddrAny { 36 #[inline] from(from: SocketAddrV4) -> Self37 fn from(from: SocketAddrV4) -> Self { 38 Self::V4(from) 39 } 40 } 41 42 impl From<SocketAddrV6> for SocketAddrAny { 43 #[inline] from(from: SocketAddrV6) -> Self44 fn from(from: SocketAddrV6) -> Self { 45 Self::V6(from) 46 } 47 } 48 49 #[cfg(unix)] 50 impl From<SocketAddrUnix> for SocketAddrAny { 51 #[inline] from(from: SocketAddrUnix) -> Self52 fn from(from: SocketAddrUnix) -> Self { 53 Self::Unix(from) 54 } 55 } 56 57 impl SocketAddrAny { 58 /// Return the address family of this socket address. 59 #[inline] address_family(&self) -> AddressFamily60 pub const fn address_family(&self) -> AddressFamily { 61 match self { 62 Self::V4(_) => AddressFamily::INET, 63 Self::V6(_) => AddressFamily::INET6, 64 #[cfg(unix)] 65 Self::Unix(_) => AddressFamily::UNIX, 66 } 67 } 68 69 /// Writes a platform-specific encoding of this socket address to 70 /// the memory pointed to by `storage`, and returns the number of 71 /// bytes used. 72 /// 73 /// # Safety 74 /// 75 /// `storage` must point to valid memory for encoding the socket 76 /// address. write(&self, storage: *mut SocketAddrStorage) -> usize77 pub unsafe fn write(&self, storage: *mut SocketAddrStorage) -> usize { 78 backend::net::write_sockaddr::write_sockaddr(self, storage) 79 } 80 81 /// Reads a platform-specific encoding of a socket address from 82 /// the memory pointed to by `storage`, which uses `len` bytes. 83 /// 84 /// # Safety 85 /// 86 /// `storage` must point to valid memory for decoding a socket 87 /// address. read(storage: *const SocketAddrStorage, len: usize) -> io::Result<Self>88 pub unsafe fn read(storage: *const SocketAddrStorage, len: usize) -> io::Result<Self> { 89 backend::net::read_sockaddr::read_sockaddr(storage, len) 90 } 91 } 92 93 #[cfg(feature = "std")] 94 impl fmt::Debug for SocketAddrAny { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result95 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 96 match self { 97 Self::V4(v4) => v4.fmt(fmt), 98 Self::V6(v6) => v6.fmt(fmt), 99 #[cfg(unix)] 100 Self::Unix(unix) => unix.fmt(fmt), 101 } 102 } 103 } 104