mirror of https://github.com/chipsenkbeil/distant
Move around some net structs and impls to their own modules, add some client tests
parent
aded5fd16f
commit
f12c3428eb
@ -1,5 +1,5 @@
|
||||
mod transport;
|
||||
pub use transport::{DataStream, Transport, TransportError, TransportReadHalf, TransportWriteHalf};
|
||||
pub use transport::*;
|
||||
|
||||
mod client;
|
||||
pub use client::Client;
|
||||
|
@ -0,0 +1,123 @@
|
||||
use super::DataStream;
|
||||
use std::{
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tokio::{
|
||||
io::{self, AsyncRead, AsyncWrite, ReadBuf},
|
||||
sync::mpsc,
|
||||
};
|
||||
|
||||
/// Represents a data stream comprised of two inmemory channels
|
||||
pub struct InmemoryStream {
|
||||
incoming: InmemoryStreamReadHalf,
|
||||
outgoing: InmemoryStreamWriteHalf,
|
||||
}
|
||||
|
||||
impl InmemoryStream {
|
||||
pub fn new(incoming: mpsc::Receiver<Vec<u8>>, outgoing: mpsc::Sender<Vec<u8>>) -> Self {
|
||||
Self {
|
||||
incoming: InmemoryStreamReadHalf(incoming),
|
||||
outgoing: InmemoryStreamWriteHalf(outgoing),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns (incoming_tx, outgoing_rx, stream)
|
||||
pub fn make(buffer: usize) -> (mpsc::Sender<Vec<u8>>, mpsc::Receiver<Vec<u8>>, Self) {
|
||||
let (incoming_tx, incoming_rx) = mpsc::channel(buffer);
|
||||
let (outgoing_tx, outgoing_rx) = mpsc::channel(buffer);
|
||||
|
||||
(
|
||||
incoming_tx,
|
||||
outgoing_rx,
|
||||
Self::new(incoming_rx, outgoing_tx),
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns pair of streams that are connected such that one sends to the other and
|
||||
/// vice versa
|
||||
pub fn pair(buffer: usize) -> (Self, Self) {
|
||||
let (tx, rx, stream) = Self::make(buffer);
|
||||
(stream, Self::new(rx, tx))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncRead for InmemoryStream {
|
||||
fn poll_read(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &mut ReadBuf<'_>,
|
||||
) -> Poll<io::Result<()>> {
|
||||
Pin::new(&mut self.incoming).poll_read(cx, buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncWrite for InmemoryStream {
|
||||
fn poll_write(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> Poll<io::Result<usize>> {
|
||||
Pin::new(&mut self.outgoing).poll_write(cx, buf)
|
||||
}
|
||||
|
||||
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
Pin::new(&mut self.outgoing).poll_flush(cx)
|
||||
}
|
||||
|
||||
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
Pin::new(&mut self.outgoing).poll_shutdown(cx)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InmemoryStreamReadHalf(mpsc::Receiver<Vec<u8>>);
|
||||
impl AsyncRead for InmemoryStreamReadHalf {
|
||||
fn poll_read(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &mut ReadBuf<'_>,
|
||||
) -> Poll<io::Result<()>> {
|
||||
self.0.poll_recv(cx).map(|x| match x {
|
||||
Some(x) => {
|
||||
buf.put_slice(&x);
|
||||
Ok(())
|
||||
}
|
||||
None => Ok(()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InmemoryStreamWriteHalf(mpsc::Sender<Vec<u8>>);
|
||||
impl AsyncWrite for InmemoryStreamWriteHalf {
|
||||
fn poll_write(
|
||||
self: Pin<&mut Self>,
|
||||
_: &mut Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> Poll<io::Result<usize>> {
|
||||
match self.0.try_send(buf.to_vec()) {
|
||||
Ok(_) => Poll::Ready(Ok(buf.len())),
|
||||
Err(_) => Poll::Ready(Ok(0)),
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
self.poll_flush(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl DataStream for InmemoryStream {
|
||||
type Read = InmemoryStreamReadHalf;
|
||||
type Write = InmemoryStreamWriteHalf;
|
||||
|
||||
fn to_connection_tag(&self) -> String {
|
||||
String::from("test-stream")
|
||||
}
|
||||
|
||||
fn into_split(self) -> (Self::Read, Self::Write) {
|
||||
(self.incoming, self.outgoing)
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
use super::{DataStream, Transport};
|
||||
use crate::core::session::Session;
|
||||
use std::{net::SocketAddr, sync::Arc};
|
||||
use tokio::{
|
||||
io,
|
||||
net::{
|
||||
tcp::{OwnedReadHalf, OwnedWriteHalf},
|
||||
TcpStream,
|
||||
},
|
||||
};
|
||||
|
||||
impl DataStream for TcpStream {
|
||||
type Read = OwnedReadHalf;
|
||||
type Write = OwnedWriteHalf;
|
||||
|
||||
fn to_connection_tag(&self) -> String {
|
||||
self.peer_addr()
|
||||
.map(|addr| format!("{}", addr))
|
||||
.unwrap_or_else(|_| String::from("--"))
|
||||
}
|
||||
|
||||
fn into_split(self) -> (Self::Read, Self::Write) {
|
||||
TcpStream::into_split(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Transport<TcpStream> {
|
||||
/// Establishes a connection using the provided session and performs a handshake to establish
|
||||
/// means of encryption, returning a transport ready to communicate with the other side
|
||||
///
|
||||
/// TCP Streams will always use a session's authentication key
|
||||
pub async fn connect(session: Session) -> io::Result<Self> {
|
||||
let stream = TcpStream::connect(session.to_socket_addr().await?).await?;
|
||||
Self::from_handshake(stream, Some(Arc::new(session.auth_key))).await
|
||||
}
|
||||
|
||||
/// Returns the address of the peer the transport is connected to
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
self.conn.get_ref().peer_addr()
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
use super::{DataStream, Transport};
|
||||
use orion::aead::SecretKey;
|
||||
use std::sync::Arc;
|
||||
use tokio::{
|
||||
io,
|
||||
net::{
|
||||
unix::{OwnedReadHalf, OwnedWriteHalf, SocketAddr},
|
||||
UnixStream,
|
||||
},
|
||||
};
|
||||
|
||||
impl DataStream for UnixStream {
|
||||
type Read = OwnedReadHalf;
|
||||
type Write = OwnedWriteHalf;
|
||||
|
||||
fn to_connection_tag(&self) -> String {
|
||||
self.peer_addr()
|
||||
.map(|addr| format!("{:?}", addr))
|
||||
.unwrap_or_else(|_| String::from("--"))
|
||||
}
|
||||
|
||||
fn into_split(self) -> (Self::Read, Self::Write) {
|
||||
UnixStream::into_split(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Transport<UnixStream> {
|
||||
/// Establishes a connection using the provided session and performs a handshake to establish
|
||||
/// means of encryption, returning a transport ready to communicate with the other side
|
||||
///
|
||||
/// Takes an optional authentication key
|
||||
pub async fn connect(
|
||||
path: impl AsRef<std::path::Path>,
|
||||
auth_key: Option<Arc<SecretKey>>,
|
||||
) -> io::Result<Self> {
|
||||
let stream = UnixStream::connect(path.as_ref()).await?;
|
||||
Self::from_handshake(stream, auth_key).await
|
||||
}
|
||||
|
||||
/// Returns the address of the peer the transport is connected to
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
self.conn.get_ref().peer_addr()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue