fix wasm and finish refactor
This commit is contained in:
parent
2564d35cc1
commit
3035bc079f
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -225,12 +225,6 @@ 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"
|
||||||
@ -276,7 +270,7 @@ dependencies = [
|
|||||||
"async-channel",
|
"async-channel",
|
||||||
"async-global-executor",
|
"async-global-executor",
|
||||||
"async-io",
|
"async-io",
|
||||||
"async-lock 2.4.0",
|
"async-lock",
|
||||||
"async-process",
|
"async-process",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
@ -3749,7 +3743,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"android_logger",
|
"android_logger",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-lock 0.1.0",
|
"async-lock",
|
||||||
"async-std",
|
"async-std",
|
||||||
"async-tls",
|
"async-tls",
|
||||||
"async-tungstenite 0.16.0",
|
"async-tungstenite 0.16.0",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
name = "veilid-cli"
|
name = "veilid-cli"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["John Smith <jsmith@example.com>"]
|
authors = ["John Smith <jsmith@example.com>"]
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
license = "LGPL-2.0-or-later OR MPL-2.0 OR (MIT AND BSD-3-Clause)"
|
license = "LGPL-2.0-or-later OR MPL-2.0 OR (MIT AND BSD-3-Clause)"
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
name = "veilid-core"
|
name = "veilid-core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["John Smith <nobody@example.com>"]
|
authors = ["John Smith <nobody@example.com>"]
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
license = "LGPL-2.0-or-later OR MPL-2.0 OR (MIT AND BSD-3-Clause)"
|
license = "LGPL-2.0-or-later OR MPL-2.0 OR (MIT AND BSD-3-Clause)"
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ keyvaluedb-sqlite = { path = "../external/keyvaluedb/keyvaluedb-sqlite" }
|
|||||||
data-encoding = { version = "^2" }
|
data-encoding = { version = "^2" }
|
||||||
serde = { version = "^1", features = ["derive" ] }
|
serde = { version = "^1", features = ["derive" ] }
|
||||||
serde_cbor = { version = "^0" }
|
serde_cbor = { version = "^0" }
|
||||||
async_executors = { version = "^0", features = [ "async_std" ]}
|
async_executors = { version = "^0", default-features = false, features = [ "async_std" ]}
|
||||||
socket2 = "^0"
|
socket2 = "^0"
|
||||||
bugsalot = "^0"
|
bugsalot = "^0"
|
||||||
chrono = "^0"
|
chrono = "^0"
|
||||||
@ -85,8 +85,8 @@ serde = { version = "^1", default-features = false, features = ["derive", "alloc
|
|||||||
serde_cbor = { version = "^0", default-features = false, features = ["alloc"] }
|
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", default-features = false, features = [ "bindgen" ]}
|
||||||
async-lock = "^0"
|
async-lock = "^2"
|
||||||
|
|
||||||
# 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]
|
||||||
|
@ -83,7 +83,7 @@ impl ConnectionManager {
|
|||||||
// Returns a network connection if one already is established
|
// Returns a network connection if one already is established
|
||||||
pub async fn get_connection(
|
pub async fn get_connection(
|
||||||
&self,
|
&self,
|
||||||
descriptor: &ConnectionDescriptor,
|
descriptor: ConnectionDescriptor,
|
||||||
) -> Option<NetworkConnection> {
|
) -> Option<NetworkConnection> {
|
||||||
let inner = self.arc.inner.lock().await;
|
let inner = self.arc.inner.lock().await;
|
||||||
inner.connection_table.get_connection(descriptor)
|
inner.connection_table.get_connection(descriptor)
|
||||||
@ -92,7 +92,7 @@ impl ConnectionManager {
|
|||||||
// Internal routine to register new connection atomically
|
// Internal routine to register new connection atomically
|
||||||
async fn on_new_connection_internal(
|
async fn on_new_connection_internal(
|
||||||
&self,
|
&self,
|
||||||
mut inner: AsyncMutexGuard<'_, ConnectionManagerInner>,
|
inner: &mut ConnectionManagerInner,
|
||||||
conn: NetworkConnection,
|
conn: NetworkConnection,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let tx = inner
|
let tx = inner
|
||||||
@ -116,8 +116,8 @@ impl ConnectionManager {
|
|||||||
// 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 inner = self.arc.inner.lock().await;
|
let mut inner = self.arc.inner.lock().await;
|
||||||
self.on_new_connection_internal(inner, conn).await
|
self.on_new_connection_internal(&mut *inner, conn).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_or_create_connection(
|
pub async fn get_or_create_connection(
|
||||||
@ -134,16 +134,17 @@ impl ConnectionManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// If connection exists, then return it
|
// If connection exists, then return it
|
||||||
let inner = self.arc.inner.lock().await;
|
let mut inner = self.arc.inner.lock().await;
|
||||||
|
|
||||||
if let Some(conn) = inner.connection_table.get_connection(&descriptor) {
|
if let Some(conn) = inner.connection_table.get_connection(descriptor) {
|
||||||
return Ok(conn);
|
return Ok(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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_internal(inner, conn.clone()).await?;
|
self.on_new_connection_internal(&mut *inner, conn.clone())
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(conn)
|
Ok(conn)
|
||||||
}
|
}
|
||||||
@ -178,7 +179,7 @@ impl ConnectionManager {
|
|||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.connection_table
|
.connection_table
|
||||||
.remove_connection(&descriptor)
|
.remove_connection(descriptor)
|
||||||
{
|
{
|
||||||
log_net!(error e);
|
log_net!(error e);
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@ impl ConnectionTable {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_connection(&self, descriptor: &ConnectionDescriptor) -> Option<NetworkConnection> {
|
pub fn get_connection(&self, descriptor: ConnectionDescriptor) -> Option<NetworkConnection> {
|
||||||
self.conn_by_addr.get(descriptor).cloned()
|
self.conn_by_addr.get(&descriptor).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connection_count(&self) -> usize {
|
pub fn connection_count(&self) -> usize {
|
||||||
@ -42,10 +42,10 @@ impl ConnectionTable {
|
|||||||
|
|
||||||
pub fn remove_connection(
|
pub fn remove_connection(
|
||||||
&mut self,
|
&mut self,
|
||||||
descriptor: &ConnectionDescriptor,
|
descriptor: ConnectionDescriptor,
|
||||||
) -> Result<NetworkConnection, String> {
|
) -> Result<NetworkConnection, String> {
|
||||||
self.conn_by_addr
|
self.conn_by_addr
|
||||||
.remove(descriptor)
|
.remove(&descriptor)
|
||||||
.ok_or_else(|| format!("Connection not in table: {:?}", descriptor))
|
.ok_or_else(|| format!("Connection not in table: {:?}", descriptor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,32 +255,33 @@ impl Network {
|
|||||||
// This bypasses the connection table as it is not a 'node to node' connection.
|
// This bypasses the connection table as it is not a 'node to node' connection.
|
||||||
pub async fn send_data_unbound_to_dial_info(
|
pub async fn send_data_unbound_to_dial_info(
|
||||||
&self,
|
&self,
|
||||||
dial_info: &DialInfo,
|
dial_info: DialInfo,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
match &dial_info {
|
match dial_info.protocol_type() {
|
||||||
DialInfo::UDP(_) => {
|
ProtocolType::UDP => {
|
||||||
let peer_socket_addr = dial_info.to_socket_addr();
|
let peer_socket_addr = dial_info.to_socket_addr();
|
||||||
RawUdpProtocolHandler::send_unbound_message(peer_socket_addr, data)
|
RawUdpProtocolHandler::send_unbound_message(peer_socket_addr, data)
|
||||||
.await
|
.await
|
||||||
.map_err(logthru_net!())
|
.map_err(logthru_net!())
|
||||||
}
|
}
|
||||||
DialInfo::TCP(_) => {
|
ProtocolType::TCP => {
|
||||||
let peer_socket_addr = dial_info.to_socket_addr();
|
let peer_socket_addr = dial_info.to_socket_addr();
|
||||||
RawTcpProtocolHandler::send_unbound_message(peer_socket_addr, data)
|
RawTcpProtocolHandler::send_unbound_message(peer_socket_addr, data)
|
||||||
.await
|
.await
|
||||||
.map_err(logthru_net!())
|
.map_err(logthru_net!())
|
||||||
}
|
}
|
||||||
DialInfo::WS(_) => Err("WS protocol does not support unbound messages".to_owned())
|
ProtocolType::WS | ProtocolType::WSS => {
|
||||||
.map_err(logthru_net!(error)),
|
WebsocketProtocolHandler::send_unbound_message(dial_info, data)
|
||||||
DialInfo::WSS(_) => Err("WSS protocol does not support unbound messages".to_owned())
|
.await
|
||||||
.map_err(logthru_net!(error)),
|
.map_err(logthru_net!())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_data_to_existing_connection(
|
async fn send_data_to_existing_connection(
|
||||||
&self,
|
&self,
|
||||||
descriptor: &ConnectionDescriptor,
|
descriptor: ConnectionDescriptor,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Result<Option<Vec<u8>>, String> {
|
) -> Result<Option<Vec<u8>>, String> {
|
||||||
// Handle connectionless protocol
|
// Handle connectionless protocol
|
||||||
@ -317,7 +318,7 @@ impl Network {
|
|||||||
// Send data directly to a dial info, possibly without knowing which node it is going to
|
// Send data directly to a dial info, possibly without knowing which node it is going to
|
||||||
pub async fn send_data_to_dial_info(
|
pub async fn send_data_to_dial_info(
|
||||||
&self,
|
&self,
|
||||||
dial_info: &DialInfo,
|
dial_info: DialInfo,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
// Handle connectionless protocol
|
// Handle connectionless protocol
|
||||||
@ -334,10 +335,10 @@ impl Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle connection-oriented protocols
|
// Handle connection-oriented protocols
|
||||||
let local_addr = self.get_preferred_local_address(dial_info);
|
let local_addr = self.get_preferred_local_address(&dial_info);
|
||||||
let conn = self
|
let conn = self
|
||||||
.connection_manager()
|
.connection_manager()
|
||||||
.get_or_create_connection(Some(local_addr), dial_info.clone())
|
.get_or_create_connection(Some(local_addr), dial_info)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
conn.send(data).await.map_err(logthru_net!(error))
|
conn.send(data).await.map_err(logthru_net!(error))
|
||||||
@ -353,7 +354,7 @@ impl Network {
|
|||||||
let data = if let Some(descriptor) = node_ref.last_connection() {
|
let data = if let Some(descriptor) = node_ref.last_connection() {
|
||||||
match self
|
match self
|
||||||
.clone()
|
.clone()
|
||||||
.send_data_to_existing_connection(&descriptor, data)
|
.send_data_to_existing_connection(descriptor, data)
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
None => {
|
None => {
|
||||||
@ -370,8 +371,7 @@ impl Network {
|
|||||||
.best_dial_info()
|
.best_dial_info()
|
||||||
.ok_or_else(|| "couldn't send data, no dial info or peer address".to_owned())?;
|
.ok_or_else(|| "couldn't send data, no dial info or peer address".to_owned())?;
|
||||||
|
|
||||||
// Handle connectionless protocol
|
self.send_data_to_dial_info(dial_info, data).await
|
||||||
self.send_data_to_dial_info(&dial_info, data).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
@ -36,7 +36,7 @@ impl ProtocolNetworkConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
||||||
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();
|
||||||
|
@ -290,7 +290,7 @@ impl WebsocketProtocolHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
||||||
if data.len() > MAX_MESSAGE_SIZE {
|
if data.len() > MAX_MESSAGE_SIZE {
|
||||||
return Err("sending too large unbound WS message".to_owned());
|
return Err("sending too large unbound WS message".to_owned());
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
mod protocol;
|
mod protocol;
|
||||||
|
|
||||||
use crate::intf::*;
|
use crate::connection_manager::*;
|
||||||
use crate::network_manager::*;
|
use crate::network_manager::*;
|
||||||
use crate::routing_table::*;
|
use crate::routing_table::*;
|
||||||
|
use crate::intf::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use protocol::ws::WebsocketProtocolHandler;
|
use protocol::ws::WebsocketProtocolHandler;
|
||||||
pub use protocol::*;
|
pub use protocol::*;
|
||||||
@ -42,11 +43,15 @@ impl Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn connection_manager(&self) -> ConnectionManager {
|
||||||
|
self.inner.lock().network_manager.connection_manager()
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
async fn send_data_to_existing_connection(
|
async fn send_data_to_existing_connection(
|
||||||
&self,
|
&self,
|
||||||
descriptor: &ConnectionDescriptor,
|
descriptor: ConnectionDescriptor,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Result<Option<Vec<u8>>, String> {
|
) -> Result<Option<Vec<u8>>, String> {
|
||||||
match descriptor.protocol_type() {
|
match descriptor.protocol_type() {
|
||||||
@ -56,79 +61,70 @@ impl Network {
|
|||||||
ProtocolType::TCP => {
|
ProtocolType::TCP => {
|
||||||
return Err("no support for tcp protocol".to_owned()).map_err(logthru_net!(error))
|
return Err("no support for tcp protocol".to_owned()).map_err(logthru_net!(error))
|
||||||
}
|
}
|
||||||
ProtocolType::WS | ProtocolType::WSS => {
|
_ => {}
|
||||||
// find an existing connection in the connection table if one exists
|
}
|
||||||
let network_manager = self.inner.lock().network_manager.clone();
|
|
||||||
if let Some(entry) = network_manager
|
// Handle connection-oriented protocols
|
||||||
.connection_table()
|
if let Some(conn) = self.connection_manager().get_connection(descriptor).await {
|
||||||
.get_connection(&descriptor)
|
// connection exists, send over it
|
||||||
{
|
conn.send(data).await.map_err(logthru_net!())?;
|
||||||
// connection exists, send over it
|
|
||||||
entry.conn.send(data).await.map_err(logthru_net!())?;
|
// Data was consumed
|
||||||
// Data was consumed
|
Ok(None)
|
||||||
return Ok(None);
|
} else {
|
||||||
}
|
// Connection or didn't exist
|
||||||
}
|
// Pass the data back out so we don't own it any more
|
||||||
|
Ok(Some(data))
|
||||||
}
|
}
|
||||||
// connection or local socket didn't exist, we'll need to use dialinfo to create one
|
|
||||||
// Pass the data back out so we don't own it any more
|
|
||||||
Ok(Some(data))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_data_unbound_to_dial_info(
|
pub async fn send_data_unbound_to_dial_info(
|
||||||
&self,
|
&self,
|
||||||
dial_info: &DialInfo,
|
dial_info: DialInfo,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let network_manager = self.inner.lock().network_manager.clone();
|
match dial_info.protocol_type() {
|
||||||
|
ProtocolType::UDP => {
|
||||||
match &dial_info {
|
|
||||||
DialInfo::UDP(_) => {
|
|
||||||
return Err("no support for UDP protocol".to_owned()).map_err(logthru_net!(error))
|
return Err("no support for UDP protocol".to_owned()).map_err(logthru_net!(error))
|
||||||
}
|
}
|
||||||
DialInfo::TCP(_) => {
|
ProtocolType::TCP => {
|
||||||
return Err("no support for TCP protocol".to_owned()).map_err(logthru_net!(error))
|
return Err("no support for TCP protocol".to_owned()).map_err(logthru_net!(error))
|
||||||
}
|
}
|
||||||
DialInfo::WS(_) => Err("WS protocol does not support unbound messages".to_owned())
|
ProtocolType::WS | ProtocolType::WSS => {
|
||||||
.map_err(logthru_net!(error)),
|
WebsocketProtocolHandler::send_unbound_message(dial_info, data)
|
||||||
DialInfo::WSS(_) => Err("WSS protocol does not support unbound messages".to_owned())
|
.await
|
||||||
.map_err(logthru_net!(error)),
|
.map_err(logthru_net!())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_data_to_dial_info(
|
pub async fn send_data_to_dial_info(
|
||||||
&self,
|
&self,
|
||||||
dial_info: &DialInfo,
|
dial_info: DialInfo,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let network_manager = self.inner.lock().network_manager.clone();
|
if dial_info.protocol_type() == ProtocolType::UDP {
|
||||||
|
return Err("no support for UDP protocol".to_owned()).map_err(logthru_net!(error))
|
||||||
|
}
|
||||||
|
if dial_info.protocol_type() == ProtocolType::TCP {
|
||||||
|
return Err("no support for TCP protocol".to_owned()).map_err(logthru_net!(error))
|
||||||
|
}
|
||||||
|
|
||||||
let conn = match &dial_info {
|
// Handle connection-oriented protocols
|
||||||
DialInfo::UDP(_) => {
|
let conn = self
|
||||||
return Err("no support for UDP protocol".to_owned()).map_err(logthru_net!(error))
|
.connection_manager()
|
||||||
}
|
.get_or_create_connection(None, dial_info)
|
||||||
DialInfo::TCP(_) => {
|
.await?;
|
||||||
return Err("no support for TCP protocol".to_owned()).map_err(logthru_net!(error))
|
|
||||||
}
|
|
||||||
DialInfo::WS(_) => WebsocketProtocolHandler::connect(network_manager, dial_info)
|
|
||||||
.await
|
|
||||||
.map_err(logthru_net!(error))?,
|
|
||||||
DialInfo::WSS(_) => WebsocketProtocolHandler::connect(network_manager, dial_info)
|
|
||||||
.await
|
|
||||||
.map_err(logthru_net!(error))?,
|
|
||||||
};
|
|
||||||
|
|
||||||
conn.send(data).await.map_err(logthru_net!(error))
|
conn.send(data).await.map_err(logthru_net!(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_data(&self, node_ref: NodeRef, data: Vec<u8>) -> Result<(), String> {
|
pub async fn send_data(&self, node_ref: NodeRef, data: Vec<u8>) -> Result<(), String> {
|
||||||
let dial_info = node_ref.best_dial_info();
|
|
||||||
let descriptor = node_ref.last_connection();
|
|
||||||
|
|
||||||
// First try to send data to the last socket we've seen this peer on
|
// First try to send data to the last socket we've seen this peer on
|
||||||
let di_data = if let Some(descriptor) = descriptor {
|
let data = if let Some(descriptor) = node_ref.last_connection() {
|
||||||
match self
|
match self
|
||||||
.clone()
|
.clone()
|
||||||
.send_data_to_existing_connection(&descriptor, data)
|
.send_data_to_existing_connection(descriptor, data)
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
None => {
|
None => {
|
||||||
@ -141,15 +137,11 @@ impl Network {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// If that fails, try to make a connection or reach out to the peer via its dial info
|
// If that fails, try to make a connection or reach out to the peer via its dial info
|
||||||
if let Some(di) = dial_info {
|
let dial_info = node_ref
|
||||||
self.clone()
|
.best_dial_info()
|
||||||
.send_data_to_dial_info(&di, di_data)
|
.ok_or_else(|| "couldn't send data, no dial info or peer address".to_owned())?;
|
||||||
.await
|
|
||||||
.map_err(logthru_net!(error))
|
self.send_data_to_dial_info(dial_info, data).await
|
||||||
} else {
|
|
||||||
Err("couldn't send data, no dial info or peer address".to_owned())
|
|
||||||
.map_err(logthru_net!(error))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
pub mod wrtc;
|
pub mod wrtc;
|
||||||
pub mod ws;
|
pub mod ws;
|
||||||
|
|
||||||
use crate::connection_manager::*;
|
use crate::network_connection::*;
|
||||||
use crate::veilid_api::ProtocolType;
|
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ProtocolNetworkConnection {
|
pub enum ProtocolNetworkConnection {
|
||||||
@ -31,7 +31,7 @@ impl ProtocolNetworkConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_unbound_message(
|
pub async fn send_unbound_message(
|
||||||
dial_info: &DialInfo,
|
dial_info: DialInfo,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
match dial_info.protocol_type() {
|
match dial_info.protocol_type() {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use crate::intf::*;
|
use crate::intf::*;
|
||||||
use crate::network_manager::{NetworkManager, MAX_MESSAGE_SIZE};
|
use crate::network_connection::*;
|
||||||
|
use crate::network_manager::MAX_MESSAGE_SIZE;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use alloc::fmt;
|
use alloc::fmt;
|
||||||
use futures_util::stream::StreamExt;
|
|
||||||
use web_sys::WebSocket;
|
|
||||||
use ws_stream_wasm::*;
|
use ws_stream_wasm::*;
|
||||||
|
use futures_util::{StreamExt, SinkExt};
|
||||||
|
|
||||||
struct WebsocketNetworkConnectionInner {
|
struct WebsocketNetworkConnectionInner {
|
||||||
ws_meta: WsMeta,
|
ws_meta: WsMeta,
|
||||||
@ -27,7 +27,7 @@ impl WebsocketNetworkConnection {
|
|||||||
pub fn new(tls: bool, ws_meta: WsMeta, ws_stream: WsStream) -> Self {
|
pub fn new(tls: bool, ws_meta: WsMeta, ws_stream: WsStream) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tls,
|
tls,
|
||||||
inner: Arc::new(Mutex::new(WebsocketNetworkConnectionInner {
|
inner: Arc::new(AsyncMutex::new(WebsocketNetworkConnectionInner {
|
||||||
ws_meta,
|
ws_meta,
|
||||||
ws_stream,
|
ws_stream,
|
||||||
})),
|
})),
|
||||||
@ -36,7 +36,7 @@ impl WebsocketNetworkConnection {
|
|||||||
|
|
||||||
pub async fn close(&self) -> Result<(), String> {
|
pub async fn close(&self) -> Result<(), String> {
|
||||||
let inner = self.inner.lock().await;
|
let inner = self.inner.lock().await;
|
||||||
inner.ws_meta.close().await;
|
inner.ws_meta.close().await.map_err(map_to_string).map(drop)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||||
@ -77,46 +77,37 @@ pub struct WebsocketProtocolHandler {}
|
|||||||
impl WebsocketProtocolHandler {
|
impl WebsocketProtocolHandler {
|
||||||
pub async fn connect(
|
pub async fn connect(
|
||||||
local_address: Option<SocketAddr>,
|
local_address: Option<SocketAddr>,
|
||||||
dial_info: &DialInfo,
|
dial_info: DialInfo,
|
||||||
) -> Result<NetworkConnection, String> {
|
) -> Result<NetworkConnection, String> {
|
||||||
let url = dial_info
|
|
||||||
.request()
|
assert!(local_address.is_none());
|
||||||
.ok_or_else(|| format!("missing url in websocket dialinfo: {:?}", dial_info))?;
|
|
||||||
let split_url = SplitUrl::from_str(&url)?;
|
|
||||||
let tls = match dial_info {
|
|
||||||
DialInfo::WS(ws) => {
|
|
||||||
if split_url.scheme.to_ascii_lowercase() != "ws" {
|
|
||||||
return Err(format!("wrong scheme for WS websocket url: {}", url));
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
DialInfo::WSS(wss) => {
|
|
||||||
if split_url.scheme.to_ascii_lowercase() != "wss" {
|
|
||||||
return Err(format!("wrong scheme for WSS websocket url: {}", url));
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err("wrong protocol for WebsocketProtocolHandler".to_owned())
|
|
||||||
.map_err(logthru_net!(error))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let (_, wsio) = WsMeta::connect(url, None)
|
// Split dial info up
|
||||||
|
let (tls, scheme) = match &dial_info {
|
||||||
|
DialInfo::WS(_) => (false, "ws"),
|
||||||
|
DialInfo::WSS(_) => (true, "wss"),
|
||||||
|
_ => panic!("invalid dialinfo for WS/WSS protocol"),
|
||||||
|
};
|
||||||
|
let request = dial_info.request().unwrap();
|
||||||
|
let split_url = SplitUrl::from_str(&request)?;
|
||||||
|
if split_url.scheme != scheme {
|
||||||
|
return Err("invalid websocket url scheme".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let (wsmeta, wsio) = WsMeta::connect(request, None)
|
||||||
.await
|
.await
|
||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
.map_err(logthru_net!(error))?;
|
.map_err(logthru_net!(error))?;
|
||||||
|
|
||||||
// Make our connection descriptor
|
// Make our connection descriptor
|
||||||
let connection_descriptor = ConnectionDescriptor {
|
|
||||||
|
Ok(NetworkConnection::from_protocol(ConnectionDescriptor {
|
||||||
local: None,
|
local: None,
|
||||||
remote: dial_info.to_peer_address(),
|
remote: dial_info.to_peer_address(),
|
||||||
};
|
},ProtocolNetworkConnection::Ws(WebsocketNetworkConnection::new(tls, wsmeta, 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> {
|
||||||
if data.len() > MAX_MESSAGE_SIZE {
|
if data.len() > MAX_MESSAGE_SIZE {
|
||||||
return Err("sending too large unbound WS message".to_owned());
|
return Err("sending too large unbound WS message".to_owned());
|
||||||
}
|
}
|
||||||
@ -126,7 +117,7 @@ impl WebsocketProtocolHandler {
|
|||||||
dial_info,
|
dial_info,
|
||||||
);
|
);
|
||||||
|
|
||||||
let conn = Self::connect(None, dial_info.clone())
|
let conn = Self::connect(None, dial_info)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("failed to connect websocket for unbound message: {}", e))?;
|
.map_err(|e| format!("failed to connect websocket for unbound message: {}", e))?;
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ impl NetworkManager {
|
|||||||
// Called by the RPC handler when we want to issue an direct receipt
|
// Called by the RPC handler when we want to issue an direct receipt
|
||||||
pub async fn send_direct_receipt<B: AsRef<[u8]>>(
|
pub async fn send_direct_receipt<B: AsRef<[u8]>>(
|
||||||
&self,
|
&self,
|
||||||
dial_info: &DialInfo,
|
dial_info: DialInfo,
|
||||||
rcpt_data: B,
|
rcpt_data: B,
|
||||||
alternate_port: bool,
|
alternate_port: bool,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
|
@ -941,7 +941,7 @@ impl RPCProcessor {
|
|||||||
// Possibly from an alternate port
|
// Possibly from an alternate port
|
||||||
let network_manager = self.network_manager();
|
let network_manager = self.network_manager();
|
||||||
network_manager
|
network_manager
|
||||||
.send_direct_receipt(&dial_info, rcpt_data, alternate_port)
|
.send_direct_receipt(dial_info.clone(), rcpt_data, alternate_port)
|
||||||
.await
|
.await
|
||||||
.map_err(map_error_string!())
|
.map_err(map_error_string!())
|
||||||
.map_err(
|
.map_err(
|
||||||
|
@ -59,37 +59,37 @@ pub async fn test_add_get_remove() {
|
|||||||
assert_ne!(a4, c5.connection_descriptor());
|
assert_ne!(a4, c5.connection_descriptor());
|
||||||
|
|
||||||
assert_eq!(table.connection_count(), 0);
|
assert_eq!(table.connection_count(), 0);
|
||||||
assert_eq!(table.get_connection(&a1), None);
|
assert_eq!(table.get_connection(a1), None);
|
||||||
table.add_connection(c1.clone()).unwrap();
|
table.add_connection(c1.clone()).unwrap();
|
||||||
|
|
||||||
assert_eq!(table.connection_count(), 1);
|
assert_eq!(table.connection_count(), 1);
|
||||||
assert_err!(table.remove_connection(&a3));
|
assert_err!(table.remove_connection(a3));
|
||||||
assert_err!(table.remove_connection(&a4));
|
assert_err!(table.remove_connection(a4));
|
||||||
assert_eq!(table.connection_count(), 1);
|
assert_eq!(table.connection_count(), 1);
|
||||||
assert_eq!(table.get_connection(&a1), Some(c1.clone()));
|
assert_eq!(table.get_connection(a1), Some(c1.clone()));
|
||||||
assert_eq!(table.get_connection(&a1), Some(c1.clone()));
|
assert_eq!(table.get_connection(a1), Some(c1.clone()));
|
||||||
assert_eq!(table.connection_count(), 1);
|
assert_eq!(table.connection_count(), 1);
|
||||||
assert_err!(table.add_connection(c1.clone()));
|
assert_err!(table.add_connection(c1.clone()));
|
||||||
assert_err!(table.add_connection(c2.clone()));
|
assert_err!(table.add_connection(c2.clone()));
|
||||||
assert_eq!(table.connection_count(), 1);
|
assert_eq!(table.connection_count(), 1);
|
||||||
assert_eq!(table.get_connection(&a1), Some(c1.clone()));
|
assert_eq!(table.get_connection(a1), Some(c1.clone()));
|
||||||
assert_eq!(table.get_connection(&a1), Some(c1.clone()));
|
assert_eq!(table.get_connection(a1), Some(c1.clone()));
|
||||||
assert_eq!(table.connection_count(), 1);
|
assert_eq!(table.connection_count(), 1);
|
||||||
assert_eq!(table.remove_connection(&a2), Ok(c1.clone()));
|
assert_eq!(table.remove_connection(a2), Ok(c1.clone()));
|
||||||
assert_eq!(table.connection_count(), 0);
|
assert_eq!(table.connection_count(), 0);
|
||||||
assert_err!(table.remove_connection(&a2));
|
assert_err!(table.remove_connection(a2));
|
||||||
assert_eq!(table.connection_count(), 0);
|
assert_eq!(table.connection_count(), 0);
|
||||||
assert_eq!(table.get_connection(&a2), None);
|
assert_eq!(table.get_connection(a2), None);
|
||||||
assert_eq!(table.get_connection(&a1), None);
|
assert_eq!(table.get_connection(a1), None);
|
||||||
assert_eq!(table.connection_count(), 0);
|
assert_eq!(table.connection_count(), 0);
|
||||||
table.add_connection(c1.clone()).unwrap();
|
table.add_connection(c1.clone()).unwrap();
|
||||||
assert_err!(table.add_connection(c2));
|
assert_err!(table.add_connection(c2));
|
||||||
table.add_connection(c3.clone()).unwrap();
|
table.add_connection(c3.clone()).unwrap();
|
||||||
table.add_connection(c4.clone()).unwrap();
|
table.add_connection(c4.clone()).unwrap();
|
||||||
assert_eq!(table.connection_count(), 3);
|
assert_eq!(table.connection_count(), 3);
|
||||||
assert_eq!(table.remove_connection(&a2), Ok(c1));
|
assert_eq!(table.remove_connection(a2), Ok(c1));
|
||||||
assert_eq!(table.remove_connection(&a3), Ok(c3));
|
assert_eq!(table.remove_connection(a3), Ok(c3));
|
||||||
assert_eq!(table.remove_connection(&a4), Ok(c4));
|
assert_eq!(table.remove_connection(a4), Ok(c4));
|
||||||
assert_eq!(table.connection_count(), 0);
|
assert_eq!(table.connection_count(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ pub type SendPinBoxFutureLifetime<'a, T> = PinBox<dyn Future<Output = T> + Send
|
|||||||
|
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(target_arch = "wasm32")] {
|
if #[cfg(target_arch = "wasm32")] {
|
||||||
extern crate alloc;
|
|
||||||
pub use alloc::string::String;
|
pub use alloc::string::String;
|
||||||
pub use alloc::vec::Vec;
|
pub use alloc::vec::Vec;
|
||||||
pub use alloc::collections::btree_map::BTreeMap;
|
pub use alloc::collections::btree_map::BTreeMap;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
name = "veilid-server"
|
name = "veilid-server"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["John Smith <jsmith@example.com>"]
|
authors = ["John Smith <jsmith@example.com>"]
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
license = "LGPL-2.0-or-later OR MPL-2.0 OR (MIT AND BSD-3-Clause)"
|
license = "LGPL-2.0-or-later OR MPL-2.0 OR (MIT AND BSD-3-Clause)"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user