refactor and make tcp work

This commit is contained in:
John Smith
2022-01-05 12:01:02 -05:00
parent 3035bc079f
commit b66aca0ce0
25 changed files with 339 additions and 447 deletions

View File

@@ -14,7 +14,6 @@ use protocol::tcp::RawTcpProtocolHandler;
use protocol::udp::RawUdpProtocolHandler;
use protocol::ws::WebsocketProtocolHandler;
pub use protocol::*;
use utils::async_peek_stream::*;
use utils::network_interfaces::*;
use async_std::io;
@@ -302,6 +301,8 @@ impl Network {
}
// Handle connection-oriented protocols
// Try to send to the exact existing connection if one exists
if let Some(conn) = self.connection_manager().get_connection(descriptor).await {
// connection exists, send over it
conn.send(data).await.map_err(logthru_net!())?;
@@ -355,7 +356,8 @@ impl Network {
match self
.clone()
.send_data_to_existing_connection(descriptor, data)
.await?
.await
.map_err(logthru_net!())?
{
None => {
return Ok(());
@@ -371,7 +373,9 @@ impl Network {
.best_dial_info()
.ok_or_else(|| "couldn't send data, no dial info or peer address".to_owned())?;
self.send_data_to_dial_info(dial_info, data).await
self.send_data_to_dial_info(dial_info, data)
.await
.map_err(logthru_net!())
}
/////////////////////////////////////////////////////////////////

View File

@@ -1,8 +1,6 @@
use super::*;
use crate::intf::*;
use crate::network_connection::*;
use utils::clone_stream::*;
use async_tls::TlsAcceptor;
/////////////////////////////////////////////////////////////////
@@ -135,7 +133,7 @@ impl Network {
let addr = match tcp_stream.peer_addr() {
Ok(addr) => addr,
Err(e) => {
error!("failed to get peer address: {}", e);
log_net!(error "failed to get peer address: {}", e);
return;
}
};
@@ -159,6 +157,7 @@ impl Network {
{
// If we fail to get a packet within the connection initial timeout
// then we punt this connection
log_net!(warn "connection initial timeout from: {:?}", addr);
return;
}

View File

@@ -56,7 +56,7 @@ impl ProtocolNetworkConnection {
}
}
pub async fn close(&mut self) -> Result<(), String> {
pub async fn close(&self) -> Result<(), String> {
match self {
Self::Dummy(d) => d.close(),
Self::RawTcp(t) => t.close().await,
@@ -66,7 +66,7 @@ impl ProtocolNetworkConnection {
}
}
pub async fn send(&mut self, message: Vec<u8>) -> Result<(), String> {
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
match self {
Self::Dummy(d) => d.send(message),
Self::RawTcp(t) => t.send(message).await,
@@ -75,7 +75,7 @@ impl ProtocolNetworkConnection {
Self::Wss(w) => w.send(message).await,
}
}
pub async fn recv(&mut self) -> Result<Vec<u8>, String> {
pub async fn recv(&self) -> Result<Vec<u8>, String> {
match self {
Self::Dummy(d) => d.recv(),
Self::RawTcp(t) => t.recv().await,

View File

@@ -1,5 +1,4 @@
use super::*;
use crate::intf::native::utils::async_peek_stream::*;
use crate::intf::*;
use crate::network_manager::MAX_MESSAGE_SIZE;
use crate::*;
@@ -22,37 +21,43 @@ impl RawTcpNetworkConnection {
Self { stream }
}
pub async fn close(&mut self) -> Result<(), String> {
pub async fn close(&self) -> Result<(), String> {
self.stream
.clone()
.close()
.await
.map_err(map_to_string)
.map_err(logthru_net!())
}
pub async fn send(&mut self, message: Vec<u8>) -> Result<(), String> {
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
log_net!("sending TCP message of size {}", message.len());
if message.len() > MAX_MESSAGE_SIZE {
return Err("sending too large TCP message".to_owned());
}
let len = message.len() as u16;
let header = [b'V', b'L', len as u8, (len >> 8) as u8];
self.stream
let mut stream = self.stream.clone();
stream
.write_all(&header)
.await
.map_err(map_to_string)
.map_err(logthru_net!())?;
self.stream
stream
.write_all(&message)
.await
.map_err(map_to_string)
.map_err(logthru_net!())
}
pub async fn recv(&mut self) -> Result<Vec<u8>, String> {
pub async fn recv(&self) -> Result<Vec<u8>, String> {
let mut header = [0u8; 4];
self.stream
let mut stream = self.stream.clone();
stream
.read_exact(&mut header)
.await
.map_err(|e| format!("TCP recv error: {}", e))?;
@@ -65,10 +70,7 @@ impl RawTcpNetworkConnection {
}
let mut out: Vec<u8> = vec![0u8; len];
self.stream
.read_exact(&mut out)
.await
.map_err(map_to_string)?;
stream.read_exact(&mut out).await.map_err(map_to_string)?;
Ok(out)
}
}
@@ -122,6 +124,8 @@ impl RawTcpProtocolHandler {
ProtocolNetworkConnection::RawTcp(RawTcpNetworkConnection::new(stream)),
);
warn!("on_accept_async from: {}", socket_addr);
Ok(Some(conn))
}

View File

@@ -1,5 +1,4 @@
use super::*;
use crate::intf::native::utils::async_peek_stream::*;
use crate::intf::*;
use crate::network_manager::MAX_MESSAGE_SIZE;
use crate::*;
@@ -19,31 +18,12 @@ pub type WebsocketNetworkConnectionWSS =
WebsocketNetworkConnection<async_tls::client::TlsStream<async_std::net::TcpStream>>;
pub type WebsocketNetworkConnectionWS = WebsocketNetworkConnection<async_std::net::TcpStream>;
struct WebSocketNetworkConnectionInner<T>
where
T: io::Read + io::Write + Send + Unpin + 'static,
{
ws_stream: WebSocketStream<T>,
}
pub struct WebsocketNetworkConnection<T>
where
T: io::Read + io::Write + Send + Unpin + 'static,
{
tls: bool,
inner: Arc<AsyncMutex<WebSocketNetworkConnectionInner<T>>>,
}
impl<T> Clone for WebsocketNetworkConnection<T>
where
T: io::Read + io::Write + Send + Unpin + 'static,
{
fn clone(&self) -> Self {
Self {
tls: self.tls,
inner: self.inner.clone(),
}
}
ws_stream: CloneStream<WebSocketStream<T>>,
}
impl<T> fmt::Debug for WebsocketNetworkConnection<T>
@@ -62,38 +42,28 @@ where
pub fn new(tls: bool, ws_stream: WebSocketStream<T>) -> Self {
Self {
tls,
inner: Arc::new(AsyncMutex::new(WebSocketNetworkConnectionInner {
ws_stream,
})),
ws_stream: CloneStream::new(ws_stream),
}
}
pub async fn close(&self) -> Result<(), String> {
let mut inner = self.inner.lock().await;
inner
.ws_stream
.close(None)
.await
.map_err(map_to_string)
.map_err(logthru_net!(error "failed to close websocket"))
self.ws_stream.clone().close().await.map_err(map_to_string)
}
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
if message.len() > MAX_MESSAGE_SIZE {
return Err("received too large WS message".to_owned());
}
let mut inner = self.inner.lock().await;
inner
.ws_stream
self.ws_stream
.clone()
.send(Message::binary(message))
.await
.map_err(map_to_string)
.map_err(logthru_net!(error "failed to send websocket message"))
}
pub async fn recv(&self) -> Result<Vec<u8>, String> {
let mut inner = self.inner.lock().await;
let out = match inner.ws_stream.next().await {
pub async fn recv(&self) -> Result<Vec<u8>, String> {
let out = match self.ws_stream.clone().next().await {
Some(Ok(Message::Binary(v))) => v,
Some(Ok(_)) => {
return Err("Unexpected WS message type".to_owned()).map_err(logthru_net!(error));

View File

@@ -1,171 +0,0 @@
use crate::xx::*;
use async_std::io::{Read, ReadExt, Result, Write};
use core::pin::Pin;
use core::task::{Context, Poll};
////////
///
trait SendStream: Read + Write + Send + Unpin {
fn clone_stream(&self) -> Box<dyn SendStream>;
}
impl<S> SendStream for S
where
S: Read + Write + Send + Clone + Unpin + 'static,
{
fn clone_stream(&self) -> Box<dyn SendStream> {
Box::new(self.clone())
}
}
/////////
///
struct AsyncPeekStreamInner {
stream: Box<dyn SendStream>,
peekbuf: Vec<u8>,
peekbuf_len: usize,
}
#[derive(Clone)]
pub struct AsyncPeekStream
where
Self: Read + Write + Send + Unpin,
{
inner: Arc<Mutex<AsyncPeekStreamInner>>,
}
impl AsyncPeekStream {
pub fn new<S>(stream: S) -> Self
where
S: Read + Write + Send + Clone + Unpin + 'static,
{
Self {
inner: Arc::new(Mutex::new(AsyncPeekStreamInner {
stream: Box::new(stream),
peekbuf: Vec::new(),
peekbuf_len: 0,
})),
}
}
pub async fn peek(&'_ self, buf: &'_ mut [u8]) -> Result<usize> {
let (mut stream, mut peekbuf, mut peekbuf_len) = {
let inner = self.inner.lock();
(
inner.stream.clone_stream(),
inner.peekbuf.clone(),
inner.peekbuf_len,
)
};
//
let buf_len = buf.len();
let mut copy_len = buf_len;
if buf_len > peekbuf_len {
//
peekbuf.resize(buf_len, 0u8);
let read_len = stream
.read(&mut peekbuf.as_mut_slice()[peekbuf_len..buf_len])
.await?;
peekbuf_len += read_len;
copy_len = peekbuf_len;
}
buf[..copy_len].copy_from_slice(&peekbuf[..copy_len]);
let mut inner = self.inner.lock();
inner.peekbuf = peekbuf;
inner.peekbuf_len = peekbuf_len;
Ok(copy_len)
}
pub async fn peek_exact(&'_ self, buf: &'_ mut [u8]) -> Result<()> {
let (mut stream, mut peekbuf, mut peekbuf_len) = {
let inner = self.inner.lock();
(
inner.stream.clone_stream(),
inner.peekbuf.clone(),
inner.peekbuf_len,
)
};
//
let buf_len = buf.len();
if buf_len > peekbuf_len {
//
peekbuf.resize(buf_len, 0u8);
stream
.read_exact(&mut peekbuf.as_mut_slice()[peekbuf_len..buf_len])
.await?;
peekbuf_len = buf_len;
}
buf.copy_from_slice(&peekbuf[..buf_len]);
let mut inner = self.inner.lock();
inner.peekbuf = peekbuf;
inner.peekbuf_len = peekbuf_len;
Ok(())
}
}
impl Read for AsyncPeekStream {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<usize>> {
let mut inner = self.inner.lock();
//
let buflen = buf.len();
let bufcopylen = cmp::min(buflen, inner.peekbuf_len);
let bufreadlen = if buflen > inner.peekbuf_len {
buflen - inner.peekbuf_len
} else {
0
};
if bufreadlen > 0 {
match Pin::new(&mut inner.stream).poll_read(cx, &mut buf[bufcopylen..buflen]) {
Poll::Ready(res) => {
let readlen = res?;
buf[0..bufcopylen].copy_from_slice(&inner.peekbuf[0..bufcopylen]);
inner.peekbuf_len = 0;
Poll::Ready(Ok(bufcopylen + readlen))
}
Poll::Pending => {
if bufcopylen > 0 {
buf[0..bufcopylen].copy_from_slice(&inner.peekbuf[0..bufcopylen]);
inner.peekbuf_len = 0;
Poll::Ready(Ok(bufcopylen))
} else {
Poll::Pending
}
}
}
} else {
buf[0..bufcopylen].copy_from_slice(&inner.peekbuf[0..bufcopylen]);
if bufcopylen == inner.peekbuf_len {
inner.peekbuf_len = 0;
} else if bufcopylen != 0 {
// slide buffer over by bufcopylen
let tail = inner.peekbuf.split_off(bufcopylen);
inner.peekbuf = tail;
inner.peekbuf_len -= bufcopylen;
}
Poll::Ready(Ok(bufcopylen))
}
}
}
impl Write for AsyncPeekStream {
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> {
let mut inner = self.inner.lock();
Pin::new(&mut inner.stream).poll_write(cx, buf)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
let mut inner = self.inner.lock();
Pin::new(&mut inner.stream).poll_flush(cx)
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
let mut inner = self.inner.lock();
Pin::new(&mut inner.stream).poll_close(cx)
}
}
impl std::marker::Unpin for AsyncPeekStream {}

View File

@@ -1,83 +0,0 @@
pub use async_std::channel;
#[derive(Debug)]
pub struct Sender<T> {
imp: channel::Sender<T>,
}
impl<T> Clone for Sender<T> {
fn clone(&self) -> Self {
Self {
imp: self.imp.clone(),
}
}
}
#[derive(Debug)]
pub struct Receiver<T> {
imp: channel::Receiver<T>,
}
impl<T> Clone for Receiver<T> {
fn clone(&self) -> Self {
Self {
imp: self.imp.clone(),
}
}
}
pub fn channel<T>(cap: usize) -> (Sender<T>, Receiver<T>) {
let imp = channel::bounded(cap);
(Sender { imp: imp.0 }, Receiver { imp: imp.1 })
}
pub use channel::SendError;
pub use channel::TrySendError;
#[allow(dead_code)]
impl<T> Sender<T> {
// NOTE: This needs a timeout or you could block a very long time
// pub async fn send(&self, msg: T) -> Result<(), SendError<T>> {
// self.imp.send(msg).await
// }
pub async fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> {
self.imp.try_send(msg)
}
pub fn capacity(&self) -> usize {
self.imp.capacity().unwrap()
}
pub fn is_empty(&self) -> bool {
self.imp.is_empty()
}
pub fn is_full(&self) -> bool {
self.imp.is_full()
}
pub fn len(&self) -> usize {
self.imp.len()
}
}
pub use channel::RecvError;
pub use channel::TryRecvError;
#[allow(dead_code)]
impl<T> Receiver<T> {
pub async fn recv(&self) -> Result<T, RecvError> {
self.imp.recv().await
}
pub async fn try_recv(&self) -> Result<T, TryRecvError> {
self.imp.try_recv()
}
pub fn capacity(&self) -> usize {
self.imp.capacity().unwrap()
}
pub fn is_empty(&self) -> bool {
self.imp.is_empty()
}
pub fn is_full(&self) -> bool {
self.imp.is_full()
}
pub fn len(&self) -> usize {
self.imp.len()
}
}

View File

@@ -1,66 +0,0 @@
use crate::xx::*;
use async_std::io::{Read, Result, Write};
use core::task::{Context, Poll};
use std::pin::Pin;
pub struct CloneStream<T>
where
T: Read + Write + Send + Unpin,
{
inner: Arc<Mutex<T>>,
}
impl<T> Clone for CloneStream<T>
where
T: Read + Write + Send + Unpin,
{
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl<T> CloneStream<T>
where
T: Read + Write + Send + Unpin,
{
pub fn new(t: T) -> Self {
Self {
inner: Arc::new(Mutex::new(t)),
}
}
}
impl<T> Read for CloneStream<T>
where
T: Read + Write + Send + Unpin,
{
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<usize>> {
let mut inner = self.inner.lock();
Pin::new(&mut *inner).poll_read(cx, buf)
}
}
impl<T> Write for CloneStream<T>
where
T: Read + Write + Send + Unpin,
{
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> {
let mut inner = self.inner.lock();
Pin::new(&mut *inner).poll_write(cx, buf)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
let mut inner = self.inner.lock();
Pin::new(&mut *inner).poll_flush(cx)
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
let mut inner = self.inner.lock();
Pin::new(&mut *inner).poll_close(cx)
}
}

View File

@@ -1,8 +1,5 @@
#[cfg(target_os = "android")]
pub mod android;
pub mod async_peek_stream;
pub mod channel;
pub mod clone_stream;
#[cfg(target_os = "ios")]
pub mod ios;
pub mod network_interfaces;

View File

@@ -65,6 +65,8 @@ impl Network {
}
// Handle connection-oriented protocols
// Try to send to the exact existing connection if one exists
if let Some(conn) = self.connection_manager().get_connection(descriptor).await {
// connection exists, send over it
conn.send(data).await.map_err(logthru_net!())?;

View File

@@ -46,20 +46,20 @@ impl ProtocolNetworkConnection {
}
}
}
pub async fn close(&mut self) -> Result<(), String> {
pub async fn close(&self) -> Result<(), String> {
match self {
Self::Dummy(d) => d.close(),
Self::Ws(w) => w.close().await,
}
}
pub async fn send(&mut self, message: Vec<u8>) -> Result<(), String> {
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
match self {
Self::Dummy(d) => d.send(message),
Self::Ws(w) => w.send(message).await,
}
}
pub async fn recv(&mut self) -> Result<Vec<u8>, String> {
pub async fn recv(&self) -> Result<Vec<u8>, String> {
match self {
Self::Dummy(d) => d.recv(),
Self::Ws(w) => w.recv().await,

View File

@@ -1,154 +0,0 @@
use crate::xx::*;
use alloc::collections::VecDeque;
use core::fmt;
#[derive(Debug)]
pub struct Channel<T> {
items: VecDeque<T>,
cap: usize,
eventual: Eventual,
}
#[derive(Debug)]
pub struct Sender<T> {
imp: Arc<Mutex<Channel<T>>>,
}
impl<T> Clone for Sender<T> {
fn clone(&self) -> Self {
Self {
imp: self.imp.clone(),
}
}
}
#[derive(Debug)]
pub struct Receiver<T> {
imp: Arc<Mutex<Channel<T>>>,
}
impl<T> Clone for Receiver<T> {
fn clone(&self) -> Self {
Self {
imp: self.imp.clone(),
}
}
}
pub fn channel<T>(cap: usize) -> (Sender<T>, Receiver<T>) {
let imp = Channel {
items: VecDeque::with_capacity(cap),
cap,
eventual: Eventual::new(),
};
let imparc = Arc::new(Mutex::new(imp));
(
Sender {
imp: imparc.clone(),
},
Receiver {
imp: imparc.clone(),
},
)
}
#[derive(Debug, PartialEq, Eq)]
pub enum TrySendError<T> {
Full(T),
Disconnected(T),
}
impl<T> fmt::Display for TrySendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TrySendError::Full(_) => {
write!(f, "Full")
}
TrySendError::Disconnected(_) => {
write!(f, "Disconnected")
}
}
}
}
impl<T> Sender<T> {
// NOTE: This needs a timeout or you could block a very long time
// pub async fn send(&self, msg: T) -> Result<(), SendError<T>> {
// xxx
// }
pub async fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> {
let eventual = {
let mut inner = self.imp.lock();
if inner.items.len() == inner.cap {
return Err(TrySendError::Full(msg));
}
let empty = inner.items.is_empty();
inner.items.push_back(msg);
if empty {
Some(inner.eventual.clone())
} else {
None
}
};
if let Some(e) = eventual {
e.resolve().await;
}
Ok(())
}
pub fn capacity(&self) -> usize {
self.imp.lock().cap
}
pub fn is_empty(&self) -> bool {
self.imp.lock().items.is_empty()
}
pub fn is_full(&self) -> bool {
let inner = self.imp.lock();
inner.items.len() == inner.cap
}
pub fn len(&self) -> usize {
self.imp.lock().items.len()
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct RecvError;
#[derive(Debug, PartialEq, Eq)]
pub enum TryRecvError {
Empty,
Disconnected,
}
impl<T> Receiver<T> {
pub async fn recv(&self) -> Result<T, RecvError> {
let eventual = {
let inner = self.imp.lock();
inner.eventual.clone()
};
while self.is_empty() {
eventual.instance_clone(true).await;
}
Ok(self.imp.lock().items.pop_front().unwrap())
}
pub async fn try_recv(&self) -> Result<T, TryRecvError> {
if self.is_empty() {
return Err(TryRecvError::Empty);
}
Ok(self.imp.lock().items.pop_front().unwrap())
}
pub fn capacity(&self) -> usize {
self.imp.lock().cap
}
pub fn is_empty(&self) -> bool {
self.imp.lock().items.is_empty()
}
pub fn is_full(&self) -> bool {
let inner = self.imp.lock();
inner.items.len() == inner.cap
}
pub fn len(&self) -> usize {
self.imp.lock().items.len()
}
}

View File

@@ -1,7 +1,5 @@
#![cfg(target_arch = "wasm32")]
pub mod channel;
use crate::xx::*;
use core::sync::atomic::{AtomicI8, Ordering};
use js_sys::{global, Reflect};