#[cfg(windows)]
use std::os::windows::io::OwnedSocket;
use std::
{
fmt,
io::{self, ErrorKind, IoSlice, IoSliceMut},
marker::PhantomData,
net::{Shutdown, SocketAddr, TcpListener, TcpStream, ToSocketAddrs, UdpSocket},
time::Duration
};
#[cfg(unix)]
use std::os::
{
fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd},
unix::net::{UnixDatagram, UnixListener, UnixStream}
};
#[cfg(unix)]
use uds_fork::{ UnixSeqpacketConn, UnixSeqpacketListener, nonblocking::UnixSeqpacketListener as NonBlkUnixSeqpacketListener };
#[cfg(windows)]
use uds_fork::{WindowsUnixListener, WindowsUnixStream};
#[cfg(unix)]
use crate::unix::
{
So9DomainRange
};
#[cfg(windows)]
use crate::windows::
{
So9DomainRange
};
use crate::
{
POLLIN, AsOsDescr, So9MsgFlags, So9SockDwFlags, So9SockType, So9SockProtocol, Socket9ExtIp, Socket9ExtIp6, Socket9ExtIpTcp,
Socket9ExtIpTcpExt, Socket9ExtSo, SocketTypeImps,
address::
{
IntoSockAddrSpec, So9AddrDomain, So9AddrIntoRaw
},
socket_split::{Socket9Read, Socket9Write}
};
use crate::address::So9SocketAddr;
#[cfg(unix)]
pub trait So9MarkerSockUnix{}
pub trait So9MarkerStateless{}
pub trait So9MarkerBind{}
pub trait So9MarkerListener
{
const SOCK_ACCEPT_FLAGS: i32;
type AcceptedType: So9Marker;
}
#[cfg(unix)]
pub trait So9MarkerPairable
{
fn pair() -> io::Result<(OwnedFd, OwnedFd)> where Self: Sized;
}
#[cfg(windows)]
pub trait So9MarkerPairableWin: So9Marker
{
fn pair() -> io::Result<(Socket9<Self>, Socket9<Self>)> where Self: Sized;
}
pub trait So9Marker: fmt::Debug + From<Socket9<Self>>
{
type SockType: SocketTypeImps;
const IS_LISTENING: bool;
const SO_DOMAIN_GROUP: So9DomainRange;
const SO_TYPE: So9SockType;
const SO_DEF_FLAGS: So9SockDwFlags;
const SO_PROTO: So9SockProtocol;
const SOCK_SND_FLAGS: So9MsgFlags;
const SOCK_SND_VECT_FLAGS: So9MsgFlags;
const SOCK_RCV_FLAGS: So9MsgFlags;
const SOCK_RCV_VECT_FLAGS: So9MsgFlags;
type SockAddrType: TryFrom<So9SocketAddr, Error = io::Error> + So9AddrIntoRaw + So9AddrDomain + IntoSockAddrSpec<Self::SockAddrType> + Clone + PartialEq + fmt::Debug;
type SockAddrDomain: So9AddrDomain;
}
fn check_proto<M: So9Marker>(so_proto: Option<So9SockProtocol>) -> io::Result<()>
{
if let Some(so_pr) = so_proto
{
if M::SO_PROTO != so_pr
{
return Err(
io::Error::new(ErrorKind::InvalidData,
format!("so_proto mismatch exp: {:?}, rcv: {:?}", M::SO_PROTO, so_proto))
);
}
}
return Ok(());
}
#[derive(Debug)]
pub struct Socket9<SO: So9Marker>
{
ofd: SO::SockType,
_p: PhantomData<SO>
}
impl<SO: So9Marker> Socket9<SO>
{
pub
fn new_unbound(remote_addr_type: SO::SockAddrDomain) -> io::Result<Socket9<SO>>
{
return
SO::SockType::new_sock(remote_addr_type.get_addr_domain(), SO::SO_TYPE, SO::SO_PROTO, SO::SO_DEF_FLAGS)
.map(
|a|
Self::new_internal(a),
);
}
pub
fn new_unbound_into<S: So9AddrDomain>(remote_addr_type: &S) -> io::Result<Socket9<SO>>
{
let so_dom = remote_addr_type.get_addr_domain();
return
SO::SockType::new_sock(so_dom, SO::SO_TYPE, SO::SO_PROTO, SO::SO_DEF_FLAGS)
.map(
|a|
Self::new_internal(a),
);
}
pub
fn new_unbound_by_addr<S>(remote_addr_type: S) -> io::Result<Socket9<SO>>
where
S: IntoSockAddrSpec<SO::SockAddrType>
{
let sa_addr = remote_addr_type.from_type()?;
let new_sock = Self::new_with_internal(sa_addr.get_addr_domain())?;
return Ok(new_sock);
}
fn new_internal(ofd: <SO as So9Marker>::SockType) -> Socket9<SO>
{
return
Self
{
ofd:
ofd,
_p:
PhantomData,
};
}
fn new_with_internal<SA: So9AddrDomain>(remote_addr_type: SA) -> io::Result<Socket9<SO>>
{
let new_sock =
SO::SockType::new_sock(remote_addr_type.get_addr_domain(), SO::SO_TYPE, SO::SO_PROTO, SO::SO_DEF_FLAGS)
.map(
|a|
Self::new_internal(a),
)?;
return Ok(new_sock);
}
fn bind_internal<A: So9AddrIntoRaw>(&self, addr: &A) -> io::Result<()>
{
self.ofd.bind_sock(addr)
}
pub
fn to_sock_addr<A, F>(addr: A, mut so_op: F) -> io::Result<Socket9<SO>>
where
A: ToSocketAddrs,
F: FnMut(SocketAddr) -> io::Result<Socket9<SO>>,
{
let mut err = None;
for addr in addr.to_socket_addrs()?
{
match (so_op)(addr)
{
Ok(res) =>
return Ok(res),
Err(e) =>
{
err.replace(e);
}
}
}
return
err
.map_or(
Err(io::Error::new(ErrorKind::InvalidInput, "could not resolve to any addresses")),
|e| Err(e)
);
}
pub
fn to_sock_addr_no<A, F, RET>(addr: A, mut so_op: F) -> io::Result<RET>
where
A: ToSocketAddrs,
F: FnMut(SocketAddr) -> io::Result<RET>,
{
let mut err = None;
for addr in addr.to_socket_addrs()?
{
match (so_op)(addr)
{
Ok(r) =>
return Ok(r),
Err(e) =>
{
err.replace(e);
}
}
}
return
err
.map_or(
Err(io::Error::new(ErrorKind::InvalidInput, "could not resolve to any addresses")),
|e| Err(e)
);
}
}
impl<SO: So9Marker + So9MarkerBind> Socket9<SO>
{
pub
fn new_with_bind<S>(local_addr: &S) -> io::Result<Socket9<SO>>
where
S: IntoSockAddrSpec<SO::SockAddrType>
{
let local_addr_s = local_addr.from_type()?;
let new_sock = Self::new_with_internal(local_addr_s.get_addr_domain())?;
new_sock.bind_internal(local_addr_s.as_ref())?;
return Ok(new_sock);
}
pub
fn bind<S>(&self, sa: &S) -> io::Result<()>
where
S: IntoSockAddrSpec<SO::SockAddrType>
{
self.bind_internal(sa.from_type()?.as_ref())
}
}
impl<SO: So9Marker + So9MarkerListener> Socket9<SO>
{
pub
fn new_with_bind_listen<S>(local_addr: &S, backlog: i32) -> io::Result<Socket9<SO>>
where
S: IntoSockAddrSpec<SO::SockAddrType>
{
let local_addr_s = local_addr.from_type()?;
let new_sock = Self::new_with_internal(local_addr_s.get_addr_domain())?;
new_sock.bind_internal(local_addr_s.as_ref())?;
new_sock.listen(backlog)?;
return Ok(new_sock);
}
pub
fn listen(&self, backlog: i32) -> io::Result<()>
{
self.ofd.listen_sock(backlog)
}
pub
fn accept(&self) -> io::Result<(Socket9<<SO as So9MarkerListener>::AcceptedType>, SO::SockAddrType)>
{
self.accept_with_flags(SO::SOCK_ACCEPT_FLAGS)
}
pub
fn accept_with_flags(&self, flags: i32) -> io::Result<(Socket9<<SO as So9MarkerListener>::AcceptedType>, SO::SockAddrType)>
{
self
.ofd
.accept_with_flags::<SO::SockAddrType, <<SO as So9MarkerListener>::AcceptedType as So9Marker>::SockType>(flags)
.map(|(ofd, addr)|
( Socket9::<<SO as So9MarkerListener>::AcceptedType>::new_internal(ofd), addr)
)
}
pub
fn accept_timeout(&self, timeout: Duration) -> io::Result<(Socket9<<SO as So9MarkerListener>::AcceptedType>, SO::SockAddrType)>
{
self.set_nonblocking(true)?;
let res = self.accept();
self.set_nonblocking(false)?;
match res
{
Ok(r) =>
return Ok(r),
Err(e) =>
{
if e.kind() == ErrorKind::WouldBlock
{
self.ofd.poll_sock(POLLIN, timeout)?;
return self.accept();
}
else
{
return Err(e);
}
}
}
}
}
impl<SO: So9Marker<SockAddrType = SocketAddr> + So9MarkerListener> Socket9<SO>
{
pub
fn new_with_bind_hostname_listen<A>(addr: A, backlog: i32) -> io::Result<Socket9<SO>>
where
A: ToSocketAddrs
{
Self::to_sock_addr(addr,
|addr|
{
Socket9::<SO>::new_with_bind_listen(&addr, backlog)
}
)
}
}
impl<SO: So9Marker<SockAddrType = SocketAddr> + So9MarkerBind> Socket9<SO>
{
pub
fn new_with_bind_host<A>(addr: A) -> io::Result<Socket9<SO>>
where
A: ToSocketAddrs
{
Self::to_sock_addr(addr,
|addr|
{
Socket9::<SO>::new_with_bind(&addr)
}
)
}
pub
fn bind_host<A>(&self, addr: A) -> io::Result<()>
where
A: ToSocketAddrs
{
Self::to_sock_addr_no(addr,
|addr|
{
self.bind_internal(&addr)
}
)
}
}
impl<SO: So9Marker<SockAddrType = SocketAddr>> Socket9<SO>
{
pub
fn connect_host_unbound<A>(addr: A) -> io::Result<Self>
where
A: ToSocketAddrs
{
Self::to_sock_addr(addr,
|addr|
{
Self::connect_unbound(&addr)
}
)
}
pub
fn connect_host<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()>
{
Self::to_sock_addr_no(addr,
|addr|
{
self.connect(&addr)
}
)
}
pub
fn connect_host_timeout<A: ToSocketAddrs>(&self, addr: A, timeout: Duration) -> io::Result<()>
{
Self::to_sock_addr_no(addr,
|addr|
{
self.connect_timeout(&addr, timeout)
}
)
}
}
impl<SO: So9Marker> Socket9<SO>
{
pub
fn connect_unbound<S>(dst_addr: S) -> io::Result<Self>
where
S: IntoSockAddrSpec<SO::SockAddrType>
{
let addr = dst_addr.from_type()?;
let sock = Self::new_unbound_into(addr.as_ref())?;
sock.connect(dst_addr)?;
return Ok(sock);
}
pub
fn connect<S>(&self, dst_addr: S) -> io::Result<()>
where
S: IntoSockAddrSpec<SO::SockAddrType>
{
self.ofd.connect_sock(dst_addr.from_type()?.as_ref())
}
pub
fn connect_timeout<S>(&self, dst_addr: S, timeout: Duration) -> io::Result<()>
where
S: IntoSockAddrSpec<SO::SockAddrType>
{
self.set_nonblocking(true)?;
let res = self.connect(dst_addr);
self.set_nonblocking(false)?;
let poll_res =
if let Err(e) = res
{
#[cfg(unix)]
let einprogress =
e.raw_os_error() == Some(libc::EINPROGRESS);
#[cfg(windows)]
let einprogress = false;
if e.kind() == ErrorKind::WouldBlock || einprogress == true
{
self.ofd.poll_connect_sock(timeout)
}
else
{
Err(e)
}
}
else
{
Ok(())
};
return poll_res;
}
}
#[cfg(unix)]
impl<SO: So9Marker<SockType = OwnedFd> + So9MarkerPairable> Socket9<SO>
{
pub
fn pair() -> io::Result<(Self, Self)>
{
let (a, b) = SO::pair()?;
let a = Socket9::<SO>::try_from(a)?;
let b = Socket9::<SO>::try_from(b)?;
a.set_cloexec_sock(true)?;
b.set_cloexec_sock(true)?;
return Ok((a, b));
}
}
#[cfg(windows)]
impl<SO: So9Marker + So9MarkerPairableWin> Socket9<SO>
{
pub
fn pair() -> io::Result<(Self, Self)>
{
let (a, b) = SO::pair()?;
a.set_cloexec_sock(true)?;
b.set_cloexec_sock(true)?;
return Ok((a, b));
}
}
impl<SO: So9Marker> Socket9<SO>
{
pub
fn local_addr(&self) -> io::Result<SO::SockAddrType>
{
self.ofd.get_socket_local_addr()
}
pub
fn peer_addr(&self) -> io::Result<SO::SockAddrType>
{
self.ofd.get_socket_peer_addr()
}
pub
fn try_clone(&self) -> io::Result<Socket9<SO>>
{
let ofd = self.ofd.try_clone_sock(SO::SO_DEF_FLAGS)?;
return Ok(
Self
{
ofd:
ofd,
_p:
PhantomData
});
}
pub
fn try_split(self) -> Result<(Socket9Read<SO>, Socket9Write<SO>), (Self, io::Error)>
{
if let Err(e) = self.set_nonblocking(true)
{
return Err((self, e));
}
let clonned =
match self.try_clone()
{
Ok(r) => r,
Err(e) =>
{
if let Err(e) = self.set_nonblocking(false)
{
return Err((self, e));
}
return Err((self, e));
},
};
let orig_fd = self.ofd.get_raw();
let write_p = Socket9Write::<SO>::new(self, orig_fd);
let read_p = Socket9Read::<SO>::new(clonned, orig_fd);
return Ok((read_p, write_p));
}
pub
fn try_unsplit(so9r: Socket9Read<SO>, so9w: Socket9Write<SO>) -> io::Result<Self>
{
if so9r != so9w
{
return Err(
io::Error::new(ErrorKind::Other,
format!("read protion belongs to other write portion: {:?} {:?}",
so9r, so9w)
)
)
}
let _ = so9r.take();
let so9write = so9w.take();
return Ok(so9write);
}
#[cfg(unix)]
pub
fn is_nonblocking(&self) -> io::Result<bool>
{
self.ofd.is_nonblocking_sock()
}
pub
fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()>
{
self.ofd.set_nonblocking_sock(nonblocking)
}
pub
fn set_cloexec_sock(&self, cloexec: bool) -> io::Result<()>
{
self.ofd.set_cloexec_sock(cloexec)
}
#[cfg(unix)]
pub
fn is_cloexec_sock(&self) -> io::Result<bool>
{
self.ofd.is_cloexec_sock()
}
pub
fn shutdown(&self, how: Shutdown) -> io::Result<()>
{
self.ofd.shutdown_sock(how)
}
pub
fn send(&self, data: &[u8]) -> Result<usize, io::Error>
{
self.send_with_flags(data, SO::SOCK_SND_FLAGS)
}
pub
fn send_with_flags(&self, data: &[u8], flags: So9MsgFlags) -> Result<usize, io::Error>
{
self.ofd.send_with_flags(data, flags)
}
pub
fn send_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize>
{
self.ofd.send_vectored(bufs)
}
pub
fn recv(&self, buffer: &mut[u8]) -> Result<usize, io::Error>
{
self.recv_with_flags(buffer, SO::SOCK_RCV_FLAGS.bits())
}
pub
fn recv_with_flags(&self, buffer: &mut[u8], flags: i32) -> Result<usize, io::Error>
{
self.ofd.recv_with_flags(buffer, flags)
}
pub
fn recv_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>
{
self.ofd.recv_vectored_flags(bufs, 0).map(|(sz, _)| sz)
}
pub
fn peek(&self, buf: &mut [u8]) -> io::Result<usize>
{
self.recv_with_flags(buf, SO::SOCK_RCV_FLAGS.union(So9MsgFlags::MSG_PEEK).bits())
}
}
impl<SO: So9Marker<SockAddrType = SocketAddr> + So9MarkerStateless> Socket9<SO>
{
pub
fn send_to_host<A>(&self, buf: &[u8], addr_to: A) -> io::Result<usize>
where
A: ToSocketAddrs
{
self.send_to_host_with_flags(buf, addr_to, SO::SOCK_SND_FLAGS.bits())
}
pub
fn send_to_host_with_flags<A>(&self, buf: &[u8], addr_to: A, flags: i32) -> io::Result<usize>
where
A: ToSocketAddrs
{
Self::to_sock_addr_no(addr_to,
|addr|
{
self.send_to_with_flags(buf, &addr, flags)
}
)
}
pub
fn send_to_host_vectored<A>(&self, buffers: &[IoSlice<'_>], addr_to: A) -> io::Result<usize>
where
A: ToSocketAddrs
{
self.send_to_host_vectored_with_flags(buffers, addr_to, SO::SOCK_SND_VECT_FLAGS)
}
pub
fn send_to_host_vectored_with_flags<A>(&self, buffers: &[IoSlice<'_>], addr_to: A, flags: So9MsgFlags) -> io::Result<usize>
where
A: ToSocketAddrs
{
Self::to_sock_addr_no(addr_to,
|addr|
{
self.ofd.send_to_sock_vect(&addr, buffers, flags.bits())
}
)
}
}
impl<SO: So9Marker + So9MarkerStateless> Socket9<SO>
{
pub
fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SO::SockAddrType)>
{
self.recv_from(buf, SO::SOCK_RCV_FLAGS.union(So9MsgFlags::MSG_PEEK))
}
pub
fn recv_from(&self, buf: &mut [u8], flags: So9MsgFlags) -> io::Result<(usize, SO::SockAddrType)>
{
self.ofd.recv_from(buf, flags.bits())
}
pub
fn recv_from_flags_timeout(&self, buf: &mut [u8], flags: So9MsgFlags, timeout: Duration) -> io::Result<(usize, SO::SockAddrType)>
{
let Err(e) = self.ofd.poll_sock(POLLIN, timeout)
else
{
return self.recv_from(buf, flags);
};
return Err(e);
}
pub
fn recv_from_vectored(&self, buffers: &mut[IoSliceMut]) -> io::Result<(usize, SO::SockAddrType)>
{
self
.recv_from_flags_vectored(buffers, SO::SOCK_RCV_VECT_FLAGS)
.map(|(sz, _, from)| (sz, from))
}
pub
fn recv_from_flags_vectored(&self, buffers: &mut[IoSliceMut], flags: So9MsgFlags) -> io::Result<(usize, So9MsgFlags, SO::SockAddrType)>
{
self
.ofd
.recv_vect_from_flags(buffers, true, flags.bits())
.map(|(sz, flags, from)| (sz, flags, from.unwrap()))
}
pub
fn recv_from_flags_vectored_timeout(&self, buffers: &mut[IoSliceMut], flags: So9MsgFlags, timeout: Duration) -> io::Result<(usize, So9MsgFlags, SO::SockAddrType)>
{
let Err(e) = self.ofd.poll_sock(POLLIN, timeout)
else
{
return self.recv_from_flags_vectored(buffers, flags);
};
return Err(e);
}
pub
fn send_to<S>(&self, buf: &[u8], addr_to: &S) -> io::Result<usize>
where
S: IntoSockAddrSpec<SO::SockAddrType>
{
self.send_to_with_flags(buf, addr_to, SO::SOCK_SND_FLAGS.bits())
}
pub
fn send_to_with_flags<S>(&self, buf: &[u8], addr_to: &S, flags: i32) -> io::Result<usize>
where
S: IntoSockAddrSpec<SO::SockAddrType>
{
let addr = addr_to.from_type()?;
self.ofd.send_to_sock(addr.as_ref(), buf, flags)
}
pub
fn send_to_vectored<S>(&self, buffers: &[IoSlice<'_>], addr_to: &S) -> io::Result<usize>
where
S: IntoSockAddrSpec<SO::SockAddrType>
{
self.send_to_vectored_with_flags(buffers, addr_to, SO::SOCK_SND_VECT_FLAGS)
}
pub
fn send_to_vectored_with_flags<S>(&self, buffers: &[IoSlice<'_>], addr_to: &S, flags: So9MsgFlags) -> io::Result<usize>
where
S: IntoSockAddrSpec<SO::SockAddrType>
{
let addr = addr_to.from_type()?;
self.ofd.send_to_sock_vect(addr.as_ref(), buffers, flags.bits())
}
}
#[cfg(unix)]
impl<SO: So9Marker + So9MarkerSockUnix> Socket9<SO>
{
pub
fn send_vectored_with(&self, slices: &[IoSlice]) -> io::Result<usize>
{
self.send_vectored_with_flags(slices, SO::SOCK_SND_VECT_FLAGS)
}
pub
fn send_vectored_with_flags(&self, slices: &[IoSlice], flags: So9MsgFlags) -> io::Result<usize>
{
self.ofd.send_vect_with_flags::<SO::SockAddrType>(slices, None,flags.bits())
}
}
#[cfg(unix)]
impl<SO: So9Marker + So9MarkerSockUnix> Socket9<SO>
{
pub
fn send_fd(&self, fd: OwnedFd) -> io::Result<usize>
{
self.send_fd_with_flags(fd, SO::SOCK_SND_FLAGS)
}
pub
fn send_fd_with_flags(&self, fd: OwnedFd, flags: So9MsgFlags) -> io::Result<usize>
{
self.ofd.send_fd_with_flags(fd, flags.bits())
}
pub
fn recv_vectored_with(&self, buffers: &mut[IoSliceMut]) -> io::Result<usize>
{
self.recv_vectored_flags(buffers, SO::SOCK_RCV_VECT_FLAGS)
.map(|(sz, _)| sz)
}
pub
fn recv_vectored_from(&self, buffers: &mut[IoSliceMut]) -> io::Result<(usize, SO::SockAddrType)>
{
self.recv_vectored_from_flags(buffers, SO::SOCK_RCV_VECT_FLAGS)
.map(|(sz, _, from)| (sz, from))
}
pub
fn recv_vectored_flags(&self, buffers: &mut[IoSliceMut], flags: So9MsgFlags) -> io::Result<(usize, So9MsgFlags)>
{
self
.ofd
.recv_vect_from_flags::<SO::SockAddrType>(buffers, false, flags.bits())
.map(|(sz, msg_flags, _)| (sz, msg_flags))
}
pub
fn recv_vectored_from_flags(&self, buffers: &mut[IoSliceMut], flags: So9MsgFlags) -> io::Result<(usize, So9MsgFlags, SO::SockAddrType)>
{
self
.ofd
.recv_vect_from_flags::<SO::SockAddrType>(buffers, true, flags.bits())
.map(
|(sz, msg_flags, sa_opt)|
(sz, msg_flags, sa_opt.unwrap())
)
}
pub
fn recv_fd(&self) -> io::Result<OwnedFd>
{
self.recv_fd_with_flags(SO::SOCK_RCV_FLAGS)
.map(|(ofd, _)| ofd)
}
pub
fn recv_fd_with_flags(&self, flags: So9MsgFlags) -> io::Result<(OwnedFd, So9MsgFlags)>
{
self
.ofd
.recv_fd(flags.bits())
}
}
impl<SO: So9Marker> io::Read for Socket9<SO>
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
{
self.recv(buf)
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>
{
self.recv_vectored(bufs)
}
}
impl<'temp, SO: So9Marker> io::Read for &'temp Socket9<SO>
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
{
self.recv(buf)
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>
{
self.recv_vectored(bufs)
}
}
impl<SO: So9Marker> io::Write for Socket9<SO>
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize>
{
self.send(buf)
}
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>
{
self.send_vectored(bufs)
}
fn flush(&mut self) -> io::Result<()>
{
Ok(())
}
}
impl<'temp, SO: So9Marker> io::Write for &'temp Socket9<SO>
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize>
{
self.send(buf)
}
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>
{
self.send_vectored(bufs)
}
fn flush(&mut self) -> io::Result<()>
{
Ok(())
}
}
#[cfg(unix)]
pub mod unix_socket9
{
use super::*;
impl<SO: So9Marker<SockType = OwnedFd>> FromRawFd for Socket9<SO>
{
unsafe
fn from_raw_fd(fd: RawFd) -> Self
{
let ofd = unsafe { OwnedFd::from_raw_fd(fd) };
return Socket9::<SO>::try_from(ofd).unwrap();
}
}
impl<SO: So9Marker> AsFd for Socket9<SO>
{
fn as_fd(&self) -> BorrowedFd<'_>
{
return self.ofd.as_fd();
}
}
impl<SO: So9Marker> AsRawFd for Socket9<SO>
{
fn as_raw_fd(&self) -> RawFd
{
return self.ofd.as_raw_fd();
}
}
impl<SO: So9Marker<SockType = OwnedFd>> From<Socket9<SO>> for OwnedFd
{
fn from(value: Socket9<SO>) -> Self
{
return value.ofd;
}
}
impl<SO: So9Marker<SockType = OwnedFd>> TryFrom<OwnedFd> for Socket9<SO>
{
type Error = io::Error;
fn try_from(ofd: OwnedFd) -> Result<Socket9<SO>, Self::Error>
{
let inst =
Self
{
ofd:
ofd,
_p:
PhantomData,
};
let is_accepting = inst.ofd.get_so_listening_status()?;
if SO::IS_LISTENING != is_accepting
{
return Err(
io::Error::new(ErrorKind::InvalidData,
format!("expected listening: {}, got: {}", SO::IS_LISTENING, is_accepting))
);
}
let sock_fam = inst.ofd.get_socket_addr_type()?;
SO::SO_DOMAIN_GROUP.check_fam(sock_fam)?;
let so_type = inst.ofd.get_so_type()?;
if so_type != SO::SO_TYPE
{
return Err(
io::Error::new(ErrorKind::InvalidData,
format!("expected sock type: {}, got: {}", SO::SO_TYPE, so_type))
);
}
check_proto::<SO>(inst.ofd.get_socket_proto()?)?;
return Ok(inst);
}
}
}
#[cfg(windows)]
pub mod unix_socket9
{
use std::os::windows::io::{AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, RawSocket};
use super::*;
impl<SO: So9Marker<SockType = OwnedSocket>> FromRawSocket for Socket9<SO>
{
unsafe
fn from_raw_socket(sock: RawSocket) -> Self
{
let ofd = unsafe { OwnedSocket::from_raw_socket(sock) };
return Socket9::<SO>::try_from(ofd).unwrap();
}
}
impl<SO: So9Marker> AsSocket for Socket9<SO>
{
fn as_socket(&self) -> BorrowedSocket<'_>
{
return self.ofd.as_socket();
}
}
impl<SO: So9Marker> AsRawSocket for Socket9<SO>
{
fn as_raw_socket(&self) -> RawSocket
{
return self.ofd.as_raw_socket();
}
}
impl<SO: So9Marker<SockType = OwnedSocket>> From<Socket9<SO>> for OwnedSocket
{
fn from(value: Socket9<SO>) -> Self
{
return value.ofd;
}
}
impl<SO: So9Marker<SockType = OwnedSocket>> TryFrom<OwnedSocket> for Socket9<SO>
{
type Error = io::Error;
fn try_from(ofd: OwnedSocket) -> Result<Socket9<SO>, Self::Error>
{
let inst =
Self
{
ofd:
ofd,
_p:
PhantomData,
};
let sock_fam = inst.ofd.get_socket_addr_type()?;
SO::SO_DOMAIN_GROUP.check_fam(sock_fam)?;
let sotype = inst.ofd.get_so_type()?;
if sotype != SO::SO_TYPE
{
return Err(
io::Error::new(ErrorKind::InvalidData,
format!("expected sock type: {}, got: {}", SO::SO_TYPE, sotype))
);
}
if sotype == So9SockType::STREAM
{
let is_accepting = inst.ofd.get_so_listening_status()?;
if SO::IS_LISTENING != is_accepting
{
return Err(
io::Error::new(ErrorKind::InvalidData,
format!("expected listening: {}, got: {}", SO::IS_LISTENING, is_accepting))
);
}
}
check_proto::<SO>(inst.ofd.get_socket_proto()?)?;
return Ok(inst);
}
}
}
impl<SO: So9Marker> AsOsDescr for Socket9<SO>{}
impl From<Socket9<TcpListener>> for TcpListener
{
fn from(value: Socket9<TcpListener>) -> Self
{
return TcpListener::from(value.ofd);
}
}
impl Socket9ExtSo for Socket9<TcpListener> {}
impl Socket9ExtIp for Socket9<TcpListener> {}
impl Socket9ExtIp6 for Socket9<TcpListener> {}
impl From<Socket9<TcpStream>> for TcpStream
{
fn from(value: Socket9<TcpStream>) -> Self
{
return TcpStream::from(value.ofd);
}
}
impl Socket9ExtSo for Socket9<TcpStream> {}
impl Socket9ExtIp for Socket9<TcpStream> {}
impl Socket9ExtIp6 for Socket9<TcpStream> {}
impl Socket9ExtIpTcp for Socket9<TcpStream> {}
impl Socket9ExtIpTcpExt for Socket9<TcpStream> {}
impl From<Socket9<UdpSocket>> for UdpSocket
{
fn from(value: Socket9<UdpSocket>) -> Self
{
return UdpSocket::from(value.ofd);
}
}
impl Socket9ExtSo for Socket9<UdpSocket> {}
impl Socket9ExtIp for Socket9<UdpSocket> {}
impl Socket9ExtIp6 for Socket9<UdpSocket> {}
#[cfg(windows)]
pub mod windows_from_so9
{
use std::os::windows::io::IntoRawSocket;
use super::*;
impl From<Socket9<WindowsUnixStream>> for WindowsUnixStream
{
fn from(value: Socket9<WindowsUnixStream>) -> Self
{
return WindowsUnixStream::from(value.ofd);
}
}
impl Socket9ExtSo for Socket9<WindowsUnixStream> {}
impl From<Socket9<WindowsUnixListener>> for WindowsUnixListener
{
fn from(value: Socket9<WindowsUnixListener>) -> Self
{
return WindowsUnixListener::from(value.ofd);
}
}
impl Socket9ExtSo for Socket9<WindowsUnixListener> {}
}
#[cfg(unix)]
pub mod unix_from_so9
{
use super::*;
impl From<Socket9<UnixDatagram>> for UnixDatagram
{
fn from(value: Socket9<UnixDatagram>) -> Self
{
return UnixDatagram::from(value.ofd);
}
}
impl Socket9ExtSo for Socket9<UnixDatagram> {}
impl From<Socket9<UnixStream>> for UnixStream
{
fn from(value: Socket9<UnixStream>) -> Self
{
return UnixStream::from(value.ofd);
}
}
impl Socket9ExtSo for Socket9<UnixStream> {}
impl From<Socket9<UnixListener>> for UnixListener
{
fn from(value: Socket9<UnixListener>) -> Self
{
return UnixListener::from(value.ofd);
}
}
impl Socket9ExtSo for Socket9<UnixListener> {}
impl From<Socket9<UnixSeqpacketListener>> for UnixSeqpacketListener
{
fn from(value: Socket9<UnixSeqpacketListener>) -> Self
{
return UnixSeqpacketListener::from(value.ofd);
}
}
impl Socket9ExtSo for Socket9<UnixSeqpacketListener> {}
impl From<Socket9<UnixSeqpacketConn>> for UnixSeqpacketConn
{
fn from(value: Socket9<UnixSeqpacketConn>) -> Self
{
return UnixSeqpacketConn::from(value.ofd);
}
}
impl Socket9ExtSo for Socket9<UnixSeqpacketConn> {}
impl From<Socket9<NonBlkUnixSeqpacketListener>> for NonBlkUnixSeqpacketListener
{
fn from(value: Socket9<NonBlkUnixSeqpacketListener>) -> Self
{
return NonBlkUnixSeqpacketListener::from(value.ofd);
}
}
}
#[cfg(test)]
mod test_socket_int
{
use crate::So9SockDomain;
use super::*;
#[test]
fn check_domain_range()
{
So9DomainRange::DoUnixs.check_fam(So9SockDomain::UNIX).unwrap();
assert_eq!(So9DomainRange::DoUnixs.check_fam(So9SockDomain::IPV4).is_err(),
true);
So9DomainRange::DoInets.check_fam(So9SockDomain::IPV4).unwrap();
So9DomainRange::DoInets.check_fam(So9SockDomain::IPV6).unwrap();
assert_eq!(So9DomainRange::DoInets.check_fam(So9SockDomain::UNIX).is_err(),
true);
}
}