2019-07-18 13:05:40 +02:00
|
|
|
use std::{fmt, io, net};
|
|
|
|
|
|
|
|
use tokio_io::{AsyncRead, AsyncWrite};
|
2019-11-14 13:38:24 +01:00
|
|
|
use tokio_net::driver::Handle;
|
|
|
|
use tokio_net::tcp::TcpStream;
|
2019-07-18 13:05:40 +02:00
|
|
|
|
|
|
|
pub(crate) enum StdListener {
|
|
|
|
Tcp(net::TcpListener),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
Uds(std::os::unix::net::UnixListener),
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) enum SocketAddr {
|
|
|
|
Tcp(net::SocketAddr),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
Uds(std::os::unix::net::SocketAddr),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for SocketAddr {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
match *self {
|
|
|
|
SocketAddr::Tcp(ref addr) => write!(f, "{}", addr),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
SocketAddr::Uds(ref addr) => write!(f, "{:?}", addr),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for SocketAddr {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
match *self {
|
|
|
|
SocketAddr::Tcp(ref addr) => write!(f, "{:?}", addr),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
SocketAddr::Uds(ref addr) => write!(f, "{:?}", addr),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for StdListener {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
match *self {
|
|
|
|
StdListener::Tcp(ref lst) => write!(f, "{}", lst.local_addr().ok().unwrap()),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
StdListener::Uds(ref lst) => write!(f, "{:?}", lst.local_addr().ok().unwrap()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl StdListener {
|
|
|
|
pub(crate) fn local_addr(&self) -> SocketAddr {
|
|
|
|
match self {
|
|
|
|
StdListener::Tcp(lst) => SocketAddr::Tcp(lst.local_addr().unwrap()),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
StdListener::Uds(lst) => SocketAddr::Uds(lst.local_addr().unwrap()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn into_listener(self) -> SocketListener {
|
|
|
|
match self {
|
|
|
|
StdListener::Tcp(lst) => SocketListener::Tcp(
|
|
|
|
mio::net::TcpListener::from_std(lst)
|
|
|
|
.expect("Can not create mio::net::TcpListener"),
|
|
|
|
),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
StdListener::Uds(lst) => SocketListener::Uds(
|
|
|
|
mio_uds::UnixListener::from_listener(lst)
|
|
|
|
.expect("Can not create mio_uds::UnixListener"),
|
|
|
|
),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum StdStream {
|
|
|
|
Tcp(std::net::TcpStream),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
Uds(std::os::unix::net::UnixStream),
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) enum SocketListener {
|
|
|
|
Tcp(mio::net::TcpListener),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
Uds(mio_uds::UnixListener),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SocketListener {
|
|
|
|
pub(crate) fn accept(&self) -> io::Result<Option<(StdStream, SocketAddr)>> {
|
|
|
|
match *self {
|
|
|
|
SocketListener::Tcp(ref lst) => lst
|
|
|
|
.accept_std()
|
|
|
|
.map(|(stream, addr)| Some((StdStream::Tcp(stream), SocketAddr::Tcp(addr)))),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
SocketListener::Uds(ref lst) => lst.accept_std().map(|res| {
|
|
|
|
res.map(|(stream, addr)| (StdStream::Uds(stream), SocketAddr::Uds(addr)))
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl mio::Evented for SocketListener {
|
|
|
|
fn register(
|
|
|
|
&self,
|
|
|
|
poll: &mio::Poll,
|
|
|
|
token: mio::Token,
|
|
|
|
interest: mio::Ready,
|
|
|
|
opts: mio::PollOpt,
|
|
|
|
) -> io::Result<()> {
|
|
|
|
match *self {
|
|
|
|
SocketListener::Tcp(ref lst) => lst.register(poll, token, interest, opts),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
SocketListener::Uds(ref lst) => lst.register(poll, token, interest, opts),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn reregister(
|
|
|
|
&self,
|
|
|
|
poll: &mio::Poll,
|
|
|
|
token: mio::Token,
|
|
|
|
interest: mio::Ready,
|
|
|
|
opts: mio::PollOpt,
|
|
|
|
) -> io::Result<()> {
|
|
|
|
match *self {
|
|
|
|
SocketListener::Tcp(ref lst) => lst.reregister(poll, token, interest, opts),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
SocketListener::Uds(ref lst) => lst.reregister(poll, token, interest, opts),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn deregister(&self, poll: &mio::Poll) -> io::Result<()> {
|
|
|
|
match *self {
|
|
|
|
SocketListener::Tcp(ref lst) => lst.deregister(poll),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
SocketListener::Uds(ref lst) => {
|
|
|
|
let res = lst.deregister(poll);
|
|
|
|
|
|
|
|
// cleanup file path
|
|
|
|
if let Ok(addr) = lst.local_addr() {
|
|
|
|
if let Some(path) = addr.as_pathname() {
|
|
|
|
let _ = std::fs::remove_file(path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
res
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait FromStream: AsyncRead + AsyncWrite + Sized {
|
|
|
|
fn from_stdstream(sock: StdStream) -> io::Result<Self>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromStream for TcpStream {
|
|
|
|
fn from_stdstream(sock: StdStream) -> io::Result<Self> {
|
|
|
|
match sock {
|
|
|
|
StdStream::Tcp(stream) => TcpStream::from_std(stream, &Handle::default()),
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
2019-07-18 13:05:40 +02:00
|
|
|
StdStream::Uds(_) => {
|
|
|
|
panic!("Should not happen, bug in server impl");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-20 19:35:44 +01:00
|
|
|
#[cfg(all(unix))]
|
|
|
|
impl FromStream for tokio_net::uds::UnixStream {
|
2019-07-18 13:05:40 +02:00
|
|
|
fn from_stdstream(sock: StdStream) -> io::Result<Self> {
|
|
|
|
match sock {
|
|
|
|
StdStream::Tcp(_) => panic!("Should not happen, bug in server impl"),
|
|
|
|
StdStream::Uds(stream) => {
|
2019-11-20 19:35:44 +01:00
|
|
|
tokio_net::uds::UnixStream::from_std(stream, &Handle::default())
|
2019-07-18 13:05:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|