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§ion=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§ion=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§ion=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§ion=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}