#![cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
use std::{io, net::ToSocketAddrs, os::fd::AsFd, path::Path};
use tokio::net::{TcpSocket, UdpSocket, UnixDatagram, UnixListener};
use super::CapNetAgent;
pub trait TcpSocketExt {
fn cap_bind(
&self,
agent: &mut CapNetAgent,
addr: std::net::SocketAddr,
) -> io::Result<()>;
}
impl TcpSocketExt for TcpSocket {
fn cap_bind(
&self,
agent: &mut CapNetAgent,
addr: std::net::SocketAddr,
) -> io::Result<()> {
let sock = self.as_fd();
agent.bind_std_fd(sock, addr)
}
}
pub trait UdpSocketExt {
fn cap_bind<A: ToSocketAddrs>(
agent: &mut CapNetAgent,
addrs: A,
) -> io::Result<UdpSocket>;
}
impl UdpSocketExt for UdpSocket {
fn cap_bind<A: ToSocketAddrs>(
agent: &mut CapNetAgent,
addrs: A,
) -> io::Result<UdpSocket> {
let std_sock =
<std::net::UdpSocket as crate::std::UdpSocketExt>::cap_bind(
agent, addrs,
)?;
std_sock.set_nonblocking(true)?;
UdpSocket::from_std(std_sock)
}
}
pub trait UnixDatagramExt {
fn cap_bind<P>(
agent: &mut CapNetAgent,
path: P,
) -> io::Result<UnixDatagram>
where
P: AsRef<Path>;
}
impl UnixDatagramExt for UnixDatagram {
fn cap_bind<P>(agent: &mut CapNetAgent, path: P) -> io::Result<UnixDatagram>
where
P: AsRef<Path>,
{
let std_sock = <std::os::unix::net::UnixDatagram as crate::std::UnixDatagramExt>::cap_bind(
agent, path,
)?;
std_sock.set_nonblocking(true)?;
UnixDatagram::from_std(std_sock)
}
}
pub trait UnixListenerExt {
fn cap_bind<P>(
agent: &mut CapNetAgent,
path: P,
) -> io::Result<UnixListener>
where
P: AsRef<Path>;
}
impl UnixListenerExt for UnixListener {
fn cap_bind<P>(agent: &mut CapNetAgent, path: P) -> io::Result<UnixListener>
where
P: AsRef<Path>,
{
let std_sock = <std::os::unix::net::UnixListener as crate::std::UnixListenerExt>::cap_bind(
agent, path,
)?;
std_sock.set_nonblocking(true)?;
UnixListener::from_std(std_sock)
}
}