rustix/net/send_recv/
mod.rs

1//! `recv`, `send`, and variants.
2
3#![allow(unsafe_code)]
4
5use crate::buffer::Buffer;
6use crate::net::addr::SocketAddrArg;
7use crate::net::SocketAddrAny;
8use crate::{backend, io};
9use backend::fd::AsFd;
10use core::cmp::min;
11
12pub use backend::net::send_recv::{RecvFlags, ReturnFlags, SendFlags};
13
14#[cfg(not(any(
15    windows,
16    target_os = "espidf",
17    target_os = "horizon",
18    target_os = "redox",
19    target_os = "vita"
20)))]
21mod msg;
22
23#[cfg(not(any(
24    windows,
25    target_os = "espidf",
26    target_os = "horizon",
27    target_os = "redox",
28    target_os = "vita"
29)))]
30pub use msg::*;
31
32/// `recv(fd, buf, flags)`—Reads data from a socket.
33///
34/// In addition to the `Buffer::Output` return value, this also returns the
35/// number of bytes received before any truncation due to the
36/// [`RecvFlags::TRUNC`] flag.
37///
38/// # References
39///  - [Beej's Guide to Network Programming]
40///  - [POSIX]
41///  - [Linux]
42///  - [Apple]
43///  - [Winsock]
44///  - [FreeBSD]
45///  - [NetBSD]
46///  - [OpenBSD]
47///  - [DragonFly BSD]
48///  - [illumos]
49///  - [glibc]
50///
51/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendrecv
52/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/recv.html
53/// [Linux]: https://man7.org/linux/man-pages/man2/recv.2.html
54/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recv.2.html
55/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recv
56/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=recv&sektion=2
57/// [NetBSD]: https://man.netbsd.org/recv.2
58/// [OpenBSD]: https://man.openbsd.org/recv.2
59/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=recv&section=2
60/// [illumos]: https://illumos.org/man/3SOCKET/recv
61/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Receiving-Data.html
62#[inline]
63#[allow(clippy::type_complexity)]
64pub fn recv<Fd: AsFd, Buf: Buffer<u8>>(
65    fd: Fd,
66    mut buf: Buf,
67    flags: RecvFlags,
68) -> io::Result<(Buf::Output, usize)> {
69    let (ptr, len) = buf.parts_mut();
70    // SAFETY: `recv` behaves.
71    let recv_len = unsafe { backend::net::syscalls::recv(fd.as_fd(), (ptr, len), flags)? };
72    // If the `TRUNC` flag is set, the returned `length` may be longer than the
73    // buffer length.
74    let min_len = min(len, recv_len);
75    // SAFETY: `recv` behaves.
76    unsafe { Ok((buf.assume_init(min_len), recv_len)) }
77}
78
79/// `send(fd, buf, flags)`—Writes data to a socket.
80///
81/// # References
82///  - [Beej's Guide to Network Programming]
83///  - [POSIX]
84///  - [Linux]
85///  - [Apple]
86///  - [Winsock]
87///  - [FreeBSD]
88///  - [NetBSD]
89///  - [OpenBSD]
90///  - [DragonFly BSD]
91///  - [illumos]
92///  - [glibc]
93///
94/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendrecv
95/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/send.html
96/// [Linux]: https://man7.org/linux/man-pages/man2/send.2.html
97/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/send.2.html
98/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send
99/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=send&sektion=2
100/// [NetBSD]: https://man.netbsd.org/send.2
101/// [OpenBSD]: https://man.openbsd.org/send.2
102/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=send&section=2
103/// [illumos]: https://illumos.org/man/3SOCKET/send
104/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Sending-Data.html
105#[inline]
106pub fn send<Fd: AsFd>(fd: Fd, buf: &[u8], flags: SendFlags) -> io::Result<usize> {
107    backend::net::syscalls::send(fd.as_fd(), buf, flags)
108}
109
110/// `recvfrom(fd, buf, flags, addr, len)`—Reads data from a socket and
111/// returns the sender address.
112///
113/// In addition to the `Buffer::Output` return value, this also returns the
114/// number of bytes received before any truncation due to the
115/// [`RecvFlags::TRUNC`] flag.
116///
117/// # References
118///  - [Beej's Guide to Network Programming]
119///  - [POSIX]
120///  - [Linux]
121///  - [Apple]
122///  - [Winsock]
123///  - [FreeBSD]
124///  - [NetBSD]
125///  - [OpenBSD]
126///  - [DragonFly BSD]
127///  - [illumos]
128///  - [glibc]
129///
130/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv
131/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/recvfrom.html
132/// [Linux]: https://man7.org/linux/man-pages/man2/recvfrom.2.html
133/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recvfrom.2.html
134/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recvfrom
135/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=recvfrom&sektion=2
136/// [NetBSD]: https://man.netbsd.org/recvfrom.2
137/// [OpenBSD]: https://man.openbsd.org/recvfrom.2
138/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=recvfrom&section=2
139/// [illumos]: https://illumos.org/man/3SOCKET/recvfrom
140/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Receiving-Datagrams.html
141#[inline]
142pub fn recvfrom<Fd: AsFd, Buf: Buffer<u8>>(
143    fd: Fd,
144    mut buf: Buf,
145    flags: RecvFlags,
146) -> io::Result<(Buf::Output, usize, Option<SocketAddrAny>)> {
147    let (ptr, len) = buf.parts_mut();
148    // SAFETY: `recvfrom` behaves.
149    let (recv_len, addr) =
150        unsafe { backend::net::syscalls::recvfrom(fd.as_fd(), (ptr, len), flags)? };
151    // If the `TRUNC` flag is set, the returned `length` may be longer than the
152    // buffer length.
153    let min_len = min(len, recv_len);
154    // SAFETY: `recvfrom` behaves.
155    unsafe { Ok((buf.assume_init(min_len), recv_len, addr)) }
156}
157
158/// `sendto(fd, buf, flags, addr)`—Writes data to a socket to a specific IP
159/// address.
160///
161/// # References
162///  - [Beej's Guide to Network Programming]
163///  - [POSIX]
164///  - [Linux]
165///  - [Apple]
166///  - [Winsock]
167///  - [FreeBSD]
168///  - [NetBSD]
169///  - [OpenBSD]
170///  - [DragonFly BSD]
171///  - [illumos]
172///  - [glibc]
173///
174/// [Beej's Guide to Network Programming]: https://beej.us/guide/bgnet/html/split/system-calls-or-bust.html#sendtorecv
175/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sendto.html
176/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
177/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html
178/// [Winsock]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
179/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=sendto&sektion=2
180/// [NetBSD]: https://man.netbsd.org/sendto.2
181/// [OpenBSD]: https://man.openbsd.org/sendto.2
182/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=sendto&section=2
183/// [illumos]: https://illumos.org/man/3SOCKET/sendto
184/// [glibc]: https://sourceware.org/glibc/manual/latest/html_node/Sending-Datagrams.html
185pub fn sendto<Fd: AsFd>(
186    fd: Fd,
187    buf: &[u8],
188    flags: SendFlags,
189    addr: &impl SocketAddrArg,
190) -> io::Result<usize> {
191    backend::net::syscalls::sendto(fd.as_fd(), buf, flags, addr)
192}