|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
//! Socket handling
|
|
|
|
|
use super::*;
|
|
|
|
|
use std::str;
|
|
|
|
|
use std::io;
|
|
|
|
|
use std::path::{
|
|
|
|
|
Path, PathBuf
|
|
|
|
|
};
|
|
|
|
@ -31,6 +32,25 @@ pub enum SocketAddr
|
|
|
|
|
IP(std::net::SocketAddr),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl TryFrom<tokio::net::unix::SocketAddr> for SocketAddrUnix
|
|
|
|
|
{
|
|
|
|
|
type Error = AddrParseError;
|
|
|
|
|
|
|
|
|
|
fn try_from(from: tokio::net::unix::SocketAddr) -> Result<Self, Self::Error>
|
|
|
|
|
{
|
|
|
|
|
from.as_pathname().ok_or(AddrParseError).map(|path| Self{path: path.into()})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<SocketAddrUnix> for SocketAddr
|
|
|
|
|
{
|
|
|
|
|
fn from(from: SocketAddrUnix) -> Self
|
|
|
|
|
{
|
|
|
|
|
Self::Unix(from)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl From<std::net::SocketAddr> for SocketAddr
|
|
|
|
|
{
|
|
|
|
|
fn from(from: std::net::SocketAddr) -> Self
|
|
|
|
@ -62,3 +82,79 @@ impl str::FromStr for SocketAddr
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
enum ListenerInner
|
|
|
|
|
{
|
|
|
|
|
Unix(tokio::net::UnixListener),
|
|
|
|
|
Tcp(tokio::net::TcpListener),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
enum StreamInner
|
|
|
|
|
{
|
|
|
|
|
Unix(tokio::net::UnixStream),
|
|
|
|
|
Tcp(tokio::net::TcpStream),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ListenerInner
|
|
|
|
|
{
|
|
|
|
|
fn con_unix(sock: &SocketAddrUnix) -> io::Result<Self>
|
|
|
|
|
{
|
|
|
|
|
tokio::net::UnixListener::bind(&sock.path).map(Self::Unix)
|
|
|
|
|
}
|
|
|
|
|
async fn con_tcp(sock: &std::net::SocketAddr) -> io::Result<Self>
|
|
|
|
|
{
|
|
|
|
|
tokio::net::TcpListener::bind(sock).await.map(Self::Tcp)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A connected socket.
|
|
|
|
|
//TODO: Stream::connect(), direct connection
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub struct Stream(Box<StreamInner>, SocketAddr);
|
|
|
|
|
|
|
|
|
|
impl From<(tokio::net::UnixStream, tokio::net::unix::SocketAddr)> for Stream
|
|
|
|
|
{
|
|
|
|
|
fn from((s, a): (tokio::net::UnixStream, tokio::net::unix::SocketAddr)) -> Self
|
|
|
|
|
{
|
|
|
|
|
Self(Box::new(StreamInner::Unix(s)), SocketAddrUnix::try_from(a).unwrap().into())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<(tokio::net::TcpStream, std::net::SocketAddr)> for Stream
|
|
|
|
|
{
|
|
|
|
|
fn from((s, a): (tokio::net::TcpStream, std::net::SocketAddr)) -> Self
|
|
|
|
|
{
|
|
|
|
|
Self(Box::new(StreamInner::Tcp(s)), a.into())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A network listener, for either a Unix socket or TCP socket.
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub struct Listener(Box<ListenerInner>);
|
|
|
|
|
|
|
|
|
|
impl Listener
|
|
|
|
|
{
|
|
|
|
|
/// Bind to Unix socket or IP/port.
|
|
|
|
|
///
|
|
|
|
|
/// Completes immediately when binding unix socket
|
|
|
|
|
pub async fn bind(sock: impl Into<SocketAddr>) -> io::Result<Self>
|
|
|
|
|
{
|
|
|
|
|
match sock.into() {
|
|
|
|
|
SocketAddr::Unix(ref unix) => ListenerInner::con_unix(unix).map(Box::new),
|
|
|
|
|
SocketAddr::IP(ref tcp) => ListenerInner::con_tcp(tcp).await.map(Box::new),
|
|
|
|
|
}.map(Self)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Accept connection on this listener.
|
|
|
|
|
pub async fn accept(&self) -> io::Result<Stream>
|
|
|
|
|
{
|
|
|
|
|
match self.0.as_ref()
|
|
|
|
|
{
|
|
|
|
|
ListenerInner::Unix(un) => un.accept().await.map(Into::into),
|
|
|
|
|
ListenerInner::Tcp(tcp) => tcp.accept().await.map(Into::into),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//TODO: impl Stream
|
|
|
|
|