rustix/net/
sockopt.rs

1//! `getsockopt` and `setsockopt` functions.
2//!
3//! In the rustix API, there is a separate function for each option, so that it
4//! can be given an option-specific type signature.
5//!
6//! # References for all `get_*` functions:
7//!
8//!  - [POSIX `getsockopt`]
9//!  - [Linux `getsockopt`]
10//!  - [Winsock `getsockopt`]
11//!  - [Apple `getsockopt`]
12//!  - [FreeBSD `getsockopt`]
13//!  - [NetBSD `getsockopt`]
14//!  - [OpenBSD `getsockopt`]
15//!  - [DragonFly BSD `getsockopt`]
16//!  - [illumos `getsockopt`]
17//!  - [glibc `getsockopt`]
18//!
19//! [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getsockopt.html
20//! [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
21//! [Winsock `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
22//! [Apple `getsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html
23//! [FreeBSD `getsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2
24//! [NetBSD `getsockopt`]: https://man.netbsd.org/getsockopt.2
25//! [OpenBSD `getsockopt`]: https://man.openbsd.org/getsockopt.2
26//! [DragonFly BSD `getsockopt`]: https://man.dragonflybsd.org/?command=getsockopt&section=2
27//! [illumos `getsockopt`]: https://illumos.org/man/3SOCKET/getsockopt
28//! [glibc `getsockopt`]: https://sourceware.org/glibc/manual/latest/html_node/Socket-Option-Functions.html
29//!
30//! # References for all `set_*` functions:
31//!
32//!  - [POSIX `setsockopt`]
33//!  - [Linux `setsockopt`]
34//!  - [Winsock `setsockopt`]
35//!  - [Apple `setsockopt`]
36//!  - [FreeBSD `setsockopt`]
37//!  - [NetBSD `setsockopt`]
38//!  - [OpenBSD `setsockopt`]
39//!  - [DragonFly BSD `setsockopt`]
40//!  - [illumos `setsockopt`]
41//!  - [glibc `setsockopt`]
42//!
43//! [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setsockopt.html
44//! [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html
45//! [Winsock `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
46//! [Apple `setsockopt`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setsockopt.2.html
47//! [FreeBSD `setsockopt`]: https://man.freebsd.org/cgi/man.cgi?query=setsockopt&sektion=2
48//! [NetBSD `setsockopt`]: https://man.netbsd.org/setsockopt.2
49//! [OpenBSD `setsockopt`]: https://man.openbsd.org/setsockopt.2
50//! [DragonFly BSD `setsockopt`]: https://man.dragonflybsd.org/?command=setsockopt&section=2
51//! [illumos `setsockopt`]: https://illumos.org/man/3SOCKET/setsockopt
52//! [glibc `setsockopt`]: https://sourceware.org/glibc/manual/latest/html_node/Socket-Option-Functions.html
53//!
54//! # References for `get_socket_*` and `set_socket_*` functions:
55//!
56//!  - [References for all `get_*` functions]
57//!  - [References for all `set_*` functions]
58//!  - [POSIX `sys/socket.h`]
59//!  - [Linux `socket`]
60//!  - [Winsock `SOL_SOCKET` options]
61//!  - [glibc `SOL_SOCKET` Options]
62//!
63//! [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_socket.h.html
64//! [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
65//! [Winsock `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options
66//! [glibc `SOL_SOCKET` options]: https://sourceware.org/glibc/manual/latest/html_node/Socket_002dLevel-Options.html
67//!
68//! # References for `get_ip_*` and `set_ip_*` functions:
69//!
70//!  - [References for all `get_*` functions]
71//!  - [References for all `set_*` functions]
72//!  - [POSIX `netinet/in.h`]
73//!  - [Linux `ip`]
74//!  - [Winsock `IPPROTO_IP` options]
75//!  - [Apple `ip`]
76//!  - [FreeBSD `ip`]
77//!  - [NetBSD `ip`]
78//!  - [OpenBSD `ip`]
79//!  - [DragonFly BSD `ip`]
80//!  - [illumos `ip`]
81//!
82//! [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/netinet_in.h.html
83//! [Linux `ip`]: https://man7.org/linux/man-pages/man7/ip.7.html
84//! [Winsock `IPPROTO_IP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options
85//! [Apple `ip`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip.4.auto.html
86//! [FreeBSD `ip`]: https://man.freebsd.org/cgi/man.cgi?query=ip&sektion=4
87//! [NetBSD `ip`]: https://man.netbsd.org/ip.4
88//! [OpenBSD `ip`]: https://man.openbsd.org/ip.4
89//! [DragonFly BSD `ip`]: https://man.dragonflybsd.org/?command=ip&section=4
90//! [illumos `ip`]: https://illumos.org/man/4P/ip
91//!
92//! # References for `get_ipv6_*` and `set_ipv6_*` functions:
93//!
94//!  - [References for all `get_*` functions]
95//!  - [References for all `set_*` functions]
96//!  - [POSIX `netinet/in.h`]
97//!  - [Linux `ipv6`]
98//!  - [Winsock `IPPROTO_IPV6` options]
99//!  - [Apple `ip6`]
100//!  - [FreeBSD `ip6`]
101//!  - [NetBSD `ip6`]
102//!  - [OpenBSD `ip6`]
103//!  - [DragonFly BSD `ip6`]
104//!  - [illumos `ip6`]
105//!
106//! [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/netinet_in.h.html
107//! [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html
108//! [Winsock `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options
109//! [Apple `ip6`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/ip6.4.auto.html
110//! [FreeBSD `ip6`]: https://man.freebsd.org/cgi/man.cgi?query=ip6&sektion=4
111//! [NetBSD `ip6`]: https://man.netbsd.org/ip6.4
112//! [OpenBSD `ip6`]: https://man.openbsd.org/ip6.4
113//! [DragonFly BSD `ip6`]: https://man.dragonflybsd.org/?command=ip6&section=4
114//! [illumos `ip6`]: https://illumos.org/man/4P/ip6
115//!
116//! # References for `get_tcp_*` and `set_tcp_*` functions:
117//!
118//!  - [References for all `get_*` functions]
119//!  - [References for all `set_*` functions]
120//!  - [POSIX `netinet/tcp.h`]
121//!  - [Linux `tcp`]
122//!  - [Winsock `IPPROTO_TCP` options]
123//!  - [Apple `tcp`]
124//!  - [FreeBSD `tcp`]
125//!  - [NetBSD `tcp`]
126//!  - [OpenBSD `tcp`]
127//!  - [DragonFly BSD `tcp`]
128//!  - [illumos `tcp`]
129//!
130//! [POSIX `netinet/tcp.h`]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/netinet_tcp.h.html
131//! [Linux `tcp`]: https://man7.org/linux/man-pages/man7/tcp.7.html
132//! [Winsock `IPPROTO_TCP` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options
133//! [Apple `tcp`]: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/man/man4/tcp.4.auto.html
134//! [FreeBSD `tcp`]: https://man.freebsd.org/cgi/man.cgi?query=tcp&sektion=4
135//! [NetBSD `tcp`]: https://man.netbsd.org/tcp.4
136//! [OpenBSD `tcp`]: https://man.openbsd.org/tcp.4
137//! [DragonFly BSD `tcp`]: https://man.dragonflybsd.org/?command=tcp&section=4
138//! [illumos `tcp`]: https://illumos.org/man/4P/tcp
139//!
140//! [References for all `get_*` functions]: #references-for-all-get_-functions
141//! [References for all `set_*` functions]: #references-for-all-set_-functions
142
143#![doc(alias = "getsockopt")]
144#![doc(alias = "setsockopt")]
145
146#[cfg(target_os = "linux")]
147use crate::net::xdp::{XdpMmapOffsets, XdpOptionsFlags, XdpStatistics, XdpUmemReg};
148#[cfg(not(any(
149    apple,
150    windows,
151    target_os = "aix",
152    target_os = "dragonfly",
153    target_os = "emscripten",
154    target_os = "espidf",
155    target_os = "haiku",
156    target_os = "netbsd",
157    target_os = "nto",
158    target_os = "vita",
159)))]
160use crate::net::AddressFamily;
161#[cfg(any(
162    linux_kernel,
163    target_os = "freebsd",
164    target_os = "fuchsia",
165    target_os = "openbsd",
166    target_os = "redox",
167    target_env = "newlib"
168))]
169use crate::net::Protocol;
170#[cfg(any(linux_kernel, target_os = "fuchsia"))]
171use crate::net::SocketAddrV4;
172#[cfg(linux_kernel)]
173use crate::net::SocketAddrV6;
174use crate::net::{Ipv4Addr, Ipv6Addr, SocketType};
175use crate::{backend, io};
176#[cfg(feature = "alloc")]
177#[cfg(any(
178    linux_like,
179    target_os = "freebsd",
180    target_os = "fuchsia",
181    target_os = "illumos"
182))]
183use alloc::string::String;
184use backend::c;
185use backend::fd::AsFd;
186use core::time::Duration;
187
188/// Timeout identifier for use with [`set_socket_timeout`] and
189/// [`get_socket_timeout`].
190#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
191#[repr(u32)]
192pub enum Timeout {
193    /// `SO_RCVTIMEO`—Timeout for receiving.
194    Recv = c::SO_RCVTIMEO as _,
195
196    /// `SO_SNDTIMEO`—Timeout for sending.
197    Send = c::SO_SNDTIMEO as _,
198}
199
200/// `getsockopt(fd, SOL_SOCKET, SO_TYPE)`—Returns the type of a socket.
201///
202/// See the [module-level documentation] for more.
203///
204/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
205#[inline]
206#[doc(alias = "SO_TYPE")]
207pub fn get_socket_type<Fd: AsFd>(fd: Fd) -> io::Result<SocketType> {
208    backend::net::sockopt::get_socket_type(fd.as_fd())
209}
210
211/// `setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, value)`—Set whether local
212/// addresses may be reused in `bind`.
213///
214/// See the [module-level documentation] for more.
215///
216/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
217#[inline]
218#[doc(alias = "SO_REUSEADDR")]
219pub fn set_socket_reuseaddr<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
220    backend::net::sockopt::set_socket_reuseaddr(fd.as_fd(), value)
221}
222
223/// `getsockopt(fd, SOL_SOCKET, SO_REUSEADDR)`
224///
225/// See the [module-level documentation] for more.
226///
227/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
228#[inline]
229#[doc(alias = "SO_REUSEADDR")]
230pub fn get_socket_reuseaddr<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
231    backend::net::sockopt::get_socket_reuseaddr(fd.as_fd())
232}
233
234/// `setsockopt(fd, SOL_SOCKET, SO_BROADCAST, value)`
235///
236/// See the [module-level documentation] for more.
237///
238/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
239#[inline]
240#[doc(alias = "SO_BROADCAST")]
241pub fn set_socket_broadcast<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
242    backend::net::sockopt::set_socket_broadcast(fd.as_fd(), value)
243}
244
245/// `getsockopt(fd, SOL_SOCKET, SO_BROADCAST)`
246///
247/// See the [module-level documentation] for more.
248///
249/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
250#[inline]
251#[doc(alias = "SO_BROADCAST")]
252pub fn get_socket_broadcast<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
253    backend::net::sockopt::get_socket_broadcast(fd.as_fd())
254}
255
256/// `setsockopt(fd, SOL_SOCKET, SO_LINGER, value)`
257///
258/// See the [module-level documentation] for more.
259///
260/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
261#[inline]
262#[doc(alias = "SO_LINGER")]
263pub fn set_socket_linger<Fd: AsFd>(fd: Fd, value: Option<Duration>) -> io::Result<()> {
264    backend::net::sockopt::set_socket_linger(fd.as_fd(), value)
265}
266
267/// `getsockopt(fd, SOL_SOCKET, SO_LINGER)`
268///
269/// See the [module-level documentation] for more.
270///
271/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
272#[inline]
273#[doc(alias = "SO_LINGER")]
274pub fn get_socket_linger<Fd: AsFd>(fd: Fd) -> io::Result<Option<Duration>> {
275    backend::net::sockopt::get_socket_linger(fd.as_fd())
276}
277
278/// `setsockopt(fd, SOL_SOCKET, SO_PASSCRED, value)`
279///
280/// See the [module-level documentation] for more.
281///
282/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
283#[cfg(linux_kernel)]
284#[inline]
285#[doc(alias = "SO_PASSCRED")]
286pub fn set_socket_passcred<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
287    backend::net::sockopt::set_socket_passcred(fd.as_fd(), value)
288}
289
290/// `getsockopt(fd, SOL_SOCKET, SO_PASSCRED)`
291///
292/// See the [module-level documentation] for more.
293///
294/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
295#[cfg(linux_kernel)]
296#[inline]
297#[doc(alias = "SO_PASSCRED")]
298pub fn get_socket_passcred<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
299    backend::net::sockopt::get_socket_passcred(fd.as_fd())
300}
301
302/// `setsockopt(fd, SOL_SOCKET, id, value)`—Set the sending or receiving
303/// timeout.
304///
305/// See the [module-level documentation] for more.
306///
307/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
308#[inline]
309#[doc(alias = "SO_RCVTIMEO")]
310#[doc(alias = "SO_SNDTIMEO")]
311pub fn set_socket_timeout<Fd: AsFd>(
312    fd: Fd,
313    id: Timeout,
314    value: Option<Duration>,
315) -> io::Result<()> {
316    backend::net::sockopt::set_socket_timeout(fd.as_fd(), id, value)
317}
318
319/// `getsockopt(fd, SOL_SOCKET, id)`—Get the sending or receiving timeout.
320///
321/// See the [module-level documentation] for more.
322///
323/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
324#[inline]
325#[doc(alias = "SO_RCVTIMEO")]
326#[doc(alias = "SO_SNDTIMEO")]
327pub fn get_socket_timeout<Fd: AsFd>(fd: Fd, id: Timeout) -> io::Result<Option<Duration>> {
328    backend::net::sockopt::get_socket_timeout(fd.as_fd(), id)
329}
330
331/// `getsockopt(fd, SOL_SOCKET, SO_ERROR)`
332///
333/// See the [module-level documentation] for more.
334///
335/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
336#[inline]
337#[doc(alias = "SO_ERROR")]
338pub fn get_socket_error<Fd: AsFd>(fd: Fd) -> io::Result<Result<(), io::Errno>> {
339    backend::net::sockopt::get_socket_error(fd.as_fd())
340}
341
342/// `getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE)`
343///
344/// See the [module-level documentation] for more.
345///
346/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
347#[cfg(any(apple, freebsdlike, target_os = "netbsd"))]
348#[doc(alias = "SO_NOSIGPIPE")]
349#[inline]
350pub fn get_socket_nosigpipe<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
351    backend::net::sockopt::get_socket_nosigpipe(fd.as_fd())
352}
353
354/// `setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, value)`
355///
356/// See the [module-level documentation] for more.
357///
358/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
359#[cfg(any(apple, freebsdlike, target_os = "netbsd"))]
360#[doc(alias = "SO_NOSIGPIPE")]
361#[inline]
362pub fn set_socket_nosigpipe<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
363    backend::net::sockopt::set_socket_nosigpipe(fd.as_fd(), value)
364}
365
366/// `setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, value)`
367///
368/// See the [module-level documentation] for more.
369///
370/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
371#[inline]
372#[doc(alias = "SO_KEEPALIVE")]
373pub fn set_socket_keepalive<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
374    backend::net::sockopt::set_socket_keepalive(fd.as_fd(), value)
375}
376
377/// `getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE)`
378///
379/// See the [module-level documentation] for more.
380///
381/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
382#[inline]
383#[doc(alias = "SO_KEEPALIVE")]
384pub fn get_socket_keepalive<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
385    backend::net::sockopt::get_socket_keepalive(fd.as_fd())
386}
387
388/// `setsockopt(fd, SOL_SOCKET, SO_RCVBUF, value)`
389///
390/// See the [module-level documentation] for more.
391///
392/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
393#[inline]
394#[doc(alias = "SO_RCVBUF")]
395pub fn set_socket_recv_buffer_size<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> {
396    backend::net::sockopt::set_socket_recv_buffer_size(fd.as_fd(), value)
397}
398
399/// `setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, value)`
400///
401/// See the [module-level documentation] for more.
402///
403/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
404#[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "redox"))]
405#[inline]
406#[doc(alias = "SO_RCVBUFFORCE")]
407pub fn set_socket_recv_buffer_size_force<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> {
408    backend::net::sockopt::set_socket_recv_buffer_size_force(fd.as_fd(), value)
409}
410
411/// `getsockopt(fd, SOL_SOCKET, SO_RCVBUF)`
412///
413/// See the [module-level documentation] for more.
414///
415/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
416#[inline]
417#[doc(alias = "SO_RCVBUF")]
418pub fn get_socket_recv_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> {
419    backend::net::sockopt::get_socket_recv_buffer_size(fd.as_fd())
420}
421
422/// `setsockopt(fd, SOL_SOCKET, SO_SNDBUF, value)`
423///
424/// See the [module-level documentation] for more.
425///
426/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
427#[inline]
428#[doc(alias = "SO_SNDBUF")]
429pub fn set_socket_send_buffer_size<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> {
430    backend::net::sockopt::set_socket_send_buffer_size(fd.as_fd(), value)
431}
432
433/// `getsockopt(fd, SOL_SOCKET, SO_SNDBUF)`
434///
435/// See the [module-level documentation] for more.
436///
437/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
438#[inline]
439#[doc(alias = "SO_SNDBUF")]
440pub fn get_socket_send_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> {
441    backend::net::sockopt::get_socket_send_buffer_size(fd.as_fd())
442}
443
444/// `getsockopt(fd, SOL_SOCKET, SO_DOMAIN)`
445///
446/// See the [module-level documentation] for more.
447///
448/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
449#[cfg(not(any(
450    apple,
451    windows,
452    target_os = "aix",
453    target_os = "dragonfly",
454    target_os = "emscripten",
455    target_os = "espidf",
456    target_os = "haiku",
457    target_os = "hurd",
458    target_os = "netbsd",
459    target_os = "nto",
460    target_os = "vita",
461)))]
462#[inline]
463#[doc(alias = "SO_DOMAIN")]
464pub fn get_socket_domain<Fd: AsFd>(fd: Fd) -> io::Result<AddressFamily> {
465    backend::net::sockopt::get_socket_domain(fd.as_fd())
466}
467
468/// `getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN)`
469///
470/// See the [module-level documentation] for more.
471///
472/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
473#[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it.
474#[inline]
475#[doc(alias = "SO_ACCEPTCONN")]
476pub fn get_socket_acceptconn<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
477    backend::net::sockopt::get_socket_acceptconn(fd.as_fd())
478}
479
480/// `setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, value)`
481///
482/// See the [module-level documentation] for more.
483///
484/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
485#[inline]
486#[doc(alias = "SO_OOBINLINE")]
487pub fn set_socket_oobinline<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
488    backend::net::sockopt::set_socket_oobinline(fd.as_fd(), value)
489}
490
491/// `getsockopt(fd, SOL_SOCKET, SO_OOBINLINE)`
492///
493/// See the [module-level documentation] for more.
494///
495/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
496#[inline]
497#[doc(alias = "SO_OOBINLINE")]
498pub fn get_socket_oobinline<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
499    backend::net::sockopt::get_socket_oobinline(fd.as_fd())
500}
501
502/// `setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, value)`
503///
504/// See the [module-level documentation] for more.
505///
506/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
507#[cfg(not(any(solarish, windows)))]
508#[cfg(not(windows))]
509#[inline]
510#[doc(alias = "SO_REUSEPORT")]
511pub fn set_socket_reuseport<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
512    backend::net::sockopt::set_socket_reuseport(fd.as_fd(), value)
513}
514
515/// `getsockopt(fd, SOL_SOCKET, SO_REUSEPORT)`
516///
517/// See the [module-level documentation] for more.
518///
519/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
520#[cfg(not(any(solarish, windows)))]
521#[inline]
522#[doc(alias = "SO_REUSEPORT")]
523pub fn get_socket_reuseport<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
524    backend::net::sockopt::get_socket_reuseport(fd.as_fd())
525}
526
527/// `setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, value)`
528///
529/// See the [module-level documentation] for more.
530///
531/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
532#[cfg(target_os = "freebsd")]
533#[inline]
534#[doc(alias = "SO_REUSEPORT_LB")]
535pub fn set_socket_reuseport_lb<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
536    backend::net::sockopt::set_socket_reuseport_lb(fd.as_fd(), value)
537}
538
539/// `getsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB)`
540///
541/// See the [module-level documentation] for more.
542///
543/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
544#[cfg(target_os = "freebsd")]
545#[inline]
546#[doc(alias = "SO_REUSEPORT_LB")]
547pub fn get_socket_reuseport_lb<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
548    backend::net::sockopt::get_socket_reuseport_lb(fd.as_fd())
549}
550
551/// `getsockopt(fd, SOL_SOCKET, SO_PROTOCOL)`
552///
553/// See the [module-level documentation] for more.
554///
555/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
556#[cfg(any(
557    linux_kernel,
558    target_os = "freebsd",
559    target_os = "fuchsia",
560    target_os = "openbsd",
561    target_os = "redox",
562    target_env = "newlib"
563))]
564#[inline]
565#[doc(alias = "SO_PROTOCOL")]
566pub fn get_socket_protocol<Fd: AsFd>(fd: Fd) -> io::Result<Option<Protocol>> {
567    backend::net::sockopt::get_socket_protocol(fd.as_fd())
568}
569
570/// `getsockopt(fd, SOL_SOCKET, SO_COOKIE)`
571///
572/// See the [module-level documentation] for more.
573///
574/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
575#[cfg(target_os = "linux")]
576#[inline]
577#[doc(alias = "SO_COOKIE")]
578pub fn get_socket_cookie<Fd: AsFd>(fd: Fd) -> io::Result<u64> {
579    backend::net::sockopt::get_socket_cookie(fd.as_fd())
580}
581
582/// `getsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU)`
583///
584/// See the [module-level documentation] for more.
585///
586/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
587#[cfg(target_os = "linux")]
588#[inline]
589#[doc(alias = "SO_INCOMING_CPU")]
590pub fn get_socket_incoming_cpu<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
591    backend::net::sockopt::get_socket_incoming_cpu(fd.as_fd())
592}
593
594/// `setsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, value)`
595///
596/// See the [module-level documentation] for more.
597///
598/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
599#[cfg(target_os = "linux")]
600#[inline]
601#[doc(alias = "SO_INCOMING_CPU")]
602pub fn set_socket_incoming_cpu<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
603    backend::net::sockopt::set_socket_incoming_cpu(fd.as_fd(), value)
604}
605
606/// `setsockopt(fd, IPPROTO_IP, IP_TTL, value)`
607///
608/// See the [module-level documentation] for more.
609///
610/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
611#[inline]
612#[doc(alias = "IP_TTL")]
613pub fn set_ip_ttl<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
614    backend::net::sockopt::set_ip_ttl(fd.as_fd(), value)
615}
616
617/// `getsockopt(fd, IPPROTO_IP, IP_TTL)`
618///
619/// See the [module-level documentation] for more.
620///
621/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
622#[inline]
623#[doc(alias = "IP_TTL")]
624pub fn get_ip_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
625    backend::net::sockopt::get_ip_ttl(fd.as_fd())
626}
627
628/// `setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, value)`
629///
630/// See the [module-level documentation] for more.
631///
632/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
633#[inline]
634#[doc(alias = "IPV6_V6ONLY")]
635pub fn set_ipv6_v6only<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
636    backend::net::sockopt::set_ipv6_v6only(fd.as_fd(), value)
637}
638
639/// `getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY)`
640///
641/// See the [module-level documentation] for more.
642///
643/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
644#[inline]
645#[doc(alias = "IPV6_V6ONLY")]
646pub fn get_ipv6_v6only<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
647    backend::net::sockopt::get_ipv6_v6only(fd.as_fd())
648}
649
650/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, value)`
651///
652/// See the [module-level documentation] for more.
653///
654/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
655#[inline]
656#[doc(alias = "IP_MULTICAST_LOOP")]
657pub fn set_ip_multicast_loop<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
658    backend::net::sockopt::set_ip_multicast_loop(fd.as_fd(), value)
659}
660
661/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP)`
662///
663/// See the [module-level documentation] for more.
664///
665/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
666#[inline]
667#[doc(alias = "IP_MULTICAST_LOOP")]
668pub fn get_ip_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
669    backend::net::sockopt::get_ip_multicast_loop(fd.as_fd())
670}
671
672/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, value)`
673///
674/// See the [module-level documentation] for more.
675///
676/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
677#[inline]
678#[doc(alias = "IP_MULTICAST_TTL")]
679pub fn set_ip_multicast_ttl<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
680    backend::net::sockopt::set_ip_multicast_ttl(fd.as_fd(), value)
681}
682
683/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL)`
684///
685/// See the [module-level documentation] for more.
686///
687/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
688#[inline]
689#[doc(alias = "IP_MULTICAST_TTL")]
690pub fn get_ip_multicast_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
691    backend::net::sockopt::get_ip_multicast_ttl(fd.as_fd())
692}
693
694/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, value)`
695///
696/// See the [module-level documentation] for more.
697///
698/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
699#[inline]
700#[doc(alias = "IPV6_MULTICAST_LOOP")]
701pub fn set_ipv6_multicast_loop<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
702    backend::net::sockopt::set_ipv6_multicast_loop(fd.as_fd(), value)
703}
704
705/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP)`
706///
707/// See the [module-level documentation] for more.
708///
709/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
710#[inline]
711#[doc(alias = "IPV6_MULTICAST_LOOP")]
712pub fn get_ipv6_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
713    backend::net::sockopt::get_ipv6_multicast_loop(fd.as_fd())
714}
715
716/// `getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS)`
717///
718/// See the [module-level documentation] for more.
719///
720/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
721#[inline]
722#[doc(alias = "IPV6_UNICAST_HOPS")]
723pub fn get_ipv6_unicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u8> {
724    backend::net::sockopt::get_ipv6_unicast_hops(fd.as_fd())
725}
726
727/// `setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, value)`
728///
729/// See the [module-level documentation] for more.
730///
731/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
732#[inline]
733#[doc(alias = "IPV6_UNICAST_HOPS")]
734pub fn set_ipv6_unicast_hops<Fd: AsFd>(fd: Fd, value: Option<u8>) -> io::Result<()> {
735    backend::net::sockopt::set_ipv6_unicast_hops(fd.as_fd(), value)
736}
737
738/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, value)`
739///
740/// See the [module-level documentation] for more.
741///
742/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
743#[inline]
744#[doc(alias = "IPV6_MULTICAST_HOPS")]
745pub fn set_ipv6_multicast_hops<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
746    backend::net::sockopt::set_ipv6_multicast_hops(fd.as_fd(), value)
747}
748
749/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS)`
750///
751/// See the [module-level documentation] for more.
752///
753/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
754#[inline]
755#[doc(alias = "IPV6_MULTICAST_HOPS")]
756pub fn get_ipv6_multicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
757    backend::net::sockopt::get_ipv6_multicast_hops(fd.as_fd())
758}
759
760/// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, interface)`
761///
762/// This is similar to [`set_ip_add_membership`] but always sets `ifindex`
763/// value to zero.
764///
765/// See the [module-level documentation] for more.
766///
767/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
768#[inline]
769#[doc(alias = "IP_ADD_MEMBERSHIP")]
770pub fn set_ip_add_membership<Fd: AsFd>(
771    fd: Fd,
772    multiaddr: &Ipv4Addr,
773    interface: &Ipv4Addr,
774) -> io::Result<()> {
775    backend::net::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface)
776}
777
778/// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, address,
779/// ifindex)`
780///
781/// This is similar to [`set_ip_add_membership_with_ifindex`] but additionally
782/// allows a `ifindex` value to be given.
783///
784/// See the [module-level documentation] for more.
785///
786/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
787#[cfg(any(
788    apple,
789    freebsdlike,
790    linux_like,
791    target_os = "fuchsia",
792    target_os = "openbsd"
793))]
794#[inline]
795#[doc(alias = "IP_ADD_MEMBERSHIP")]
796pub fn set_ip_add_membership_with_ifindex<Fd: AsFd>(
797    fd: Fd,
798    multiaddr: &Ipv4Addr,
799    address: &Ipv4Addr,
800    ifindex: i32,
801) -> io::Result<()> {
802    backend::net::sockopt::set_ip_add_membership_with_ifindex(
803        fd.as_fd(),
804        multiaddr,
805        address,
806        ifindex,
807    )
808}
809
810/// `setsockopt(fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, value)`
811///
812/// See the [module-level documentation] for more.
813///
814/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
815#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))]
816#[inline]
817#[doc(alias = "IP_ADD_SOURCE_MEMBERSHIP")]
818pub fn set_ip_add_source_membership<Fd: AsFd>(
819    fd: Fd,
820    multiaddr: &Ipv4Addr,
821    interface: &Ipv4Addr,
822    sourceaddr: &Ipv4Addr,
823) -> io::Result<()> {
824    backend::net::sockopt::set_ip_add_source_membership(
825        fd.as_fd(),
826        multiaddr,
827        interface,
828        sourceaddr,
829    )
830}
831
832/// `setsockopt(fd, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, value)`
833///
834/// See the [module-level documentation] for more.
835///
836/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
837#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))]
838#[inline]
839#[doc(alias = "IP_DROP_SOURCE_MEMBERSHIP")]
840pub fn set_ip_drop_source_membership<Fd: AsFd>(
841    fd: Fd,
842    multiaddr: &Ipv4Addr,
843    interface: &Ipv4Addr,
844    sourceaddr: &Ipv4Addr,
845) -> io::Result<()> {
846    backend::net::sockopt::set_ip_drop_source_membership(
847        fd.as_fd(),
848        multiaddr,
849        interface,
850        sourceaddr,
851    )
852}
853
854/// `setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, multiaddr, interface)`
855///
856/// See the [module-level documentation] for more.
857///
858/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
859#[inline]
860#[doc(alias = "IPV6_JOIN_GROUP")]
861#[doc(alias = "IPV6_ADD_MEMBERSHIP")]
862pub fn set_ipv6_add_membership<Fd: AsFd>(
863    fd: Fd,
864    multiaddr: &Ipv6Addr,
865    interface: u32,
866) -> io::Result<()> {
867    backend::net::sockopt::set_ipv6_add_membership(fd.as_fd(), multiaddr, interface)
868}
869
870/// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)`
871///
872/// This is similar to [`set_ip_drop_membership`] but always sets `ifindex`
873/// value to zero.
874///
875/// See the [module-level documentation] for more.
876///
877/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
878#[inline]
879#[doc(alias = "IP_DROP_MEMBERSHIP")]
880pub fn set_ip_drop_membership<Fd: AsFd>(
881    fd: Fd,
882    multiaddr: &Ipv4Addr,
883    interface: &Ipv4Addr,
884) -> io::Result<()> {
885    backend::net::sockopt::set_ip_drop_membership(fd.as_fd(), multiaddr, interface)
886}
887
888/// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)`
889///
890/// This is similar to [`set_ip_drop_membership_with_ifindex`] but additionally
891/// allows a `ifindex` value to be given.
892///
893/// See the [module-level documentation] for more.
894///
895/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
896#[cfg(any(
897    apple,
898    freebsdlike,
899    linux_like,
900    target_os = "fuchsia",
901    target_os = "openbsd"
902))]
903#[inline]
904#[doc(alias = "IP_DROP_MEMBERSHIP")]
905pub fn set_ip_drop_membership_with_ifindex<Fd: AsFd>(
906    fd: Fd,
907    multiaddr: &Ipv4Addr,
908    address: &Ipv4Addr,
909    ifindex: i32,
910) -> io::Result<()> {
911    backend::net::sockopt::set_ip_drop_membership_with_ifindex(
912        fd.as_fd(),
913        multiaddr,
914        address,
915        ifindex,
916    )
917}
918
919/// `setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, multiaddr, interface)`
920///
921/// See the [module-level documentation] for more.
922///
923/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
924#[inline]
925#[doc(alias = "IPV6_LEAVE_GROUP")]
926#[doc(alias = "IPV6_DROP_MEMBERSHIP")]
927pub fn set_ipv6_drop_membership<Fd: AsFd>(
928    fd: Fd,
929    multiaddr: &Ipv6Addr,
930    interface: u32,
931) -> io::Result<()> {
932    backend::net::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface)
933}
934
935/// `setsockopt(fd, IPPROTO_IP, IP_TOS, value)`
936///
937/// See the [module-level documentation] for more.
938///
939/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
940#[cfg(any(
941    bsd,
942    linux_like,
943    target_os = "aix",
944    target_os = "fuchsia",
945    target_os = "haiku",
946    target_os = "nto",
947    target_env = "newlib"
948))]
949#[inline]
950#[doc(alias = "IP_TOS")]
951pub fn set_ip_tos<Fd: AsFd>(fd: Fd, value: u8) -> io::Result<()> {
952    backend::net::sockopt::set_ip_tos(fd.as_fd(), value)
953}
954
955/// `getsockopt(fd, IPPROTO_IP, IP_TOS)`
956///
957/// See the [module-level documentation] for more.
958///
959/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
960#[cfg(any(
961    bsd,
962    linux_like,
963    target_os = "aix",
964    target_os = "fuchsia",
965    target_os = "haiku",
966    target_os = "nto",
967    target_env = "newlib"
968))]
969#[inline]
970#[doc(alias = "IP_TOS")]
971pub fn get_ip_tos<Fd: AsFd>(fd: Fd) -> io::Result<u8> {
972    backend::net::sockopt::get_ip_tos(fd.as_fd())
973}
974
975/// `setsockopt(fd, IPPROTO_IP, IP_RECVTOS, value)`
976///
977/// See the [module-level documentation] for more.
978///
979/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
980#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))]
981#[inline]
982#[doc(alias = "IP_RECVTOS")]
983pub fn set_ip_recvtos<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
984    backend::net::sockopt::set_ip_recvtos(fd.as_fd(), value)
985}
986
987/// `getsockopt(fd, IPPROTO_IP, IP_RECVTOS)`
988///
989/// See the [module-level documentation] for more.
990///
991/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
992#[cfg(any(apple, linux_like, target_os = "freebsd", target_os = "fuchsia"))]
993#[inline]
994#[doc(alias = "IP_RECVTOS")]
995pub fn get_ip_recvtos<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
996    backend::net::sockopt::get_ip_recvtos(fd.as_fd())
997}
998
999/// `setsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS, value)`
1000///
1001/// See the [module-level documentation] for more.
1002///
1003/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1004#[cfg(any(
1005    bsd,
1006    linux_like,
1007    target_os = "aix",
1008    target_os = "fuchsia",
1009    target_os = "nto"
1010))]
1011#[inline]
1012#[doc(alias = "IPV6_RECVTCLASS")]
1013pub fn set_ipv6_recvtclass<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1014    backend::net::sockopt::set_ipv6_recvtclass(fd.as_fd(), value)
1015}
1016
1017/// `getsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS)`
1018///
1019/// See the [module-level documentation] for more.
1020///
1021/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1022#[cfg(any(
1023    bsd,
1024    linux_like,
1025    target_os = "aix",
1026    target_os = "fuchsia",
1027    target_os = "nto"
1028))]
1029#[inline]
1030#[doc(alias = "IPV6_RECVTCLASS")]
1031pub fn get_ipv6_recvtclass<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1032    backend::net::sockopt::get_ipv6_recvtclass(fd.as_fd())
1033}
1034
1035/// `setsockopt(fd, IPPROTO_IP, IP_FREEBIND, value)`
1036///
1037/// See the [module-level documentation] for more.
1038///
1039/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1040#[cfg(any(linux_kernel, target_os = "fuchsia"))]
1041#[inline]
1042#[doc(alias = "IP_FREEBIND")]
1043pub fn set_ip_freebind<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1044    backend::net::sockopt::set_ip_freebind(fd.as_fd(), value)
1045}
1046
1047/// `getsockopt(fd, IPPROTO_IP, IP_FREEBIND)`
1048///
1049/// See the [module-level documentation] for more.
1050///
1051/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1052#[cfg(any(linux_kernel, target_os = "fuchsia"))]
1053#[inline]
1054#[doc(alias = "IP_FREEBIND")]
1055pub fn get_ip_freebind<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1056    backend::net::sockopt::get_ip_freebind(fd.as_fd())
1057}
1058
1059/// `setsockopt(fd, IPPROTO_IPV6, IPV6_FREEBIND, value)`
1060///
1061/// See the [module-level documentation] for more.
1062///
1063/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1064#[cfg(linux_kernel)]
1065#[inline]
1066#[doc(alias = "IPV6_FREEBIND")]
1067pub fn set_ipv6_freebind<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1068    backend::net::sockopt::set_ipv6_freebind(fd.as_fd(), value)
1069}
1070
1071/// `getsockopt(fd, IPPROTO_IPV6, IPV6_FREEBIND)`
1072///
1073/// See the [module-level documentation] for more.
1074///
1075/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1076#[cfg(linux_kernel)]
1077#[inline]
1078#[doc(alias = "IPV6_FREEBIND")]
1079pub fn get_ipv6_freebind<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1080    backend::net::sockopt::get_ipv6_freebind(fd.as_fd())
1081}
1082
1083/// `getsockopt(fd, IPPROTO_IP, SO_ORIGINAL_DST)`
1084///
1085/// Even though this corresponds to a `SO_*` constant, it is an `IPPROTO_IP`
1086/// option.
1087///
1088/// See the [module-level documentation] for more.
1089///
1090/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1091#[cfg(any(linux_kernel, target_os = "fuchsia"))]
1092#[inline]
1093#[doc(alias = "SO_ORIGINAL_DST")]
1094pub fn get_ip_original_dst<Fd: AsFd>(fd: Fd) -> io::Result<SocketAddrV4> {
1095    backend::net::sockopt::get_ip_original_dst(fd.as_fd())
1096}
1097
1098/// `getsockopt(fd, IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST)`
1099///
1100/// Even though this corresponds to a `IP6T_*` constant, it is an
1101/// `IPPROTO_IPV6` option.
1102///
1103/// See the [module-level documentation] for more.
1104///
1105/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1106#[cfg(linux_kernel)]
1107#[inline]
1108#[doc(alias = "IP6T_SO_ORIGINAL_DST")]
1109pub fn get_ipv6_original_dst<Fd: AsFd>(fd: Fd) -> io::Result<SocketAddrV6> {
1110    backend::net::sockopt::get_ipv6_original_dst(fd.as_fd())
1111}
1112
1113/// `setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, value)`
1114///
1115/// See the [module-level documentation] for more.
1116///
1117/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1118#[cfg(not(any(
1119    solarish,
1120    windows,
1121    target_os = "espidf",
1122    target_os = "haiku",
1123    target_os = "vita"
1124)))]
1125#[inline]
1126#[doc(alias = "IPV6_TCLASS")]
1127pub fn set_ipv6_tclass<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1128    backend::net::sockopt::set_ipv6_tclass(fd.as_fd(), value)
1129}
1130
1131/// `getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS)`
1132///
1133/// See the [module-level documentation] for more.
1134///
1135/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1136#[cfg(not(any(
1137    solarish,
1138    windows,
1139    target_os = "espidf",
1140    target_os = "haiku",
1141    target_os = "vita"
1142)))]
1143#[inline]
1144#[doc(alias = "IPV6_TCLASS")]
1145pub fn get_ipv6_tclass<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
1146    backend::net::sockopt::get_ipv6_tclass(fd.as_fd())
1147}
1148
1149/// `setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, value)`
1150///
1151/// See the [module-level documentation] for more.
1152///
1153/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1154#[inline]
1155#[doc(alias = "TCP_NODELAY")]
1156pub fn set_tcp_nodelay<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1157    backend::net::sockopt::set_tcp_nodelay(fd.as_fd(), value)
1158}
1159
1160/// `getsockopt(fd, IPPROTO_TCP, TCP_NODELAY)`
1161///
1162/// See the [module-level documentation] for more.
1163///
1164/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1165#[inline]
1166#[doc(alias = "TCP_NODELAY")]
1167pub fn get_tcp_nodelay<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1168    backend::net::sockopt::get_tcp_nodelay(fd.as_fd())
1169}
1170
1171/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, value)`
1172///
1173/// See the [module-level documentation] for more.
1174///
1175/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1176#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))]
1177#[inline]
1178#[doc(alias = "TCP_KEEPCNT")]
1179pub fn set_tcp_keepcnt<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1180    backend::net::sockopt::set_tcp_keepcnt(fd.as_fd(), value)
1181}
1182
1183/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT)`
1184///
1185/// See the [module-level documentation] for more.
1186///
1187/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1188#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))]
1189#[inline]
1190#[doc(alias = "TCP_KEEPCNT")]
1191pub fn get_tcp_keepcnt<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
1192    backend::net::sockopt::get_tcp_keepcnt(fd.as_fd())
1193}
1194
1195/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, value)`
1196///
1197/// `TCP_KEEPALIVE` on Apple platforms.
1198///
1199/// See the [module-level documentation] for more.
1200///
1201/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1202#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))]
1203#[inline]
1204#[doc(alias = "TCP_KEEPIDLE")]
1205pub fn set_tcp_keepidle<Fd: AsFd>(fd: Fd, value: Duration) -> io::Result<()> {
1206    backend::net::sockopt::set_tcp_keepidle(fd.as_fd(), value)
1207}
1208
1209/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE)`
1210///
1211/// `TCP_KEEPALIVE` on Apple platforms.
1212///
1213/// See the [module-level documentation] for more.
1214///
1215/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1216#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))]
1217#[inline]
1218#[doc(alias = "TCP_KEEPIDLE")]
1219pub fn get_tcp_keepidle<Fd: AsFd>(fd: Fd) -> io::Result<Duration> {
1220    backend::net::sockopt::get_tcp_keepidle(fd.as_fd())
1221}
1222
1223/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, value)`
1224///
1225/// See the [module-level documentation] for more.
1226///
1227/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1228#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))]
1229#[inline]
1230#[doc(alias = "TCP_KEEPINTVL")]
1231pub fn set_tcp_keepintvl<Fd: AsFd>(fd: Fd, value: Duration) -> io::Result<()> {
1232    backend::net::sockopt::set_tcp_keepintvl(fd.as_fd(), value)
1233}
1234
1235/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL)`
1236///
1237/// See the [module-level documentation] for more.
1238///
1239/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1240#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "nto")))]
1241#[inline]
1242#[doc(alias = "TCP_KEEPINTVL")]
1243pub fn get_tcp_keepintvl<Fd: AsFd>(fd: Fd) -> io::Result<Duration> {
1244    backend::net::sockopt::get_tcp_keepintvl(fd.as_fd())
1245}
1246
1247/// `setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, value)`
1248///
1249/// See the [module-level documentation] for more.
1250///
1251/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1252#[cfg(any(linux_like, target_os = "fuchsia"))]
1253#[inline]
1254#[doc(alias = "TCP_USER_TIMEOUT")]
1255pub fn set_tcp_user_timeout<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1256    backend::net::sockopt::set_tcp_user_timeout(fd.as_fd(), value)
1257}
1258
1259/// `getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT)`
1260///
1261/// See the [module-level documentation] for more.
1262///
1263/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1264#[cfg(any(linux_like, target_os = "fuchsia"))]
1265#[inline]
1266#[doc(alias = "TCP_USER_TIMEOUT")]
1267pub fn get_tcp_user_timeout<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
1268    backend::net::sockopt::get_tcp_user_timeout(fd.as_fd())
1269}
1270
1271/// `setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, value)`
1272///
1273/// See the [module-level documentation] for more.
1274///
1275/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1276#[cfg(any(linux_like, target_os = "fuchsia"))]
1277#[inline]
1278#[doc(alias = "TCP_QUICKACK")]
1279pub fn set_tcp_quickack<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1280    backend::net::sockopt::set_tcp_quickack(fd.as_fd(), value)
1281}
1282
1283/// `getsockopt(fd, IPPROTO_TCP, TCP_QUICKACK)`
1284///
1285/// See the [module-level documentation] for more.
1286///
1287/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1288#[cfg(any(linux_like, target_os = "fuchsia"))]
1289#[inline]
1290#[doc(alias = "TCP_QUICKACK")]
1291pub fn get_tcp_quickack<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1292    backend::net::sockopt::get_tcp_quickack(fd.as_fd())
1293}
1294
1295/// `setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, value)`
1296///
1297/// See the [module-level documentation] for more.
1298///
1299/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1300#[cfg(any(
1301    linux_like,
1302    target_os = "freebsd",
1303    target_os = "fuchsia",
1304    target_os = "illumos"
1305))]
1306#[inline]
1307#[doc(alias = "TCP_CONGESTION")]
1308pub fn set_tcp_congestion<Fd: AsFd>(fd: Fd, value: &str) -> io::Result<()> {
1309    backend::net::sockopt::set_tcp_congestion(fd.as_fd(), value)
1310}
1311
1312/// `getsockopt(fd, IPPROTO_TCP, TCP_CONGESTION)`
1313///
1314/// See the [module-level documentation] for more.
1315///
1316/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1317#[cfg(feature = "alloc")]
1318#[cfg(any(
1319    linux_like,
1320    target_os = "freebsd",
1321    target_os = "fuchsia",
1322    target_os = "illumos"
1323))]
1324#[inline]
1325#[doc(alias = "TCP_CONGESTION")]
1326pub fn get_tcp_congestion<Fd: AsFd>(fd: Fd) -> io::Result<String> {
1327    backend::net::sockopt::get_tcp_congestion(fd.as_fd())
1328}
1329
1330/// `setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, value)`
1331///
1332/// See the [module-level documentation] for more.
1333///
1334/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1335#[cfg(any(linux_like, target_os = "fuchsia"))]
1336#[inline]
1337#[doc(alias = "TCP_THIN_LINEAR_TIMEOUTS")]
1338pub fn set_tcp_thin_linear_timeouts<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1339    backend::net::sockopt::set_tcp_thin_linear_timeouts(fd.as_fd(), value)
1340}
1341
1342/// `getsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS)`
1343///
1344/// See the [module-level documentation] for more.
1345///
1346/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1347#[cfg(any(linux_like, target_os = "fuchsia"))]
1348#[inline]
1349#[doc(alias = "TCP_THIN_LINEAR_TIMEOUTS")]
1350pub fn get_tcp_thin_linear_timeouts<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1351    backend::net::sockopt::get_tcp_thin_linear_timeouts(fd.as_fd())
1352}
1353
1354/// `setsockopt(fd, IPPROTO_TCP, TCP_CORK, value)`
1355///
1356/// See the [module-level documentation] for more.
1357///
1358/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1359#[cfg(any(linux_like, solarish, target_os = "fuchsia"))]
1360#[inline]
1361#[doc(alias = "TCP_CORK")]
1362pub fn set_tcp_cork<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1363    backend::net::sockopt::set_tcp_cork(fd.as_fd(), value)
1364}
1365
1366/// `getsockopt(fd, IPPROTO_TCP, TCP_CORK)`
1367///
1368/// See the [module-level documentation] for more.
1369///
1370/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1371#[cfg(any(linux_like, solarish, target_os = "fuchsia"))]
1372#[inline]
1373#[doc(alias = "TCP_CORK")]
1374pub fn get_tcp_cork<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1375    backend::net::sockopt::get_tcp_cork(fd.as_fd())
1376}
1377
1378/// `getsockopt(fd, SOL_SOCKET, SO_PEERCRED)`—Get credentials of Unix domain
1379/// socket peer process.
1380///
1381/// # References
1382///  - [Linux `unix`]
1383///
1384/// [Linux `unix`]: https://man7.org/linux/man-pages/man7/unix.7.html
1385#[cfg(linux_kernel)]
1386#[doc(alias = "SO_PEERCRED")]
1387pub fn get_socket_peercred<Fd: AsFd>(fd: Fd) -> io::Result<super::UCred> {
1388    backend::net::sockopt::get_socket_peercred(fd.as_fd())
1389}
1390
1391/// `setsockopt(fd, SOL_XDP, XDP_UMEM_REG, value)`
1392///
1393/// On kernel versions only supporting v1, the flags are ignored.
1394///
1395/// # References
1396///   - [Linux]
1397///
1398/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-umem-reg-setsockopt
1399#[cfg(target_os = "linux")]
1400#[doc(alias = "XDP_UMEM_REG")]
1401pub fn set_xdp_umem_reg<Fd: AsFd>(fd: Fd, value: XdpUmemReg) -> io::Result<()> {
1402    backend::net::sockopt::set_xdp_umem_reg(fd.as_fd(), value)
1403}
1404
1405/// `setsockopt(fd, SOL_XDP, XDP_UMEM_FILL_RING, value)`
1406///
1407/// # References
1408///   - [Linux]
1409///
1410/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts
1411#[cfg(target_os = "linux")]
1412#[doc(alias = "XDP_UMEM_FILL_RING")]
1413pub fn set_xdp_umem_fill_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1414    backend::net::sockopt::set_xdp_umem_fill_ring_size(fd.as_fd(), value)
1415}
1416
1417/// `setsockopt(fd, SOL_XDP, XDP_UMEM_COMPLETION_RING, value)`
1418///
1419/// # References
1420///   - [Linux]
1421///
1422/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts
1423#[cfg(target_os = "linux")]
1424#[doc(alias = "XDP_UMEM_COMPLETION_RING")]
1425pub fn set_xdp_umem_completion_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1426    backend::net::sockopt::set_xdp_umem_completion_ring_size(fd.as_fd(), value)
1427}
1428
1429/// `setsockopt(fd, SOL_XDP, XDP_TX_RING, value)`
1430///
1431/// # References
1432///   - [Linux]
1433///
1434/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts
1435#[cfg(target_os = "linux")]
1436#[doc(alias = "XDP_TX_RING")]
1437pub fn set_xdp_tx_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1438    backend::net::sockopt::set_xdp_tx_ring_size(fd.as_fd(), value)
1439}
1440
1441/// `setsockopt(fd, SOL_XDP, XDP_RX_RING, value)`
1442///
1443/// # References
1444///   - [Linux]
1445///
1446/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts
1447#[cfg(target_os = "linux")]
1448#[doc(alias = "XDP_RX_RING")]
1449pub fn set_xdp_rx_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1450    backend::net::sockopt::set_xdp_rx_ring_size(fd.as_fd(), value)
1451}
1452
1453/// `getsockopt(fd, SOL_XDP, XDP_MMAP_OFFSETS)`
1454///
1455/// # References
1456///   - [Linux]
1457///
1458/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html
1459#[cfg(target_os = "linux")]
1460#[doc(alias = "XDP_MMAP_OFFSETS")]
1461pub fn get_xdp_mmap_offsets<Fd: AsFd>(fd: Fd) -> io::Result<XdpMmapOffsets> {
1462    backend::net::sockopt::get_xdp_mmap_offsets(fd.as_fd())
1463}
1464
1465/// `getsockopt(fd, SOL_XDP, XDP_STATISTICS)`
1466///
1467/// # References
1468///   - [Linux]
1469///
1470/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-statistics-getsockopt
1471#[cfg(target_os = "linux")]
1472#[doc(alias = "XDP_STATISTICS")]
1473pub fn get_xdp_statistics<Fd: AsFd>(fd: Fd) -> io::Result<XdpStatistics> {
1474    backend::net::sockopt::get_xdp_statistics(fd.as_fd())
1475}
1476
1477/// `getsockopt(fd, SOL_XDP, XDP_OPTIONS)`
1478///
1479/// # References
1480///   - [Linux]
1481///
1482/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-options-getsockopt
1483#[cfg(target_os = "linux")]
1484#[doc(alias = "XDP_OPTIONS")]
1485pub fn get_xdp_options<Fd: AsFd>(fd: Fd) -> io::Result<XdpOptionsFlags> {
1486    backend::net::sockopt::get_xdp_options(fd.as_fd())
1487}
1488
1489#[cfg(test)]
1490mod tests {
1491    use super::*;
1492
1493    #[test]
1494    fn test_sizes() {
1495        use c::c_int;
1496
1497        // Backend code needs to cast these to `c_int` so make sure that cast
1498        // isn't lossy.
1499        assert_eq_size!(Timeout, c_int);
1500    }
1501}