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 getter 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 getter 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 getter 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://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man4/ip.4
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 getter 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://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man4/ip6.4
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 getter 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://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man4/tcp.4
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 getter functions]: #references-for-all-getter-functions
141//! [References for all `set_*` functions]: #references-for-all-set_-functions
142
143#![doc(alias = "getsockopt")]
144#![doc(alias = "setsockopt")]
145
146#[cfg(all(target_os = "linux", feature = "time"))]
147use crate::clockid::ClockId;
148#[cfg(target_os = "linux")]
149use crate::net::xdp::{XdpMmapOffsets, XdpOptionsFlags, XdpStatistics, XdpUmemReg};
150#[cfg(not(any(
151    apple,
152    windows,
153    target_os = "aix",
154    target_os = "cygwin",
155    target_os = "dragonfly",
156    target_os = "emscripten",
157    target_os = "espidf",
158    target_os = "haiku",
159    target_os = "netbsd",
160    target_os = "nto",
161    target_os = "vita",
162)))]
163use crate::net::AddressFamily;
164#[cfg(any(
165    linux_kernel,
166    target_os = "freebsd",
167    target_os = "fuchsia",
168    target_os = "openbsd",
169    target_os = "redox",
170    target_env = "newlib"
171))]
172use crate::net::Protocol;
173#[cfg(any(linux_kernel, target_os = "fuchsia"))]
174use crate::net::SocketAddrV4;
175#[cfg(linux_kernel)]
176use crate::net::SocketAddrV6;
177#[cfg(all(target_os = "linux", feature = "time"))]
178use crate::net::TxTimeFlags;
179use crate::net::{Ipv4Addr, Ipv6Addr, SocketType};
180use crate::{backend, io};
181#[cfg(feature = "alloc")]
182#[cfg(any(
183    linux_like,
184    target_os = "freebsd",
185    target_os = "fuchsia",
186    target_os = "illumos"
187))]
188use alloc::string::String;
189use backend::c;
190use backend::fd::AsFd;
191use core::time::Duration;
192
193/// Timeout identifier for use with [`set_socket_timeout`] and
194/// [`socket_timeout`].
195#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
196#[repr(u32)]
197pub enum Timeout {
198    /// `SO_RCVTIMEO`—Timeout for receiving.
199    Recv = c::SO_RCVTIMEO as _,
200
201    /// `SO_SNDTIMEO`—Timeout for sending.
202    Send = c::SO_SNDTIMEO as _,
203}
204
205/// A type for holding raw integer IPv4 Path MTU Discovery options.
206#[cfg(linux_kernel)]
207pub type RawIpv4PathMtuDiscovery = i32;
208
209/// IPv4 Path MTU Discovery option values (`IP_PMTUDISC_*`) for use with
210/// [`set_ip_mtu_discover`] and [`ip_mtu_discover`].
211///
212/// # References
213/// - [Linux]
214/// - [Linux INET header]
215///
216/// [Linux]: https://man7.org/linux/man-pages/man7/ip.7.html
217/// [Linux INET header]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/in.h?h=v6.14#n135
218#[cfg(linux_kernel)]
219#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
220#[repr(transparent)]
221pub struct Ipv4PathMtuDiscovery(RawIpv4PathMtuDiscovery);
222
223#[cfg(linux_kernel)]
224impl Ipv4PathMtuDiscovery {
225    /// `IP_PMTUDISC_DONT`
226    #[doc(alias = "IP_PMTUDISC_DONT")]
227    pub const DONT: Self = Self(c::IP_PMTUDISC_DONT as _);
228    /// `IP_PMTUDISC_WANT`
229    #[doc(alias = "IP_PMTUDISC_WANT")]
230    pub const WANT: Self = Self(c::IP_PMTUDISC_WANT as _);
231    /// `IP_PMTUDISC_DO`
232    #[doc(alias = "IP_PMTUDISC_DO")]
233    pub const DO: Self = Self(c::IP_PMTUDISC_DO as _);
234    /// `IP_PMTUDISC_PROBE`
235    #[doc(alias = "IP_PMTUDISC_PROBE")]
236    pub const PROBE: Self = Self(c::IP_PMTUDISC_PROBE as _);
237    /// `IP_PMTUDISC_INTERFACE`
238    #[doc(alias = "IP_PMTUDISC_INTERFACE")]
239    pub const INTERFACE: Self = Self(c::IP_PMTUDISC_INTERFACE as _);
240    /// `IP_PMTUDISC_OMIT`
241    #[doc(alias = "IP_PMTUDISC_OMIT")]
242    pub const OMIT: Self = Self(c::IP_PMTUDISC_OMIT as _);
243
244    /// Constructs an option from a raw integer.
245    #[inline]
246    pub const fn from_raw(raw: RawIpv4PathMtuDiscovery) -> Self {
247        Self(raw)
248    }
249
250    /// Returns the raw integer for this option.
251    #[inline]
252    pub const fn as_raw(self) -> RawIpv4PathMtuDiscovery {
253        self.0
254    }
255}
256
257/// A type for holding raw integer IPv6 Path MTU Discovery options.
258#[cfg(linux_kernel)]
259pub type RawIpv6PathMtuDiscovery = i32;
260
261/// IPv6 Path MTU Discovery option values (`IPV6_PMTUDISC_*`) for use with
262/// [`set_ipv6_mtu_discover`] and [`ipv6_mtu_discover`].
263///
264/// # References
265/// - [Linux]
266/// - [Linux INET6 header]
267///
268/// [Linux]: https://man7.org/linux/man-pages/man7/ipv6.7.html
269/// [Linux INET6 header]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/in6.h?h=v6.14#n185
270#[cfg(linux_kernel)]
271#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
272#[repr(transparent)]
273pub struct Ipv6PathMtuDiscovery(RawIpv6PathMtuDiscovery);
274
275#[cfg(linux_kernel)]
276impl Ipv6PathMtuDiscovery {
277    /// `IPV6_PMTUDISC_DONT`
278    #[doc(alias = "IPV6_PMTUDISC_DONT")]
279    pub const DONT: Self = Self(c::IPV6_PMTUDISC_DONT as _);
280    /// `IPV6_PMTUDISC_WANT`
281    #[doc(alias = "IPV6_PMTUDISC_WANT")]
282    pub const WANT: Self = Self(c::IPV6_PMTUDISC_WANT as _);
283    /// `IPV6_PMTUDISC_DO`
284    #[doc(alias = "IPV6_PMTUDISC_DO")]
285    pub const DO: Self = Self(c::IPV6_PMTUDISC_DO as _);
286    /// `IPV6_PMTUDISC_PROBE`
287    #[doc(alias = "IPV6_PMTUDISC_PROBE")]
288    pub const PROBE: Self = Self(c::IPV6_PMTUDISC_PROBE as _);
289    /// `IPV6_PMTUDISC_INTERFACE`
290    #[doc(alias = "IPV6_PMTUDISC_INTERFACE")]
291    pub const INTERFACE: Self = Self(c::IPV6_PMTUDISC_INTERFACE as _);
292    /// `IPV6_PMTUDISC_OMIT`
293    #[doc(alias = "IPV6_PMTUDISC_OMIT")]
294    pub const OMIT: Self = Self(c::IPV6_PMTUDISC_OMIT as _);
295
296    /// Constructs an option from a raw integer.
297    #[inline]
298    pub const fn from_raw(raw: RawIpv6PathMtuDiscovery) -> Self {
299        Self(raw)
300    }
301
302    /// Returns the raw integer for this option.
303    #[inline]
304    pub const fn as_raw(self) -> RawIpv6PathMtuDiscovery {
305        self.0
306    }
307}
308
309/// `getsockopt(fd, SOL_SOCKET, SO_TYPE)`—Returns the type of a socket.
310///
311/// See the [module-level documentation] for more.
312///
313/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
314#[inline]
315#[doc(alias = "SO_TYPE")]
316pub fn socket_type<Fd: AsFd>(fd: Fd) -> io::Result<SocketType> {
317    backend::net::sockopt::socket_type(fd.as_fd())
318}
319
320/// `setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, value)`—Set whether local
321/// addresses may be reused in `bind`.
322///
323/// See the [module-level documentation] for more.
324///
325/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
326#[inline]
327#[doc(alias = "SO_REUSEADDR")]
328pub fn set_socket_reuseaddr<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
329    backend::net::sockopt::set_socket_reuseaddr(fd.as_fd(), value)
330}
331
332/// `getsockopt(fd, SOL_SOCKET, SO_REUSEADDR)`
333///
334/// See the [module-level documentation] for more.
335///
336/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
337#[inline]
338#[doc(alias = "SO_REUSEADDR")]
339pub fn socket_reuseaddr<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
340    backend::net::sockopt::socket_reuseaddr(fd.as_fd())
341}
342
343/// `setsockopt(fd, SOL_SOCKET, SO_BROADCAST, value)`
344///
345/// See the [module-level documentation] for more.
346///
347/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
348#[inline]
349#[doc(alias = "SO_BROADCAST")]
350pub fn set_socket_broadcast<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
351    backend::net::sockopt::set_socket_broadcast(fd.as_fd(), value)
352}
353
354/// `getsockopt(fd, SOL_SOCKET, SO_BROADCAST)`
355///
356/// See the [module-level documentation] for more.
357///
358/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
359#[inline]
360#[doc(alias = "SO_BROADCAST")]
361pub fn socket_broadcast<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
362    backend::net::sockopt::socket_broadcast(fd.as_fd())
363}
364
365/// `setsockopt(fd, SOL_SOCKET, SO_LINGER, value)`
366///
367/// See the [module-level documentation] for more.
368///
369/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
370#[inline]
371#[doc(alias = "SO_LINGER")]
372pub fn set_socket_linger<Fd: AsFd>(fd: Fd, value: Option<Duration>) -> io::Result<()> {
373    backend::net::sockopt::set_socket_linger(fd.as_fd(), value)
374}
375
376/// `getsockopt(fd, SOL_SOCKET, SO_LINGER)`
377///
378/// See the [module-level documentation] for more.
379///
380/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
381#[inline]
382#[doc(alias = "SO_LINGER")]
383pub fn socket_linger<Fd: AsFd>(fd: Fd) -> io::Result<Option<Duration>> {
384    backend::net::sockopt::socket_linger(fd.as_fd())
385}
386
387/// `setsockopt(fd, SOL_SOCKET, SO_PASSCRED, value)`
388///
389/// See the [module-level documentation] for more.
390///
391/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
392#[cfg(linux_kernel)]
393#[inline]
394#[doc(alias = "SO_PASSCRED")]
395pub fn set_socket_passcred<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
396    backend::net::sockopt::set_socket_passcred(fd.as_fd(), value)
397}
398
399/// `getsockopt(fd, SOL_SOCKET, SO_PASSCRED)`
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(linux_kernel)]
405#[inline]
406#[doc(alias = "SO_PASSCRED")]
407pub fn socket_passcred<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
408    backend::net::sockopt::socket_passcred(fd.as_fd())
409}
410
411/// `setsockopt(fd, SOL_SOCKET, id, value)`—Set the sending or receiving
412/// timeout.
413///
414/// See the [module-level documentation] for more.
415///
416/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
417#[inline]
418#[doc(alias = "SO_RCVTIMEO")]
419#[doc(alias = "SO_SNDTIMEO")]
420pub fn set_socket_timeout<Fd: AsFd>(
421    fd: Fd,
422    id: Timeout,
423    value: Option<Duration>,
424) -> io::Result<()> {
425    backend::net::sockopt::set_socket_timeout(fd.as_fd(), id, value)
426}
427
428/// `getsockopt(fd, SOL_SOCKET, id)`—Get the sending or receiving timeout.
429///
430/// See the [module-level documentation] for more.
431///
432/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
433#[inline]
434#[doc(alias = "SO_RCVTIMEO")]
435#[doc(alias = "SO_SNDTIMEO")]
436pub fn socket_timeout<Fd: AsFd>(fd: Fd, id: Timeout) -> io::Result<Option<Duration>> {
437    backend::net::sockopt::socket_timeout(fd.as_fd(), id)
438}
439
440/// `getsockopt(fd, SOL_SOCKET, SO_ERROR)`
441///
442/// See the [module-level documentation] for more.
443///
444/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
445#[inline]
446#[doc(alias = "SO_ERROR")]
447pub fn socket_error<Fd: AsFd>(fd: Fd) -> io::Result<Result<(), io::Errno>> {
448    backend::net::sockopt::socket_error(fd.as_fd())
449}
450
451/// `getsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE)`
452///
453/// See the [module-level documentation] for more.
454///
455/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
456#[cfg(any(apple, freebsdlike, target_os = "netbsd"))]
457#[doc(alias = "SO_NOSIGPIPE")]
458#[inline]
459pub fn socket_nosigpipe<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
460    backend::net::sockopt::socket_nosigpipe(fd.as_fd())
461}
462
463/// `setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, value)`
464///
465/// See the [module-level documentation] for more.
466///
467/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
468#[cfg(any(apple, freebsdlike, target_os = "netbsd"))]
469#[doc(alias = "SO_NOSIGPIPE")]
470#[inline]
471pub fn set_socket_nosigpipe<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
472    backend::net::sockopt::set_socket_nosigpipe(fd.as_fd(), value)
473}
474
475/// `setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, value)`
476///
477/// See the [module-level documentation] for more.
478///
479/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
480#[inline]
481#[doc(alias = "SO_KEEPALIVE")]
482pub fn set_socket_keepalive<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
483    backend::net::sockopt::set_socket_keepalive(fd.as_fd(), value)
484}
485
486/// `getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE)`
487///
488/// See the [module-level documentation] for more.
489///
490/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
491#[inline]
492#[doc(alias = "SO_KEEPALIVE")]
493pub fn socket_keepalive<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
494    backend::net::sockopt::socket_keepalive(fd.as_fd())
495}
496
497/// `setsockopt(fd, SOL_SOCKET, SO_RCVBUF, value)`
498///
499/// See the [module-level documentation] for more.
500///
501/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
502#[inline]
503#[doc(alias = "SO_RCVBUF")]
504pub fn set_socket_recv_buffer_size<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> {
505    backend::net::sockopt::set_socket_recv_buffer_size(fd.as_fd(), value)
506}
507
508/// `setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, value)`
509///
510/// See the [module-level documentation] for more.
511///
512/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
513#[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "redox"))]
514#[inline]
515#[doc(alias = "SO_RCVBUFFORCE")]
516pub fn set_socket_recv_buffer_size_force<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> {
517    backend::net::sockopt::set_socket_recv_buffer_size_force(fd.as_fd(), value)
518}
519
520/// `getsockopt(fd, SOL_SOCKET, SO_RCVBUF)`
521///
522/// See the [module-level documentation] for more.
523///
524/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
525#[inline]
526#[doc(alias = "SO_RCVBUF")]
527pub fn socket_recv_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> {
528    backend::net::sockopt::socket_recv_buffer_size(fd.as_fd())
529}
530
531/// `setsockopt(fd, SOL_SOCKET, SO_SNDBUF, value)`
532///
533/// See the [module-level documentation] for more.
534///
535/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
536#[inline]
537#[doc(alias = "SO_SNDBUF")]
538pub fn set_socket_send_buffer_size<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> {
539    backend::net::sockopt::set_socket_send_buffer_size(fd.as_fd(), value)
540}
541
542/// `setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, value)`
543///
544/// See the [module-level documentation] for more.
545///
546/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
547#[cfg(any(linux_kernel, target_os = "fuchsia", target_os = "redox"))]
548#[inline]
549#[doc(alias = "SO_SNDBUFFORCE")]
550pub fn set_socket_send_buffer_size_force<Fd: AsFd>(fd: Fd, value: usize) -> io::Result<()> {
551    backend::net::sockopt::set_socket_send_buffer_size_force(fd.as_fd(), value)
552}
553
554/// `getsockopt(fd, SOL_SOCKET, SO_SNDBUF)`
555///
556/// See the [module-level documentation] for more.
557///
558/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
559#[inline]
560#[doc(alias = "SO_SNDBUF")]
561pub fn socket_send_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> {
562    backend::net::sockopt::socket_send_buffer_size(fd.as_fd())
563}
564
565/// `getsockopt(fd, SOL_SOCKET, SO_DOMAIN)`
566///
567/// See the [module-level documentation] for more.
568///
569/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
570#[cfg(not(any(
571    apple,
572    windows,
573    target_os = "aix",
574    target_os = "cygwin",
575    target_os = "dragonfly",
576    target_os = "emscripten",
577    target_os = "espidf",
578    target_os = "haiku",
579    target_os = "horizon",
580    target_os = "hurd",
581    target_os = "netbsd",
582    target_os = "nto",
583    target_os = "vita",
584)))]
585#[inline]
586#[doc(alias = "SO_DOMAIN")]
587pub fn socket_domain<Fd: AsFd>(fd: Fd) -> io::Result<AddressFamily> {
588    backend::net::sockopt::socket_domain(fd.as_fd())
589}
590
591/// `getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN)`
592///
593/// See the [module-level documentation] for more.
594///
595/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
596#[cfg(not(apple))] // Apple platforms declare the constant, but do not actually implement it.
597#[inline]
598#[doc(alias = "SO_ACCEPTCONN")]
599pub fn socket_acceptconn<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
600    backend::net::sockopt::socket_acceptconn(fd.as_fd())
601}
602
603/// `setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, value)`
604///
605/// See the [module-level documentation] for more.
606///
607/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
608#[inline]
609#[doc(alias = "SO_OOBINLINE")]
610pub fn set_socket_oobinline<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
611    backend::net::sockopt::set_socket_oobinline(fd.as_fd(), value)
612}
613
614/// `getsockopt(fd, SOL_SOCKET, SO_OOBINLINE)`
615///
616/// See the [module-level documentation] for more.
617///
618/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
619#[inline]
620#[doc(alias = "SO_OOBINLINE")]
621pub fn socket_oobinline<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
622    backend::net::sockopt::socket_oobinline(fd.as_fd())
623}
624
625/// `setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, value)`
626///
627/// See the [module-level documentation] for more.
628///
629/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
630#[cfg(not(any(solarish, windows, target_os = "cygwin")))]
631#[cfg(not(windows))]
632#[inline]
633#[doc(alias = "SO_REUSEPORT")]
634pub fn set_socket_reuseport<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
635    backend::net::sockopt::set_socket_reuseport(fd.as_fd(), value)
636}
637
638/// `getsockopt(fd, SOL_SOCKET, SO_REUSEPORT)`
639///
640/// See the [module-level documentation] for more.
641///
642/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
643#[cfg(not(any(solarish, windows, target_os = "cygwin")))]
644#[inline]
645#[doc(alias = "SO_REUSEPORT")]
646pub fn socket_reuseport<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
647    backend::net::sockopt::socket_reuseport(fd.as_fd())
648}
649
650/// `setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, value)`
651///
652/// See the [module-level documentation] for more.
653///
654/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
655#[cfg(target_os = "freebsd")]
656#[inline]
657#[doc(alias = "SO_REUSEPORT_LB")]
658pub fn set_socket_reuseport_lb<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
659    backend::net::sockopt::set_socket_reuseport_lb(fd.as_fd(), value)
660}
661
662/// `getsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB)`
663///
664/// See the [module-level documentation] for more.
665///
666/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
667#[cfg(target_os = "freebsd")]
668#[inline]
669#[doc(alias = "SO_REUSEPORT_LB")]
670pub fn socket_reuseport_lb<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
671    backend::net::sockopt::socket_reuseport_lb(fd.as_fd())
672}
673
674/// `getsockopt(fd, SOL_SOCKET, SO_PROTOCOL)`
675///
676/// See the [module-level documentation] for more.
677///
678/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
679#[cfg(any(
680    linux_kernel,
681    target_os = "freebsd",
682    target_os = "fuchsia",
683    target_os = "openbsd",
684    target_os = "redox",
685    target_env = "newlib"
686))]
687#[inline]
688#[doc(alias = "SO_PROTOCOL")]
689pub fn socket_protocol<Fd: AsFd>(fd: Fd) -> io::Result<Option<Protocol>> {
690    backend::net::sockopt::socket_protocol(fd.as_fd())
691}
692
693/// `getsockopt(fd, SOL_SOCKET, SO_COOKIE)`
694///
695/// See the [module-level documentation] for more.
696///
697/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
698#[cfg(target_os = "linux")]
699#[inline]
700#[doc(alias = "SO_COOKIE")]
701pub fn socket_cookie<Fd: AsFd>(fd: Fd) -> io::Result<u64> {
702    backend::net::sockopt::socket_cookie(fd.as_fd())
703}
704
705/// `getsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU)`
706///
707/// See the [module-level documentation] for more.
708///
709/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
710#[cfg(target_os = "linux")]
711#[inline]
712#[doc(alias = "SO_INCOMING_CPU")]
713pub fn socket_incoming_cpu<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
714    backend::net::sockopt::socket_incoming_cpu(fd.as_fd())
715}
716
717/// `setsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, value)`
718///
719/// See the [module-level documentation] for more.
720///
721/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
722#[cfg(target_os = "linux")]
723#[inline]
724#[doc(alias = "SO_INCOMING_CPU")]
725pub fn set_socket_incoming_cpu<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
726    backend::net::sockopt::set_socket_incoming_cpu(fd.as_fd(), value)
727}
728
729/// `setsockopt(fd, IPPROTO_IP, IP_TTL, value)`
730///
731/// See the [module-level documentation] for more.
732///
733/// [module-level documentation]: self#references-for-get_socket_-and-set_socket_-functions
734#[inline]
735#[doc(alias = "IP_TTL")]
736pub fn set_ip_ttl<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
737    backend::net::sockopt::set_ip_ttl(fd.as_fd(), value)
738}
739
740/// `getsockopt(fd, IPPROTO_IP, IP_TTL)`
741///
742/// See the [module-level documentation] for more.
743///
744/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
745#[inline]
746#[doc(alias = "IP_TTL")]
747pub fn ip_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
748    backend::net::sockopt::ip_ttl(fd.as_fd())
749}
750
751/// `setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, value)`
752///
753/// See the [module-level documentation] for more.
754///
755/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
756#[inline]
757#[doc(alias = "IPV6_V6ONLY")]
758pub fn set_ipv6_v6only<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
759    backend::net::sockopt::set_ipv6_v6only(fd.as_fd(), value)
760}
761
762/// `getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY)`
763///
764/// See the [module-level documentation] for more.
765///
766/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
767#[inline]
768#[doc(alias = "IPV6_V6ONLY")]
769pub fn ipv6_v6only<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
770    backend::net::sockopt::ipv6_v6only(fd.as_fd())
771}
772
773/// `getsockopt(fd, IPPROTO_IP, IP_MTU)`
774///
775/// See the [module-level documentation] for more.
776///
777/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
778#[inline]
779#[cfg(any(linux_kernel, target_os = "cygwin"))]
780#[doc(alias = "IP_MTU")]
781pub fn ip_mtu<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
782    backend::net::sockopt::ip_mtu(fd.as_fd())
783}
784
785/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MTU)`
786///
787/// See the [module-level documentation] for more.
788///
789/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
790#[inline]
791#[cfg(any(linux_kernel, target_os = "cygwin"))]
792#[doc(alias = "IPV6_MTU")]
793pub fn ipv6_mtu<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
794    backend::net::sockopt::ipv6_mtu(fd.as_fd())
795}
796
797/// `setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, value)`
798///
799/// See the [module-level documentation] for more.
800///
801/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
802#[cfg(linux_kernel)]
803#[inline]
804#[doc(alias = "IP_MTU_DISCOVER")]
805pub fn set_ip_mtu_discover<Fd: AsFd>(fd: Fd, value: Ipv4PathMtuDiscovery) -> io::Result<()> {
806    backend::net::sockopt::set_ip_mtu_discover(fd.as_fd(), value)
807}
808
809/// `getsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER)`
810///
811/// See the [module-level documentation] for more.
812///
813/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
814#[cfg(linux_kernel)]
815#[inline]
816#[doc(alias = "IP_MTU_DISCOVER")]
817pub fn ip_mtu_discover<Fd: AsFd>(fd: Fd) -> io::Result<Ipv4PathMtuDiscovery> {
818    backend::net::sockopt::ip_mtu_discover(fd.as_fd())
819}
820
821/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, value)`
822///
823/// See the [module-level documentation] for more.
824///
825/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
826#[cfg(linux_kernel)]
827#[inline]
828#[doc(alias = "IPV6_MTU_DISCOVER")]
829pub fn set_ipv6_mtu_discover<Fd: AsFd>(fd: Fd, value: Ipv6PathMtuDiscovery) -> io::Result<()> {
830    backend::net::sockopt::set_ipv6_mtu_discover(fd.as_fd(), value)
831}
832
833/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER)`
834///
835/// See the [module-level documentation] for more.
836///
837/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
838#[cfg(linux_kernel)]
839#[inline]
840#[doc(alias = "IPV6_MTU_DISCOVER")]
841pub fn ipv6_mtu_discover<Fd: AsFd>(fd: Fd) -> io::Result<Ipv6PathMtuDiscovery> {
842    backend::net::sockopt::ipv6_mtu_discover(fd.as_fd())
843}
844
845/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, value)`
846///
847/// See the [module-level documentation] for more.
848///
849/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
850#[inline]
851#[doc(alias = "IP_MULTICAST_IF")]
852pub fn set_ip_multicast_if<Fd: AsFd>(fd: Fd, value: &Ipv4Addr) -> io::Result<()> {
853    backend::net::sockopt::set_ip_multicast_if(fd.as_fd(), value)
854}
855
856/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, multiaddr, address,
857/// ifindex)`
858///
859/// This is similar to [`set_ip_multicast_if`] but additionally allows an
860/// `ifindex` value to be given.
861///
862/// See the [module-level documentation] for more.
863///
864/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
865#[cfg(any(
866    apple,
867    freebsdlike,
868    linux_like,
869    target_os = "fuchsia",
870    target_os = "openbsd"
871))]
872#[inline]
873#[doc(alias = "IP_MULTICAST_IF")]
874pub fn set_ip_multicast_if_with_ifindex<Fd: AsFd>(
875    fd: Fd,
876    multiaddr: &Ipv4Addr,
877    address: &Ipv4Addr,
878    ifindex: u32,
879) -> io::Result<()> {
880    backend::net::sockopt::set_ip_multicast_if_with_ifindex(fd.as_fd(), multiaddr, address, ifindex)
881}
882
883/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF)`
884///
885/// See the [module-level documentation] for more.
886///
887/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
888#[inline]
889#[doc(alias = "IP_MULTICAST_IF")]
890pub fn ip_multicast_if<Fd: AsFd>(fd: Fd) -> io::Result<Ipv4Addr> {
891    backend::net::sockopt::ip_multicast_if(fd.as_fd())
892}
893
894/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, value)`
895///
896/// See the [module-level documentation] for more.
897///
898/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
899#[inline]
900#[doc(alias = "IPV6_MULTICAST_IF")]
901pub fn set_ipv6_multicast_if<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
902    backend::net::sockopt::set_ipv6_multicast_if(fd.as_fd(), value)
903}
904
905/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF)`
906///
907/// See the [module-level documentation] for more.
908///
909/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
910#[inline]
911#[doc(alias = "IPV6_MULTICAST_IF")]
912pub fn ipv6_multicast_if<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
913    backend::net::sockopt::ipv6_multicast_if(fd.as_fd())
914}
915
916/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, value)`
917///
918/// See the [module-level documentation] for more.
919///
920/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
921#[inline]
922#[doc(alias = "IP_MULTICAST_LOOP")]
923pub fn set_ip_multicast_loop<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
924    backend::net::sockopt::set_ip_multicast_loop(fd.as_fd(), value)
925}
926
927/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP)`
928///
929/// See the [module-level documentation] for more.
930///
931/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
932#[inline]
933#[doc(alias = "IP_MULTICAST_LOOP")]
934pub fn ip_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
935    backend::net::sockopt::ip_multicast_loop(fd.as_fd())
936}
937
938/// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, value)`
939///
940/// See the [module-level documentation] for more.
941///
942/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
943#[inline]
944#[doc(alias = "IP_MULTICAST_TTL")]
945pub fn set_ip_multicast_ttl<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
946    backend::net::sockopt::set_ip_multicast_ttl(fd.as_fd(), value)
947}
948
949/// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL)`
950///
951/// See the [module-level documentation] for more.
952///
953/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
954#[inline]
955#[doc(alias = "IP_MULTICAST_TTL")]
956pub fn ip_multicast_ttl<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
957    backend::net::sockopt::ip_multicast_ttl(fd.as_fd())
958}
959
960/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, value)`
961///
962/// See the [module-level documentation] for more.
963///
964/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
965#[inline]
966#[doc(alias = "IPV6_MULTICAST_LOOP")]
967pub fn set_ipv6_multicast_loop<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
968    backend::net::sockopt::set_ipv6_multicast_loop(fd.as_fd(), value)
969}
970
971/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP)`
972///
973/// See the [module-level documentation] for more.
974///
975/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
976#[inline]
977#[doc(alias = "IPV6_MULTICAST_LOOP")]
978pub fn ipv6_multicast_loop<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
979    backend::net::sockopt::ipv6_multicast_loop(fd.as_fd())
980}
981
982/// `getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS)`
983///
984/// See the [module-level documentation] for more.
985///
986/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
987#[inline]
988#[doc(alias = "IPV6_UNICAST_HOPS")]
989pub fn ipv6_unicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u8> {
990    backend::net::sockopt::ipv6_unicast_hops(fd.as_fd())
991}
992
993/// `setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, value)`
994///
995/// See the [module-level documentation] for more.
996///
997/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
998#[inline]
999#[doc(alias = "IPV6_UNICAST_HOPS")]
1000pub fn set_ipv6_unicast_hops<Fd: AsFd>(fd: Fd, value: Option<u8>) -> io::Result<()> {
1001    backend::net::sockopt::set_ipv6_unicast_hops(fd.as_fd(), value)
1002}
1003
1004/// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, value)`
1005///
1006/// See the [module-level documentation] for more.
1007///
1008/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1009#[inline]
1010#[doc(alias = "IPV6_MULTICAST_HOPS")]
1011pub fn set_ipv6_multicast_hops<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1012    backend::net::sockopt::set_ipv6_multicast_hops(fd.as_fd(), value)
1013}
1014
1015/// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS)`
1016///
1017/// See the [module-level documentation] for more.
1018///
1019/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1020#[inline]
1021#[doc(alias = "IPV6_MULTICAST_HOPS")]
1022pub fn ipv6_multicast_hops<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
1023    backend::net::sockopt::ipv6_multicast_hops(fd.as_fd())
1024}
1025
1026/// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, interface)`
1027///
1028/// This is similar to [`set_ip_add_membership`] but always sets the `ifindex`
1029/// value to zero. See [`set_ip_add_membership_with_ifindex`] instead to also
1030/// give the `ifindex` value.
1031///
1032/// See the [module-level documentation] for more.
1033///
1034/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
1035#[inline]
1036#[doc(alias = "IP_ADD_MEMBERSHIP")]
1037pub fn set_ip_add_membership<Fd: AsFd>(
1038    fd: Fd,
1039    multiaddr: &Ipv4Addr,
1040    interface: &Ipv4Addr,
1041) -> io::Result<()> {
1042    backend::net::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface)
1043}
1044
1045/// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, address,
1046/// ifindex)`
1047///
1048/// This is similar to [`set_ip_add_membership`] but additionally allows an
1049/// `ifindex` value to be given.
1050///
1051/// See the [module-level documentation] for more.
1052///
1053/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
1054#[cfg(any(
1055    apple,
1056    freebsdlike,
1057    linux_like,
1058    target_os = "fuchsia",
1059    target_os = "openbsd"
1060))]
1061#[inline]
1062#[doc(alias = "IP_ADD_MEMBERSHIP")]
1063pub fn set_ip_add_membership_with_ifindex<Fd: AsFd>(
1064    fd: Fd,
1065    multiaddr: &Ipv4Addr,
1066    address: &Ipv4Addr,
1067    ifindex: u32,
1068) -> io::Result<()> {
1069    backend::net::sockopt::set_ip_add_membership_with_ifindex(
1070        fd.as_fd(),
1071        multiaddr,
1072        address,
1073        ifindex,
1074    )
1075}
1076
1077/// `setsockopt(fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, value)`
1078///
1079/// See the [module-level documentation] for more.
1080///
1081/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
1082#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))]
1083#[inline]
1084#[doc(alias = "IP_ADD_SOURCE_MEMBERSHIP")]
1085pub fn set_ip_add_source_membership<Fd: AsFd>(
1086    fd: Fd,
1087    multiaddr: &Ipv4Addr,
1088    interface: &Ipv4Addr,
1089    sourceaddr: &Ipv4Addr,
1090) -> io::Result<()> {
1091    backend::net::sockopt::set_ip_add_source_membership(
1092        fd.as_fd(),
1093        multiaddr,
1094        interface,
1095        sourceaddr,
1096    )
1097}
1098
1099/// `setsockopt(fd, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, value)`
1100///
1101/// See the [module-level documentation] for more.
1102///
1103/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
1104#[cfg(any(apple, freebsdlike, linux_like, solarish, target_os = "aix"))]
1105#[inline]
1106#[doc(alias = "IP_DROP_SOURCE_MEMBERSHIP")]
1107pub fn set_ip_drop_source_membership<Fd: AsFd>(
1108    fd: Fd,
1109    multiaddr: &Ipv4Addr,
1110    interface: &Ipv4Addr,
1111    sourceaddr: &Ipv4Addr,
1112) -> io::Result<()> {
1113    backend::net::sockopt::set_ip_drop_source_membership(
1114        fd.as_fd(),
1115        multiaddr,
1116        interface,
1117        sourceaddr,
1118    )
1119}
1120
1121/// `setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, multiaddr, interface)`
1122///
1123/// See the [module-level documentation] for more.
1124///
1125/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1126#[inline]
1127#[doc(alias = "IPV6_JOIN_GROUP")]
1128#[doc(alias = "IPV6_ADD_MEMBERSHIP")]
1129pub fn set_ipv6_add_membership<Fd: AsFd>(
1130    fd: Fd,
1131    multiaddr: &Ipv6Addr,
1132    interface: u32,
1133) -> io::Result<()> {
1134    backend::net::sockopt::set_ipv6_add_membership(fd.as_fd(), multiaddr, interface)
1135}
1136
1137/// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)`
1138///
1139/// This is similar to [`set_ip_drop_membership`] but always sets `ifindex`
1140/// value to zero.
1141///
1142/// See the [module-level documentation] for more.
1143///
1144/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
1145#[inline]
1146#[doc(alias = "IP_DROP_MEMBERSHIP")]
1147pub fn set_ip_drop_membership<Fd: AsFd>(
1148    fd: Fd,
1149    multiaddr: &Ipv4Addr,
1150    interface: &Ipv4Addr,
1151) -> io::Result<()> {
1152    backend::net::sockopt::set_ip_drop_membership(fd.as_fd(), multiaddr, interface)
1153}
1154
1155/// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)`
1156///
1157/// This is similar to [`set_ip_drop_membership_with_ifindex`] but additionally
1158/// allows a `ifindex` value to be given.
1159///
1160/// See the [module-level documentation] for more.
1161///
1162/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
1163#[cfg(any(
1164    apple,
1165    freebsdlike,
1166    linux_like,
1167    target_os = "fuchsia",
1168    target_os = "openbsd"
1169))]
1170#[inline]
1171#[doc(alias = "IP_DROP_MEMBERSHIP")]
1172pub fn set_ip_drop_membership_with_ifindex<Fd: AsFd>(
1173    fd: Fd,
1174    multiaddr: &Ipv4Addr,
1175    address: &Ipv4Addr,
1176    ifindex: u32,
1177) -> io::Result<()> {
1178    backend::net::sockopt::set_ip_drop_membership_with_ifindex(
1179        fd.as_fd(),
1180        multiaddr,
1181        address,
1182        ifindex,
1183    )
1184}
1185
1186/// `setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, multiaddr, interface)`
1187///
1188/// See the [module-level documentation] for more.
1189///
1190/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1191#[inline]
1192#[doc(alias = "IPV6_LEAVE_GROUP")]
1193#[doc(alias = "IPV6_DROP_MEMBERSHIP")]
1194pub fn set_ipv6_drop_membership<Fd: AsFd>(
1195    fd: Fd,
1196    multiaddr: &Ipv6Addr,
1197    interface: u32,
1198) -> io::Result<()> {
1199    backend::net::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface)
1200}
1201
1202/// `setsockopt(fd, IPPROTO_IP, IP_TOS, value)`
1203///
1204/// See the [module-level documentation] for more.
1205///
1206/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
1207#[cfg(any(
1208    bsd,
1209    linux_like,
1210    target_os = "aix",
1211    target_os = "fuchsia",
1212    target_os = "haiku",
1213    target_os = "nto",
1214    target_env = "newlib"
1215))]
1216#[inline]
1217#[doc(alias = "IP_TOS")]
1218pub fn set_ip_tos<Fd: AsFd>(fd: Fd, value: u8) -> io::Result<()> {
1219    backend::net::sockopt::set_ip_tos(fd.as_fd(), value)
1220}
1221
1222/// `getsockopt(fd, IPPROTO_IP, IP_TOS)`
1223///
1224/// See the [module-level documentation] for more.
1225///
1226/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
1227#[cfg(any(
1228    bsd,
1229    linux_like,
1230    target_os = "aix",
1231    target_os = "fuchsia",
1232    target_os = "haiku",
1233    target_os = "nto",
1234    target_env = "newlib"
1235))]
1236#[inline]
1237#[doc(alias = "IP_TOS")]
1238pub fn ip_tos<Fd: AsFd>(fd: Fd) -> io::Result<u8> {
1239    backend::net::sockopt::ip_tos(fd.as_fd())
1240}
1241
1242/// `setsockopt(fd, IPPROTO_IP, IP_RECVTOS, value)`
1243///
1244/// See the [module-level documentation] for more.
1245///
1246/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
1247#[cfg(any(
1248    apple,
1249    linux_like,
1250    target_os = "cygwin",
1251    target_os = "freebsd",
1252    target_os = "fuchsia",
1253))]
1254#[inline]
1255#[doc(alias = "IP_RECVTOS")]
1256pub fn set_ip_recvtos<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1257    backend::net::sockopt::set_ip_recvtos(fd.as_fd(), value)
1258}
1259
1260/// `getsockopt(fd, IPPROTO_IP, IP_RECVTOS)`
1261///
1262/// See the [module-level documentation] for more.
1263///
1264/// [module-level documentation]: self#references-for-get_ip_-and-set_ip_-functions
1265#[cfg(any(
1266    apple,
1267    linux_like,
1268    target_os = "cygwin",
1269    target_os = "freebsd",
1270    target_os = "fuchsia",
1271))]
1272#[inline]
1273#[doc(alias = "IP_RECVTOS")]
1274pub fn ip_recvtos<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1275    backend::net::sockopt::ip_recvtos(fd.as_fd())
1276}
1277
1278/// `setsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS, value)`
1279///
1280/// See the [module-level documentation] for more.
1281///
1282/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1283#[cfg(any(
1284    bsd,
1285    linux_like,
1286    target_os = "aix",
1287    target_os = "fuchsia",
1288    target_os = "nto"
1289))]
1290#[inline]
1291#[doc(alias = "IPV6_RECVTCLASS")]
1292pub fn set_ipv6_recvtclass<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1293    backend::net::sockopt::set_ipv6_recvtclass(fd.as_fd(), value)
1294}
1295
1296/// `getsockopt(fd, IPPROTO_IPV6, IPV6_RECVTCLASS)`
1297///
1298/// See the [module-level documentation] for more.
1299///
1300/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1301#[cfg(any(
1302    bsd,
1303    linux_like,
1304    target_os = "aix",
1305    target_os = "fuchsia",
1306    target_os = "nto"
1307))]
1308#[inline]
1309#[doc(alias = "IPV6_RECVTCLASS")]
1310pub fn ipv6_recvtclass<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1311    backend::net::sockopt::ipv6_recvtclass(fd.as_fd())
1312}
1313
1314/// `setsockopt(fd, IPPROTO_IP, IP_FREEBIND, value)`
1315///
1316/// See the [module-level documentation] for more.
1317///
1318/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1319#[cfg(any(linux_kernel, target_os = "fuchsia"))]
1320#[inline]
1321#[doc(alias = "IP_FREEBIND")]
1322pub fn set_ip_freebind<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1323    backend::net::sockopt::set_ip_freebind(fd.as_fd(), value)
1324}
1325
1326/// `getsockopt(fd, IPPROTO_IP, IP_FREEBIND)`
1327///
1328/// See the [module-level documentation] for more.
1329///
1330/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1331#[cfg(any(linux_kernel, target_os = "fuchsia"))]
1332#[inline]
1333#[doc(alias = "IP_FREEBIND")]
1334pub fn ip_freebind<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1335    backend::net::sockopt::ip_freebind(fd.as_fd())
1336}
1337
1338/// `setsockopt(fd, IPPROTO_IPV6, IPV6_FREEBIND, value)`
1339///
1340/// See the [module-level documentation] for more.
1341///
1342/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1343#[cfg(linux_kernel)]
1344#[inline]
1345#[doc(alias = "IPV6_FREEBIND")]
1346pub fn set_ipv6_freebind<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1347    backend::net::sockopt::set_ipv6_freebind(fd.as_fd(), value)
1348}
1349
1350/// `getsockopt(fd, IPPROTO_IPV6, IPV6_FREEBIND)`
1351///
1352/// See the [module-level documentation] for more.
1353///
1354/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1355#[cfg(linux_kernel)]
1356#[inline]
1357#[doc(alias = "IPV6_FREEBIND")]
1358pub fn ipv6_freebind<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1359    backend::net::sockopt::ipv6_freebind(fd.as_fd())
1360}
1361
1362/// `getsockopt(fd, IPPROTO_IP, SO_ORIGINAL_DST)`
1363///
1364/// Even though this corresponds to a `SO_*` constant, it is an `IPPROTO_IP`
1365/// option.
1366///
1367/// See the [module-level documentation] for more.
1368///
1369/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1370#[cfg(any(linux_kernel, target_os = "fuchsia"))]
1371#[inline]
1372#[doc(alias = "SO_ORIGINAL_DST")]
1373pub fn ip_original_dst<Fd: AsFd>(fd: Fd) -> io::Result<SocketAddrV4> {
1374    backend::net::sockopt::ip_original_dst(fd.as_fd())
1375}
1376
1377/// `getsockopt(fd, IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST)`
1378///
1379/// Even though this corresponds to a `IP6T_*` constant, it is an
1380/// `IPPROTO_IPV6` option.
1381///
1382/// See the [module-level documentation] for more.
1383///
1384/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1385#[cfg(linux_kernel)]
1386#[inline]
1387#[doc(alias = "IP6T_SO_ORIGINAL_DST")]
1388pub fn ipv6_original_dst<Fd: AsFd>(fd: Fd) -> io::Result<SocketAddrV6> {
1389    backend::net::sockopt::ipv6_original_dst(fd.as_fd())
1390}
1391
1392/// `setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, value)`
1393///
1394/// See the [module-level documentation] for more.
1395///
1396/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1397#[cfg(not(any(
1398    solarish,
1399    windows,
1400    target_os = "espidf",
1401    target_os = "haiku",
1402    target_os = "horizon",
1403    target_os = "redox",
1404    target_os = "vita"
1405)))]
1406#[inline]
1407#[doc(alias = "IPV6_TCLASS")]
1408pub fn set_ipv6_tclass<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1409    backend::net::sockopt::set_ipv6_tclass(fd.as_fd(), value)
1410}
1411
1412/// `getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS)`
1413///
1414/// See the [module-level documentation] for more.
1415///
1416/// [module-level documentation]: self#references-for-get_ipv6_-and-set_ipv6_-functions
1417#[cfg(not(any(
1418    solarish,
1419    windows,
1420    target_os = "espidf",
1421    target_os = "haiku",
1422    target_os = "horizon",
1423    target_os = "redox",
1424    target_os = "vita"
1425)))]
1426#[inline]
1427#[doc(alias = "IPV6_TCLASS")]
1428pub fn ipv6_tclass<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
1429    backend::net::sockopt::ipv6_tclass(fd.as_fd())
1430}
1431
1432/// `setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, value)`
1433///
1434/// See the [module-level documentation] for more.
1435///
1436/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1437#[inline]
1438#[doc(alias = "TCP_NODELAY")]
1439pub fn set_tcp_nodelay<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1440    backend::net::sockopt::set_tcp_nodelay(fd.as_fd(), value)
1441}
1442
1443/// `getsockopt(fd, IPPROTO_TCP, TCP_NODELAY)`
1444///
1445/// See the [module-level documentation] for more.
1446///
1447/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1448#[inline]
1449#[doc(alias = "TCP_NODELAY")]
1450pub fn tcp_nodelay<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1451    backend::net::sockopt::tcp_nodelay(fd.as_fd())
1452}
1453
1454/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, value)`
1455///
1456/// See the [module-level documentation] for more.
1457///
1458/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1459#[cfg(not(any(
1460    target_os = "haiku",
1461    target_os = "nto",
1462    target_os = "openbsd",
1463    target_os = "redox"
1464)))]
1465#[inline]
1466#[doc(alias = "TCP_KEEPCNT")]
1467pub fn set_tcp_keepcnt<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1468    backend::net::sockopt::set_tcp_keepcnt(fd.as_fd(), value)
1469}
1470
1471/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT)`
1472///
1473/// See the [module-level documentation] for more.
1474///
1475/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1476#[cfg(not(any(
1477    target_os = "haiku",
1478    target_os = "nto",
1479    target_os = "openbsd",
1480    target_os = "redox"
1481)))]
1482#[inline]
1483#[doc(alias = "TCP_KEEPCNT")]
1484pub fn tcp_keepcnt<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
1485    backend::net::sockopt::tcp_keepcnt(fd.as_fd())
1486}
1487
1488/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, value)`
1489///
1490/// `TCP_KEEPALIVE` on Apple platforms.
1491///
1492/// See the [module-level documentation] for more.
1493///
1494/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1495#[cfg(not(any(target_os = "haiku", target_os = "nto", target_os = "openbsd")))]
1496#[inline]
1497#[doc(alias = "TCP_KEEPIDLE")]
1498pub fn set_tcp_keepidle<Fd: AsFd>(fd: Fd, value: Duration) -> io::Result<()> {
1499    backend::net::sockopt::set_tcp_keepidle(fd.as_fd(), value)
1500}
1501
1502/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE)`
1503///
1504/// `TCP_KEEPALIVE` on Apple platforms.
1505///
1506/// See the [module-level documentation] for more.
1507///
1508/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1509#[cfg(not(any(target_os = "haiku", target_os = "nto", target_os = "openbsd")))]
1510#[inline]
1511#[doc(alias = "TCP_KEEPIDLE")]
1512pub fn tcp_keepidle<Fd: AsFd>(fd: Fd) -> io::Result<Duration> {
1513    backend::net::sockopt::tcp_keepidle(fd.as_fd())
1514}
1515
1516/// `setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, value)`
1517///
1518/// See the [module-level documentation] for more.
1519///
1520/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1521#[cfg(not(any(
1522    target_os = "haiku",
1523    target_os = "nto",
1524    target_os = "openbsd",
1525    target_os = "redox"
1526)))]
1527#[inline]
1528#[doc(alias = "TCP_KEEPINTVL")]
1529pub fn set_tcp_keepintvl<Fd: AsFd>(fd: Fd, value: Duration) -> io::Result<()> {
1530    backend::net::sockopt::set_tcp_keepintvl(fd.as_fd(), value)
1531}
1532
1533/// `getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL)`
1534///
1535/// See the [module-level documentation] for more.
1536///
1537/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1538#[cfg(not(any(
1539    target_os = "haiku",
1540    target_os = "nto",
1541    target_os = "openbsd",
1542    target_os = "redox"
1543)))]
1544#[inline]
1545#[doc(alias = "TCP_KEEPINTVL")]
1546pub fn tcp_keepintvl<Fd: AsFd>(fd: Fd) -> io::Result<Duration> {
1547    backend::net::sockopt::tcp_keepintvl(fd.as_fd())
1548}
1549
1550/// `setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, value)`
1551///
1552/// See the [module-level documentation] for more.
1553///
1554/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1555#[cfg(any(linux_like, target_os = "fuchsia"))]
1556#[inline]
1557#[doc(alias = "TCP_USER_TIMEOUT")]
1558pub fn set_tcp_user_timeout<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1559    backend::net::sockopt::set_tcp_user_timeout(fd.as_fd(), value)
1560}
1561
1562/// `getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT)`
1563///
1564/// See the [module-level documentation] for more.
1565///
1566/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1567#[cfg(any(linux_like, target_os = "fuchsia"))]
1568#[inline]
1569#[doc(alias = "TCP_USER_TIMEOUT")]
1570pub fn tcp_user_timeout<Fd: AsFd>(fd: Fd) -> io::Result<u32> {
1571    backend::net::sockopt::tcp_user_timeout(fd.as_fd())
1572}
1573
1574/// `setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, value)`
1575///
1576/// See the [module-level documentation] for more.
1577///
1578/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1579#[cfg(any(linux_like, target_os = "fuchsia"))]
1580#[inline]
1581#[doc(alias = "TCP_QUICKACK")]
1582pub fn set_tcp_quickack<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1583    backend::net::sockopt::set_tcp_quickack(fd.as_fd(), value)
1584}
1585
1586/// `getsockopt(fd, IPPROTO_TCP, TCP_QUICKACK)`
1587///
1588/// See the [module-level documentation] for more.
1589///
1590/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1591#[cfg(any(linux_like, target_os = "fuchsia"))]
1592#[inline]
1593#[doc(alias = "TCP_QUICKACK")]
1594pub fn tcp_quickack<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1595    backend::net::sockopt::tcp_quickack(fd.as_fd())
1596}
1597
1598/// `setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, value)`
1599///
1600/// See the [module-level documentation] for more.
1601///
1602/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1603#[cfg(any(
1604    linux_like,
1605    target_os = "freebsd",
1606    target_os = "fuchsia",
1607    target_os = "illumos"
1608))]
1609#[inline]
1610#[doc(alias = "TCP_CONGESTION")]
1611pub fn set_tcp_congestion<Fd: AsFd>(fd: Fd, value: &str) -> io::Result<()> {
1612    backend::net::sockopt::set_tcp_congestion(fd.as_fd(), value)
1613}
1614
1615/// `getsockopt(fd, IPPROTO_TCP, TCP_CONGESTION)`
1616///
1617/// See the [module-level documentation] for more.
1618///
1619/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1620#[cfg(feature = "alloc")]
1621#[cfg(any(
1622    linux_like,
1623    target_os = "freebsd",
1624    target_os = "fuchsia",
1625    target_os = "illumos"
1626))]
1627#[inline]
1628#[doc(alias = "TCP_CONGESTION")]
1629#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
1630pub fn tcp_congestion<Fd: AsFd>(fd: Fd) -> io::Result<String> {
1631    backend::net::sockopt::tcp_congestion(fd.as_fd())
1632}
1633
1634/// `setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, value)`
1635///
1636/// See the [module-level documentation] for more.
1637///
1638/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1639#[cfg(any(linux_like, target_os = "fuchsia"))]
1640#[inline]
1641#[doc(alias = "TCP_THIN_LINEAR_TIMEOUTS")]
1642pub fn set_tcp_thin_linear_timeouts<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1643    backend::net::sockopt::set_tcp_thin_linear_timeouts(fd.as_fd(), value)
1644}
1645
1646/// `getsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS)`
1647///
1648/// See the [module-level documentation] for more.
1649///
1650/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1651#[cfg(any(linux_like, target_os = "fuchsia"))]
1652#[inline]
1653#[doc(alias = "TCP_THIN_LINEAR_TIMEOUTS")]
1654pub fn tcp_thin_linear_timeouts<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1655    backend::net::sockopt::tcp_thin_linear_timeouts(fd.as_fd())
1656}
1657
1658/// `setsockopt(fd, IPPROTO_TCP, TCP_CORK, value)`
1659///
1660/// See the [module-level documentation] for more.
1661///
1662/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1663#[cfg(any(linux_like, solarish, target_os = "fuchsia"))]
1664#[inline]
1665#[doc(alias = "TCP_CORK")]
1666pub fn set_tcp_cork<Fd: AsFd>(fd: Fd, value: bool) -> io::Result<()> {
1667    backend::net::sockopt::set_tcp_cork(fd.as_fd(), value)
1668}
1669
1670/// `getsockopt(fd, IPPROTO_TCP, TCP_CORK)`
1671///
1672/// See the [module-level documentation] for more.
1673///
1674/// [module-level documentation]: self#references-for-get_tcp_-and-set_tcp_-functions
1675#[cfg(any(linux_like, solarish, target_os = "fuchsia"))]
1676#[inline]
1677#[doc(alias = "TCP_CORK")]
1678pub fn tcp_cork<Fd: AsFd>(fd: Fd) -> io::Result<bool> {
1679    backend::net::sockopt::tcp_cork(fd.as_fd())
1680}
1681
1682/// `getsockopt(fd, SOL_SOCKET, SO_PEERCRED)`—Get credentials of Unix domain
1683/// socket peer process.
1684///
1685/// # References
1686///  - [Linux `unix`]
1687///
1688/// [Linux `unix`]: https://man7.org/linux/man-pages/man7/unix.7.html
1689#[cfg(linux_kernel)]
1690#[doc(alias = "SO_PEERCRED")]
1691pub fn socket_peercred<Fd: AsFd>(fd: Fd) -> io::Result<super::UCred> {
1692    backend::net::sockopt::socket_peercred(fd.as_fd())
1693}
1694
1695/// `getsockopt(fd, SOL_SOCKET, SO_TXTIME)` — Get transmission timing configuration.
1696#[cfg(all(target_os = "linux", feature = "time"))]
1697#[doc(alias = "SO_TXTIME")]
1698pub fn get_txtime<Fd: AsFd>(fd: Fd) -> io::Result<(ClockId, TxTimeFlags)> {
1699    backend::net::sockopt::get_txtime(fd.as_fd())
1700}
1701
1702/// `setsockopt(fd, SOL_SOCKET, SO_TXTIME)` — Configure transmission timing.
1703#[cfg(all(target_os = "linux", feature = "time"))]
1704#[doc(alias = "SO_TXTIME")]
1705pub fn set_txtime<Fd: AsFd>(fd: Fd, clockid: ClockId, flags: TxTimeFlags) -> io::Result<()> {
1706    backend::net::sockopt::set_txtime(fd.as_fd(), clockid, flags)
1707}
1708
1709/// `setsockopt(fd, SOL_XDP, XDP_UMEM_REG, value)`
1710///
1711/// On kernel versions only supporting v1, the flags are ignored.
1712///
1713/// # References
1714///   - [Linux]
1715///
1716/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-umem-reg-setsockopt
1717#[cfg(target_os = "linux")]
1718#[doc(alias = "XDP_UMEM_REG")]
1719pub fn set_xdp_umem_reg<Fd: AsFd>(fd: Fd, value: XdpUmemReg) -> io::Result<()> {
1720    backend::net::sockopt::set_xdp_umem_reg(fd.as_fd(), value)
1721}
1722
1723/// `setsockopt(fd, SOL_XDP, XDP_UMEM_FILL_RING, value)`
1724///
1725/// # References
1726///   - [Linux]
1727///
1728/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts
1729#[cfg(target_os = "linux")]
1730#[doc(alias = "XDP_UMEM_FILL_RING")]
1731pub fn set_xdp_umem_fill_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1732    backend::net::sockopt::set_xdp_umem_fill_ring_size(fd.as_fd(), value)
1733}
1734
1735/// `setsockopt(fd, SOL_XDP, XDP_UMEM_COMPLETION_RING, value)`
1736///
1737/// # References
1738///   - [Linux]
1739///
1740/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts
1741#[cfg(target_os = "linux")]
1742#[doc(alias = "XDP_UMEM_COMPLETION_RING")]
1743pub fn set_xdp_umem_completion_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1744    backend::net::sockopt::set_xdp_umem_completion_ring_size(fd.as_fd(), value)
1745}
1746
1747/// `setsockopt(fd, SOL_XDP, XDP_TX_RING, value)`
1748///
1749/// # References
1750///   - [Linux]
1751///
1752/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts
1753#[cfg(target_os = "linux")]
1754#[doc(alias = "XDP_TX_RING")]
1755pub fn set_xdp_tx_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1756    backend::net::sockopt::set_xdp_tx_ring_size(fd.as_fd(), value)
1757}
1758
1759/// `setsockopt(fd, SOL_XDP, XDP_RX_RING, value)`
1760///
1761/// # References
1762///   - [Linux]
1763///
1764/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-rx-tx-umem-fill-umem-completion-ring-setsockopts
1765#[cfg(target_os = "linux")]
1766#[doc(alias = "XDP_RX_RING")]
1767pub fn set_xdp_rx_ring_size<Fd: AsFd>(fd: Fd, value: u32) -> io::Result<()> {
1768    backend::net::sockopt::set_xdp_rx_ring_size(fd.as_fd(), value)
1769}
1770
1771/// `getsockopt(fd, SOL_XDP, XDP_MMAP_OFFSETS)`
1772///
1773/// # References
1774///   - [Linux]
1775///
1776/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html
1777#[cfg(linux_raw_dep)]
1778#[doc(alias = "XDP_MMAP_OFFSETS")]
1779pub fn xdp_mmap_offsets<Fd: AsFd>(fd: Fd) -> io::Result<XdpMmapOffsets> {
1780    backend::net::sockopt::xdp_mmap_offsets(fd.as_fd())
1781}
1782
1783/// `getsockopt(fd, SOL_XDP, XDP_STATISTICS)`
1784///
1785/// # References
1786///   - [Linux]
1787///
1788/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-statistics-getsockopt
1789#[cfg(linux_raw_dep)]
1790#[doc(alias = "XDP_STATISTICS")]
1791pub fn xdp_statistics<Fd: AsFd>(fd: Fd) -> io::Result<XdpStatistics> {
1792    backend::net::sockopt::xdp_statistics(fd.as_fd())
1793}
1794
1795/// `getsockopt(fd, SOL_XDP, XDP_OPTIONS)`
1796///
1797/// # References
1798///   - [Linux]
1799///
1800/// [Linux]: https://www.kernel.org/doc/html/next/networking/af_xdp.html#xdp-options-getsockopt
1801#[cfg(target_os = "linux")]
1802#[doc(alias = "XDP_OPTIONS")]
1803pub fn xdp_options<Fd: AsFd>(fd: Fd) -> io::Result<XdpOptionsFlags> {
1804    backend::net::sockopt::xdp_options(fd.as_fd())
1805}
1806
1807#[cfg(test)]
1808mod tests {
1809    use super::*;
1810
1811    #[test]
1812    fn test_sizes() {
1813        use c::c_int;
1814
1815        // Backend code needs to cast these to `c_int` so make sure that cast
1816        // isn't lossy.
1817        assert_eq_size!(Timeout, c_int);
1818    }
1819}