| 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 ] |
| 42 | fn from(from: SocketAddr) -> Self { |
| 43 | match from { |
| 44 | SocketAddr::V4(v4: SocketAddrV4) => Self::V4(v4), |
| 45 | SocketAddr::V6(v6: SocketAddrV6) => Self::V6(v6), |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | impl From<SocketAddrV4> for SocketAddrAny { |
| 51 | #[inline ] |
| 52 | fn from(from: SocketAddrV4) -> Self { |
| 53 | Self::V4(from) |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | impl From<SocketAddrV6> for SocketAddrAny { |
| 58 | #[inline ] |
| 59 | fn from(from: SocketAddrV6) -> Self { |
| 60 | Self::V6(from) |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | #[cfg (unix)] |
| 65 | impl From<SocketAddrUnix> for SocketAddrAny { |
| 66 | #[inline ] |
| 67 | 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 ] |
| 75 | 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. |
| 94 | 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. |
| 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 { |
| 112 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 113 | match self { |
| 114 | Self::V4(v4: &SocketAddrV4) => v4.fmt(f), |
| 115 | Self::V6(v6: &SocketAddrV6) => v6.fmt(f), |
| 116 | #[cfg (unix)] |
| 117 | Self::Unix(unix: &SocketAddrUnix) => unix.fmt(f), |
| 118 | #[cfg (target_os = "linux" )] |
| 119 | Self::Xdp(xdp: &SocketAddrXdp) => xdp.fmt(f), |
| 120 | } |
| 121 | } |
| 122 | } |
| 123 | |