1//! `recv` and `send`, and variants.
2
3#[cfg(unix)]
4use crate::net::SocketAddrUnix;
5use crate::net::{SocketAddr, SocketAddrAny, SocketAddrV4, SocketAddrV6};
6use crate::{backend, io};
7use backend::fd::{AsFd, BorrowedFd};
8
9pub use backend::net::send_recv::{RecvFlags, SendFlags};
10
11/// `recv(fd, buf, flags)`—Reads data from a socket.
12///
13/// # References
14///  - [POSIX]
15///  - [Linux]
16///  - [Apple]
17///  - [Winsock2]
18///
19/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html
20/// [Linux]: https://man7.org/linux/man-pages/man2/recv.2.html
21/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recv.2.html
22/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recv
23#[inline]
24pub fn recv<Fd: AsFd>(fd: Fd, buf: &mut [u8], flags: RecvFlags) -> io::Result<usize> {
25    backend::net::syscalls::recv(fd.as_fd(), buf, flags)
26}
27
28/// `send(fd, buf, flags)`—Writes data to a socket.
29///
30/// # References
31///  - [POSIX]
32///  - [Linux]
33///  - [Apple]
34///  - [Winsock2]
35///
36/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html
37/// [Linux]: https://man7.org/linux/man-pages/man2/send.2.html
38/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/send.2.html
39/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-send
40#[inline]
41pub fn send<Fd: AsFd>(fd: Fd, buf: &[u8], flags: SendFlags) -> io::Result<usize> {
42    backend::net::syscalls::send(fd.as_fd(), buf, flags)
43}
44
45/// `recvfrom(fd, buf, flags, addr, len)`—Reads data from a socket and
46/// returns the sender address.
47///
48/// # References
49///  - [POSIX]
50///  - [Linux]
51///  - [Apple]
52///  - [Winsock2]
53///
54/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html
55/// [Linux]: https://man7.org/linux/man-pages/man2/recvfrom.2.html
56/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/recvfrom.2.html
57/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recvfrom
58#[inline]
59pub fn recvfrom<Fd: AsFd>(
60    fd: Fd,
61    buf: &mut [u8],
62    flags: RecvFlags,
63) -> io::Result<(usize, Option<SocketAddrAny>)> {
64    backend::net::syscalls::recvfrom(fd.as_fd(), buf, flags)
65}
66
67/// `sendto(fd, buf, flags, addr)`—Writes data to a socket to a specific IP
68/// address.
69///
70/// # References
71///  - [POSIX]
72///  - [Linux]
73///  - [Apple]
74///  - [Winsock2]
75///
76/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
77/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
78/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html
79/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
80pub fn sendto<Fd: AsFd>(
81    fd: Fd,
82    buf: &[u8],
83    flags: SendFlags,
84    addr: &SocketAddr,
85) -> io::Result<usize> {
86    _sendto(fd.as_fd(), buf, flags, addr)
87}
88
89fn _sendto(
90    fd: BorrowedFd<'_>,
91    buf: &[u8],
92    flags: SendFlags,
93    addr: &SocketAddr,
94) -> io::Result<usize> {
95    match addr {
96        SocketAddr::V4(v4) => backend::net::syscalls::sendto_v4(fd, buf, flags, v4),
97        SocketAddr::V6(v6) => backend::net::syscalls::sendto_v6(fd, buf, flags, v6),
98    }
99}
100
101/// `sendto(fd, buf, flags, addr)`—Writes data to a socket to a specific
102/// address.
103///
104/// # References
105///  - [POSIX]
106///  - [Linux]
107///  - [Apple]
108///  - [Winsock2]
109///
110/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
111/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
112/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html
113/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
114pub fn sendto_any<Fd: AsFd>(
115    fd: Fd,
116    buf: &[u8],
117    flags: SendFlags,
118    addr: &SocketAddrAny,
119) -> io::Result<usize> {
120    _sendto_any(fd.as_fd(), buf, flags, addr)
121}
122
123fn _sendto_any(
124    fd: BorrowedFd<'_>,
125    buf: &[u8],
126    flags: SendFlags,
127    addr: &SocketAddrAny,
128) -> io::Result<usize> {
129    match addr {
130        SocketAddrAny::V4(v4) => backend::net::syscalls::sendto_v4(fd, buf, flags, v4),
131        SocketAddrAny::V6(v6) => backend::net::syscalls::sendto_v6(fd, buf, flags, v6),
132        #[cfg(unix)]
133        SocketAddrAny::Unix(unix) => backend::net::syscalls::sendto_unix(fd, buf, flags, unix),
134    }
135}
136
137/// `sendto(fd, buf, flags, addr, sizeof(struct sockaddr_in))`—Writes data to
138/// a socket to a specific IPv4 address.
139///
140/// # References
141///  - [POSIX]
142///  - [Linux]
143///  - [Apple]
144///  - [Winsock2]
145///
146/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
147/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
148/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html
149/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
150#[inline]
151#[doc(alias = "sendto")]
152pub fn sendto_v4<Fd: AsFd>(
153    fd: Fd,
154    buf: &[u8],
155    flags: SendFlags,
156    addr: &SocketAddrV4,
157) -> io::Result<usize> {
158    backend::net::syscalls::sendto_v4(fd.as_fd(), buf, flags, addr)
159}
160
161/// `sendto(fd, buf, flags, addr, sizeof(struct sockaddr_in6))`—Writes data
162/// to a socket to a specific IPv6 address.
163///
164/// # References
165///  - [POSIX]
166///  - [Linux]
167///  - [Apple]
168///  - [Winsock2]
169///
170/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
171/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
172/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html
173/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
174#[inline]
175#[doc(alias = "sendto")]
176pub fn sendto_v6<Fd: AsFd>(
177    fd: Fd,
178    buf: &[u8],
179    flags: SendFlags,
180    addr: &SocketAddrV6,
181) -> io::Result<usize> {
182    backend::net::syscalls::sendto_v6(fd.as_fd(), buf, flags, addr)
183}
184
185/// `sendto(fd, buf, flags, addr, sizeof(struct sockaddr_un))`—Writes data to
186/// a socket to a specific Unix-domain socket address.
187///
188/// # References
189///  - [POSIX]
190///  - [Linux]
191///  - [Apple]
192///  - [Winsock2]
193///
194/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html
195/// [Linux]: https://man7.org/linux/man-pages/man2/sendto.2.html
196/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/sendto.2.html
197/// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-sendto
198#[cfg(unix)]
199#[inline]
200#[doc(alias = "sendto")]
201pub fn sendto_unix<Fd: AsFd>(
202    fd: Fd,
203    buf: &[u8],
204    flags: SendFlags,
205    addr: &SocketAddrUnix,
206) -> io::Result<usize> {
207    backend::net::syscalls::sendto_unix(fd.as_fd(), buf, flags, addr)
208}
209
210// TODO: `recvmsg`, `sendmsg`
211