mirror of
https://gitlab.com/veilid/veilid.git
synced 2024-12-24 23:09:25 -05:00
more refactor, not quite done.
This commit is contained in:
parent
55a44e0c8f
commit
e32984a5aa
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -225,6 +225,12 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-lock"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ab86ee898bb6d5d0118270acaa8536c59885231ca6f653b4c35a148f8ee6235"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-lock"
|
name = "async-lock"
|
||||||
version = "2.4.0"
|
version = "2.4.0"
|
||||||
@ -270,7 +276,7 @@ dependencies = [
|
|||||||
"async-channel",
|
"async-channel",
|
||||||
"async-global-executor",
|
"async-global-executor",
|
||||||
"async-io",
|
"async-io",
|
||||||
"async-lock",
|
"async-lock 2.4.0",
|
||||||
"async-process",
|
"async-process",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
@ -3743,6 +3749,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"android_logger",
|
"android_logger",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"async-lock 0.1.0",
|
||||||
"async-std",
|
"async-std",
|
||||||
"async-tls",
|
"async-tls",
|
||||||
"async-tungstenite 0.16.0",
|
"async-tungstenite 0.16.0",
|
||||||
|
@ -86,15 +86,16 @@ serde_cbor = { version = "^0", default-features = false, features = ["alloc"] }
|
|||||||
getrandom = { version = "^0", features = ["js"] }
|
getrandom = { version = "^0", features = ["js"] }
|
||||||
ws_stream_wasm = "^0"
|
ws_stream_wasm = "^0"
|
||||||
async_executors = { version = "^0", features = [ "bindgen" ]}
|
async_executors = { version = "^0", features = [ "bindgen" ]}
|
||||||
|
async-lock = "^0"
|
||||||
|
|
||||||
# Configuration for WASM32 'web-sys' crate
|
# Configuration for WASM32 'web-sys' crate
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
|
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
|
||||||
version = "^0"
|
version = "^0"
|
||||||
features = [
|
features = [
|
||||||
# 'Document',
|
# 'Document',
|
||||||
# 'Element',
|
# 'Element',
|
||||||
# 'HtmlElement',
|
# 'HtmlElement',
|
||||||
# 'Node',
|
# 'Node',
|
||||||
'IdbFactory',
|
'IdbFactory',
|
||||||
'IdbOpenDbRequest',
|
'IdbOpenDbRequest',
|
||||||
'Storage',
|
'Storage',
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::connection_table::*;
|
use crate::connection_table::*;
|
||||||
use crate::intf::*;
|
use crate::intf::*;
|
||||||
|
use crate::network_connection::*;
|
||||||
use crate::network_manager::*;
|
use crate::network_manager::*;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
@ -8,73 +9,10 @@ use futures_util::stream::{FuturesUnordered, StreamExt};
|
|||||||
|
|
||||||
const CONNECTION_PROCESSOR_CHANNEL_SIZE: usize = 128usize;
|
const CONNECTION_PROCESSOR_CHANNEL_SIZE: usize = 128usize;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// Accept
|
|
||||||
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(not(target_arch = "wasm32"))] {
|
|
||||||
use async_std::net::*;
|
|
||||||
use utils::async_peek_stream::*;
|
|
||||||
|
|
||||||
pub trait ProtocolAcceptHandler: ProtocolAcceptHandlerClone + Send + Sync {
|
|
||||||
fn on_accept(
|
|
||||||
&self,
|
|
||||||
stream: AsyncPeekStream,
|
|
||||||
peer_addr: SocketAddr,
|
|
||||||
) -> SystemPinBoxFuture<Result<Option<NetworkConnection>, String>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ProtocolAcceptHandlerClone {
|
|
||||||
fn clone_box(&self) -> Box<dyn ProtocolAcceptHandler>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ProtocolAcceptHandlerClone for T
|
|
||||||
where
|
|
||||||
T: 'static + ProtocolAcceptHandler + Clone,
|
|
||||||
{
|
|
||||||
fn clone_box(&self) -> Box<dyn ProtocolAcceptHandler> {
|
|
||||||
Box::new(self.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Clone for Box<dyn ProtocolAcceptHandler> {
|
|
||||||
fn clone(&self) -> Box<dyn ProtocolAcceptHandler> {
|
|
||||||
self.clone_box()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type NewProtocolAcceptHandler =
|
|
||||||
dyn Fn(VeilidConfig, bool, SocketAddr) -> Box<dyn ProtocolAcceptHandler> + Send;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
|
||||||
// Dummy network connection for testing
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct DummyNetworkConnection {
|
|
||||||
descriptor: ConnectionDescriptor,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DummyNetworkConnection {
|
|
||||||
pub fn new(descriptor: ConnectionDescriptor) -> Self {
|
|
||||||
Self { descriptor }
|
|
||||||
}
|
|
||||||
pub fn connection_descriptor(&self) -> ConnectionDescriptor {
|
|
||||||
self.descriptor.clone()
|
|
||||||
}
|
|
||||||
pub async fn send(&self, _message: Vec<u8>) -> Result<(), String> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
pub async fn recv(&self) -> Result<Vec<u8>, String> {
|
|
||||||
Ok(Vec::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// Connection manager
|
// Connection manager
|
||||||
|
|
||||||
pub struct ConnectionManagerInner {
|
struct ConnectionManagerInner {
|
||||||
network_manager: NetworkManager,
|
|
||||||
connection_table: ConnectionTable,
|
connection_table: ConnectionTable,
|
||||||
connection_processor_jh: Option<JoinHandle<()>>,
|
connection_processor_jh: Option<JoinHandle<()>>,
|
||||||
connection_add_channel_tx: Option<utils::channel::Sender<SystemPinBoxFuture<()>>>,
|
connection_add_channel_tx: Option<utils::channel::Sender<SystemPinBoxFuture<()>>>,
|
||||||
@ -88,75 +26,98 @@ impl core::fmt::Debug for ConnectionManagerInner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
struct ConnectionManagerArc {
|
||||||
pub struct ConnectionManager {
|
network_manager: NetworkManager,
|
||||||
inner: Arc<Mutex<ConnectionManagerInner>>,
|
inner: AsyncMutex<ConnectionManagerInner>,
|
||||||
}
|
}
|
||||||
impl core::fmt::Debug for ConnectionManager {
|
impl core::fmt::Debug for ConnectionManagerArc {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
f.debug_struct("ConnectionManager")
|
f.debug_struct("ConnectionManagerArc")
|
||||||
.field("inner", &*self.inner.lock())
|
.field("inner", &self.inner)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ConnectionManager {
|
||||||
|
arc: Arc<ConnectionManagerArc>,
|
||||||
|
}
|
||||||
|
|
||||||
impl ConnectionManager {
|
impl ConnectionManager {
|
||||||
fn new_inner(network_manager: NetworkManager) -> ConnectionManagerInner {
|
fn new_inner() -> ConnectionManagerInner {
|
||||||
ConnectionManagerInner {
|
ConnectionManagerInner {
|
||||||
network_manager,
|
|
||||||
connection_table: ConnectionTable::new(),
|
connection_table: ConnectionTable::new(),
|
||||||
connection_processor_jh: None,
|
connection_processor_jh: None,
|
||||||
connection_add_channel_tx: None,
|
connection_add_channel_tx: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn new_arc(network_manager: NetworkManager) -> ConnectionManagerArc {
|
||||||
|
ConnectionManagerArc {
|
||||||
|
network_manager,
|
||||||
|
inner: AsyncMutex::new(Self::new_inner()),
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn new(network_manager: NetworkManager) -> Self {
|
pub fn new(network_manager: NetworkManager) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: Arc::new(Mutex::new(Self::new_inner(network_manager))),
|
arc: Arc::new(Self::new_arc(network_manager)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn network_manager(&self) -> NetworkManager {
|
pub fn network_manager(&self) -> NetworkManager {
|
||||||
self.inner.lock().network_manager.clone()
|
self.arc.network_manager.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn startup(&self) {
|
pub async fn startup(&self) {
|
||||||
|
let mut inner = self.arc.inner.lock().await;
|
||||||
let cac = utils::channel::channel(CONNECTION_PROCESSOR_CHANNEL_SIZE); // xxx move to config
|
let cac = utils::channel::channel(CONNECTION_PROCESSOR_CHANNEL_SIZE); // xxx move to config
|
||||||
self.inner.lock().connection_add_channel_tx = Some(cac.0);
|
inner.connection_add_channel_tx = Some(cac.0);
|
||||||
let rx = cac.1.clone();
|
let rx = cac.1.clone();
|
||||||
let this = self.clone();
|
let this = self.clone();
|
||||||
self.inner.lock().connection_processor_jh = Some(spawn(this.connection_processor(rx)));
|
inner.connection_processor_jh = Some(spawn(this.connection_processor(rx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn shutdown(&self) {
|
pub async fn shutdown(&self) {
|
||||||
*self.inner.lock() = Self::new_inner(self.network_manager());
|
*self.arc.inner.lock().await = Self::new_inner();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a network connection if one already is established
|
// Returns a network connection if one already is established
|
||||||
pub fn get_connection(&self, descriptor: &ConnectionDescriptor) -> Option<NetworkConnection> {
|
pub async fn get_connection(
|
||||||
self.inner
|
&self,
|
||||||
.lock()
|
descriptor: &ConnectionDescriptor,
|
||||||
.connection_table
|
) -> Option<NetworkConnection> {
|
||||||
.get_connection(descriptor)
|
let inner = self.arc.inner.lock().await;
|
||||||
.map(|e| e.conn)
|
inner.connection_table.get_connection(descriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal routine to register new connection
|
||||||
|
async fn on_new_connection_internal(
|
||||||
|
&self,
|
||||||
|
mut inner: AsyncMutexGuard<'_, ConnectionManagerInner>,
|
||||||
|
conn: NetworkConnection,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let tx = inner
|
||||||
|
.connection_add_channel_tx
|
||||||
|
.as_ref()
|
||||||
|
.ok_or_else(fn_string!("connection channel isn't open yet"))?
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
let receiver_loop_future = Self::process_connection(self.clone(), conn.clone());
|
||||||
|
tx.try_send(receiver_loop_future)
|
||||||
|
.await
|
||||||
|
.map_err(map_to_string)
|
||||||
|
.map_err(logthru_net!(error "failed to start receiver loop"))?;
|
||||||
|
|
||||||
|
// If the receiver loop started successfully,
|
||||||
|
// add the new connection to the table
|
||||||
|
inner.connection_table.add_connection(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by low-level network when any connection-oriented protocol connection appears
|
// Called by low-level network when any connection-oriented protocol connection appears
|
||||||
// either from incoming or outgoing connections. Registers connection in the connection table for later access
|
// either from incoming or outgoing connections. Registers connection in the connection table for later access
|
||||||
// and spawns a message processing loop for the connection
|
// and spawns a message processing loop for the connection
|
||||||
pub async fn on_new_connection(&self, conn: NetworkConnection) -> Result<(), String> {
|
pub async fn on_new_connection(&self, conn: NetworkConnection) -> Result<(), String> {
|
||||||
let tx = self
|
let inner = self.arc.inner.lock().await;
|
||||||
.inner
|
self.on_new_connection_internal(inner, conn).await
|
||||||
.lock()
|
|
||||||
.connection_add_channel_tx
|
|
||||||
.as_ref()
|
|
||||||
.ok_or_else(fn_string!("connection channel isn't open yet"))?
|
|
||||||
.clone();
|
|
||||||
|
|
||||||
let receiver_loop_future = Self::process_connection(self.clone(), conn);
|
|
||||||
tx.try_send(receiver_loop_future)
|
|
||||||
.await
|
|
||||||
.map_err(map_to_string)
|
|
||||||
.map_err(logthru_net!(error "failed to start receiver loop"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_or_create_connection(
|
pub async fn get_or_create_connection(
|
||||||
@ -173,9 +134,9 @@ impl ConnectionManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// If connection exists, then return it
|
// If connection exists, then return it
|
||||||
if let Some(conn) = self
|
let inner = self.arc.inner.lock().await;
|
||||||
.inner
|
|
||||||
.lock()
|
if let Some(conn) = inner
|
||||||
.connection_table
|
.connection_table
|
||||||
.get_connection(&descriptor)
|
.get_connection(&descriptor)
|
||||||
.map(|e| e.conn)
|
.map(|e| e.conn)
|
||||||
@ -186,7 +147,7 @@ impl ConnectionManager {
|
|||||||
// If not, attempt new connection
|
// If not, attempt new connection
|
||||||
let conn = NetworkConnection::connect(local_addr, dial_info).await?;
|
let conn = NetworkConnection::connect(local_addr, dial_info).await?;
|
||||||
|
|
||||||
self.on_new_connection(conn.clone()).await?;
|
self.on_new_connection_internal(inner, conn).await;
|
||||||
|
|
||||||
Ok(conn)
|
Ok(conn)
|
||||||
}
|
}
|
||||||
@ -198,20 +159,6 @@ impl ConnectionManager {
|
|||||||
) -> SystemPinBoxFuture<()> {
|
) -> SystemPinBoxFuture<()> {
|
||||||
let network_manager = this.network_manager();
|
let network_manager = this.network_manager();
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
// Add new connections to the table
|
|
||||||
let entry = match this
|
|
||||||
.inner
|
|
||||||
.lock()
|
|
||||||
.connection_table
|
|
||||||
.add_connection(conn.clone())
|
|
||||||
{
|
|
||||||
Ok(e) => e,
|
|
||||||
Err(err) => {
|
|
||||||
error!(target: "net", "{}", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
let exit_value: Result<Vec<u8>, ()> = Err(());
|
let exit_value: Result<Vec<u8>, ()> = Err(());
|
||||||
let descriptor = conn.connection_descriptor();
|
let descriptor = conn.connection_descriptor();
|
||||||
|
@ -1,37 +1,11 @@
|
|||||||
use crate::intf::*;
|
use crate::intf::*;
|
||||||
|
use crate::network_connection::*;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct ConnectionTableEntry {
|
|
||||||
pub conn: NetworkConnection,
|
|
||||||
pub established_time: u64,
|
|
||||||
pub last_message_sent_time: Option<u64>,
|
|
||||||
pub last_message_recv_time: Option<u64>,
|
|
||||||
pub stopper: Eventual,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for ConnectionTableEntry {
|
|
||||||
fn eq(&self, other: &ConnectionTableEntry) -> bool {
|
|
||||||
if self.conn != other.conn {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if self.established_time != other.established_time {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if self.last_message_sent_time != other.last_message_sent_time {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if self.last_message_recv_time != other.last_message_recv_time {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ConnectionTable {
|
pub struct ConnectionTable {
|
||||||
conn_by_addr: BTreeMap<ConnectionDescriptor, ConnectionTableEntry>,
|
conn_by_addr: BTreeMap<ConnectionDescriptor, NetworkConnection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConnectionTable {
|
impl ConnectionTable {
|
||||||
@ -41,10 +15,7 @@ impl ConnectionTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_connection(
|
pub fn add_connection(&mut self, conn: NetworkConnection) -> Result<(), String> {
|
||||||
&mut self,
|
|
||||||
conn: NetworkConnection,
|
|
||||||
) -> Result<ConnectionTableEntry, String> {
|
|
||||||
let descriptor = conn.connection_descriptor();
|
let descriptor = conn.connection_descriptor();
|
||||||
|
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
|
@ -301,7 +301,7 @@ impl Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle connection-oriented protocols
|
// Handle connection-oriented protocols
|
||||||
if let Some(conn) = self.connection_manager().get_connection(descriptor) {
|
if let Some(conn) = self.connection_manager().get_connection(descriptor).await {
|
||||||
// connection exists, send over it
|
// connection exists, send over it
|
||||||
conn.send(data).await.map_err(logthru_net!())?;
|
conn.send(data).await.map_err(logthru_net!())?;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::connection_manager::*;
|
|
||||||
use crate::intf::*;
|
use crate::intf::*;
|
||||||
|
use crate::network_connection::*;
|
||||||
use utils::clone_stream::*;
|
use utils::clone_stream::*;
|
||||||
|
|
||||||
use async_tls::TlsAcceptor;
|
use async_tls::TlsAcceptor;
|
||||||
|
@ -3,13 +3,13 @@ pub mod udp;
|
|||||||
pub mod wrtc;
|
pub mod wrtc;
|
||||||
pub mod ws;
|
pub mod ws;
|
||||||
|
|
||||||
use crate::connection_manager::*;
|
use crate::network_connection::*;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use socket2::{Domain, Protocol, Socket, Type};
|
use socket2::{Domain, Protocol, Socket, Type};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Debug)]
|
||||||
pub enum NetworkConnection {
|
pub enum ProtocolNetworkConnection {
|
||||||
Dummy(DummyNetworkConnection),
|
Dummy(DummyNetworkConnection),
|
||||||
RawTcp(tcp::RawTcpNetworkConnection),
|
RawTcp(tcp::RawTcpNetworkConnection),
|
||||||
WsAccepted(ws::WebSocketNetworkConnectionAccepted),
|
WsAccepted(ws::WebSocketNetworkConnectionAccepted),
|
||||||
@ -18,7 +18,7 @@ pub enum NetworkConnection {
|
|||||||
//WebRTC(wrtc::WebRTCNetworkConnection),
|
//WebRTC(wrtc::WebRTCNetworkConnection),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkConnection {
|
impl ProtocolNetworkConnection {
|
||||||
pub async fn connect(
|
pub async fn connect(
|
||||||
local_address: Option<SocketAddr>,
|
local_address: Option<SocketAddr>,
|
||||||
dial_info: DialInfo,
|
dial_info: DialInfo,
|
||||||
@ -35,11 +35,8 @@ impl NetworkConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub async fn send_unbound_message(
|
|
||||||
&self,
|
pub async fn send_unbound_message(dial_info: &DialInfo, data: Vec<u8>) -> Result<(), String> {
|
||||||
dial_info: &DialInfo,
|
|
||||||
data: Vec<u8>,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
match dial_info.protocol_type() {
|
match dial_info.protocol_type() {
|
||||||
ProtocolType::UDP => {
|
ProtocolType::UDP => {
|
||||||
let peer_socket_addr = dial_info.to_socket_addr();
|
let peer_socket_addr = dial_info.to_socket_addr();
|
||||||
@ -59,27 +56,18 @@ impl NetworkConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connection_descriptor(&self) -> ConnectionDescriptor {
|
pub async fn send(&mut self, message: Vec<u8>) -> Result<(), String> {
|
||||||
match self {
|
match self {
|
||||||
Self::Dummy(d) => d.connection_descriptor(),
|
Self::Dummy(d) => d.send(message),
|
||||||
Self::RawTcp(t) => t.connection_descriptor(),
|
|
||||||
Self::WsAccepted(w) => w.connection_descriptor(),
|
|
||||||
Self::Ws(w) => w.connection_descriptor(),
|
|
||||||
Self::Wss(w) => w.connection_descriptor(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
|
||||||
match self {
|
|
||||||
Self::Dummy(d) => d.send(message).await,
|
|
||||||
Self::RawTcp(t) => t.send(message).await,
|
Self::RawTcp(t) => t.send(message).await,
|
||||||
Self::WsAccepted(w) => w.send(message).await,
|
Self::WsAccepted(w) => w.send(message).await,
|
||||||
Self::Ws(w) => w.send(message).await,
|
Self::Ws(w) => w.send(message).await,
|
||||||
Self::Wss(w) => w.send(message).await,
|
Self::Wss(w) => w.send(message).await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub async fn recv(&self) -> Result<Vec<u8>, String> {
|
pub async fn recv(&mut self) -> Result<Vec<u8>, String> {
|
||||||
match self {
|
match self {
|
||||||
Self::Dummy(d) => d.recv().await,
|
Self::Dummy(d) => d.recv(),
|
||||||
Self::RawTcp(t) => t.recv().await,
|
Self::RawTcp(t) => t.recv().await,
|
||||||
Self::WsAccepted(w) => w.recv().await,
|
Self::WsAccepted(w) => w.recv().await,
|
||||||
Self::Ws(w) => w.recv().await,
|
Self::Ws(w) => w.recv().await,
|
||||||
|
@ -5,79 +5,46 @@ use crate::network_manager::MAX_MESSAGE_SIZE;
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
use async_std::net::*;
|
use async_std::net::*;
|
||||||
use async_std::prelude::*;
|
use async_std::prelude::*;
|
||||||
use async_std::sync::Mutex as AsyncMutex;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
struct RawTcpNetworkConnectionInner {
|
|
||||||
stream: AsyncPeekStream,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct RawTcpNetworkConnection {
|
pub struct RawTcpNetworkConnection {
|
||||||
inner: Arc<AsyncMutex<RawTcpNetworkConnectionInner>>,
|
stream: AsyncPeekStream,
|
||||||
connection_descriptor: ConnectionDescriptor,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for RawTcpNetworkConnection {
|
impl fmt::Debug for RawTcpNetworkConnection {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("RawTCPNetworkConnection")
|
f.debug_struct("RawTCPNetworkConnection").finish()
|
||||||
.field("connection_descriptor", &self.connection_descriptor)
|
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for RawTcpNetworkConnection {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
Arc::as_ptr(&self.inner) == Arc::as_ptr(&other.inner)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for RawTcpNetworkConnection {}
|
|
||||||
|
|
||||||
impl RawTcpNetworkConnection {
|
impl RawTcpNetworkConnection {
|
||||||
fn new_inner(stream: AsyncPeekStream) -> RawTcpNetworkConnectionInner {
|
pub fn new(stream: AsyncPeekStream) -> Self {
|
||||||
RawTcpNetworkConnectionInner { stream }
|
Self { stream }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(stream: AsyncPeekStream, connection_descriptor: ConnectionDescriptor) -> Self {
|
pub async fn send(&mut self, message: Vec<u8>) -> Result<(), String> {
|
||||||
Self {
|
|
||||||
inner: Arc::new(AsyncMutex::new(Self::new_inner(stream))),
|
|
||||||
connection_descriptor,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn connection_descriptor(&self) -> ConnectionDescriptor {
|
|
||||||
self.connection_descriptor.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
|
||||||
if message.len() > MAX_MESSAGE_SIZE {
|
if message.len() > MAX_MESSAGE_SIZE {
|
||||||
return Err("sending too large TCP message".to_owned());
|
return Err("sending too large TCP message".to_owned());
|
||||||
}
|
}
|
||||||
let len = message.len() as u16;
|
let len = message.len() as u16;
|
||||||
let header = [b'V', b'L', len as u8, (len >> 8) as u8];
|
let header = [b'V', b'L', len as u8, (len >> 8) as u8];
|
||||||
|
|
||||||
let mut inner = self.inner.lock().await;
|
self.stream
|
||||||
inner
|
|
||||||
.stream
|
|
||||||
.write_all(&header)
|
.write_all(&header)
|
||||||
.await
|
.await
|
||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
.map_err(logthru_net!())?;
|
.map_err(logthru_net!())?;
|
||||||
inner
|
self.stream
|
||||||
.stream
|
|
||||||
.write_all(&message)
|
.write_all(&message)
|
||||||
.await
|
.await
|
||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
.map_err(logthru_net!())
|
.map_err(logthru_net!())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn recv(&self) -> Result<Vec<u8>, String> {
|
pub async fn recv(&mut self) -> Result<Vec<u8>, String> {
|
||||||
let mut header = [0u8; 4];
|
let mut header = [0u8; 4];
|
||||||
let mut inner = self.inner.lock().await;
|
|
||||||
|
|
||||||
inner
|
self.stream
|
||||||
.stream
|
|
||||||
.read_exact(&mut header)
|
.read_exact(&mut header)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("TCP recv error: {}", e))?;
|
.map_err(|e| format!("TCP recv error: {}", e))?;
|
||||||
@ -90,8 +57,7 @@ impl RawTcpNetworkConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut out: Vec<u8> = vec![0u8; len];
|
let mut out: Vec<u8> = vec![0u8; len];
|
||||||
inner
|
self.stream
|
||||||
.stream
|
|
||||||
.read_exact(&mut out)
|
.read_exact(&mut out)
|
||||||
.await
|
.await
|
||||||
.map_err(map_to_string)?;
|
.map_err(map_to_string)?;
|
||||||
@ -143,10 +109,10 @@ impl RawTcpProtocolHandler {
|
|||||||
ProtocolType::TCP,
|
ProtocolType::TCP,
|
||||||
);
|
);
|
||||||
let local_address = self.inner.lock().local_address;
|
let local_address = self.inner.lock().local_address;
|
||||||
let conn = NetworkConnection::RawTcp(RawTcpNetworkConnection::new(
|
let conn = NetworkConnection::from_protocol(
|
||||||
stream,
|
|
||||||
ConnectionDescriptor::new(peer_addr, SocketAddress::from_socket_addr(local_address)),
|
ConnectionDescriptor::new(peer_addr, SocketAddress::from_socket_addr(local_address)),
|
||||||
));
|
ProtocolNetworkConnection::RawTcp(RawTcpNetworkConnection::new(stream)),
|
||||||
|
);
|
||||||
|
|
||||||
Ok(Some(conn))
|
Ok(Some(conn))
|
||||||
}
|
}
|
||||||
@ -182,13 +148,13 @@ impl RawTcpProtocolHandler {
|
|||||||
let ps = AsyncPeekStream::new(ts);
|
let ps = AsyncPeekStream::new(ts);
|
||||||
|
|
||||||
// Wrap the stream in a network connection and return it
|
// Wrap the stream in a network connection and return it
|
||||||
let conn = NetworkConnection::RawTcp(RawTcpNetworkConnection::new(
|
let conn = NetworkConnection::from_protocol(
|
||||||
ps,
|
|
||||||
ConnectionDescriptor {
|
ConnectionDescriptor {
|
||||||
local: Some(SocketAddress::from_socket_addr(actual_local_address)),
|
local: Some(SocketAddress::from_socket_addr(actual_local_address)),
|
||||||
remote: dial_info.to_peer_address(),
|
remote: dial_info.to_peer_address(),
|
||||||
},
|
},
|
||||||
));
|
ProtocolNetworkConnection::RawTcp(RawTcpNetworkConnection::new(ps)),
|
||||||
|
);
|
||||||
Ok(conn)
|
Ok(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,32 +3,21 @@ use crate::network_manager::MAX_MESSAGE_SIZE;
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
use async_std::net::*;
|
use async_std::net::*;
|
||||||
|
|
||||||
struct RawUdpProtocolHandlerInner {
|
#[derive(Clone)]
|
||||||
|
pub struct RawUdpProtocolHandler {
|
||||||
socket: Arc<UdpSocket>,
|
socket: Arc<UdpSocket>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct RawUdpProtocolHandler {
|
|
||||||
inner: Arc<Mutex<RawUdpProtocolHandlerInner>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RawUdpProtocolHandler {
|
impl RawUdpProtocolHandler {
|
||||||
fn new_inner(socket: Arc<UdpSocket>) -> RawUdpProtocolHandlerInner {
|
|
||||||
RawUdpProtocolHandlerInner { socket }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(socket: Arc<UdpSocket>) -> Self {
|
pub fn new(socket: Arc<UdpSocket>) -> Self {
|
||||||
Self {
|
Self { socket }
|
||||||
inner: Arc::new(Mutex::new(Self::new_inner(socket))),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn recv_message(
|
pub async fn recv_message(
|
||||||
&self,
|
&self,
|
||||||
data: &mut [u8],
|
data: &mut [u8],
|
||||||
) -> Result<(usize, ConnectionDescriptor), String> {
|
) -> Result<(usize, ConnectionDescriptor), String> {
|
||||||
let socket = self.inner.lock().socket.clone();
|
let (size, remote_addr) = self.socket.recv_from(data).await.map_err(map_to_string)?;
|
||||||
let (size, remote_addr) = socket.recv_from(data).await.map_err(map_to_string)?;
|
|
||||||
|
|
||||||
if size > MAX_MESSAGE_SIZE {
|
if size > MAX_MESSAGE_SIZE {
|
||||||
return Err("received too large UDP message".to_owned());
|
return Err("received too large UDP message".to_owned());
|
||||||
@ -45,7 +34,7 @@ impl RawUdpProtocolHandler {
|
|||||||
SocketAddress::from_socket_addr(remote_addr),
|
SocketAddress::from_socket_addr(remote_addr),
|
||||||
ProtocolType::UDP,
|
ProtocolType::UDP,
|
||||||
);
|
);
|
||||||
let local_socket_addr = socket.local_addr().map_err(map_to_string)?;
|
let local_socket_addr = self.socket.local_addr().map_err(map_to_string)?;
|
||||||
let descriptor = ConnectionDescriptor::new(
|
let descriptor = ConnectionDescriptor::new(
|
||||||
peer_addr,
|
peer_addr,
|
||||||
SocketAddress::from_socket_addr(local_socket_addr),
|
SocketAddress::from_socket_addr(local_socket_addr),
|
||||||
@ -64,8 +53,8 @@ impl RawUdpProtocolHandler {
|
|||||||
socket_addr
|
socket_addr
|
||||||
);
|
);
|
||||||
|
|
||||||
let socket = self.inner.lock().socket.clone();
|
let len = self
|
||||||
let len = socket
|
.socket
|
||||||
.send_to(&data, socket_addr)
|
.send_to(&data, socket_addr)
|
||||||
.await
|
.await
|
||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
|
@ -5,7 +5,6 @@ use crate::network_manager::MAX_MESSAGE_SIZE;
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
use async_std::io;
|
use async_std::io;
|
||||||
use async_std::net::*;
|
use async_std::net::*;
|
||||||
use async_std::sync::Mutex as AsyncMutex;
|
|
||||||
use async_tls::TlsConnector;
|
use async_tls::TlsConnector;
|
||||||
use async_tungstenite::tungstenite::protocol::Message;
|
use async_tungstenite::tungstenite::protocol::Message;
|
||||||
use async_tungstenite::{accept_async, client_async, WebSocketStream};
|
use async_tungstenite::{accept_async, client_async, WebSocketStream};
|
||||||
@ -32,7 +31,6 @@ where
|
|||||||
T: io::Read + io::Write + Send + Unpin + 'static,
|
T: io::Read + io::Write + Send + Unpin + 'static,
|
||||||
{
|
{
|
||||||
tls: bool,
|
tls: bool,
|
||||||
connection_descriptor: ConnectionDescriptor,
|
|
||||||
inner: Arc<AsyncMutex<WebSocketNetworkConnectionInner<T>>>,
|
inner: Arc<AsyncMutex<WebSocketNetworkConnectionInner<T>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +41,6 @@ where
|
|||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tls: self.tls,
|
tls: self.tls,
|
||||||
connection_descriptor: self.connection_descriptor.clone(),
|
|
||||||
inner: self.inner.clone(),
|
inner: self.inner.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,41 +55,19 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PartialEq for WebsocketNetworkConnection<T>
|
|
||||||
where
|
|
||||||
T: io::Read + io::Write + Send + Unpin + 'static,
|
|
||||||
{
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.tls == other.tls
|
|
||||||
&& self.connection_descriptor == other.connection_descriptor
|
|
||||||
&& Arc::as_ptr(&self.inner) == Arc::as_ptr(&other.inner)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Eq for WebsocketNetworkConnection<T> where T: io::Read + io::Write + Send + Unpin + 'static {}
|
|
||||||
|
|
||||||
impl<T> WebsocketNetworkConnection<T>
|
impl<T> WebsocketNetworkConnection<T>
|
||||||
where
|
where
|
||||||
T: io::Read + io::Write + Send + Unpin + 'static,
|
T: io::Read + io::Write + Send + Unpin + 'static,
|
||||||
{
|
{
|
||||||
pub fn new(
|
pub fn new(tls: bool, ws_stream: WebSocketStream<T>) -> Self {
|
||||||
tls: bool,
|
|
||||||
connection_descriptor: ConnectionDescriptor,
|
|
||||||
ws_stream: WebSocketStream<T>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
tls,
|
tls,
|
||||||
connection_descriptor,
|
|
||||||
inner: Arc::new(AsyncMutex::new(WebSocketNetworkConnectionInner {
|
inner: Arc::new(AsyncMutex::new(WebSocketNetworkConnectionInner {
|
||||||
ws_stream,
|
ws_stream,
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connection_descriptor(&self) -> ConnectionDescriptor {
|
|
||||||
self.connection_descriptor.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||||
if message.len() > MAX_MESSAGE_SIZE {
|
if message.len() > MAX_MESSAGE_SIZE {
|
||||||
return Err("received too large WS message".to_owned());
|
return Err("received too large WS message".to_owned());
|
||||||
@ -130,7 +105,7 @@ where
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
struct WebsocketProtocolHandlerInner {
|
struct WebsocketProtocolHandlerArc {
|
||||||
tls: bool,
|
tls: bool,
|
||||||
local_address: SocketAddr,
|
local_address: SocketAddr,
|
||||||
request_path: Vec<u8>,
|
request_path: Vec<u8>,
|
||||||
@ -142,7 +117,7 @@ pub struct WebsocketProtocolHandler
|
|||||||
where
|
where
|
||||||
Self: ProtocolAcceptHandler,
|
Self: ProtocolAcceptHandler,
|
||||||
{
|
{
|
||||||
inner: Arc<WebsocketProtocolHandlerInner>,
|
arc: Arc<WebsocketProtocolHandlerArc>,
|
||||||
}
|
}
|
||||||
impl WebsocketProtocolHandler {
|
impl WebsocketProtocolHandler {
|
||||||
pub fn new(config: VeilidConfig, tls: bool, local_address: SocketAddr) -> Self {
|
pub fn new(config: VeilidConfig, tls: bool, local_address: SocketAddr) -> Self {
|
||||||
@ -158,14 +133,13 @@ impl WebsocketProtocolHandler {
|
|||||||
c.network.connection_initial_timeout
|
c.network.connection_initial_timeout
|
||||||
};
|
};
|
||||||
|
|
||||||
let inner = WebsocketProtocolHandlerInner {
|
Self {
|
||||||
|
arc: Arc::new(WebsocketProtocolHandlerArc {
|
||||||
tls,
|
tls,
|
||||||
local_address,
|
local_address,
|
||||||
request_path: path.as_bytes().to_vec(),
|
request_path: path.as_bytes().to_vec(),
|
||||||
connection_initial_timeout,
|
connection_initial_timeout,
|
||||||
};
|
}),
|
||||||
Self {
|
|
||||||
inner: Arc::new(inner),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,10 +148,10 @@ impl WebsocketProtocolHandler {
|
|||||||
ps: AsyncPeekStream,
|
ps: AsyncPeekStream,
|
||||||
socket_addr: SocketAddr,
|
socket_addr: SocketAddr,
|
||||||
) -> Result<Option<NetworkConnection>, String> {
|
) -> Result<Option<NetworkConnection>, String> {
|
||||||
let request_path_len = self.inner.request_path.len() + 2;
|
let request_path_len = self.arc.request_path.len() + 2;
|
||||||
let mut peekbuf: Vec<u8> = vec![0u8; request_path_len];
|
let mut peekbuf: Vec<u8> = vec![0u8; request_path_len];
|
||||||
match io::timeout(
|
match io::timeout(
|
||||||
Duration::from_micros(self.inner.connection_initial_timeout),
|
Duration::from_micros(self.arc.connection_initial_timeout),
|
||||||
ps.peek_exact(&mut peekbuf),
|
ps.peek_exact(&mut peekbuf),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -191,7 +165,7 @@ impl WebsocketProtocolHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check for websocket path
|
// Check for websocket path
|
||||||
let matches_path = &peekbuf[0..request_path_len - 2] == self.inner.request_path.as_slice()
|
let matches_path = &peekbuf[0..request_path_len - 2] == self.arc.request_path.as_slice()
|
||||||
&& (peekbuf[request_path_len - 2] == b' '
|
&& (peekbuf[request_path_len - 2] == b' '
|
||||||
|| (peekbuf[request_path_len - 2] == b'/'
|
|| (peekbuf[request_path_len - 2] == b'/'
|
||||||
&& peekbuf[request_path_len - 1] == b' '));
|
&& peekbuf[request_path_len - 1] == b' '));
|
||||||
@ -208,7 +182,7 @@ impl WebsocketProtocolHandler {
|
|||||||
.map_err(logthru_net!("failed websockets handshake"))?;
|
.map_err(logthru_net!("failed websockets handshake"))?;
|
||||||
|
|
||||||
// Wrap the websocket in a NetworkConnection and register it
|
// Wrap the websocket in a NetworkConnection and register it
|
||||||
let protocol_type = if self.inner.tls {
|
let protocol_type = if self.arc.tls {
|
||||||
ProtocolType::WSS
|
ProtocolType::WSS
|
||||||
} else {
|
} else {
|
||||||
ProtocolType::WS
|
ProtocolType::WS
|
||||||
@ -217,14 +191,16 @@ impl WebsocketProtocolHandler {
|
|||||||
let peer_addr =
|
let peer_addr =
|
||||||
PeerAddress::new(SocketAddress::from_socket_addr(socket_addr), protocol_type);
|
PeerAddress::new(SocketAddress::from_socket_addr(socket_addr), protocol_type);
|
||||||
|
|
||||||
let conn = NetworkConnection::WsAccepted(WebsocketNetworkConnection::new(
|
let conn = NetworkConnection::from_protocol(
|
||||||
self.inner.tls,
|
|
||||||
ConnectionDescriptor::new(
|
ConnectionDescriptor::new(
|
||||||
peer_addr,
|
peer_addr,
|
||||||
SocketAddress::from_socket_addr(self.inner.local_address),
|
SocketAddress::from_socket_addr(self.arc.local_address),
|
||||||
),
|
),
|
||||||
|
ProtocolNetworkConnection::WsAccepted(WebsocketNetworkConnection::new(
|
||||||
|
self.arc.tls,
|
||||||
ws_stream,
|
ws_stream,
|
||||||
));
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
Ok(Some(conn))
|
Ok(Some(conn))
|
||||||
}
|
}
|
||||||
@ -271,7 +247,7 @@ impl WebsocketProtocolHandler {
|
|||||||
.map_err(logthru_net!())?;
|
.map_err(logthru_net!())?;
|
||||||
|
|
||||||
// Make our connection descriptor
|
// Make our connection descriptor
|
||||||
let connection_descriptor = ConnectionDescriptor {
|
let descriptor = ConnectionDescriptor {
|
||||||
local: Some(SocketAddress::from_socket_addr(actual_local_addr)),
|
local: Some(SocketAddress::from_socket_addr(actual_local_addr)),
|
||||||
remote: dial_info.to_peer_address(),
|
remote: dial_info.to_peer_address(),
|
||||||
};
|
};
|
||||||
@ -288,21 +264,19 @@ impl WebsocketProtocolHandler {
|
|||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
.map_err(logthru_net!(error))?;
|
.map_err(logthru_net!(error))?;
|
||||||
|
|
||||||
Ok(NetworkConnection::Wss(WebsocketNetworkConnection::new(
|
Ok(NetworkConnection::from_protocol(
|
||||||
tls,
|
descriptor,
|
||||||
connection_descriptor,
|
ProtocolNetworkConnection::Wss(WebsocketNetworkConnection::new(tls, ws_stream)),
|
||||||
ws_stream,
|
))
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
let (ws_stream, _response) = client_async(request, tcp_stream)
|
let (ws_stream, _response) = client_async(request, tcp_stream)
|
||||||
.await
|
.await
|
||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
.map_err(logthru_net!(error))?;
|
.map_err(logthru_net!(error))?;
|
||||||
Ok(NetworkConnection::Ws(WebsocketNetworkConnection::new(
|
Ok(NetworkConnection::from_protocol(
|
||||||
tls,
|
descriptor,
|
||||||
connection_descriptor,
|
ProtocolNetworkConnection::Ws(WebsocketNetworkConnection::new(tls, ws_stream)),
|
||||||
ws_stream,
|
))
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,14 +5,14 @@ use crate::connection_manager::*;
|
|||||||
use crate::veilid_api::ProtocolType;
|
use crate::veilid_api::ProtocolType;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Debug)]
|
||||||
pub enum NetworkConnection {
|
pub enum ProtocolNetworkConnection {
|
||||||
Dummy(DummyNetworkConnection),
|
Dummy(DummyNetworkConnection),
|
||||||
WS(ws::WebsocketNetworkConnection),
|
WS(ws::WebsocketNetworkConnection),
|
||||||
//WebRTC(wrtc::WebRTCNetworkConnection),
|
//WebRTC(wrtc::WebRTCNetworkConnection),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkConnection {
|
impl ProtocolNetworkConnection {
|
||||||
pub async fn connect(
|
pub async fn connect(
|
||||||
local_address: Option<SocketAddr>,
|
local_address: Option<SocketAddr>,
|
||||||
dial_info: DialInfo,
|
dial_info: DialInfo,
|
||||||
@ -31,7 +31,6 @@ impl NetworkConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_unbound_message(
|
pub async fn send_unbound_message(
|
||||||
&self,
|
|
||||||
dial_info: &DialInfo,
|
dial_info: &DialInfo,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
@ -48,17 +47,17 @@ impl NetworkConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
pub async fn send(&mut self, message: Vec<u8>) -> Result<(), String> {
|
||||||
match self {
|
match self {
|
||||||
Self::Dummy(d) => d.send(message).await,
|
Self::Dummy(d) => d.send(message),
|
||||||
Self::WS(w) => w.send(message).await,
|
Self::WS(w) => w.send(message),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn recv(&self) -> Result<Vec<u8>, String> {
|
pub async fn recv(&mut self) -> Result<Vec<u8>, String> {
|
||||||
match self {
|
match self {
|
||||||
Self::Dummy(d) => d.recv().await,
|
Self::Dummy(d) => d.recv(),
|
||||||
Self::WS(w) => w.recv().await,
|
Self::WS(w) => w.recv(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ struct WebsocketNetworkConnectionInner {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WebsocketNetworkConnection {
|
pub struct WebsocketNetworkConnection {
|
||||||
tls: bool,
|
tls: bool,
|
||||||
connection_descriptor: ConnectionDescriptor,
|
|
||||||
inner: Arc<Mutex<WebsocketNetworkConnectionInner>>,
|
inner: Arc<Mutex<WebsocketNetworkConnectionInner>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,20 +23,11 @@ impl fmt::Debug for WebsocketNetworkConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for WebsocketNetworkConnection {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.tls == other.tls && Arc::as_ptr(&self.inner) == Arc::as_ptr(&other.inner)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for WebsocketNetworkConnection {}
|
|
||||||
|
|
||||||
impl WebsocketNetworkConnection {
|
impl WebsocketNetworkConnection {
|
||||||
pub fn new(tls: bool, connection_descriptor: ConnectionDescriptor, ws_stream: WsStream) -> Self {
|
pub fn new(tls: bool, ws_stream: WsStream) -> Self {
|
||||||
let ws = ws_stream.wrapped().clone();
|
let ws = ws_stream.wrapped().clone();
|
||||||
Self {
|
Self {
|
||||||
tls,
|
tls,
|
||||||
connection_descriptor,
|
|
||||||
inner: Arc::new(Mutex::new(WebsocketNetworkConnectionInner {
|
inner: Arc::new(Mutex::new(WebsocketNetworkConnectionInner {
|
||||||
ws_stream,
|
ws_stream,
|
||||||
ws,
|
ws,
|
||||||
@ -45,11 +35,10 @@ impl WebsocketNetworkConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connection_descriptor(&self) -> ConnectionDescriptor {
|
xxx convert this to async and use stream api not low level websocket
|
||||||
self.connection_descriptor.clone()
|
xxx implement close() everywhere and skip using eventual for loop shutdown
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
pub fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||||
if message.len() > MAX_MESSAGE_SIZE {
|
if message.len() > MAX_MESSAGE_SIZE {
|
||||||
return Err("sending too large WS message".to_owned()).map_err(logthru_net!(error));
|
return Err("sending too large WS message".to_owned()).map_err(logthru_net!(error));
|
||||||
}
|
}
|
||||||
@ -60,7 +49,7 @@ impl WebsocketNetworkConnection {
|
|||||||
.map_err(|_| "failed to send to websocket".to_owned())
|
.map_err(|_| "failed to send to websocket".to_owned())
|
||||||
.map_err(logthru_net!(error))
|
.map_err(logthru_net!(error))
|
||||||
}
|
}
|
||||||
pub async fn recv(&self) -> Result<Vec<u8>, String> {
|
pub fn recv(&self) -> Result<Vec<u8>, String> {
|
||||||
let out = match self.inner.lock().ws_stream.next().await {
|
let out = match self.inner.lock().ws_stream.next().await {
|
||||||
Some(WsMessage::Binary(v)) => v,
|
Some(WsMessage::Binary(v)) => v,
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
@ -123,7 +112,7 @@ impl WebsocketProtocolHandler {
|
|||||||
remote: dial_info.to_peer_address(),
|
remote: dial_info.to_peer_address(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(NetworkConnection::WS(WebsocketNetworkConnection::new(tls, connection_descriptor, wsio)))
|
Ok(NetworkConnection::from_protocol(descriptor,ProtocolNetworkConnection::WS(WebsocketNetworkConnection::new(tls, wsio))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_unbound_message(dial_info: &DialInfo, data: Vec<u8>) -> Result<(), String> {
|
pub async fn send_unbound_message(dial_info: &DialInfo, data: Vec<u8>) -> Result<(), String> {
|
||||||
|
@ -12,6 +12,7 @@ mod connection_table;
|
|||||||
mod dht;
|
mod dht;
|
||||||
mod intf;
|
mod intf;
|
||||||
mod lease_manager;
|
mod lease_manager;
|
||||||
|
mod network_connection;
|
||||||
mod network_manager;
|
mod network_manager;
|
||||||
mod receipt_manager;
|
mod receipt_manager;
|
||||||
mod routing_table;
|
mod routing_table;
|
||||||
|
139
veilid-core/src/network_connection.rs
Normal file
139
veilid-core/src/network_connection.rs
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
use crate::intf::*;
|
||||||
|
use crate::xx::*;
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// Accept
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(not(target_arch = "wasm32"))] {
|
||||||
|
use async_std::net::*;
|
||||||
|
use utils::async_peek_stream::*;
|
||||||
|
|
||||||
|
pub trait ProtocolAcceptHandler: ProtocolAcceptHandlerClone + Send + Sync {
|
||||||
|
fn on_accept(
|
||||||
|
&self,
|
||||||
|
stream: AsyncPeekStream,
|
||||||
|
peer_addr: SocketAddr,
|
||||||
|
) -> SystemPinBoxFuture<Result<Option<NetworkConnection>, String>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ProtocolAcceptHandlerClone {
|
||||||
|
fn clone_box(&self) -> Box<dyn ProtocolAcceptHandler>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ProtocolAcceptHandlerClone for T
|
||||||
|
where
|
||||||
|
T: 'static + ProtocolAcceptHandler + Clone,
|
||||||
|
{
|
||||||
|
fn clone_box(&self) -> Box<dyn ProtocolAcceptHandler> {
|
||||||
|
Box::new(self.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Clone for Box<dyn ProtocolAcceptHandler> {
|
||||||
|
fn clone(&self) -> Box<dyn ProtocolAcceptHandler> {
|
||||||
|
self.clone_box()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type NewProtocolAcceptHandler =
|
||||||
|
dyn Fn(VeilidConfig, bool, SocketAddr) -> Box<dyn ProtocolAcceptHandler> + Send;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// Dummy protocol network connection for testing
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DummyNetworkConnection {}
|
||||||
|
|
||||||
|
impl DummyNetworkConnection {
|
||||||
|
pub fn new(descriptor: ConnectionDescriptor) -> NetworkConnection {
|
||||||
|
NetworkConnection::from_protocol(descriptor, ProtocolNetworkConnection::Dummy(Self {}))
|
||||||
|
}
|
||||||
|
pub fn send(&self, _message: Vec<u8>) -> Result<(), String> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
pub fn recv(&self) -> Result<Vec<u8>, String> {
|
||||||
|
Ok(Vec::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// Top-level protocol independent network connection object
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NetworkConnectionInner {
|
||||||
|
protocol_connection: ProtocolNetworkConnection,
|
||||||
|
last_message_sent_time: Option<u64>,
|
||||||
|
last_message_recv_time: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NetworkConnectionArc {
|
||||||
|
descriptor: ConnectionDescriptor,
|
||||||
|
established_time: u64,
|
||||||
|
inner: AsyncMutex<NetworkConnectionInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct NetworkConnection {
|
||||||
|
arc: Arc<NetworkConnectionArc>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetworkConnection {
|
||||||
|
fn new_inner(protocol_connection: ProtocolNetworkConnection) -> NetworkConnectionInner {
|
||||||
|
NetworkConnectionInner {
|
||||||
|
protocol_connection,
|
||||||
|
last_message_sent_time: None,
|
||||||
|
last_message_recv_time: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn new_arc(
|
||||||
|
descriptor: ConnectionDescriptor,
|
||||||
|
protocol_connection: ProtocolNetworkConnection,
|
||||||
|
) -> NetworkConnectionArc {
|
||||||
|
NetworkConnectionArc {
|
||||||
|
descriptor,
|
||||||
|
established_time: intf::get_timestamp(),
|
||||||
|
inner: AsyncMutex::new(Self::new_inner(protocol_connection)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_protocol(
|
||||||
|
descriptor: ConnectionDescriptor,
|
||||||
|
protocol_connection: ProtocolNetworkConnection,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
arc: Arc::new(Self::new_arc(descriptor, protocol_connection)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn connect(
|
||||||
|
local_address: Option<SocketAddr>,
|
||||||
|
dial_info: DialInfo,
|
||||||
|
) -> Result<NetworkConnection, String> {
|
||||||
|
ProtocolNetworkConnection::connect(local_address, dial_info).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn connection_descriptor(&self) -> ConnectionDescriptor {
|
||||||
|
self.arc.descriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||||
|
let mut inner = self.arc.inner.lock().await;
|
||||||
|
let out = inner.protocol_connection.send(message).await;
|
||||||
|
if out.is_ok() {
|
||||||
|
inner.last_message_sent_time = Some(intf::get_timestamp());
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
pub async fn recv(&self) -> Result<Vec<u8>, String> {
|
||||||
|
let mut inner = self.arc.inner.lock().await;
|
||||||
|
let out = inner.protocol_connection.recv().await;
|
||||||
|
if out.is_ok() {
|
||||||
|
inner.last_message_recv_time = Some(intf::get_timestamp());
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
use crate::connection_manager::*;
|
|
||||||
use crate::connection_table::*;
|
use crate::connection_table::*;
|
||||||
use crate::intf::*;
|
use crate::network_connection::*;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
@ -49,11 +48,11 @@ pub async fn test_add_get_remove() {
|
|||||||
))),
|
))),
|
||||||
);
|
);
|
||||||
|
|
||||||
let c1 = NetworkConnection::Dummy(DummyNetworkConnection::new(a1.clone()));
|
let c1 = DummyNetworkConnection::new(a1.clone());
|
||||||
let c2 = NetworkConnection::Dummy(DummyNetworkConnection::new(a2.clone()));
|
let c2 = DummyNetworkConnection::new(a2.clone());
|
||||||
let c3 = NetworkConnection::Dummy(DummyNetworkConnection::new(a3.clone()));
|
let c3 = DummyNetworkConnection::new(a3.clone());
|
||||||
let c4 = NetworkConnection::Dummy(DummyNetworkConnection::new(a4.clone()));
|
let c4 = DummyNetworkConnection::new(a4.clone());
|
||||||
let c5 = NetworkConnection::Dummy(DummyNetworkConnection::new(a5));
|
let c5 = DummyNetworkConnection::new(a5);
|
||||||
|
|
||||||
assert_eq!(a1, c2.connection_descriptor());
|
assert_eq!(a1, c2.connection_descriptor());
|
||||||
assert_ne!(a3, c4.connection_descriptor());
|
assert_ne!(a3, c4.connection_descriptor());
|
||||||
|
@ -686,7 +686,7 @@ pub struct PeerInfo {
|
|||||||
pub dial_infos: Vec<DialInfo>,
|
pub dial_infos: Vec<DialInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
pub struct PeerAddress {
|
pub struct PeerAddress {
|
||||||
pub socket_address: SocketAddress,
|
pub socket_address: SocketAddress,
|
||||||
pub protocol_type: ProtocolType,
|
pub protocol_type: ProtocolType,
|
||||||
@ -709,7 +709,7 @@ impl PeerAddress {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct ConnectionDescriptor {
|
pub struct ConnectionDescriptor {
|
||||||
pub remote: PeerAddress,
|
pub remote: PeerAddress,
|
||||||
pub local: Option<SocketAddress>,
|
pub local: Option<SocketAddress>,
|
||||||
|
@ -45,6 +45,8 @@ cfg_if! {
|
|||||||
pub use core::sync::atomic::{Ordering, AtomicBool};
|
pub use core::sync::atomic::{Ordering, AtomicBool};
|
||||||
pub use alloc::sync::{Arc, Weak};
|
pub use alloc::sync::{Arc, Weak};
|
||||||
pub use core::ops::{FnOnce, FnMut, Fn};
|
pub use core::ops::{FnOnce, FnMut, Fn};
|
||||||
|
pub use async_lock::Mutex as AsyncMutex;
|
||||||
|
pub use async_lock::MutexGuard as AsyncMutexGuard;
|
||||||
pub use no_std_net::{ SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs, IpAddr, Ipv4Addr, Ipv6Addr };
|
pub use no_std_net::{ SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs, IpAddr, Ipv4Addr, Ipv6Addr };
|
||||||
pub type SystemPinBoxFuture<T> = PinBox<dyn Future<Output = T> + 'static>;
|
pub type SystemPinBoxFuture<T> = PinBox<dyn Future<Output = T> + 'static>;
|
||||||
pub type SystemPinBoxFutureLifetime<'a, T> = PinBox<dyn Future<Output = T> + 'a>;
|
pub type SystemPinBoxFutureLifetime<'a, T> = PinBox<dyn Future<Output = T> + 'a>;
|
||||||
@ -65,6 +67,8 @@ cfg_if! {
|
|||||||
pub use std::ops::{FnOnce, FnMut, Fn};
|
pub use std::ops::{FnOnce, FnMut, Fn};
|
||||||
pub use async_std::future::Future;
|
pub use async_std::future::Future;
|
||||||
pub use async_std::pin::Pin;
|
pub use async_std::pin::Pin;
|
||||||
|
pub use async_std::sync::Mutex as AsyncMutex;
|
||||||
|
pub use async_std::sync::MutexGuard as AsyncMutexGuard;
|
||||||
pub use std::net::{ SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs, IpAddr, Ipv4Addr, Ipv6Addr };
|
pub use std::net::{ SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs, IpAddr, Ipv4Addr, Ipv6Addr };
|
||||||
pub type SystemPinBoxFuture<T> = PinBox<dyn Future<Output = T> + Send + 'static>;
|
pub type SystemPinBoxFuture<T> = PinBox<dyn Future<Output = T> + Send + 'static>;
|
||||||
pub type SystemPinBoxFutureLifetime<'a, T> = PinBox<dyn Future<Output = T> + Send + 'a>;
|
pub type SystemPinBoxFutureLifetime<'a, T> = PinBox<dyn Future<Output = T> + Send + 'a>;
|
||||||
|
@ -13,6 +13,8 @@ where
|
|||||||
join_handle: Option<JoinHandle<T>>,
|
join_handle: Option<JoinHandle<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Spawns a single background processing task idempotently, possibly returning the return value of the previously executed background task
|
||||||
|
/// This does not queue, just ensures that no more than a single copy of the task is running at a time, but allowing tasks to be retriggered
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SingleFuture<T>
|
pub struct SingleFuture<T>
|
||||||
where
|
where
|
||||||
|
@ -13,6 +13,9 @@ cfg_if! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Runs a single-future background processing task, attempting to run it once every 'tick period' microseconds.
|
||||||
|
/// If the prior tick is still running, it will allow it to finish, and do another tick when the timer comes around again.
|
||||||
|
/// One should attempt to make tasks short-lived things that run in less than the tick period if you want things to happen with regular periodicity.
|
||||||
pub struct TickTask {
|
pub struct TickTask {
|
||||||
last_timestamp_us: AtomicU64,
|
last_timestamp_us: AtomicU64,
|
||||||
tick_period_us: u64,
|
tick_period_us: u64,
|
||||||
|
Loading…
Reference in New Issue
Block a user