Split out connection
This commit is contained in:
parent
0d79ccd068
commit
01ef65c787
2 changed files with 81 additions and 78 deletions
76
src/connection.rs
Normal file
76
src/connection.rs
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
use crate::message::Message;
|
||||||
|
use crate::Error;
|
||||||
|
use bytes::{Bytes, BytesMut};
|
||||||
|
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
|
/// Read from a socket and convert the reads into Messages to put into the
|
||||||
|
/// queue until the socket is closed for reading or an error occurs.
|
||||||
|
async fn connection_read<T: AsyncRead + Unpin>(
|
||||||
|
channel: u64,
|
||||||
|
read: &mut T,
|
||||||
|
writer: &mut mpsc::Sender<Message>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let result = loop {
|
||||||
|
let mut buffer = BytesMut::with_capacity(64 * 1024);
|
||||||
|
if let Err(e) = read.read_buf(&mut buffer).await {
|
||||||
|
break Err(Error::IO(e));
|
||||||
|
}
|
||||||
|
if buffer.len() == 0 {
|
||||||
|
break Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(_) = writer.send(Message::Data(channel, buffer.into())).await {
|
||||||
|
break Err(Error::ConnectionReset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Flow control here, wait for the packet to be acknowleged so
|
||||||
|
// there isn't head-of-line blocking or infinite bufferingon the
|
||||||
|
// remote side. Also buffer re-use!
|
||||||
|
};
|
||||||
|
|
||||||
|
// We are effectively closed on this side, send the close to drop the
|
||||||
|
// corresponding write side on the other end of the pipe.
|
||||||
|
_ = writer.send(Message::Close(channel)).await;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get messages from a queue and write them out to a socket until there are
|
||||||
|
/// no more messages in the queue or the write breaks for some reason.
|
||||||
|
async fn connection_write<T: AsyncWrite + Unpin>(
|
||||||
|
data: &mut mpsc::Receiver<Bytes>,
|
||||||
|
write: &mut T,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
while let Some(buf) = data.recv().await {
|
||||||
|
if let Err(e) = write.write_all(&buf[..]).await {
|
||||||
|
return Err(Error::IO(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handle a connection, from the socket to the multiplexer and from the
|
||||||
|
/// multiplexer to the socket.
|
||||||
|
pub async fn process(
|
||||||
|
channel: u64,
|
||||||
|
stream: &mut TcpStream,
|
||||||
|
data: &mut mpsc::Receiver<Bytes>,
|
||||||
|
writer: &mut mpsc::Sender<Message>,
|
||||||
|
) {
|
||||||
|
let (mut read_half, mut write_half) = stream.split();
|
||||||
|
|
||||||
|
let read = connection_read(channel, &mut read_half, writer);
|
||||||
|
let write = connection_write(data, &mut write_half);
|
||||||
|
|
||||||
|
tokio::pin!(read);
|
||||||
|
tokio::pin!(write);
|
||||||
|
|
||||||
|
let (mut done_reading, mut done_writing) = (false, false);
|
||||||
|
while !(done_reading && done_writing) {
|
||||||
|
tokio::select! {
|
||||||
|
_ = &mut read, if !done_reading => { done_reading = true; },
|
||||||
|
_ = &mut write, if !done_writing => { done_writing = true;},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
83
src/lib.rs
83
src/lib.rs
|
|
@ -1,4 +1,5 @@
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::Bytes;
|
||||||
|
use message::{Message, MessageReader, MessageWriter};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::{Ipv4Addr, SocketAddrV4};
|
use std::net::{Ipv4Addr, SocketAddrV4};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
@ -8,11 +9,10 @@ use tokio::process;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
|
|
||||||
|
mod connection;
|
||||||
mod message;
|
mod message;
|
||||||
mod refresh;
|
mod refresh;
|
||||||
|
|
||||||
use message::{Message, MessageReader, MessageWriter};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Protocol,
|
Protocol,
|
||||||
|
|
@ -70,79 +70,6 @@ async fn pump_write<T: AsyncWrite + Unpin>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Connection
|
|
||||||
|
|
||||||
/// Read from a socket and convert the reads into Messages to put into the
|
|
||||||
/// queue until the socket is closed for reading or an error occurs.
|
|
||||||
async fn connection_read<T: AsyncRead + Unpin>(
|
|
||||||
channel: u64,
|
|
||||||
read: &mut T,
|
|
||||||
writer: &mut mpsc::Sender<Message>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let result = loop {
|
|
||||||
let mut buffer = BytesMut::with_capacity(64 * 1024);
|
|
||||||
if let Err(e) = read.read_buf(&mut buffer).await {
|
|
||||||
break Err(Error::IO(e));
|
|
||||||
}
|
|
||||||
if buffer.len() == 0 {
|
|
||||||
break Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(_) = writer.send(Message::Data(channel, buffer.into())).await {
|
|
||||||
break Err(Error::ConnectionReset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Flow control here, wait for the packet to be acknowleged so
|
|
||||||
// there isn't head-of-line blocking or infinite bufferingon the
|
|
||||||
// remote side. Also buffer re-use!
|
|
||||||
};
|
|
||||||
|
|
||||||
// We are effectively closed on this side, send the close to drop the
|
|
||||||
// corresponding write side on the other end of the pipe.
|
|
||||||
_ = writer.send(Message::Close(channel)).await;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get messages from a queue and write them out to a socket until there are
|
|
||||||
/// no more messages in the queue or the write breaks for some reason.
|
|
||||||
async fn connection_write<T: AsyncWrite + Unpin>(
|
|
||||||
data: &mut mpsc::Receiver<Bytes>,
|
|
||||||
write: &mut T,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
while let Some(buf) = data.recv().await {
|
|
||||||
if let Err(e) = write.write_all(&buf[..]).await {
|
|
||||||
return Err(Error::IO(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle a connection, from the socket to the multiplexer and from the
|
|
||||||
/// multiplexer to the socket.
|
|
||||||
async fn connection_process(
|
|
||||||
channel: u64,
|
|
||||||
stream: &mut TcpStream,
|
|
||||||
data: &mut mpsc::Receiver<Bytes>,
|
|
||||||
writer: &mut mpsc::Sender<Message>,
|
|
||||||
) {
|
|
||||||
let (mut read_half, mut write_half) = stream.split();
|
|
||||||
|
|
||||||
let read = connection_read(channel, &mut read_half, writer);
|
|
||||||
let write = connection_write(data, &mut write_half);
|
|
||||||
|
|
||||||
tokio::pin!(read);
|
|
||||||
tokio::pin!(write);
|
|
||||||
|
|
||||||
let (mut done_reading, mut done_writing) = (false, false);
|
|
||||||
while !(done_reading && done_writing) {
|
|
||||||
tokio::select! {
|
|
||||||
_ = &mut read, if !done_reading => { done_reading = true; },
|
|
||||||
_ = &mut write, if !done_writing => { done_writing = true;},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Server
|
// Server
|
||||||
|
|
||||||
|
|
@ -200,7 +127,7 @@ async fn server_handle_connection(
|
||||||
connections.add(channel, send_data);
|
connections.add(channel, send_data);
|
||||||
if let Ok(_) = writer.send(Message::Connected(channel)).await {
|
if let Ok(_) = writer.send(Message::Connected(channel)).await {
|
||||||
let mut writer = writer.clone();
|
let mut writer = writer.clone();
|
||||||
connection_process(channel, &mut stream, &mut data, &mut writer).await;
|
connection::process(channel, &mut stream, &mut data, &mut writer).await;
|
||||||
|
|
||||||
eprintln!("< Done server!");
|
eprintln!("< Done server!");
|
||||||
}
|
}
|
||||||
|
|
@ -417,7 +344,7 @@ async fn client_handle_connection(
|
||||||
if let Ok(_) = writer.send(Message::Connect(channel, port)).await {
|
if let Ok(_) = writer.send(Message::Connect(channel, port)).await {
|
||||||
if let Ok(_) = connected.await {
|
if let Ok(_) = connected.await {
|
||||||
let mut writer = writer.clone();
|
let mut writer = writer.clone();
|
||||||
connection_process(channel, socket, &mut data, &mut writer).await;
|
connection::process(channel, socket, &mut data, &mut writer).await;
|
||||||
|
|
||||||
eprintln!("> Done client!");
|
eprintln!("> Done client!");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue