1 use crate::fd::OwnedFd;
2 use crate::net::{SocketAddr, SocketAddrAny, SocketAddrV4, SocketAddrV6};
3 use crate::{backend, io};
4 use backend::fd::{AsFd, BorrowedFd};
5 
6 #[cfg(target_os = "linux")]
7 use crate::net::xdp::SocketAddrXdp;
8 pub use crate::net::{AddressFamily, Protocol, Shutdown, SocketFlags, SocketType};
9 #[cfg(unix)]
10 pub use backend::net::addr::SocketAddrUnix;
11 
12 /// `socket(domain, type_, protocol)`—Creates a socket.
13 ///
14 /// POSIX guarantees that `socket` will use the lowest unused file descriptor,
15 /// however it is not safe in general to rely on this, as file descriptors may
16 /// be unexpectedly allocated on other threads or in libraries.
17 ///
18 /// To pass extra flags such as [`SocketFlags::CLOEXEC`] or
19 /// [`SocketFlags::NONBLOCK`], use [`socket_with`].
20 ///
21 /// # References
22 ///  - [Beej's Guide to Network Programming]
23 ///  - [POSIX]
24 ///  - [Linux]
25 ///  - [Apple]
26 ///  - [Winsock]
27 ///  - [FreeBSD]
28 ///  - [NetBSD]
29 ///  - [OpenBSD]
30 ///  - [DragonFly BSD]
31 ///  - [illumos]
32 ///  - [glibc]
33 ///
34 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#socket
35 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html
36 /// [Linux]: https://man7.org/linux/man-pages/man2/socket.2.html
37 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socket.2.html
38 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
39 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2
40 /// [NetBSD]: https://man.netbsd.org/socket.2
41 /// [OpenBSD]: https://man.openbsd.org/socket.2
42 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socket&section=2
43 /// [illumos]: https://illumos.org/man/3SOCKET/socket
44 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Creating-a-Socket.html
45 #[inline]
socket( domain: AddressFamily, type_: SocketType, protocol: Option<Protocol>, ) -> io::Result<OwnedFd>46 pub fn socket(
47     domain: AddressFamily,
48     type_: SocketType,
49     protocol: Option<Protocol>,
50 ) -> io::Result<OwnedFd> {
51     backend::net::syscalls::socket(domain, type_, protocol)
52 }
53 
54 /// `socket_with(domain, type_ | flags, protocol)`—Creates a socket, with
55 /// flags.
56 ///
57 /// POSIX guarantees that `socket` will use the lowest unused file descriptor,
58 /// however it is not safe in general to rely on this, as file descriptors may
59 /// be unexpectedly allocated on other threads or in libraries.
60 ///
61 /// `socket_with` is the same as [`socket`] but adds an additional flags
62 /// operand.
63 ///
64 /// # References
65 ///  - [Beej's Guide to Network Programming]
66 ///  - [POSIX]
67 ///  - [Linux]
68 ///  - [Apple]
69 ///  - [Winsock]
70 ///  - [FreeBSD]
71 ///  - [NetBSD]
72 ///  - [OpenBSD]
73 ///  - [DragonFly BSD]
74 ///  - [illumos]
75 ///  - [glibc]
76 ///
77 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#socket
78 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html
79 /// [Linux]: https://man7.org/linux/man-pages/man2/socket.2.html
80 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socket.2.html
81 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
82 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2
83 /// [NetBSD]: https://man.netbsd.org/socket.2
84 /// [OpenBSD]: https://man.openbsd.org/socket.2
85 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socket&section=2
86 /// [illumos]: https://illumos.org/man/3SOCKET/socket
87 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Creating-a-Socket.html
88 #[doc(alias("socket"))]
89 #[inline]
socket_with( domain: AddressFamily, type_: SocketType, flags: SocketFlags, protocol: Option<Protocol>, ) -> io::Result<OwnedFd>90 pub fn socket_with(
91     domain: AddressFamily,
92     type_: SocketType,
93     flags: SocketFlags,
94     protocol: Option<Protocol>,
95 ) -> io::Result<OwnedFd> {
96     backend::net::syscalls::socket_with(domain, type_, flags, protocol)
97 }
98 
99 /// `bind(sockfd, addr)`—Binds a socket to an IP address.
100 ///
101 /// # References
102 ///  - [Beej's Guide to Network Programming]
103 ///  - [POSIX]
104 ///  - [Linux]
105 ///  - [Apple]
106 ///  - [Winsock]
107 ///  - [FreeBSD]
108 ///  - [NetBSD]
109 ///  - [OpenBSD]
110 ///  - [DragonFly BSD]
111 ///  - [illumos]
112 ///  - [glibc]
113 ///
114 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind
115 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
116 /// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
117 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html
118 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind
119 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2
120 /// [NetBSD]: https://man.netbsd.org/bind.2
121 /// [OpenBSD]: https://man.openbsd.org/bind.2
122 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind&section=2
123 /// [illumos]: https://illumos.org/man/3SOCKET/bind
124 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Setting-Address.html
bind<Fd: AsFd>(sockfd: Fd, addr: &SocketAddr) -> io::Result<()>125 pub fn bind<Fd: AsFd>(sockfd: Fd, addr: &SocketAddr) -> io::Result<()> {
126     _bind(sockfd.as_fd(), addr)
127 }
128 
_bind(sockfd: BorrowedFd<'_>, addr: &SocketAddr) -> io::Result<()>129 fn _bind(sockfd: BorrowedFd<'_>, addr: &SocketAddr) -> io::Result<()> {
130     match addr {
131         SocketAddr::V4(v4) => backend::net::syscalls::bind_v4(sockfd, v4),
132         SocketAddr::V6(v6) => backend::net::syscalls::bind_v6(sockfd, v6),
133     }
134 }
135 
136 /// `bind(sockfd, addr)`—Binds a socket to an address.
137 ///
138 /// # References
139 ///  - [Beej's Guide to Network Programming]
140 ///  - [POSIX]
141 ///  - [Linux]
142 ///  - [Apple]
143 ///  - [Winsock]
144 ///  - [FreeBSD]
145 ///  - [NetBSD]
146 ///  - [OpenBSD]
147 ///  - [DragonFly BSD]
148 ///  - [illumos]
149 ///  - [glibc]
150 ///
151 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind
152 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
153 /// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
154 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html
155 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind
156 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2
157 /// [NetBSD]: https://man.netbsd.org/bind.2
158 /// [OpenBSD]: https://man.openbsd.org/bind.2
159 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind&section=2
160 /// [illumos]: https://illumos.org/man/3SOCKET/bind
161 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Setting-Address.html
162 #[doc(alias = "bind")]
bind_any<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrAny) -> io::Result<()>163 pub fn bind_any<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrAny) -> io::Result<()> {
164     _bind_any(sockfd.as_fd(), addr)
165 }
166 
_bind_any(sockfd: BorrowedFd<'_>, addr: &SocketAddrAny) -> io::Result<()>167 fn _bind_any(sockfd: BorrowedFd<'_>, addr: &SocketAddrAny) -> io::Result<()> {
168     match addr {
169         SocketAddrAny::V4(v4) => backend::net::syscalls::bind_v4(sockfd, v4),
170         SocketAddrAny::V6(v6) => backend::net::syscalls::bind_v6(sockfd, v6),
171         #[cfg(unix)]
172         SocketAddrAny::Unix(unix) => backend::net::syscalls::bind_unix(sockfd, unix),
173         #[cfg(target_os = "linux")]
174         SocketAddrAny::Xdp(xdp) => backend::net::syscalls::bind_xdp(sockfd, xdp),
175     }
176 }
177 
178 /// `bind(sockfd, addr, sizeof(struct sockaddr_in))`—Binds a socket to an
179 /// IPv4 address.
180 ///
181 /// # References
182 ///  - [Beej's Guide to Network Programming]
183 ///  - [POSIX]
184 ///  - [Linux]
185 ///  - [Apple]
186 ///  - [Winsock]
187 ///  - [FreeBSD]
188 ///  - [NetBSD]
189 ///  - [OpenBSD]
190 ///  - [DragonFly BSD]
191 ///  - [illumos]
192 ///  - [glibc]
193 ///
194 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind
195 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
196 /// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
197 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html
198 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind
199 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2
200 /// [NetBSD]: https://man.netbsd.org/bind.2
201 /// [OpenBSD]: https://man.openbsd.org/bind.2
202 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind&section=2
203 /// [illumos]: https://illumos.org/man/3SOCKET/bind
204 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Setting-Address.html
205 #[inline]
206 #[doc(alias = "bind")]
bind_v4<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV4) -> io::Result<()>207 pub fn bind_v4<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV4) -> io::Result<()> {
208     backend::net::syscalls::bind_v4(sockfd.as_fd(), addr)
209 }
210 
211 /// `bind(sockfd, addr, sizeof(struct sockaddr_in6))`—Binds a socket to an
212 /// IPv6 address.
213 ///
214 /// # References
215 ///  - [Beej's Guide to Network Programming]
216 ///  - [POSIX]
217 ///  - [Linux]
218 ///  - [Apple]
219 ///  - [Winsock]
220 ///  - [FreeBSD]
221 ///  - [NetBSD]
222 ///  - [OpenBSD]
223 ///  - [DragonFly BSD]
224 ///  - [illumos]
225 ///  - [glibc]
226 ///
227 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind
228 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
229 /// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
230 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html
231 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind
232 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2
233 /// [NetBSD]: https://man.netbsd.org/bind.2
234 /// [OpenBSD]: https://man.openbsd.org/bind.2
235 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind&section=2
236 /// [illumos]: https://illumos.org/man/3SOCKET/bind
237 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Setting-Address.html
238 #[inline]
239 #[doc(alias = "bind")]
bind_v6<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV6) -> io::Result<()>240 pub fn bind_v6<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV6) -> io::Result<()> {
241     backend::net::syscalls::bind_v6(sockfd.as_fd(), addr)
242 }
243 
244 /// `bind(sockfd, addr, sizeof(struct sockaddr_un))`—Binds a socket to a
245 /// Unix-domain address.
246 ///
247 /// # References
248 ///  - [Beej's Guide to Network Programming]
249 ///  - [POSIX]
250 ///  - [Linux]
251 ///  - [Apple]
252 ///  - [Winsock]
253 ///  - [FreeBSD]
254 ///  - [NetBSD]
255 ///  - [OpenBSD]
256 ///  - [DragonFly BSD]
257 ///  - [illumos]
258 ///  - [glibc]
259 ///
260 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind
261 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html
262 /// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
263 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html
264 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind
265 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2
266 /// [NetBSD]: https://man.netbsd.org/bind.2
267 /// [OpenBSD]: https://man.openbsd.org/bind.2
268 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind&section=2
269 /// [illumos]: https://illumos.org/man/3SOCKET/bind
270 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Setting-Address.html
271 #[cfg(unix)]
272 #[inline]
273 #[doc(alias = "bind")]
bind_unix<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrUnix) -> io::Result<()>274 pub fn bind_unix<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrUnix) -> io::Result<()> {
275     backend::net::syscalls::bind_unix(sockfd.as_fd(), addr)
276 }
277 
278 /// `bind(sockfd, addr, sizeof(struct sockaddr_un))`—Binds a socket to a XDP address.
279 ///
280 /// # References
281 ///  - [Linux]
282 ///
283 /// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
284 #[cfg(target_os = "linux")]
285 #[inline]
286 #[doc(alias = "bind")]
bind_xdp<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrXdp) -> io::Result<()>287 pub fn bind_xdp<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrXdp) -> io::Result<()> {
288     backend::net::syscalls::bind_xdp(sockfd.as_fd(), addr)
289 }
290 
291 /// `connect(sockfd, addr)`—Initiates a connection to an IP address.
292 ///
293 /// On Windows, a non-blocking socket returns [`Errno::WOULDBLOCK`] if the
294 /// connection cannot be completed immediately, rather than
295 /// `Errno::INPROGRESS`.
296 ///
297 /// # References
298 ///  - [Beej's Guide to Network Programming]
299 ///  - [POSIX]
300 ///  - [Linux]
301 ///  - [Apple]
302 ///  - [Winsock]
303 ///  - [FreeBSD]
304 ///  - [NetBSD]
305 ///  - [OpenBSD]
306 ///  - [DragonFly BSD]
307 ///  - [illumos]
308 ///  - [glibc]
309 ///
310 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
311 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
312 /// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
313 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
314 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
315 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
316 /// [NetBSD]: https://man.netbsd.org/connect.2
317 /// [OpenBSD]: https://man.openbsd.org/connect.2
318 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect&section=2
319 /// [illumos]: https://illumos.org/man/3SOCKET/connect
320 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
321 /// [`Errno::WOULDBLOCK`]: io::Errno::WOULDBLOCK
connect<Fd: AsFd>(sockfd: Fd, addr: &SocketAddr) -> io::Result<()>322 pub fn connect<Fd: AsFd>(sockfd: Fd, addr: &SocketAddr) -> io::Result<()> {
323     _connect(sockfd.as_fd(), addr)
324 }
325 
_connect(sockfd: BorrowedFd<'_>, addr: &SocketAddr) -> io::Result<()>326 fn _connect(sockfd: BorrowedFd<'_>, addr: &SocketAddr) -> io::Result<()> {
327     match addr {
328         SocketAddr::V4(v4) => backend::net::syscalls::connect_v4(sockfd, v4),
329         SocketAddr::V6(v6) => backend::net::syscalls::connect_v6(sockfd, v6),
330     }
331 }
332 
333 /// `connect(sockfd, addr)`—Initiates a connection.
334 ///
335 /// # References
336 ///  - [Beej's Guide to Network Programming]
337 ///  - [POSIX]
338 ///  - [Linux]
339 ///  - [Apple]
340 ///  - [Winsock]
341 ///  - [FreeBSD]
342 ///  - [NetBSD]
343 ///  - [OpenBSD]
344 ///  - [DragonFly BSD]
345 ///  - [illumos]
346 ///  - [glibc]
347 ///
348 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
349 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
350 /// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
351 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
352 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
353 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
354 /// [NetBSD]: https://man.netbsd.org/connect.2
355 /// [OpenBSD]: https://man.openbsd.org/connect.2
356 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect&section=2
357 /// [illumos]: https://illumos.org/man/3SOCKET/connect
358 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
359 #[doc(alias = "connect")]
connect_any<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrAny) -> io::Result<()>360 pub fn connect_any<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrAny) -> io::Result<()> {
361     _connect_any(sockfd.as_fd(), addr)
362 }
363 
_connect_any(sockfd: BorrowedFd<'_>, addr: &SocketAddrAny) -> io::Result<()>364 fn _connect_any(sockfd: BorrowedFd<'_>, addr: &SocketAddrAny) -> io::Result<()> {
365     match addr {
366         SocketAddrAny::V4(v4) => backend::net::syscalls::connect_v4(sockfd, v4),
367         SocketAddrAny::V6(v6) => backend::net::syscalls::connect_v6(sockfd, v6),
368         #[cfg(unix)]
369         SocketAddrAny::Unix(unix) => backend::net::syscalls::connect_unix(sockfd, unix),
370         #[cfg(target_os = "linux")]
371         SocketAddrAny::Xdp(_) => Err(io::Errno::OPNOTSUPP),
372     }
373 }
374 
375 /// `connect(sockfd, addr, sizeof(struct sockaddr_in))`—Initiates a
376 /// connection to an IPv4 address.
377 ///
378 /// # References
379 ///  - [Beej's Guide to Network Programming]
380 ///  - [POSIX]
381 ///  - [Linux]
382 ///  - [Apple]
383 ///  - [Winsock]
384 ///  - [FreeBSD]
385 ///  - [NetBSD]
386 ///  - [OpenBSD]
387 ///  - [DragonFly BSD]
388 ///  - [illumos]
389 ///  - [glibc]
390 ///
391 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
392 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
393 /// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
394 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
395 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
396 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
397 /// [NetBSD]: https://man.netbsd.org/connect.2
398 /// [OpenBSD]: https://man.openbsd.org/connect.2
399 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect&section=2
400 /// [illumos]: https://illumos.org/man/3SOCKET/connect
401 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
402 #[inline]
403 #[doc(alias = "connect")]
connect_v4<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV4) -> io::Result<()>404 pub fn connect_v4<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV4) -> io::Result<()> {
405     backend::net::syscalls::connect_v4(sockfd.as_fd(), addr)
406 }
407 
408 /// `connect(sockfd, addr, sizeof(struct sockaddr_in6))`—Initiates a
409 /// connection to an IPv6 address.
410 ///
411 /// # References
412 ///  - [Beej's Guide to Network Programming]
413 ///  - [POSIX]
414 ///  - [Linux]
415 ///  - [Apple]
416 ///  - [Winsock]
417 ///  - [FreeBSD]
418 ///  - [NetBSD]
419 ///  - [OpenBSD]
420 ///  - [DragonFly BSD]
421 ///  - [illumos]
422 ///  - [glibc]
423 ///
424 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
425 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
426 /// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
427 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
428 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
429 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
430 /// [NetBSD]: https://man.netbsd.org/connect.2
431 /// [OpenBSD]: https://man.openbsd.org/connect.2
432 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect&section=2
433 /// [illumos]: https://illumos.org/man/3SOCKET/connect
434 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
435 #[inline]
436 #[doc(alias = "connect")]
connect_v6<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV6) -> io::Result<()>437 pub fn connect_v6<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrV6) -> io::Result<()> {
438     backend::net::syscalls::connect_v6(sockfd.as_fd(), addr)
439 }
440 
441 /// `connect(sockfd, addr, sizeof(struct sockaddr_un))`—Initiates a
442 /// connection to a Unix-domain address.
443 ///
444 /// # References
445 ///  - [Beej's Guide to Network Programming]
446 ///  - [POSIX]
447 ///  - [Linux]
448 ///  - [Apple]
449 ///  - [Winsock]
450 ///  - [FreeBSD]
451 ///  - [NetBSD]
452 ///  - [OpenBSD]
453 ///  - [DragonFly BSD]
454 ///  - [illumos]
455 ///  - [glibc]
456 ///
457 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
458 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
459 /// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
460 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
461 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
462 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
463 /// [NetBSD]: https://man.netbsd.org/connect.2
464 /// [OpenBSD]: https://man.openbsd.org/connect.2
465 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect&section=2
466 /// [illumos]: https://illumos.org/man/3SOCKET/connect
467 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
468 #[cfg(unix)]
469 #[inline]
470 #[doc(alias = "connect")]
connect_unix<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrUnix) -> io::Result<()>471 pub fn connect_unix<Fd: AsFd>(sockfd: Fd, addr: &SocketAddrUnix) -> io::Result<()> {
472     backend::net::syscalls::connect_unix(sockfd.as_fd(), addr)
473 }
474 
475 /// `connect(sockfd, {.sa_family = AF_UNSPEC}, sizeof(struct sockaddr))`
476 /// — Dissolve the socket's association.
477 ///
478 /// On UDP sockets, BSD platforms report [`Errno::AFNOSUPPORT`] or
479 /// [`Errno::INVAL`] even if the disconnect was successful.
480 ///
481 /// # References
482 ///  - [Beej's Guide to Network Programming]
483 ///  - [POSIX]
484 ///  - [Linux]
485 ///  - [Apple]
486 ///  - [Winsock]
487 ///  - [FreeBSD]
488 ///  - [NetBSD]
489 ///  - [OpenBSD]
490 ///  - [DragonFly BSD]
491 ///  - [illumos]
492 ///  - [glibc]
493 ///
494 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
495 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html
496 /// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
497 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
498 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
499 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
500 /// [NetBSD]: https://man.netbsd.org/connect.2
501 /// [OpenBSD]: https://man.openbsd.org/connect.2
502 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect&section=2
503 /// [illumos]: https://illumos.org/man/3SOCKET/connect
504 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Connecting.html
505 /// [`Errno::AFNOSUPPORT`]: io::Errno::AFNOSUPPORT
506 /// [`Errno::INVAL`]: io::Errno::INVAL
507 #[inline]
508 #[doc(alias = "connect")]
connect_unspec<Fd: AsFd>(sockfd: Fd) -> io::Result<()>509 pub fn connect_unspec<Fd: AsFd>(sockfd: Fd) -> io::Result<()> {
510     backend::net::syscalls::connect_unspec(sockfd.as_fd())
511 }
512 
513 /// `listen(fd, backlog)`—Enables listening for incoming connections.
514 ///
515 /// # References
516 ///  - [Beej's Guide to Network Programming]
517 ///  - [POSIX]
518 ///  - [Linux]
519 ///  - [Apple]
520 ///  - [Winsock]
521 ///  - [FreeBSD]
522 ///  - [NetBSD]
523 ///  - [OpenBSD]
524 ///  - [DragonFly BSD]
525 ///  - [illumos]
526 ///  - [glibc]
527 ///
528 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#listen
529 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html
530 /// [Linux]: https://man7.org/linux/man-pages/man2/listen.2.html
531 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/listen.2.html
532 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen
533 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=listen&sektion=2
534 /// [NetBSD]: https://man.netbsd.org/listen.2
535 /// [OpenBSD]: https://man.openbsd.org/listen.2
536 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=listen&section=2
537 /// [illumos]: https://illumos.org/man/3SOCKET/listen
538 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Listening.html
539 #[inline]
listen<Fd: AsFd>(sockfd: Fd, backlog: i32) -> io::Result<()>540 pub fn listen<Fd: AsFd>(sockfd: Fd, backlog: i32) -> io::Result<()> {
541     backend::net::syscalls::listen(sockfd.as_fd(), backlog)
542 }
543 
544 /// `accept(fd, NULL, NULL)`—Accepts an incoming connection.
545 ///
546 /// Use [`acceptfrom`] to retrieve the peer address.
547 ///
548 /// POSIX guarantees that `accept` will use the lowest unused file descriptor,
549 /// however it is not safe in general to rely on this, as file descriptors may
550 /// be unexpectedly allocated on other threads or in libraries.
551 ///
552 /// # References
553 ///  - [Beej's Guide to Network Programming]
554 ///  - [POSIX]
555 ///  - [Linux]
556 ///  - [Apple]
557 ///  - [Winsock]
558 ///  - [FreeBSD]
559 ///  - [NetBSD]
560 ///  - [OpenBSD]
561 ///  - [DragonFly BSD]
562 ///  - [illumos]
563 ///  - [glibc]
564 ///
565 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#acceptthank-you-for-calling-port-3490.
566 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html
567 /// [Linux]: https://man7.org/linux/man-pages/man2/accept.2.html
568 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/accept.2.html
569 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept
570 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2
571 /// [NetBSD]: https://man.netbsd.org/accept.2
572 /// [OpenBSD]: https://man.openbsd.org/accept.2
573 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept&section=2
574 /// [illumos]: https://illumos.org/man/3SOCKET/accept
575 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Accepting-Connections.html
576 #[inline]
accept<Fd: AsFd>(sockfd: Fd) -> io::Result<OwnedFd>577 pub fn accept<Fd: AsFd>(sockfd: Fd) -> io::Result<OwnedFd> {
578     backend::net::syscalls::accept(sockfd.as_fd())
579 }
580 
581 /// `accept4(fd, NULL, NULL, flags)`—Accepts an incoming connection, with
582 /// flags.
583 ///
584 /// Use [`acceptfrom_with`] to retrieve the peer address.
585 ///
586 /// Even though POSIX guarantees that this will use the lowest unused file
587 /// descriptor, it is not safe in general to rely on this, as file descriptors
588 /// may be unexpectedly allocated on other threads or in libraries.
589 ///
590 /// `accept_with` is the same as [`accept`] but adds an additional flags
591 /// operand.
592 ///
593 /// # References
594 ///  - [Linux]
595 ///  - [FreeBSD]
596 ///  - [NetBSD]
597 ///  - [OpenBSD]
598 ///  - [DragonFly BSD]
599 ///  - [illumos]
600 ///
601 /// [Linux]: https://man7.org/linux/man-pages/man2/accept4.2.html
602 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept4&sektion=2
603 /// [NetBSD]: https://man.netbsd.org/accept4.2
604 /// [OpenBSD]: https://man.openbsd.org/accept4.2
605 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept4&section=2
606 /// [illumos]: https://illumos.org/man/3SOCKET/accept4
607 #[inline]
608 #[doc(alias = "accept4")]
accept_with<Fd: AsFd>(sockfd: Fd, flags: SocketFlags) -> io::Result<OwnedFd>609 pub fn accept_with<Fd: AsFd>(sockfd: Fd, flags: SocketFlags) -> io::Result<OwnedFd> {
610     backend::net::syscalls::accept_with(sockfd.as_fd(), flags)
611 }
612 
613 /// `accept(fd, &addr, &len)`—Accepts an incoming connection and returns the
614 /// peer address.
615 ///
616 /// Use [`accept`] if the peer address isn't needed.
617 ///
618 /// # References
619 ///  - [Beej's Guide to Network Programming]
620 ///  - [POSIX]
621 ///  - [Linux]
622 ///  - [Apple]
623 ///  - [Winsock]
624 ///  - [FreeBSD]
625 ///  - [NetBSD]
626 ///  - [OpenBSD]
627 ///  - [DragonFly BSD]
628 ///  - [illumos]
629 ///  - [glibc]
630 ///
631 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#acceptthank-you-for-calling-port-3490.
632 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html
633 /// [Linux]: https://man7.org/linux/man-pages/man2/accept.2.html
634 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/accept.2.html
635 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept
636 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2
637 /// [NetBSD]: https://man.netbsd.org/accept.2
638 /// [OpenBSD]: https://man.openbsd.org/accept.2
639 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept&section=2
640 /// [illumos]: https://illumos.org/man/3SOCKET/accept
641 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Accepting-Connections.html
642 #[inline]
643 #[doc(alias = "accept")]
acceptfrom<Fd: AsFd>(sockfd: Fd) -> io::Result<(OwnedFd, Option<SocketAddrAny>)>644 pub fn acceptfrom<Fd: AsFd>(sockfd: Fd) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> {
645     backend::net::syscalls::acceptfrom(sockfd.as_fd())
646 }
647 
648 /// `accept4(fd, &addr, &len, flags)`—Accepts an incoming connection and
649 /// returns the peer address, with flags.
650 ///
651 /// Use [`accept_with`] if the peer address isn't needed.
652 ///
653 /// `acceptfrom_with` is the same as [`acceptfrom`] but adds an additional
654 /// flags operand.
655 ///
656 /// # References
657 ///  - [Linux]
658 ///  - [FreeBSD]
659 ///  - [NetBSD]
660 ///  - [OpenBSD]
661 ///  - [DragonFly BSD]
662 ///  - [illumos]
663 ///
664 /// [Linux]: https://man7.org/linux/man-pages/man2/accept4.2.html
665 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept4&sektion=2
666 /// [NetBSD]: https://man.netbsd.org/accept4.2
667 /// [OpenBSD]: https://man.openbsd.org/accept4.2
668 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept4&section=2
669 /// [illumos]: https://illumos.org/man/3SOCKET/accept4
670 #[inline]
671 #[doc(alias = "accept4")]
acceptfrom_with<Fd: AsFd>( sockfd: Fd, flags: SocketFlags, ) -> io::Result<(OwnedFd, Option<SocketAddrAny>)>672 pub fn acceptfrom_with<Fd: AsFd>(
673     sockfd: Fd,
674     flags: SocketFlags,
675 ) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> {
676     backend::net::syscalls::acceptfrom_with(sockfd.as_fd(), flags)
677 }
678 
679 /// `shutdown(fd, how)`—Closes the read and/or write sides of a stream.
680 ///
681 /// # References
682 ///  - [Beej's Guide to Network Programming]
683 ///  - [POSIX]
684 ///  - [Linux]
685 ///  - [Apple]
686 ///  - [Winsock]
687 ///  - [FreeBSD]
688 ///  - [NetBSD]
689 ///  - [OpenBSD]
690 ///  - [DragonFly BSD]
691 ///  - [illumos]
692 ///  - [glibc]
693 ///
694 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#close-and-shutdownget-outta-my-face
695 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html
696 /// [Linux]: https://man7.org/linux/man-pages/man2/shutdown.2.html
697 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/shutdown.2.html
698 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-shutdown
699 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=shutdown&sektion=2
700 /// [NetBSD]: https://man.netbsd.org/shutdown.2
701 /// [OpenBSD]: https://man.openbsd.org/shutdown.2
702 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=shutdown&section=2
703 /// [illumos]: https://illumos.org/man/3SOCKET/shutdown
704 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Closing-a-Socket.html
705 #[inline]
shutdown<Fd: AsFd>(sockfd: Fd, how: Shutdown) -> io::Result<()>706 pub fn shutdown<Fd: AsFd>(sockfd: Fd, how: Shutdown) -> io::Result<()> {
707     backend::net::syscalls::shutdown(sockfd.as_fd(), how)
708 }
709 
710 /// `getsockname(fd, addr, len)`—Returns the address a socket is bound to.
711 ///
712 /// # References
713 ///  - [POSIX]
714 ///  - [Linux]
715 ///  - [Apple]
716 ///  - [Winsock]
717 ///  - [FreeBSD]
718 ///  - [NetBSD]
719 ///  - [OpenBSD]
720 ///  - [DragonFly BSD]
721 ///  - [illumos]
722 ///  - [glibc]
723 ///
724 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html
725 /// [Linux]: https://man7.org/linux/man-pages/man2/getsockname.2.html
726 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockname.2.html
727 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockname
728 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockname&sektion=2
729 /// [NetBSD]: https://man.netbsd.org/getsockname.2
730 /// [OpenBSD]: https://man.openbsd.org/getsockname.2
731 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockname&section=2
732 /// [illumos]: https://illumos.org/man/3SOCKET/getsockname
733 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Reading-Address.html
734 #[inline]
getsockname<Fd: AsFd>(sockfd: Fd) -> io::Result<SocketAddrAny>735 pub fn getsockname<Fd: AsFd>(sockfd: Fd) -> io::Result<SocketAddrAny> {
736     backend::net::syscalls::getsockname(sockfd.as_fd())
737 }
738 
739 /// `getpeername(fd, addr, len)`—Returns the address a socket is connected
740 /// to.
741 ///
742 /// # References
743 ///  - [Beej's Guide to Network Programming]
744 ///  - [POSIX]
745 ///  - [Linux]
746 ///  - [Apple]
747 ///  - [Winsock]
748 ///  - [FreeBSD]
749 ///  - [NetBSD]
750 ///  - [OpenBSD]
751 ///  - [DragonFly BSD]
752 ///  - [illumos]
753 ///  - [glibc]
754 ///
755 /// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#getpeernamewho-are-you
756 /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html
757 /// [Linux]: https://man7.org/linux/man-pages/man2/getpeername.2.html
758 /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getpeername.2.html
759 /// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getpeername
760 /// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2
761 /// [NetBSD]: https://man.netbsd.org/getpeername.2
762 /// [OpenBSD]: https://man.openbsd.org/getpeername.2
763 /// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getpeername&section=2
764 /// [illumos]: https://illumos.org/man/3SOCKET/getpeername
765 /// [glibc]: https://www.gnu.org/software/libc/manual/html_node/Who-is-Connected.html
766 #[inline]
getpeername<Fd: AsFd>(sockfd: Fd) -> io::Result<Option<SocketAddrAny>>767 pub fn getpeername<Fd: AsFd>(sockfd: Fd) -> io::Result<Option<SocketAddrAny>> {
768     backend::net::syscalls::getpeername(sockfd.as_fd())
769 }
770