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