1//! `getsockopt` and `setsockopt` functions.
2//!
3//! In the rustix API, there is a separate function for each option, so that
4//! it can be given an option-specific type signature.
5
6#![doc(alias = "getsockopt")]
7#![doc(alias = "setsockopt")]
8
9use crate::net::{Ipv4Addr, Ipv6Addr, SocketType};
10use crate::{backend, io};
11use backend::fd::AsFd;
12use core::time::Duration;
13
14pub use backend::net::types::Timeout;
15
16/// `getsockopt(fd, SOL_SOCKET, SO_TYPE)`—Returns the type of a socket.
17///
18/// # References
19///  - [POSIX `getsockopt`]
20///  - [POSIX `sys/socket.h`]
21///  - [Linux `getsockopt`]
22///  - [Linux `socket`]
23///  - [Winsock2 `getsockopt`]
24///  - [Winsock2 `SOL_SOCKET` options]
25///
26/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
27/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
28/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
29/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
30/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
31/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options
32#[inline]
33#[doc(alias = "SO_TYPE")]
34pub fn get_socket_type<Fd: AsFd>(fd: Fd) -> io::Result<SocketType> {
35    backend::net::syscalls::sockopt::get_socket_type(fd.as_fd())
36}
37
38/// `setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, value)`
39///
40/// # References
41///  - [POSIX `setsockopt`]
42///  - [POSIX `sys/socket.h`]
43///  - [Linux `setsockopt`]
44///  - [Linux `socket`]
45///  - [Winsock2 `setsockopt`]
46///  - [Winsock2 `SOL_SOCKET` options]
47///
48/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
49/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
50/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
51/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
52/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
53/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options
54#[inline]
55#[doc(alias = "SO_REUSEADDR")]
56pub fn set_socket_reuseaddr<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
57    backend::net::syscalls::sockopt::set_socket_reuseaddr(fd.as_fd(), value)
58}
59
60/// `setsockopt(fd, SOL_SOCKET, SO_BROADCAST, broadcast)`
61///
62/// # References
63///  - [POSIX `setsockopt`]
64///  - [POSIX `sys/socket.h`]
65///  - [Linux `setsockopt`]
66///  - [Linux `socket`]
67///  - [Winsock2 `setsockopt`]
68///  - [Winsock2 `SOL_SOCKET` options]
69///
70/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
71/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
72/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
73/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
74/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
75/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options
76#[inline]
77#[doc(alias = "SO_BROADCAST")]
78pub fn set_socket_broadcast<Fd: AsFd>(fd: Fd, broadcast: bool) -> io::Result<()> {
79    backend::net::syscalls::sockopt::set_socket_broadcast(fd.as_fd(), broadcast)
80}
81
82/// `getsockopt(fd, SOL_SOCKET, SO_BROADCAST)`
83///
84/// # References
85///  - [POSIX `getsockopt`]
86///  - [POSIX `sys/socket.h`]
87///  - [Linux `getsockopt`]
88///  - [Linux `socket`]
89///  - [Winsock2 `getsockopt`]
90///  - [Winsock2 `SOL_SOCKET` options]
91///
92/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
93/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
94/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
95/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
96/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
97/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options
98#[inline]
99#[doc(alias = "SO_BROADCAST")]
100pub fn get_socket_broadcast<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
101    backend::net::syscalls::sockopt::get_socket_broadcast(fd.as_fd())
102}
103
104/// `setsockopt(fd, SOL_SOCKET, SO_LINGER, linger)`
105///
106/// # References
107///  - [POSIX `setsockopt`]
108///  - [POSIX `sys/socket.h`]
109///  - [Linux `setsockopt`]
110///  - [Linux `socket`]
111///  - [Winsock2 `setsockopt`]
112///  - [Winsock2 `SOL_SOCKET` options]
113///
114/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
115/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
116/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
117/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
118/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
119/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options
120#[inline]
121#[doc(alias = "SO_LINGER")]
122pub fn set_socket_linger<Fd: AsFd>(fd: Fd, linger: Option<Duration>) -> io::Result<()> {
123    backend::net::syscalls::sockopt::set_socket_linger(fd.as_fd(), linger)
124}
125
126/// `getsockopt(fd, SOL_SOCKET, SO_LINGER)`
127///
128/// # References
129///  - [POSIX `getsockopt`]
130///  - [POSIX `sys/socket.h`]
131///  - [Linux `getsockopt`]
132///  - [Linux `socket`]
133///  - [Winsock2 `getsockopt`]
134///  - [Winsock2 `SOL_SOCKET` options]
135///
136/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
137/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
138/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
139/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
140/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
141/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options
142#[inline]
143#[doc(alias = "SO_LINGER")]
144pub fn get_socket_linger<Fd: AsFd>(fd: Fd) -> io::Result<Option<Duration>> {
145    backend::net::syscalls::sockopt::get_socket_linger(fd.as_fd())
146}
147
148/// `setsockopt(fd, SOL_SOCKET, SO_PASSCRED, passcred)`
149///
150/// # References
151///  - [Linux `setsockopt`]
152///  - [Linux `socket`]
153///
154/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
155/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
156#[cfg(any(target_os = "android", target_os = "linux"))]
157#[inline]
158#[doc(alias = "SO_PASSCRED")]
159pub fn set_socket_passcred<Fd: AsFd>(fd: Fd, passcred: bool) -> io::Result<()> {
160    backend::net::syscalls::sockopt::set_socket_passcred(fd.as_fd(), passcred)
161}
162
163/// `getsockopt(fd, SOL_SOCKET, SO_PASSCRED)`
164///
165/// # References
166///  - [Linux `getsockopt`]
167///  - [Linux `socket`]
168///
169/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
170/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
171#[cfg(any(target_os = "android", target_os = "linux"))]
172#[inline]
173#[doc(alias = "SO_PASSCRED")]
174pub fn get_socket_passcred<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
175    backend::net::syscalls::sockopt::get_socket_passcred(fd.as_fd())
176}
177
178/// `setsockopt(fd, SOL_SOCKET, id, timeout)`—Set the sending
179/// or receiving timeout.
180///
181/// # References
182///  - [POSIX `setsockopt`]
183///  - [POSIX `sys/socket.h`]
184///  - [Linux `setsockopt`]
185///  - [Linux `socket`]
186///  - [Winsock2 `setsockopt`]
187///  - [Winsock2 `SOL_SOCKET` options]
188///
189/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
190/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
191/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
192/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
193/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
194/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options
195#[inline]
196#[doc(alias = "SO_RCVTIMEO")]
197#[doc(alias = "SO_SNDTIMEO")]
198pub fn set_socket_timeout<Fd: AsFd>(
199    fd: Fd,
200    id: Timeout,
201    timeout: Option<Duration>,
202) -> io::Result<()> {
203    backend::net::syscalls::sockopt::set_socket_timeout(fd.as_fd(), id, timeout)
204}
205
206/// `getsockopt(fd, SOL_SOCKET, id)`—Get the sending or receiving timeout.
207///
208/// # References
209///  - [POSIX `getsockopt`]
210///  - [POSIX `sys/socket.h`]
211///  - [Linux `getsockopt`]
212///  - [Linux `socket`]
213///  - [Winsock2 `getsockopt`]
214///  - [Winsock2 `SOL_SOCKET` options]
215///
216/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
217/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
218/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
219/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
220/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
221/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options
222#[inline]
223#[doc(alias = "SO_RCVTIMEO")]
224#[doc(alias = "SO_SNDTIMEO")]
225pub fn get_socket_timeout<Fd: AsFd>(fd: Fd, id: Timeout) -> io::Result<Option<Duration>> {
226    backend::net::syscalls::sockopt::get_socket_timeout(fd.as_fd(), id)
227}
228
229/// `setsockopt(fd, IPPROTO_IP, IP_TTL, ttl)`
230///
231/// # References
232///  - [POSIX `setsockopt`]
233///  - [POSIX `netinet/in.h`]
234///  - [Linux `setsockopt`]
235///  - [Linux `ip`]
236///  - [Winsock2 `setsockopt`]
237///  - [Winsock2 `IPPROTO_IP` options]
238///
239/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
240/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
241/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html
242/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
243/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options
244#[inline]
245#[doc(alias = "IP_TTL")]
246pub fn set_ip_ttl<Fd: AsFd>(fd: Fd, ttl: u32) -> io::Result<()> {
247    backend::net::syscalls::sockopt::set_ip_ttl(fd.as_fd(), ttl)
248}
249
250/// `getsockopt(fd, IPPROTO_IP, IP_TTL)`
251///
252/// # References
253///  - [POSIX `getsockopt`]
254///  - [POSIX `netinet/in.h`]
255///  - [Linux `getsockopt`]
256///  - [Linux `ip`]
257///  - [Winsock2 `getsockopt`]
258///  - [Winsock2 `IPPROTO_IPV6` options]
259///
260/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
261/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
262/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
263/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html
264/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
265/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options
266#[inline]
267#[doc(alias = "IP_TTL")]
268pub fn get_ip_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
269    backend::net::syscalls::sockopt::get_ip_ttl(fd.as_fd())
270}
271
272/// `setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, only_v6)`
273///
274/// # References
275///  - [POSIX `setsockopt`]
276///  - [POSIX `netinet/in.h`]
277///  - [Linux `setsockopt`]
278///  - [Linux `ipv6`]
279///  - [Winsock2 `setsockopt`]
280///  - [Winsock2 `IPPROTO_IPV6` options]
281///
282/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
283/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
284/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
285/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html
286/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
287/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options
288#[inline]
289#[doc(alias = "IPV6_V6ONLY")]
290pub fn set_ipv6_v6only<Fd: AsFd>(fd: Fd, only_v6: bool) -> io::Result<()> {
291    backend::net::syscalls::sockopt::set_ipv6_v6only(fd.as_fd(), only_v6)
292}
293
294/// `getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY)`
295///
296/// # References
297///  - [POSIX `getsockopt`]
298///  - [POSIX `netinet/in.h`]
299///  - [Linux `getsockopt`]
300///  - [Linux `ipv6`]
301///  - [Winsock2 `getsockopt`]
302///  - [Winsock2 `IPPROTO_IPV6` options]
303///
304/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
305/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
306/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
307/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html
308/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
309/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options
310#[inline]
311#[doc(alias = "IPV6_V6ONLY")]
312pub fn get_ipv6_v6only<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
313    backend::net::syscalls::sockopt::get_ipv6_v6only(fd.as_fd())
314}
315
316/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, multicast_loop)`
317///
318/// # References
319///  - [POSIX `setsockopt`]
320///  - [POSIX `netinet/in.h`]
321///  - [Linux `setsockopt`]
322///  - [Linux `ip`]
323///  - [Winsock2 `setsockopt`]
324///  - [Winsock2 `IPPROTO_IP` options]
325///
326/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
327/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
328/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
329/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html
330/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
331/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options
332#[inline]
333#[doc(alias = "IP_MULTICAST_LOOP")]
334pub fn set_ip_multicast_loop<Fd: AsFd>(fd: Fd, multicast_loop: bool) -> io::Result<()> {
335    backend::net::syscalls::sockopt::set_ip_multicast_loop(fd.as_fd(), multicast_loop)
336}
337
338/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP)`
339///
340/// # References
341///  - [POSIX `getsockopt`]
342///  - [POSIX `netinet/in.h`]
343///  - [Linux `getsockopt`]
344///  - [Linux `ip`]
345///  - [Winsock2 `getsockopt`]
346///  - [Winsock2 `IPPROTO_IP` options]
347///
348/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
349/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
350/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
351/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html
352/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
353/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options
354#[inline]
355#[doc(alias = "IP_MULTICAST_LOOP")]
356pub fn get_ip_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
357    backend::net::syscalls::sockopt::get_ip_multicast_loop(fd.as_fd())
358}
359
360/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, multicast_ttl)`
361///
362/// # References
363///  - [POSIX `setsockopt`]
364///  - [POSIX `netinet/in.h`]
365///  - [Linux `setsockopt`]
366///  - [Linux `ip`]
367///  - [Winsock2 `setsockopt`]
368///  - [Winsock2 `IPPROTO_IP` options]
369///
370/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
371/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
372/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
373/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html
374/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
375/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options
376#[inline]
377#[doc(alias = "IP_MULTICAST_TTL")]
378pub fn set_ip_multicast_ttl<Fd: AsFd>(fd: Fd, multicast_ttl: u32) -> io::Result<()> {
379    backend::net::syscalls::sockopt::set_ip_multicast_ttl(fd.as_fd(), multicast_ttl)
380}
381
382/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL)`
383///
384/// # References
385///  - [POSIX `getsockopt`]
386///  - [POSIX `netinet/in.h`]
387///  - [Linux `getsockopt`]
388///  - [Linux `ip`]
389///  - [Winsock2 `getsockopt`]
390///  - [Winsock2 `IPPROTO_IP` options]
391///
392/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
393/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
394/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
395/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html
396/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
397/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options
398#[inline]
399#[doc(alias = "IP_MULTICAST_TTL")]
400pub fn get_ip_multicast_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
401    backend::net::syscalls::sockopt::get_ip_multicast_ttl(fd.as_fd())
402}
403
404/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, multicast_loop)`
405///
406/// # References
407///  - [POSIX `setsockopt`]
408///  - [POSIX `netinet/in.h`]
409///  - [Linux `setsockopt`]
410///  - [Linux `ipv6`]
411///  - [Winsock2 `setsockopt`]
412///  - [Winsock2 `IPPROTO_IPV6` options]
413///
414/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
415/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
416/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
417/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html
418/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
419/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options
420#[inline]
421#[doc(alias = "IPV6_MULTICAST_LOOP")]
422pub fn set_ipv6_multicast_loop<Fd: AsFd>(fd: Fd, multicast_loop: bool) -> io::Result<()> {
423    backend::net::syscalls::sockopt::set_ipv6_multicast_loop(fd.as_fd(), multicast_loop)
424}
425
426/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP)`
427///
428/// # References
429///  - [POSIX `getsockopt`]
430///  - [POSIX `netinet/in.h`]
431///  - [Linux `getsockopt`]
432///  - [Linux `ipv6`]
433///  - [Winsock2 `getsockopt`]
434///  - [Winsock2 `IPPROTO_IPV6` options]
435///
436/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
437/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
438/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
439/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html
440/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
441/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options
442#[inline]
443#[doc(alias = "IPV6_MULTICAST_LOOP")]
444pub fn get_ipv6_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
445    backend::net::syscalls::sockopt::get_ipv6_multicast_loop(fd.as_fd())
446}
447
448/// `setsockopt(fd, IPPROTO_IP, IPV6_MULTICAST_HOPS, multicast_hops)`
449///
450/// # References
451///  - [POSIX `setsockopt`]
452///  - [POSIX `netinet/in.h`]
453///  - [Linux `setsockopt`]
454///  - [Linux `ipv6`]
455///  - [Winsock2 `setsockopt`]
456///  - [Winsock2 `IPPROTO_IPV6` options]
457///
458/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
459/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
460/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
461/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html
462/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
463/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options
464#[inline]
465#[doc(alias = "IP_MULTICAST_TTL")]
466pub fn set_ipv6_multicast_hops<Fd: AsFd>(fd: Fd, multicast_hops: u32) -> io::Result<()> {
467    backend::net::syscalls::sockopt::set_ipv6_multicast_hops(fd.as_fd(), multicast_hops)
468}
469
470/// `getsockopt(fd, IPPROTO_IP, IPV6_MULTICAST_HOPS)`
471///
472/// # References
473///  - [POSIX `getsockopt`]
474///  - [POSIX `netinet/in.h`]
475///  - [Linux `getsockopt`]
476///  - [Linux `ipv6`]
477///  - [Winsock2 `getsockopt`]
478///  - [Winsock2 `IPPROTO_IPV6` options]
479///
480/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
481/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
482/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
483/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html
484/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
485/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options
486#[inline]
487#[doc(alias = "IP_MULTICAST_TTL")]
488pub fn get_ipv6_multicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
489    backend::net::syscalls::sockopt::get_ipv6_multicast_hops(fd.as_fd())
490}
491
492/// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, interface)`
493///
494/// # References
495///  - [POSIX `setsockopt`]
496///  - [POSIX `netinet/in.h`]
497///  - [Linux `setsockopt`]
498///  - [Linux `ip`]
499///  - [Winsock2 `setsockopt`]
500///  - [Winsock2 `IPPROTO_IP` options]
501///
502/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
503/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
504/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
505/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html
506/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
507/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options
508#[inline]
509#[doc(alias = "IP_ADD_MEMBERSHIP")]
510pub fn set_ip_add_membership<Fd: AsFd>(
511    fd: Fd,
512    multiaddr: &Ipv4Addr,
513    interface: &Ipv4Addr,
514) -> io::Result<()> {
515    backend::net::syscalls::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface)
516}
517
518/// `setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, multiaddr, interface)`
519///
520/// `IPV6_ADD_MEMBERSHIP` is the same as `IPV6_JOIN_GROUP` in POSIX.
521///
522/// # References
523///  - [POSIX `setsockopt`]
524///  - [POSIX `netinet/in.h`]
525///  - [Linux `setsockopt`]
526///  - [Linux `ipv6]
527///  - [Winsock2 `setsockopt`]
528///  - [Winsock2 `IPPROTO_IPV6` options]
529///
530/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
531/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
532/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
533/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html
534/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
535/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options
536#[inline]
537#[doc(alias = "IPV6_JOIN_GROUP")]
538#[doc(alias = "IPV6_ADD_MEMBERSHIP")]
539pub fn set_ipv6_add_membership<Fd: AsFd>(
540    fd: Fd,
541    multiaddr: &Ipv6Addr,
542    interface: u32,
543) -> io::Result<()> {
544    backend::net::syscalls::sockopt::set_ipv6_add_membership(fd.as_fd(), multiaddr, interface)
545}
546
547/// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)`
548///
549/// # References
550///  - [POSIX `setsockopt`]
551///  - [POSIX `netinet/in.h`]
552///  - [Linux `setsockopt`]
553///  - [Linux `ip`]
554///  - [Winsock2 `setsockopt`]
555///  - [Winsock2 `IPPROTO_IP` options]
556///
557/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
558/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
559/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
560/// [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html
561/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
562/// [Winsock2 `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options
563#[inline]
564#[doc(alias = "IP_DROP_MEMBERSHIP")]
565pub fn set_ip_drop_membership<Fd: AsFd>(
566    fd: Fd,
567    multiaddr: &Ipv4Addr,
568    interface: &Ipv4Addr,
569) -> io::Result<()> {
570    backend::net::syscalls::sockopt::set_ip_drop_membership(fd.as_fd(), multiaddr, interface)
571}
572
573/// `setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, multiaddr, interface)`
574///
575/// `IPV6_DROP_MEMBERSHIP` is the same as `IPV6_LEAVE_GROUP` in POSIX.
576///
577/// # References
578///  - [POSIX `setsockopt`]
579///  - [POSIX `netinet/in.h`]
580///  - [Linux `setsockopt`]
581///  - [Linux `ipv6`]
582///  - [Winsock2 `setsockopt`]
583///  - [Winsock2 `IPPROTO_IPV6` options]
584///
585/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
586/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html
587/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
588/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html
589/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
590/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options
591#[inline]
592#[doc(alias = "IPV6_LEAVE_GROUP")]
593#[doc(alias = "IPV6_DROP_MEMBERSHIP")]
594pub fn set_ipv6_drop_membership<Fd: AsFd>(
595    fd: Fd,
596    multiaddr: &Ipv6Addr,
597    interface: u32,
598) -> io::Result<()> {
599    backend::net::syscalls::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface)
600}
601
602/// `setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, nodelay)`
603///
604/// # References
605///  - [POSIX `setsockopt`]
606///  - [POSIX `netinet/tcp.h`]
607///  - [Linux `setsockopt`]
608///  - [Linux `tcp`]
609///  - [Winsock2 `setsockopt`]
610///  - [Winsock2 `IPPROTO_TCP` options]
611///
612/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
613/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html
614/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
615/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html
616/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
617/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options
618#[inline]
619#[doc(alias = "TCP_NODELAY")]
620pub fn set_tcp_nodelay<Fd: AsFd>(fd: Fd, nodelay: bool) -> io::Result<()> {
621    backend::net::syscalls::sockopt::set_tcp_nodelay(fd.as_fd(), nodelay)
622}
623
624/// `getsockopt(fd, IPPROTO_TCP, TCP_NODELAY)`
625///
626/// # References
627///  - [POSIX `getsockopt`]
628///  - [POSIX `netinet/tcp.h`]
629///  - [Linux `getsockopt`]
630///  - [Linux `tcp`]
631///  - [Winsock2 `getsockopt`]
632///  - [Winsock2 `IPPROTO_TCP` options]
633///
634/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
635/// [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_tcp.h.html
636/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
637/// [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html
638/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
639/// [Winsock2 `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options
640#[inline]
641#[doc(alias = "TCP_NODELAY")]
642pub fn get_tcp_nodelay<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
643    backend::net::syscalls::sockopt::get_tcp_nodelay(fd.as_fd())
644}
645