#[allow(unreachable_pub, unused_imports, dead_code)]
#[path = "../poll/net.rs"]
mod poll;
#[allow(unreachable_pub, unused_imports, dead_code)]
#[path = "../net/mod.rs"]
mod uring;
use std::{
io,
net::{Shutdown, SocketAddr},
os::unix::io::{AsRawFd, RawFd},
time::Duration,
};
pub use crate::addr::{lookup_host, ToAddrs};
use crate::buf::{BufResult, IoBuf, IoBufMut};
pub use uring::unix::{self, UnixDatagram, UnixListener, UnixStream};
pub struct MultishotTcpAccept {
inner: uring::MultishotTcpAccept,
}
impl MultishotTcpAccept {
pub async fn next(&mut self) -> Option<io::Result<TcpStream>> {
self.inner.next().await.map(|r| r.map(TcpStream::Uring))
}
}
pub enum TcpListener {
Uring(uring::TcpListener),
Poll(poll::TcpListener),
}
impl TcpListener {
pub async fn bind(addr: impl ToAddrs) -> io::Result<Self> {
if crate::reactor::is_uring() {
uring::TcpListener::bind(addr).await.map(TcpListener::Uring)
} else {
poll::TcpListener::bind(addr).await.map(TcpListener::Poll)
}
}
pub fn bind_addr(addr: SocketAddr) -> io::Result<Self> {
if crate::reactor::is_uring() {
uring::TcpListener::bind_addr(addr).map(TcpListener::Uring)
} else {
poll::TcpListener::bind_addr(addr).map(TcpListener::Poll)
}
}
pub fn from_std(listener: std::net::TcpListener) -> io::Result<Self> {
if crate::reactor::is_uring() {
uring::TcpListener::from_std(listener).map(TcpListener::Uring)
} else {
poll::TcpListener::from_std(listener).map(TcpListener::Poll)
}
}
pub fn local_addr(&self) -> io::Result<SocketAddr> {
match self {
TcpListener::Uring(l) => l.local_addr(),
TcpListener::Poll(l) => l.local_addr(),
}
}
pub async fn accept(&self) -> io::Result<TcpStream> {
match self {
TcpListener::Uring(l) => l.accept().await.map(TcpStream::Uring),
TcpListener::Poll(l) => l.accept().await.map(TcpStream::Poll),
}
}
pub async fn accept_addr(&self) -> io::Result<(TcpStream, SocketAddr)> {
match self {
TcpListener::Uring(l) => l.accept_addr().await.map(|(s, a)| (TcpStream::Uring(s), a)),
TcpListener::Poll(l) => l.accept_addr().await.map(|(s, a)| (TcpStream::Poll(s), a)),
}
}
pub fn accept_multishot(&self) -> io::Result<MultishotTcpAccept> {
match self {
TcpListener::Uring(l) => l
.accept_multishot()
.map(|inner| MultishotTcpAccept { inner }),
TcpListener::Poll(_) => Err(io::Error::new(
io::ErrorKind::Unsupported,
"accept_multishot requires io_uring",
)),
}
}
pub fn set_reuseaddr(&self, reuse: bool) -> io::Result<()> {
match self {
TcpListener::Uring(l) => l.set_reuseaddr(reuse),
TcpListener::Poll(l) => l.set_reuseaddr(reuse),
}
}
pub fn reuseaddr(&self) -> io::Result<bool> {
match self {
TcpListener::Uring(l) => l.reuseaddr(),
TcpListener::Poll(l) => l.reuseaddr(),
}
}
pub fn set_reuseport(&self) -> io::Result<()> {
match self {
TcpListener::Uring(l) => l.set_reuseport(),
TcpListener::Poll(l) => l.set_reuseport(true),
}
}
pub fn reuseport(&self) -> io::Result<bool> {
match self {
TcpListener::Uring(l) => l.reuseport(),
TcpListener::Poll(l) => l.reuseport(),
}
}
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
match self {
TcpListener::Uring(l) => l.set_ttl(ttl),
TcpListener::Poll(l) => l.set_ttl(ttl),
}
}
pub fn ttl(&self) -> io::Result<u32> {
match self {
TcpListener::Uring(l) => l.ttl(),
TcpListener::Poll(l) => l.ttl(),
}
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
match self {
TcpListener::Uring(l) => l.take_error(),
TcpListener::Poll(l) => l.take_error(),
}
}
pub fn as_raw_fd(&self) -> RawFd {
match self {
TcpListener::Uring(l) => l.as_raw_fd(),
TcpListener::Poll(l) => l.as_raw_fd(),
}
}
pub unsafe fn from_raw_fd(fd: RawFd) -> Self {
if crate::reactor::is_uring() {
TcpListener::Uring(unsafe { uring::TcpListener::from_raw_fd(fd) })
} else {
let std_listener =
unsafe { <std::net::TcpListener as std::os::unix::io::FromRawFd>::from_raw_fd(fd) };
TcpListener::Poll(
poll::TcpListener::from_std(std_listener)
.expect("failed to register raw TcpListener on poll fallback"),
)
}
}
}
impl AsRawFd for TcpListener {
fn as_raw_fd(&self) -> RawFd {
TcpListener::as_raw_fd(self)
}
}
pub enum TcpStream {
Uring(uring::TcpStream),
Poll(poll::TcpStream),
}
impl TcpStream {
pub async fn connect(addr: impl ToAddrs) -> io::Result<Self> {
if crate::reactor::is_uring() {
uring::TcpStream::connect(addr).await.map(TcpStream::Uring)
} else {
poll::TcpStream::connect(addr).await.map(TcpStream::Poll)
}
}
pub async fn connect_addr(addr: SocketAddr) -> io::Result<Self> {
if crate::reactor::is_uring() {
uring::TcpStream::connect_addr(addr)
.await
.map(TcpStream::Uring)
} else {
poll::TcpStream::connect_addr(addr)
.await
.map(TcpStream::Poll)
}
}
pub fn from_std(stream: std::net::TcpStream) -> io::Result<Self> {
if crate::reactor::is_uring() {
uring::TcpStream::from_std(stream).map(TcpStream::Uring)
} else {
poll::TcpStream::from_std(stream).map(TcpStream::Poll)
}
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
match self {
TcpStream::Uring(s) => s.peer_addr(),
TcpStream::Poll(s) => s.peer_addr(),
}
}
pub fn local_addr(&self) -> io::Result<SocketAddr> {
match self {
TcpStream::Uring(s) => s.local_addr(),
TcpStream::Poll(s) => s.local_addr(),
}
}
pub async fn read<B>(&self, buf: B) -> BufResult<usize, B>
where
B: IoBufMut + Send + 'static,
{
match self {
TcpStream::Uring(s) => s.read(buf).await,
TcpStream::Poll(s) => s.read(buf).await,
}
}
pub async fn read_exact<B>(&self, buf: B) -> BufResult<(), B>
where
B: IoBufMut + Send + 'static,
{
match self {
TcpStream::Uring(s) => s.read_exact(buf).await,
TcpStream::Poll(s) => s.read_exact(buf).await,
}
}
pub async fn write<B>(&self, buf: B) -> BufResult<usize, B>
where
B: IoBuf + Send + 'static,
{
match self {
TcpStream::Uring(s) => s.write(buf).await,
TcpStream::Poll(s) => s.write(buf).await,
}
}
pub async fn write_all<B>(&self, buf: B) -> BufResult<(), B>
where
B: IoBuf + Send + 'static,
{
match self {
TcpStream::Uring(s) => s.write_all(buf).await,
TcpStream::Poll(s) => s.write_all(buf).await,
}
}
pub async fn read_vectored<B>(&self, bufs: Vec<B>) -> BufResult<usize, Vec<B>>
where
B: IoBufMut + Send + 'static,
{
match self {
TcpStream::Uring(s) => s.read_vectored(bufs).await,
TcpStream::Poll(s) => s.read_vectored(bufs).await,
}
}
pub async fn write_vectored<B>(&self, bufs: Vec<B>) -> BufResult<usize, Vec<B>>
where
B: IoBuf + Send + 'static,
{
match self {
TcpStream::Uring(s) => s.write_vectored(bufs).await,
TcpStream::Poll(s) => s.write_vectored(bufs).await,
}
}
pub async fn write_all_vectored<B>(&self, bufs: Vec<B>) -> BufResult<(), Vec<B>>
where
B: IoBuf + Send + 'static,
{
match self {
TcpStream::Uring(s) => s.write_all_vectored(bufs).await,
TcpStream::Poll(s) => s.write_all_vectored(bufs).await,
}
}
pub fn recv_multishot(&self, bgid: u16) -> io::Result<crate::reactor::MultishotRecv> {
match self {
TcpStream::Uring(s) => s.recv_multishot(bgid),
TcpStream::Poll(_) => Err(io::Error::new(
io::ErrorKind::Unsupported,
"recv_multishot requires io_uring",
)),
}
}
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
match self {
TcpStream::Uring(s) => s.shutdown(how),
TcpStream::Poll(s) => s.shutdown(how),
}
}
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
match self {
TcpStream::Uring(s) => s.set_nodelay(nodelay),
TcpStream::Poll(s) => s.set_nodelay(nodelay),
}
}
pub fn nodelay(&self) -> io::Result<bool> {
match self {
TcpStream::Uring(s) => s.nodelay(),
TcpStream::Poll(s) => s.nodelay(),
}
}
pub fn set_keepalive(&self, keepalive: bool) -> io::Result<()> {
match self {
TcpStream::Uring(s) => s.set_keepalive(keepalive),
TcpStream::Poll(s) => s.set_keepalive(keepalive),
}
}
pub fn keepalive(&self) -> io::Result<bool> {
match self {
TcpStream::Uring(s) => s.keepalive(),
TcpStream::Poll(s) => s.keepalive(),
}
}
pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
match self {
TcpStream::Uring(s) => s.set_linger(dur),
TcpStream::Poll(s) => s.set_linger(dur),
}
}
pub fn linger(&self) -> io::Result<Option<Duration>> {
match self {
TcpStream::Uring(s) => s.linger(),
TcpStream::Poll(s) => s.linger(),
}
}
pub fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
match self {
TcpStream::Uring(s) => s.set_recv_buffer_size(size),
TcpStream::Poll(s) => s.set_recv_buffer_size(size),
}
}
pub fn recv_buffer_size(&self) -> io::Result<usize> {
match self {
TcpStream::Uring(s) => s.recv_buffer_size(),
TcpStream::Poll(s) => s.recv_buffer_size(),
}
}
pub fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
match self {
TcpStream::Uring(s) => s.set_send_buffer_size(size),
TcpStream::Poll(s) => s.set_send_buffer_size(size),
}
}
pub fn send_buffer_size(&self) -> io::Result<usize> {
match self {
TcpStream::Uring(s) => s.send_buffer_size(),
TcpStream::Poll(s) => s.send_buffer_size(),
}
}
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
match self {
TcpStream::Uring(s) => s.set_ttl(ttl),
TcpStream::Poll(s) => s.set_ttl(ttl),
}
}
pub fn ttl(&self) -> io::Result<u32> {
match self {
TcpStream::Uring(s) => s.ttl(),
TcpStream::Poll(s) => s.ttl(),
}
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
match self {
TcpStream::Uring(s) => s.take_error(),
TcpStream::Poll(s) => s.take_error(),
}
}
pub fn as_raw_fd(&self) -> RawFd {
match self {
TcpStream::Uring(s) => s.as_raw_fd(),
TcpStream::Poll(s) => s.as_raw_fd(),
}
}
pub unsafe fn from_raw_fd(fd: RawFd) -> Self {
if crate::reactor::is_uring() {
TcpStream::Uring(unsafe { uring::TcpStream::from_raw_fd(fd) })
} else {
let std_stream =
unsafe { <std::net::TcpStream as std::os::unix::io::FromRawFd>::from_raw_fd(fd) };
TcpStream::Poll(
poll::TcpStream::from_std(std_stream)
.expect("failed to register raw TcpStream on poll fallback"),
)
}
}
}
impl AsRawFd for TcpStream {
fn as_raw_fd(&self) -> RawFd {
TcpStream::as_raw_fd(self)
}
}
define_stream_split!(TcpStream);
pub enum UdpSocket {
Uring(uring::UdpSocket),
Poll(poll::UdpSocket),
}
impl UdpSocket {
pub async fn bind(addr: impl ToAddrs) -> io::Result<Self> {
if crate::reactor::is_uring() {
uring::UdpSocket::bind(addr).await.map(UdpSocket::Uring)
} else {
poll::UdpSocket::bind(addr).await.map(UdpSocket::Poll)
}
}
pub fn bind_addr(addr: SocketAddr) -> io::Result<Self> {
if crate::reactor::is_uring() {
uring::UdpSocket::bind_addr(addr).map(UdpSocket::Uring)
} else {
poll::UdpSocket::bind_addr(addr).map(UdpSocket::Poll)
}
}
pub fn from_std(socket: std::net::UdpSocket) -> io::Result<Self> {
if crate::reactor::is_uring() {
uring::UdpSocket::from_std(socket).map(UdpSocket::Uring)
} else {
poll::UdpSocket::from_std(socket).map(UdpSocket::Poll)
}
}
pub async fn connect(&self, addr: impl ToAddrs) -> io::Result<()> {
match self {
UdpSocket::Uring(u) => u.connect(addr).await,
UdpSocket::Poll(u) => u.connect(addr).await,
}
}
pub fn connect_addr(&self, addr: SocketAddr) -> io::Result<()> {
match self {
UdpSocket::Uring(u) => u.connect_addr(addr),
UdpSocket::Poll(u) => u.connect_addr(addr),
}
}
pub fn local_addr(&self) -> io::Result<SocketAddr> {
match self {
UdpSocket::Uring(u) => u.local_addr(),
UdpSocket::Poll(u) => u.local_addr(),
}
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
match self {
UdpSocket::Uring(u) => u.peer_addr(),
UdpSocket::Poll(u) => u.peer_addr(),
}
}
pub async fn send<B>(&self, buf: B) -> BufResult<usize, B>
where
B: IoBuf + Send + Unpin + 'static,
{
match self {
UdpSocket::Uring(u) => u.send(buf).await,
UdpSocket::Poll(u) => u.send(buf).await,
}
}
pub async fn recv<B>(&self, buf: B) -> BufResult<usize, B>
where
B: IoBufMut + Send + Unpin + 'static,
{
match self {
UdpSocket::Uring(u) => u.recv(buf).await,
UdpSocket::Poll(u) => u.recv(buf).await,
}
}
pub async fn send_to<B>(&self, buf: B, target: SocketAddr) -> BufResult<usize, B>
where
B: IoBuf + Send + Unpin + 'static,
{
match self {
UdpSocket::Uring(u) => u.send_to(buf, target).await,
UdpSocket::Poll(u) => u.send_to(buf, target).await,
}
}
pub async fn recv_from<B>(&self, buf: B) -> (io::Result<(usize, SocketAddr)>, B)
where
B: IoBufMut + Send + Unpin + 'static,
{
match self {
UdpSocket::Uring(u) => u.recv_from(buf).await,
UdpSocket::Poll(u) => u.recv_from(buf).await,
}
}
pub fn try_send_to<B: IoBuf>(&self, buf: &B, target: SocketAddr) -> io::Result<usize> {
match self {
UdpSocket::Uring(u) => u.try_send_to(buf, target),
UdpSocket::Poll(u) => u.try_send_to(buf, target),
}
}
pub fn try_send<B: IoBuf>(&self, buf: &B) -> io::Result<usize> {
match self {
UdpSocket::Uring(u) => u.try_send(buf),
UdpSocket::Poll(u) => u.try_send(buf),
}
}
pub fn try_recv_from<B: IoBufMut>(&self, buf: B) -> (io::Result<(usize, SocketAddr)>, B) {
match self {
UdpSocket::Uring(u) => u.try_recv_from(buf),
UdpSocket::Poll(u) => u.try_recv_from(buf),
}
}
pub fn try_recv<B: IoBufMut>(&self, buf: B) -> BufResult<usize, B> {
match self {
UdpSocket::Uring(u) => u.try_recv(buf),
UdpSocket::Poll(u) => u.try_recv(buf),
}
}
pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
match self {
UdpSocket::Uring(u) => u.set_broadcast(on),
UdpSocket::Poll(u) => u.set_broadcast(on),
}
}
pub fn broadcast(&self) -> io::Result<bool> {
match self {
UdpSocket::Uring(u) => u.broadcast(),
UdpSocket::Poll(u) => u.broadcast(),
}
}
pub fn set_reuseaddr(&self, on: bool) -> io::Result<()> {
match self {
UdpSocket::Uring(u) => u.set_reuseaddr(on),
UdpSocket::Poll(u) => u.set_reuseaddr(on),
}
}
pub fn reuseaddr(&self) -> io::Result<bool> {
match self {
UdpSocket::Uring(u) => u.reuseaddr(),
UdpSocket::Poll(u) => u.reuseaddr(),
}
}
pub fn set_reuseport(&self, on: bool) -> io::Result<()> {
match self {
UdpSocket::Uring(u) => u.set_reuseport(on),
UdpSocket::Poll(u) => u.set_reuseport(on),
}
}
pub fn reuseport(&self) -> io::Result<bool> {
match self {
UdpSocket::Uring(u) => u.reuseport(),
UdpSocket::Poll(u) => u.reuseport(),
}
}
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
match self {
UdpSocket::Uring(u) => u.set_ttl(ttl),
UdpSocket::Poll(u) => u.set_ttl(ttl),
}
}
pub fn ttl(&self) -> io::Result<u32> {
match self {
UdpSocket::Uring(u) => u.ttl(),
UdpSocket::Poll(u) => u.ttl(),
}
}
pub fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
match self {
UdpSocket::Uring(u) => u.set_recv_buffer_size(size),
UdpSocket::Poll(u) => u.set_recv_buffer_size(size),
}
}
pub fn recv_buffer_size(&self) -> io::Result<usize> {
match self {
UdpSocket::Uring(u) => u.recv_buffer_size(),
UdpSocket::Poll(u) => u.recv_buffer_size(),
}
}
pub fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
match self {
UdpSocket::Uring(u) => u.set_send_buffer_size(size),
UdpSocket::Poll(u) => u.set_send_buffer_size(size),
}
}
pub fn send_buffer_size(&self) -> io::Result<usize> {
match self {
UdpSocket::Uring(u) => u.send_buffer_size(),
UdpSocket::Poll(u) => u.send_buffer_size(),
}
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
match self {
UdpSocket::Uring(u) => u.take_error(),
UdpSocket::Poll(u) => u.take_error(),
}
}
pub fn as_raw_fd(&self) -> RawFd {
match self {
UdpSocket::Uring(u) => u.as_raw_fd(),
UdpSocket::Poll(u) => u.as_raw_fd(),
}
}
}
impl AsRawFd for UdpSocket {
fn as_raw_fd(&self) -> RawFd {
UdpSocket::as_raw_fd(self)
}
}