use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
#[cfg(any(unix, target_os = "wasi"))]
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
#[cfg(target_os = "hermit")]
use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{
AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
};
use std::{fmt, io, net};
use crate::io_source::IoSource;
use crate::{event, sys, Interest, Registry, Token};
#[cfg_attr(feature = "os-poll", doc = "```")]
#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
pub struct UdpSocket {
inner: IoSource<net::UdpSocket>,
}
impl UdpSocket {
#[cfg_attr(feature = "os-poll", doc = "```")]
#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
pub fn bind(addr: SocketAddr) -> io::Result<UdpSocket> {
sys::udp::bind(addr).map(UdpSocket::from_std)
}
pub fn from_std(socket: net::UdpSocket) -> UdpSocket {
UdpSocket {
inner: IoSource::new(socket),
}
}
#[cfg_attr(all(feature = "os-poll", not(target_os = "freebsd")), doc = "```")]
#[cfg_attr(
any(not(feature = "os-poll"), target_os = "freebsd"),
doc = "```ignore"
)]
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.inner.local_addr()
}
#[cfg_attr(feature = "os-poll", doc = "```")]
#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
self.inner.peer_addr()
}
pub fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {
self.inner.do_io(|inner| inner.send_to(buf, target))
}
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
self.inner.do_io(|inner| inner.recv_from(buf))
}
pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
self.inner.do_io(|inner| inner.peek_from(buf))
}
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
self.inner.do_io(|inner| inner.send(buf))
}
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.do_io(|inner| inner.recv(buf))
}
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.do_io(|inner| inner.peek(buf))
}
pub fn connect(&self, addr: SocketAddr) -> io::Result<()> {
self.inner.connect(addr)
}
#[cfg_attr(feature = "os-poll", doc = "```")]
#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
self.inner.set_broadcast(on)
}
#[cfg_attr(feature = "os-poll", doc = "```")]
#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
pub fn broadcast(&self) -> io::Result<bool> {
self.inner.broadcast()
}
pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> {
self.inner.set_multicast_loop_v4(on)
}
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
self.inner.multicast_loop_v4()
}
pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
self.inner.set_multicast_ttl_v4(ttl)
}
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
self.inner.multicast_ttl_v4()
}
pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> {
self.inner.set_multicast_loop_v6(on)
}
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
self.inner.multicast_loop_v6()
}
#[cfg_attr(feature = "os-poll", doc = "```")]
#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
self.inner.set_ttl(ttl)
}
#[cfg_attr(feature = "os-poll", doc = "```")]
#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
pub fn ttl(&self) -> io::Result<u32> {
self.inner.ttl()
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
self.inner.join_multicast_v4(multiaddr, interface)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
self.inner.join_multicast_v6(multiaddr, interface)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
self.inner.leave_multicast_v4(multiaddr, interface)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
self.inner.leave_multicast_v6(multiaddr, interface)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn only_v6(&self) -> io::Result<bool> {
sys::udp::only_v6(&self.inner)
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
self.inner.take_error()
}
#[cfg_attr(unix, doc = "```no_run")]
#[cfg_attr(windows, doc = "```ignore")]
pub fn try_io<F, T>(&self, f: F) -> io::Result<T>
where
F: FnOnce() -> io::Result<T>,
{
self.inner.do_io(|_| f())
}
}
impl event::Source for UdpSocket {
fn register(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
self.inner.register(registry, token, interests)
}
fn reregister(
&mut self,
registry: &Registry,
token: Token,
interests: Interest,
) -> io::Result<()> {
self.inner.reregister(registry, token, interests)
}
fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
self.inner.deregister(registry)
}
}
impl fmt::Debug for UdpSocket {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl IntoRawFd for UdpSocket {
fn into_raw_fd(self) -> RawFd {
self.inner.into_inner().into_raw_fd()
}
}
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl AsRawFd for UdpSocket {
fn as_raw_fd(&self) -> RawFd {
self.inner.as_raw_fd()
}
}
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl FromRawFd for UdpSocket {
unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket {
UdpSocket::from_std(FromRawFd::from_raw_fd(fd))
}
}
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl From<UdpSocket> for OwnedFd {
fn from(udp_socket: UdpSocket) -> Self {
udp_socket.inner.into_inner().into()
}
}
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl AsFd for UdpSocket {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.as_fd()
}
}
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl From<OwnedFd> for UdpSocket {
fn from(fd: OwnedFd) -> Self {
UdpSocket::from_std(From::from(fd))
}
}
#[cfg(windows)]
impl IntoRawSocket for UdpSocket {
fn into_raw_socket(self) -> RawSocket {
self.inner.into_inner().into_raw_socket()
}
}
#[cfg(windows)]
impl AsRawSocket for UdpSocket {
fn as_raw_socket(&self) -> RawSocket {
self.inner.as_raw_socket()
}
}
#[cfg(windows)]
impl FromRawSocket for UdpSocket {
unsafe fn from_raw_socket(socket: RawSocket) -> UdpSocket {
UdpSocket::from_std(FromRawSocket::from_raw_socket(socket))
}
}
#[cfg(windows)]
impl From<UdpSocket> for OwnedSocket {
fn from(udp_socket: UdpSocket) -> Self {
udp_socket.inner.into_inner().into()
}
}
#[cfg(windows)]
impl AsSocket for UdpSocket {
fn as_socket(&self) -> BorrowedSocket<'_> {
self.inner.as_socket()
}
}
#[cfg(windows)]
impl From<OwnedSocket> for UdpSocket {
fn from(socket: OwnedSocket) -> Self {
UdpSocket::from_std(From::from(socket))
}
}
impl From<UdpSocket> for net::UdpSocket {
fn from(socket: UdpSocket) -> Self {
unsafe {
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
{
net::UdpSocket::from_raw_fd(socket.into_raw_fd())
}
#[cfg(windows)]
{
net::UdpSocket::from_raw_socket(socket.into_raw_socket())
}
}
}
}