use crate::io_source::IoSource;
use crate::{event, sys, Interest, Registry, Token};
use std::fmt;
use std::io;
use std::net;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
#[cfg(unix)]
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
#[cfg(windows)]
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
#[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()
}
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()
}
}
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(unix)]
impl IntoRawFd for UdpSocket {
fn into_raw_fd(self) -> RawFd {
self.inner.into_inner().into_raw_fd()
}
}
#[cfg(unix)]
impl AsRawFd for UdpSocket {
fn as_raw_fd(&self) -> RawFd {
self.inner.as_raw_fd()
}
}
#[cfg(unix)]
impl FromRawFd for UdpSocket {
unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket {
UdpSocket::from_std(FromRawFd::from_raw_fd(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))
}
}