rustix/net/socket.rs
1use crate::fd::OwnedFd;
2use crate::net::addr::SocketAddrArg;
3use crate::net::SocketAddrAny;
4use crate::{backend, io};
5use backend::fd::AsFd;
6
7pub use crate::net::{AddressFamily, Protocol, Shutdown, SocketFlags, SocketType};
8#[cfg(unix)]
9pub use backend::net::addr::SocketAddrUnix;
10
11/// `socket(domain, type_, protocol)`—Creates a socket.
12///
13/// POSIX guarantees that `socket` will use the lowest unused file descriptor,
14/// however it is not safe in general to rely on this, as file descriptors may
15/// be unexpectedly allocated on other threads or in libraries.
16///
17/// To pass extra flags such as [`SocketFlags::CLOEXEC`] or
18/// [`SocketFlags::NONBLOCK`], use [`socket_with`].
19///
20/// # References
21/// - [Beej's Guide to Network Programming]
22/// - [POSIX]
23/// - [Linux]
24/// - [Apple]
25/// - [Winsock]
26/// - [FreeBSD]
27/// - [NetBSD]
28/// - [OpenBSD]
29/// - [DragonFly BSD]
30/// - [illumos]
31/// - [glibc]
32///
33/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#socket
34/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/socket.html
35/// [Linux]: https://man7.org/linux/man-pages/man2/socket.2.html
36/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socket.2.html
37/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
38/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2
39/// [NetBSD]: https://man.netbsd.org/socket.2
40/// [OpenBSD]: https://man.openbsd.org/socket.2
41/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socket§ion=2
42/// [illumos]: https://illumos.org/man/3SOCKET/socket
43/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Creating-a-Socket.html
44#[inline]
45pub fn socket(
46 domain: AddressFamily,
47 type_: SocketType,
48 protocol: Option<Protocol>,
49) -> io::Result<OwnedFd> {
50 backend::net::syscalls::socket(domain, type_, protocol)
51}
52
53/// `socket_with(domain, type_ | flags, protocol)`—Creates a socket, with
54/// flags.
55///
56/// POSIX guarantees that `socket` will use the lowest unused file descriptor,
57/// however it is not safe in general to rely on this, as file descriptors may
58/// be unexpectedly allocated on other threads or in libraries.
59///
60/// `socket_with` is the same as [`socket`] but adds an additional flags
61/// operand.
62///
63/// # References
64/// - [Beej's Guide to Network Programming]
65/// - [POSIX]
66/// - [Linux]
67/// - [Apple]
68/// - [Winsock]
69/// - [FreeBSD]
70/// - [NetBSD]
71/// - [OpenBSD]
72/// - [DragonFly BSD]
73/// - [illumos]
74/// - [glibc]
75///
76/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#socket
77/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/socket.html
78/// [Linux]: https://man7.org/linux/man-pages/man2/socket.2.html
79/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/socket.2.html
80/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
81/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2
82/// [NetBSD]: https://man.netbsd.org/socket.2
83/// [OpenBSD]: https://man.openbsd.org/socket.2
84/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=socket§ion=2
85/// [illumos]: https://illumos.org/man/3SOCKET/socket
86/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Creating-a-Socket.html
87#[doc(alias("socket"))]
88#[inline]
89pub fn socket_with(
90 domain: AddressFamily,
91 type_: SocketType,
92 flags: SocketFlags,
93 protocol: Option<Protocol>,
94) -> io::Result<OwnedFd> {
95 backend::net::syscalls::socket_with(domain, type_, flags, protocol)
96}
97
98/// `bind(sockfd, addr)`—Binds a socket to an IP address.
99///
100/// # References
101/// - [Beej's Guide to Network Programming]
102/// - [POSIX]
103/// - [Linux]
104/// - [Apple]
105/// - [Winsock]
106/// - [FreeBSD]
107/// - [NetBSD]
108/// - [OpenBSD]
109/// - [DragonFly BSD]
110/// - [illumos]
111/// - [glibc]
112///
113/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#bind
114/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/bind.html
115/// [Linux]: https://man7.org/linux/man-pages/man2/bind.2.html
116/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/bind.2.html
117/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-bind
118/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=bind&sektion=2
119/// [NetBSD]: https://man.netbsd.org/bind.2
120/// [OpenBSD]: https://man.openbsd.org/bind.2
121/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=bind§ion=2
122/// [illumos]: https://illumos.org/man/3SOCKET/bind
123/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Setting-Address.html
124pub fn bind<Fd: AsFd>(sockfd: Fd, addr: &impl SocketAddrArg) -> io::Result<()> {
125 backend::net::syscalls::bind(sockfd.as_fd(), addr)
126}
127
128/// `connect(sockfd, addr)`—Initiates a connection to an IP address.
129///
130/// On Windows, a non-blocking socket returns [`Errno::WOULDBLOCK`] if the
131/// connection cannot be completed immediately, rather than
132/// `Errno::INPROGRESS`.
133///
134/// # References
135/// - [Beej's Guide to Network Programming]
136/// - [POSIX]
137/// - [Linux]
138/// - [Apple]
139/// - [Winsock]
140/// - [FreeBSD]
141/// - [NetBSD]
142/// - [OpenBSD]
143/// - [DragonFly BSD]
144/// - [illumos]
145/// - [glibc]
146///
147/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
148/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/connect.html
149/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
150/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
151/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
152/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
153/// [NetBSD]: https://man.netbsd.org/connect.2
154/// [OpenBSD]: https://man.openbsd.org/connect.2
155/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2
156/// [illumos]: https://illumos.org/man/3SOCKET/connect
157/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Connecting.html
158/// [`Errno::WOULDBLOCK`]: io::Errno::WOULDBLOCK
159pub fn connect<Fd: AsFd>(sockfd: Fd, addr: &impl SocketAddrArg) -> io::Result<()> {
160 backend::net::syscalls::connect(sockfd.as_fd(), addr)
161}
162
163/// `connect(sockfd, {.sa_family = AF_UNSPEC}, sizeof(struct sockaddr))`—
164/// Dissolve the socket's association.
165///
166/// On UDP sockets, BSD platforms report [`Errno::AFNOSUPPORT`] or
167/// [`Errno::INVAL`] even if the disconnect was successful.
168///
169/// # References
170/// - [Beej's Guide to Network Programming]
171/// - [POSIX]
172/// - [Linux]
173/// - [Apple]
174/// - [Winsock]
175/// - [FreeBSD]
176/// - [NetBSD]
177/// - [OpenBSD]
178/// - [DragonFly BSD]
179/// - [illumos]
180/// - [glibc]
181///
182/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#connect
183/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/connect.html
184/// [Linux]: https://man7.org/linux/man-pages/man2/connect.2.html
185/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/connect.2.html
186/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
187/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=connect&sektion=2
188/// [NetBSD]: https://man.netbsd.org/connect.2
189/// [OpenBSD]: https://man.openbsd.org/connect.2
190/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=connect§ion=2
191/// [illumos]: https://illumos.org/man/3SOCKET/connect
192/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Connecting.html
193/// [`Errno::AFNOSUPPORT`]: io::Errno::AFNOSUPPORT
194/// [`Errno::INVAL`]: io::Errno::INVAL
195#[inline]
196#[doc(alias = "connect")]
197pub fn connect_unspec<Fd: AsFd>(sockfd: Fd) -> io::Result<()> {
198 backend::net::syscalls::connect_unspec(sockfd.as_fd())
199}
200
201/// `listen(fd, backlog)`—Enables listening for incoming connections.
202///
203/// # References
204/// - [Beej's Guide to Network Programming]
205/// - [POSIX]
206/// - [Linux]
207/// - [Apple]
208/// - [Winsock]
209/// - [FreeBSD]
210/// - [NetBSD]
211/// - [OpenBSD]
212/// - [DragonFly BSD]
213/// - [illumos]
214/// - [glibc]
215///
216/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#listen
217/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/listen.html
218/// [Linux]: https://man7.org/linux/man-pages/man2/listen.2.html
219/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/listen.2.html
220/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen
221/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=listen&sektion=2
222/// [NetBSD]: https://man.netbsd.org/listen.2
223/// [OpenBSD]: https://man.openbsd.org/listen.2
224/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=listen§ion=2
225/// [illumos]: https://illumos.org/man/3SOCKET/listen
226/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Listening.html
227#[inline]
228pub fn listen<Fd: AsFd>(sockfd: Fd, backlog: i32) -> io::Result<()> {
229 backend::net::syscalls::listen(sockfd.as_fd(), backlog)
230}
231
232/// `accept(fd, NULL, NULL)`—Accepts an incoming connection.
233///
234/// Use [`acceptfrom`] to retrieve the peer address.
235///
236/// POSIX guarantees that `accept` will use the lowest unused file descriptor,
237/// however it is not safe in general to rely on this, as file descriptors may
238/// be unexpectedly allocated on other threads or in libraries.
239///
240/// See [`accept_with`] to pass additional flags.
241///
242/// # References
243/// - [Beej's Guide to Network Programming]
244/// - [POSIX]
245/// - [Linux]
246/// - [Apple]
247/// - [Winsock]
248/// - [FreeBSD]
249/// - [NetBSD]
250/// - [OpenBSD]
251/// - [DragonFly BSD]
252/// - [illumos]
253/// - [glibc]
254///
255/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#acceptthank-you-for-calling-port-3490.
256/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/accept.html
257/// [Linux]: https://man7.org/linux/man-pages/man2/accept.2.html
258/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/accept.2.html
259/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept
260/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2
261/// [NetBSD]: https://man.netbsd.org/accept.2
262/// [OpenBSD]: https://man.openbsd.org/accept.2
263/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept§ion=2
264/// [illumos]: https://illumos.org/man/3SOCKET/accept
265/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Accepting-Connections.html
266#[inline]
267pub fn accept<Fd: AsFd>(sockfd: Fd) -> io::Result<OwnedFd> {
268 backend::net::syscalls::accept(sockfd.as_fd())
269}
270
271/// `accept4(fd, NULL, NULL, flags)`—Accepts an incoming connection, with
272/// flags.
273///
274/// Use [`acceptfrom_with`] to retrieve the peer address.
275///
276/// Even though POSIX guarantees that this will use the lowest unused file
277/// descriptor, it is not safe in general to rely on this, as file descriptors
278/// may be unexpectedly allocated on other threads or in libraries.
279///
280/// `accept_with` is the same as [`accept`] but adds an additional flags
281/// operand.
282///
283/// # References
284/// - [Linux]
285/// - [FreeBSD]
286/// - [NetBSD]
287/// - [OpenBSD]
288/// - [DragonFly BSD]
289/// - [illumos]
290///
291/// [Linux]: https://man7.org/linux/man-pages/man2/accept4.2.html
292/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept4&sektion=2
293/// [NetBSD]: https://man.netbsd.org/accept4.2
294/// [OpenBSD]: https://man.openbsd.org/accept4.2
295/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept4§ion=2
296/// [illumos]: https://illumos.org/man/3SOCKET/accept4
297#[inline]
298#[doc(alias = "accept4")]
299pub fn accept_with<Fd: AsFd>(sockfd: Fd, flags: SocketFlags) -> io::Result<OwnedFd> {
300 backend::net::syscalls::accept_with(sockfd.as_fd(), flags)
301}
302
303/// `accept(fd, &addr, &len)`—Accepts an incoming connection and returns the
304/// peer address.
305///
306/// Use [`accept`] if the peer address isn't needed.
307///
308/// See [`acceptfrom_with`] to pass additional flags.
309///
310/// # References
311/// - [Beej's Guide to Network Programming]
312/// - [POSIX]
313/// - [Linux]
314/// - [Apple]
315/// - [Winsock]
316/// - [FreeBSD]
317/// - [NetBSD]
318/// - [OpenBSD]
319/// - [DragonFly BSD]
320/// - [illumos]
321/// - [glibc]
322///
323/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#acceptthank-you-for-calling-port-3490.
324/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/accept.html
325/// [Linux]: https://man7.org/linux/man-pages/man2/accept.2.html
326/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/accept.2.html
327/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-accept
328/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept&sektion=2
329/// [NetBSD]: https://man.netbsd.org/accept.2
330/// [OpenBSD]: https://man.openbsd.org/accept.2
331/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept§ion=2
332/// [illumos]: https://illumos.org/man/3SOCKET/accept
333/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Accepting-Connections.html
334#[inline]
335#[doc(alias = "accept")]
336pub fn acceptfrom<Fd: AsFd>(sockfd: Fd) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> {
337 backend::net::syscalls::acceptfrom(sockfd.as_fd())
338}
339
340/// `accept4(fd, &addr, &len, flags)`—Accepts an incoming connection and
341/// returns the peer address, with flags.
342///
343/// Use [`accept_with`] if the peer address isn't needed.
344///
345/// `acceptfrom_with` is the same as [`acceptfrom`] but adds an additional
346/// flags operand.
347///
348/// # References
349/// - [Linux]
350/// - [FreeBSD]
351/// - [NetBSD]
352/// - [OpenBSD]
353/// - [DragonFly BSD]
354/// - [illumos]
355///
356/// [Linux]: https://man7.org/linux/man-pages/man2/accept4.2.html
357/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=accept4&sektion=2
358/// [NetBSD]: https://man.netbsd.org/accept4.2
359/// [OpenBSD]: https://man.openbsd.org/accept4.2
360/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=accept4§ion=2
361/// [illumos]: https://illumos.org/man/3SOCKET/accept4
362#[inline]
363#[doc(alias = "accept4")]
364pub fn acceptfrom_with<Fd: AsFd>(
365 sockfd: Fd,
366 flags: SocketFlags,
367) -> io::Result<(OwnedFd, Option<SocketAddrAny>)> {
368 backend::net::syscalls::acceptfrom_with(sockfd.as_fd(), flags)
369}
370
371/// `shutdown(fd, how)`—Closes the read and/or write sides of a stream.
372///
373/// # References
374/// - [Beej's Guide to Network Programming]
375/// - [POSIX]
376/// - [Linux]
377/// - [Apple]
378/// - [Winsock]
379/// - [FreeBSD]
380/// - [NetBSD]
381/// - [OpenBSD]
382/// - [DragonFly BSD]
383/// - [illumos]
384/// - [glibc]
385///
386/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#close-and-shutdownget-outta-my-face
387/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/shutdown.html
388/// [Linux]: https://man7.org/linux/man-pages/man2/shutdown.2.html
389/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/shutdown.2.html
390/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-shutdown
391/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=shutdown&sektion=2
392/// [NetBSD]: https://man.netbsd.org/shutdown.2
393/// [OpenBSD]: https://man.openbsd.org/shutdown.2
394/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=shutdown§ion=2
395/// [illumos]: https://illumos.org/man/3SOCKET/shutdown
396/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Closing-a-Socket.html
397#[inline]
398pub fn shutdown<Fd: AsFd>(sockfd: Fd, how: Shutdown) -> io::Result<()> {
399 backend::net::syscalls::shutdown(sockfd.as_fd(), how)
400}
401
402/// `getsockname(fd, addr, len)`—Returns the address a socket is bound to.
403///
404/// # References
405/// - [POSIX]
406/// - [Linux]
407/// - [Apple]
408/// - [Winsock]
409/// - [FreeBSD]
410/// - [NetBSD]
411/// - [OpenBSD]
412/// - [DragonFly BSD]
413/// - [illumos]
414/// - [glibc]
415///
416/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getsockname.html
417/// [Linux]: https://man7.org/linux/man-pages/man2/getsockname.2.html
418/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockname.2.html
419/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockname
420/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockname&sektion=2
421/// [NetBSD]: https://man.netbsd.org/getsockname.2
422/// [OpenBSD]: https://man.openbsd.org/getsockname.2
423/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockname§ion=2
424/// [illumos]: https://illumos.org/man/3SOCKET/getsockname
425/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Reading-Address.html
426#[inline]
427pub fn getsockname<Fd: AsFd>(sockfd: Fd) -> io::Result<SocketAddrAny> {
428 backend::net::syscalls::getsockname(sockfd.as_fd())
429}
430
431/// `getpeername(fd, addr, len)`—Returns the address a socket is connected
432/// to.
433///
434/// # References
435/// - [Beej's Guide to Network Programming]
436/// - [POSIX]
437/// - [Linux]
438/// - [Apple]
439/// - [Winsock]
440/// - [FreeBSD]
441/// - [NetBSD]
442/// - [OpenBSD]
443/// - [DragonFly BSD]
444/// - [illumos]
445/// - [glibc]
446///
447/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#getpeernamewho-are-you
448/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpeername.html
449/// [Linux]: https://man7.org/linux/man-pages/man2/getpeername.2.html
450/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getpeername.2.html
451/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getpeername
452/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getpeername&sektion=2
453/// [NetBSD]: https://man.netbsd.org/getpeername.2
454/// [OpenBSD]: https://man.openbsd.org/getpeername.2
455/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getpeername§ion=2
456/// [illumos]: https://illumos.org/man/3SOCKET/getpeername
457/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Who-is-Connected.html
458#[inline]
459pub fn getpeername<Fd: AsFd>(sockfd: Fd) -> io::Result<Option<SocketAddrAny>> {
460 backend::net::syscalls::getpeername(sockfd.as_fd())
461}