posix_socket/address/
inet6.rs

1use crate::SpecificSocketAddress;
2
3/// IPv6 socket address.
4///
5/// This includes an IPv6 address and a 16-bit port number.
6#[derive(Clone)]
7#[repr(C)]
8pub struct Inet6SocketAddress {
9	/// The inner C-compatible socket address.
10	inner: libc::sockaddr_in6,
11}
12
13impl Inet6SocketAddress {
14	/// Create an IPv6 socket address.
15	pub fn new(ip: std::net::Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32) -> Self {
16		let inner = libc::sockaddr_in6 {
17			sin6_family: Self::static_family(),
18			sin6_addr: libc::in6_addr { s6_addr: ip.octets() },
19			sin6_port: port.to_be(),
20			sin6_flowinfo: flowinfo,
21			sin6_scope_id: scope_id,
22		};
23		Self::from_raw(inner)
24	}
25
26	/// Create an IPv6 socket address from a [`libc::sockaddr_in6`].
27	pub fn from_raw(inner: libc::sockaddr_in6) -> Self {
28		Self { inner }
29	}
30
31	/// Convert the [`SocketAddress`] into raw [`libc`] parts.
32	pub fn into_raw(self) -> libc::sockaddr_in6 {
33		self.inner
34	}
35
36	/// Get the IP address associated with the socket address.
37	pub fn ip(&self) -> std::net::Ipv6Addr {
38		self.inner.sin6_addr.s6_addr.into()
39	}
40
41	/// Set the IP address associated with the socket address.
42	pub fn set_ip(&mut self, ip: std::net::Ipv6Addr) {
43		self.inner.sin6_addr.s6_addr = ip.octets();
44	}
45
46	/// Get the port number associated with the socket address.
47	pub fn port(&self) -> u16 {
48		u16::from_be(self.inner.sin6_port)
49	}
50
51	/// Set the port number associated with the socket address.
52	pub fn set_port(&mut self, port: u16) {
53		self.inner.sin6_port = port.to_be();
54	}
55
56	/// Get the flow information associated with the socket address.
57	fn flowinfo(&self) -> u32 {
58		self.inner.sin6_flowinfo
59	}
60
61	/// Set the flow information associated with the socket address.
62	pub fn set_flowinfo(&mut self, flowinfo: u32) {
63		self.inner.sin6_flowinfo = flowinfo;
64	}
65
66	/// Get the scope ID associated with the socket address.
67	fn scope_id(&self) -> u32 {
68		self.inner.sin6_scope_id
69	}
70
71	/// Set the scope ID associated with the socket address.
72	pub fn set_scope_id(&mut self, scope_id: u32) {
73		self.inner.sin6_scope_id = scope_id;
74	}
75}
76
77impl SpecificSocketAddress for Inet6SocketAddress {
78	fn static_family() -> libc::sa_family_t {
79		libc::AF_INET6 as libc::sa_family_t
80	}
81}
82
83unsafe impl crate::AsSocketAddress for Inet6SocketAddress {
84	fn as_sockaddr(&self) -> *const libc::sockaddr {
85		&self.inner as *const _ as *const _
86	}
87
88	fn as_sockaddr_mut(address: &mut std::mem::MaybeUninit<Self>) -> *mut libc::sockaddr {
89		unsafe { &mut address.as_mut_ptr().as_mut().unwrap().inner as *mut _ as *mut _ }
90	}
91
92	fn len(&self) -> libc::socklen_t {
93		Self::max_len()
94	}
95
96	fn finalize(address: std::mem::MaybeUninit<Self>, len: libc::socklen_t) -> std::io::Result<Self> {
97		unsafe {
98			let address = address.assume_init();
99			if address.family() != Self::static_family() {
100				return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "wrong address family, expeced AF_INET6"));
101			}
102			if len != Self::max_len() {
103				return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "wrong address size"));
104			}
105			Ok(address)
106		}
107	}
108
109	fn max_len() -> libc::socklen_t {
110		std::mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t
111	}
112}
113
114impl From<Inet6SocketAddress> for crate::SocketAddress {
115	fn from(other: Inet6SocketAddress) -> Self {
116		Self::from(&other)
117	}
118}
119
120impl From<&Inet6SocketAddress> for crate::SocketAddress {
121	fn from(other: &Inet6SocketAddress) -> Self {
122		Self::from_other(other)
123	}
124}
125
126impl From<std::net::SocketAddrV6> for Inet6SocketAddress {
127	fn from(other: std::net::SocketAddrV6) -> Self {
128		Self::from(&other)
129	}
130}
131
132impl From<&std::net::SocketAddrV6> for Inet6SocketAddress {
133	fn from(other: &std::net::SocketAddrV6) -> Self {
134		Self::new(*other.ip(), other.port(), other.flowinfo(), other.scope_id())
135	}
136}
137
138impl From<Inet6SocketAddress> for std::net::SocketAddrV6 {
139	fn from(other: Inet6SocketAddress) -> Self {
140		Self::from(&other)
141	}
142}
143
144impl From<&Inet6SocketAddress> for std::net::SocketAddrV6 {
145	fn from(other: &Inet6SocketAddress) -> Self {
146		Self::new(other.ip(), other.port(), other.flowinfo(), other.scope_id())
147	}
148}