more refactor

This commit is contained in:
John Smith 2022-01-03 16:29:04 -05:00
parent 94772094c5
commit 55a44e0c8f
18 changed files with 261 additions and 239 deletions

View File

@ -8,9 +8,8 @@ use futures_util::stream::{FuturesUnordered, StreamExt};
const CONNECTION_PROCESSOR_CHANNEL_SIZE: usize = 128usize;
type ProtocolConnectHandler = fn(Option<SocketAddr>, DialInfo) -> Result<NetworkConnection, String>;
type ProtocolConnectorMap = BTreeMap<ProtocolType, ProtocolConnectHandler>;
///////////////////////////////////////////////////////////
// Accept
cfg_if! {
if #[cfg(not(target_arch = "wasm32"))] {
@ -44,10 +43,36 @@ cfg_if! {
}
pub type NewProtocolAcceptHandler =
dyn Fn(ConnectionManager, bool, SocketAddr) -> Box<dyn ProtocolAcceptHandler> + Send;
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
pub struct ConnectionManagerInner {
network_manager: NetworkManager,
connection_table: ConnectionTable,
@ -94,10 +119,6 @@ impl ConnectionManager {
self.inner.lock().network_manager.clone()
}
pub fn config(&self) -> VeilidConfig {
self.network_manager().config()
}
pub async fn startup(&self) {
let cac = utils::channel::channel(CONNECTION_PROCESSOR_CHANNEL_SIZE); // xxx move to config
self.inner.lock().connection_add_channel_tx = Some(cac.0);
@ -138,6 +159,38 @@ impl ConnectionManager {
.map_err(logthru_net!(error "failed to start receiver loop"))
}
pub async fn get_or_create_connection(
&self,
local_addr: Option<SocketAddr>,
dial_info: DialInfo,
) -> Result<NetworkConnection, String> {
let peer_address = dial_info.to_peer_address();
let descriptor = match local_addr {
Some(la) => {
ConnectionDescriptor::new(peer_address, SocketAddress::from_socket_addr(la))
}
None => ConnectionDescriptor::new_no_local(peer_address),
};
// If connection exists, then return it
if let Some(conn) = self
.inner
.lock()
.connection_table
.get_connection(&descriptor)
.map(|e| e.conn)
{
return Ok(conn);
}
// If not, attempt new connection
let conn = NetworkConnection::connect(local_addr, dial_info).await?;
self.on_new_connection(conn.clone()).await?;
Ok(conn)
}
// Connection receiver loop
fn process_connection(
this: ConnectionManager,

View File

@ -1,3 +1,4 @@
#![allow(dead_code)]
#![allow(clippy::absurd_extreme_comparisons)]
use super::crypto::*;
use super::key::*;

View File

@ -1,3 +1,4 @@
#![allow(dead_code)]
#![allow(clippy::absurd_extreme_comparisons)]
use super::envelope::{MAX_VERSION, MIN_VERSION};
use super::key::*;

View File

@ -261,13 +261,13 @@ impl Network {
match &dial_info {
DialInfo::UDP(_) => {
let peer_socket_addr = dial_info.to_socket_addr();
RawUdpProtocolHandler::send_unbound_message(data, peer_socket_addr)
RawUdpProtocolHandler::send_unbound_message(peer_socket_addr, data)
.await
.map_err(logthru_net!())
}
DialInfo::TCP(_) => {
let peer_socket_addr = dial_info.to_socket_addr();
RawTcpProtocolHandler::send_unbound_message(data, peer_socket_addr)
RawTcpProtocolHandler::send_unbound_message(peer_socket_addr, data)
.await
.map_err(logthru_net!())
}
@ -278,78 +278,40 @@ impl Network {
}
}
// Initiate a new low-level protocol connection to a node
pub async fn connect_to_dial_info(
&self,
local_addr: Option<SocketAddr>,
dial_info: &DialInfo,
) -> Result<NetworkConnection, String> {
let connection_manager = self.connection_manager();
let peer_socket_addr = dial_info.to_socket_addr();
Ok(match &dial_info {
DialInfo::UDP(_) => {
panic!("Do not attempt to connect to UDP dial info")
}
DialInfo::TCP(_) => {
let local_addr =
self.get_preferred_local_address(self.inner.lock().tcp_port, &peer_socket_addr);
RawTcpProtocolHandler::connect(connection_manager, local_addr, dial_info)
.await
.map_err(logthru_net!())?
}
DialInfo::WS(_) => {
let local_addr =
self.get_preferred_local_address(self.inner.lock().ws_port, &peer_socket_addr);
WebsocketProtocolHandler::connect(connection_manager, local_addr, dial_info)
.await
.map_err(logthru_net!(error))?
}
DialInfo::WSS(_) => {
let local_addr =
self.get_preferred_local_address(self.inner.lock().wss_port, &peer_socket_addr);
WebsocketProtocolHandler::connect(connection_manager, local_addr, dial_info)
.await
.map_err(logthru_net!(error))?
}
})
}
async fn send_data_to_existing_connection(
&self,
descriptor: &ConnectionDescriptor,
data: Vec<u8>,
) -> Result<Option<Vec<u8>>, String> {
match descriptor.protocol_type() {
ProtocolType::UDP => {
// send over the best udp socket we have bound since UDP is not connection oriented
let peer_socket_addr = descriptor.remote.to_socket_addr();
if let Some(ph) = self.find_best_udp_protocol_handler(
&peer_socket_addr,
&descriptor.local.map(|sa| sa.to_socket_addr()),
) {
ph.clone()
.send_message(data, peer_socket_addr)
.await
.map_err(logthru_net!())?;
// Data was consumed
return Ok(None);
}
}
ProtocolType::TCP | ProtocolType::WS | ProtocolType::WSS => {
// find an existing connection in the connection table if one exists
if let Some(conn) = self.connection_manager().get_connection(descriptor) {
// connection exists, send over it
conn.send(data).await.map_err(logthru_net!())?;
// Data was consumed
return Ok(None);
}
// Handle connectionless protocol
if descriptor.protocol_type() == ProtocolType::UDP {
// send over the best udp socket we have bound since UDP is not connection oriented
let peer_socket_addr = descriptor.remote.to_socket_addr();
if let Some(ph) = self.find_best_udp_protocol_handler(
&peer_socket_addr,
&descriptor.local.map(|sa| sa.to_socket_addr()),
) {
ph.clone()
.send_message(data, peer_socket_addr)
.await
.map_err(logthru_net!())?;
// Data was consumed
return Ok(None);
}
}
// 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))
// Handle connection-oriented protocols
if let Some(conn) = self.connection_manager().get_connection(descriptor) {
// connection exists, send over it
conn.send(data).await.map_err(logthru_net!())?;
// Data was consumed
Ok(None)
} else {
// Connection or didn't exist
// Pass the data back out so we don't own it any more
Ok(Some(data))
}
}
// Send data directly to a dial info, possibly without knowing which node it is going to
@ -372,7 +334,11 @@ impl Network {
}
// Handle connection-oriented protocols
let conn = self.connect_to_dial_info(dial_info).await?;
let local_addr = self.get_preferred_local_address(dial_info);
let conn = self
.connection_manager()
.get_or_create_connection(Some(local_addr), dial_info.clone())
.await?;
conn.send(data).await.map_err(logthru_net!(error))
}
@ -405,25 +371,7 @@ impl Network {
.ok_or_else(|| "couldn't send data, no dial info or peer address".to_owned())?;
// Handle connectionless protocol
if dial_info.protocol_type() == ProtocolType::UDP {
let peer_socket_addr = dial_info.to_socket_addr();
if let Some(ph) = self.find_best_udp_protocol_handler(&peer_socket_addr, &None) {
return ph
.send_message(data, peer_socket_addr)
.await
.map_err(logthru_net!());
}
return Err("no appropriate UDP protocol handler for dial_info".to_owned())
.map_err(logthru_net!(error));
}
// Handle connection-oriented protocols
let local_addr = self.get_preferred_local_address(&dial_info);
let conn = self
.connection_manager()
.get_or_create_connection(dial_info, Some(local_addr)); xxx implement this and pass thru to NetworkConnection::connect
conn.send(data).await.map_err(logthru_net!(error))
self.send_data_to_dial_info(&dial_info, data).await
}
/////////////////////////////////////////////////////////////////

View File

@ -134,8 +134,8 @@ impl Network {
// and the number of total connections
let addr = match tcp_stream.peer_addr() {
Ok(addr) => addr,
Err(err) => {
error!("failed to get peer address: {}", err);
Err(e) => {
error!("failed to get peer address: {}", e);
return;
}
};
@ -191,7 +191,9 @@ impl Network {
};
// Register the new connection in the connection manager
connection_manager.on_new_connection(conn).await;
if let Err(e) = connection_manager.on_new_connection(conn).await {
error!("failed to register new connection: {}", e);
}
})
.await;
trace!("exited incoming loop for {}", addr);
@ -248,7 +250,7 @@ impl Network {
ls.write()
.tls_protocol_handlers
.push(new_protocol_accept_handler(
self.connection_manager(),
self.network_manager().config(),
true,
addr,
));
@ -256,7 +258,7 @@ impl Network {
ls.write()
.protocol_handlers
.push(new_protocol_accept_handler(
self.connection_manager(),
self.network_manager().config(),
false,
addr,
));

View File

@ -21,6 +21,7 @@ impl Network {
////////////////////////////////////////////////////////////
// Run thread task to process stream of messages
let this = self.clone();
let jh = spawn(async move {
trace!("UDP listener task spawned");
@ -41,8 +42,26 @@ impl Network {
// Spawn a local async task for each socket
let mut protocol_handlers_unordered = stream::FuturesUnordered::new();
let network_manager = this.network_manager();
for ph in protocol_handlers {
let jh = spawn_local(ph.clone().receive_loop());
let network_manager = network_manager.clone();
let jh = spawn_local(async move {
let mut data = vec![0u8; 65536];
while let Ok((size, descriptor)) = ph.recv_message(&mut data).await {
// XXX: Limit the number of packets from the same IP address?
log_net!("UDP packet: {:?}", descriptor);
if let Err(e) = network_manager
.on_recv_envelope(&data[..size], &descriptor)
.await
{
log_net!(error "failed to process received udp envelope: {}", e);
}
}
});
protocol_handlers_unordered.push(jh);
}
// Now we wait for any join handle to exit,
@ -83,8 +102,7 @@ impl Network {
let socket_arc = Arc::new(udp_socket);
// Create protocol handler
let udpv4_handler =
RawUdpProtocolHandler::new(inner.network_manager.clone(), socket_arc);
let udpv4_handler = RawUdpProtocolHandler::new(socket_arc);
inner.outbound_udpv4_protocol_handler = Some(udpv4_handler);
}
@ -98,8 +116,7 @@ impl Network {
let socket_arc = Arc::new(udp_socket);
// Create protocol handler
let udpv6_handler =
RawUdpProtocolHandler::new(inner.network_manager.clone(), socket_arc);
let udpv6_handler = RawUdpProtocolHandler::new(socket_arc);
inner.outbound_udpv6_protocol_handler = Some(udpv6_handler);
}
@ -119,8 +136,7 @@ impl Network {
let socket_arc = Arc::new(udp_socket);
// Create protocol handler
let protocol_handler =
RawUdpProtocolHandler::new(self.inner.lock().network_manager.clone(), socket_arc);
let protocol_handler = RawUdpProtocolHandler::new(socket_arc);
// Create message_handler records
self.inner

View File

@ -3,28 +3,11 @@ pub mod udp;
pub mod wrtc;
pub mod ws;
use crate::connection_manager::*;
use crate::xx::*;
use crate::*;
use socket2::{Domain, Protocol, Socket, Type};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DummyNetworkConnection {}
impl DummyNetworkConnection {
pub fn connection_descriptor(&self) -> ConnectionDescriptor {
ConnectionDescriptor::new_no_local(PeerAddress::new(
SocketAddress::default(),
ProtocolType::UDP,
))
}
pub async fn send(&self, _message: Vec<u8>) -> Result<(), String> {
Ok(())
}
pub async fn recv(&self) -> Result<Vec<u8>, String> {
Ok(Vec::new())
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum NetworkConnection {
Dummy(DummyNetworkConnection),
@ -52,6 +35,29 @@ impl NetworkConnection {
}
}
}
pub async fn send_unbound_message(
&self,
dial_info: &DialInfo,
data: Vec<u8>,
) -> Result<(), String> {
match dial_info.protocol_type() {
ProtocolType::UDP => {
let peer_socket_addr = dial_info.to_socket_addr();
udp::RawUdpProtocolHandler::send_unbound_message(peer_socket_addr, data)
.await
.map_err(logthru_net!())
}
ProtocolType::TCP => {
let peer_socket_addr = dial_info.to_socket_addr();
tcp::RawTcpProtocolHandler::send_unbound_message(peer_socket_addr, data)
.await
.map_err(logthru_net!())
}
ProtocolType::WS | ProtocolType::WSS => {
ws::WebsocketProtocolHandler::send_unbound_message(dial_info, data).await
}
}
}
pub fn connection_descriptor(&self) -> ConnectionDescriptor {
match self {

View File

@ -1,5 +1,4 @@
use super::*;
use crate::connection_manager::*;
use crate::intf::native::utils::async_peek_stream::*;
use crate::intf::*;
use crate::network_manager::MAX_MESSAGE_SIZE;
@ -104,7 +103,6 @@ impl RawTcpNetworkConnection {
///
struct RawTcpProtocolHandlerInner {
connection_manager: ConnectionManager,
local_address: SocketAddr,
}
@ -117,22 +115,13 @@ where
}
impl RawTcpProtocolHandler {
fn new_inner(
connection_manager: ConnectionManager,
local_address: SocketAddr,
) -> RawTcpProtocolHandlerInner {
RawTcpProtocolHandlerInner {
connection_manager,
local_address,
}
fn new_inner(local_address: SocketAddr) -> RawTcpProtocolHandlerInner {
RawTcpProtocolHandlerInner { local_address }
}
pub fn new(connection_manager: ConnectionManager, local_address: SocketAddr) -> Self {
pub fn new(local_address: SocketAddr) -> Self {
Self {
inner: Arc::new(Mutex::new(Self::new_inner(
connection_manager,
local_address,
))),
inner: Arc::new(Mutex::new(Self::new_inner(local_address))),
}
}
@ -153,10 +142,7 @@ impl RawTcpProtocolHandler {
SocketAddress::from_socket_addr(socket_addr),
ProtocolType::TCP,
);
let (network_manager, local_address) = {
let inner = self.inner.lock();
(inner.connection_manager.clone(), inner.local_address)
};
let local_address = self.inner.lock().local_address;
let conn = NetworkConnection::RawTcp(RawTcpNetworkConnection::new(
stream,
ConnectionDescriptor::new(peer_addr, SocketAddress::from_socket_addr(local_address)),
@ -194,12 +180,8 @@ impl RawTcpProtocolHandler {
.map_err(map_to_string)
.map_err(logthru_net!("could not get local address from TCP stream"))?;
let ps = AsyncPeekStream::new(ts);
let peer_addr = PeerAddress::new(
SocketAddress::from_socket_addr(remote_socket_addr),
ProtocolType::TCP,
);
// Wrap the stream in a network connection and register it
// Wrap the stream in a network connection and return it
let conn = NetworkConnection::RawTcp(RawTcpNetworkConnection::new(
ps,
ConnectionDescriptor {
@ -211,8 +193,8 @@ impl RawTcpProtocolHandler {
}
pub async fn send_unbound_message(
data: Vec<u8>,
socket_addr: SocketAddr,
data: Vec<u8>,
) -> Result<(), String> {
if data.len() > MAX_MESSAGE_SIZE {
return Err("sending too large unbound TCP message".to_owned());

View File

@ -1,10 +1,9 @@
use crate::intf::*;
use crate::network_manager::{NetworkManager, MAX_MESSAGE_SIZE};
use crate::network_manager::MAX_MESSAGE_SIZE;
use crate::*;
use async_std::net::*;
struct RawUdpProtocolHandlerInner {
network_manager: NetworkManager,
socket: Arc<UdpSocket>,
}
@ -14,64 +13,44 @@ pub struct RawUdpProtocolHandler {
}
impl RawUdpProtocolHandler {
fn new_inner(
network_manager: NetworkManager,
socket: Arc<UdpSocket>,
) -> RawUdpProtocolHandlerInner {
RawUdpProtocolHandlerInner {
network_manager,
socket,
}
fn new_inner(socket: Arc<UdpSocket>) -> RawUdpProtocolHandlerInner {
RawUdpProtocolHandlerInner { socket }
}
pub fn new(network_manager: NetworkManager, socket: Arc<UdpSocket>) -> Self {
pub fn new(socket: Arc<UdpSocket>) -> Self {
Self {
inner: Arc::new(Mutex::new(Self::new_inner(network_manager, socket))),
inner: Arc::new(Mutex::new(Self::new_inner(socket))),
}
}
pub async fn receive_loop(self) {
let mut data = vec![0u8; 65536];
pub async fn recv_message(
&self,
data: &mut [u8],
) -> Result<(usize, ConnectionDescriptor), String> {
let socket = self.inner.lock().socket.clone();
while let Ok((size, socket_addr)) = socket.recv_from(&mut data).await {
// XXX: Limit the number of packets from the same IP address?
trace!("UDP packet from: {}", socket_addr);
let (size, remote_addr) = socket.recv_from(data).await.map_err(map_to_string)?;
let _processed = self.clone().on_message(&data[..size], socket_addr).await;
}
}
pub async fn on_message(&self, data: &[u8], remote_addr: SocketAddr) -> Result<bool, String> {
if data.len() > MAX_MESSAGE_SIZE {
if size > MAX_MESSAGE_SIZE {
return Err("received too large UDP message".to_owned());
}
trace!(
"receiving UDP message of length {} from {}",
data.len(),
size,
remote_addr
);
// Process envelope
let (network_manager, socket) = {
let inner = self.inner.lock();
(inner.network_manager.clone(), inner.socket.clone())
};
let peer_addr = PeerAddress::new(
SocketAddress::from_socket_addr(remote_addr),
ProtocolType::UDP,
);
let local_socket_addr = socket.local_addr().map_err(|e| format!("{}", e))?;
network_manager
.on_recv_envelope(
data,
&ConnectionDescriptor::new(
peer_addr,
SocketAddress::from_socket_addr(local_socket_addr),
),
)
.await
let local_socket_addr = socket.local_addr().map_err(map_to_string)?;
let descriptor = ConnectionDescriptor::new(
peer_addr,
SocketAddress::from_socket_addr(local_socket_addr),
);
Ok((size, descriptor))
}
pub async fn send_message(&self, data: Vec<u8>, socket_addr: SocketAddr) -> Result<(), String> {
@ -100,8 +79,8 @@ impl RawUdpProtocolHandler {
}
pub async fn send_unbound_message(
data: Vec<u8>,
socket_addr: SocketAddr,
data: Vec<u8>,
) -> Result<(), String> {
if data.len() > MAX_MESSAGE_SIZE {
return Err("sending too large unbound UDP message".to_owned())

View File

@ -1,5 +1,4 @@
use super::*;
use crate::connection_manager::*;
use crate::intf::native::utils::async_peek_stream::*;
use crate::intf::*;
use crate::network_manager::MAX_MESSAGE_SIZE;
@ -133,7 +132,6 @@ where
///
struct WebsocketProtocolHandlerInner {
tls: bool,
connection_manager: ConnectionManager,
local_address: SocketAddr,
request_path: Vec<u8>,
connection_initial_timeout: u64,
@ -147,12 +145,7 @@ where
inner: Arc<WebsocketProtocolHandlerInner>,
}
impl WebsocketProtocolHandler {
pub fn new(
connection_manager: ConnectionManager,
tls: bool,
local_address: SocketAddr,
) -> Self {
let config = connection_manager.config();
pub fn new(config: VeilidConfig, tls: bool, local_address: SocketAddr) -> Self {
let c = config.get();
let path = if tls {
format!("GET {}", c.network.protocol.ws.path.trim_end_matches('/'))
@ -167,7 +160,6 @@ impl WebsocketProtocolHandler {
let inner = WebsocketProtocolHandlerInner {
tls,
connection_manager,
local_address,
request_path: path.as_bytes().to_vec(),
connection_initial_timeout,
@ -313,6 +305,23 @@ impl WebsocketProtocolHandler {
)))
}
}
pub async fn send_unbound_message(dial_info: &DialInfo, data: Vec<u8>) -> Result<(), String> {
if data.len() > MAX_MESSAGE_SIZE {
return Err("sending too large unbound WS message".to_owned());
}
trace!(
"sending unbound websocket message of length {} to {}",
data.len(),
dial_info,
);
let conn = Self::connect(None, dial_info.clone())
.await
.map_err(|e| format!("failed to connect websocket for unbound message: {}", e))?;
conn.send(data).await
}
}
impl ProtocolAcceptHandler for WebsocketProtocolHandler {

View File

@ -160,7 +160,7 @@ impl Network {
.start_tcp_listener(
listen_address.clone(),
true,
Box::new(|n, t, a| Box::new(WebsocketProtocolHandler::new(n, t, a))),
Box::new(|c, t, a| Box::new(WebsocketProtocolHandler::new(c, t, a))),
)
.await?;
trace!("WSS: listener started");
@ -222,7 +222,7 @@ impl Network {
.start_tcp_listener(
listen_address.clone(),
false,
Box::new(|n, _, a| Box::new(RawTcpProtocolHandler::new(n, a))),
Box::new(|_, _, a| Box::new(RawTcpProtocolHandler::new(a))),
)
.await?;
trace!("TCP: listener started");

View File

@ -1,3 +1,5 @@
#![allow(dead_code)]
use crate::xx::*;
pub use async_executors::JoinHandle;
use async_executors::{AsyncStd, LocalSpawnHandleExt, SpawnHandleExt};

View File

@ -24,6 +24,7 @@ pub enum IfAddr {
V6(Ifv6Addr),
}
#[allow(dead_code)]
impl IfAddr {
pub fn ip(&self) -> IpAddr {
match *self {

View File

@ -1,3 +1,5 @@
#![allow(dead_code)]
pub fn convert_to_unsigned_4(x: [i8; 4]) -> [u8; 4] {
let mut out: [u8; 4] = [0u8; 4];
for i in 0..4 {

View File

@ -1,27 +1,10 @@
pub mod wrtc;
pub mod ws;
use crate::connection_manager::*;
use crate::veilid_api::ProtocolType;
use crate::xx::*;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DummyNetworkConnection {}
impl DummyNetworkConnection {
pub fn connection_descriptor(&self) -> ConnectionDescriptor {
ConnectionDescriptor::new_no_local(PeerAddress::new(
SocketAddress::default(),
ProtocolType::UDP,
))
}
pub async fn send(&self, _message: Vec<u8>) -> Result<(), String> {
Ok(())
}
pub async fn recv(&self) -> Result<Vec<u8>, String> {
Ok(Vec::new())
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum NetworkConnection {
Dummy(DummyNetworkConnection),
@ -36,7 +19,7 @@ impl NetworkConnection {
) -> Result<NetworkConnection, String> {
match dial_info.protocol_type() {
ProtocolType::UDP => {
panic!("Should not connect to UDP dialinfo");
panic!("UDP dial info is not support on WASM targets");
}
ProtocolType::TCP => {
panic!("TCP dial info is not support on WASM targets");
@ -46,13 +29,32 @@ impl NetworkConnection {
}
}
}
pub async fn send_unbound_message(
&self,
dial_info: &DialInfo,
data: Vec<u8>,
) -> Result<(), String> {
match dial_info.protocol_type() {
ProtocolType::UDP => {
panic!("UDP dial info is not support on WASM targets");
}
ProtocolType::TCP => {
panic!("TCP dial info is not support on WASM targets");
}
ProtocolType::WS | ProtocolType::WSS => {
ws::WebsocketProtocolHandler::send_unbound_message(dial_info, data).await
}
}
}
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
match self {
Self::Dummy(d) => d.send(message).await,
Self::WS(w) => w.send(message).await,
}
}
pub async fn recv(&self) -> Result<Vec<u8>, String> {
match self {
Self::Dummy(d) => d.recv().await,

View File

@ -125,4 +125,21 @@ impl WebsocketProtocolHandler {
Ok(NetworkConnection::WS(WebsocketNetworkConnection::new(tls, connection_descriptor, wsio)))
}
pub async fn send_unbound_message(dial_info: &DialInfo, data: Vec<u8>) -> Result<(), String> {
if data.len() > MAX_MESSAGE_SIZE {
return Err("sending too large unbound WS message".to_owned());
}
trace!(
"sending unbound websocket message of length {} to {}",
data.len(),
dial_info,
);
let conn = Self::connect(None, dial_info.clone())
.await
.map_err(|e| format!("failed to connect websocket for unbound message: {}", e))?;
conn.send(data).await
}
}

View File

@ -245,6 +245,7 @@ impl RoutingTable {
.instance_empty();
inst.await;
}
fn trigger_changed_dial_info(inner: &mut RoutingTableInner) {
let mut new_eventual = Eventual::new();
core::mem::swap(&mut inner.eventual_changed_dial_info, &mut new_eventual);

View File

@ -1,3 +1,4 @@
use crate::connection_manager::*;
use crate::connection_table::*;
use crate::intf::*;
use crate::xx::*;
@ -6,18 +7,11 @@ use crate::*;
pub async fn test_add_get_remove() {
let mut table = ConnectionTable::new();
let c1 = NetworkConnection::Dummy(DummyNetworkConnection {});
let c2 = NetworkConnection::Dummy(DummyNetworkConnection {});
let c3 = NetworkConnection::Dummy(DummyNetworkConnection {});
let a1 = ConnectionDescriptor::new_no_local(PeerAddress::new(
SocketAddress::new(Address::IPV4(Ipv4Addr::new(127, 0, 0, 1)), 8080),
ProtocolType::TCP,
));
let a2 = ConnectionDescriptor::new_no_local(PeerAddress::new(
SocketAddress::new(Address::IPV4(Ipv4Addr::new(127, 0, 0, 1)), 8080),
ProtocolType::TCP,
));
let a2 = a1.clone();
let a3 = ConnectionDescriptor::new(
PeerAddress::new(
SocketAddress::new(Address::IPV6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 8090),
@ -55,13 +49,19 @@ pub async fn test_add_get_remove() {
))),
);
assert_eq!(a1, a2);
assert_ne!(a3, a4);
assert_ne!(a4, a5);
let c1 = NetworkConnection::Dummy(DummyNetworkConnection::new(a1.clone()));
let c2 = NetworkConnection::Dummy(DummyNetworkConnection::new(a2.clone()));
let c3 = NetworkConnection::Dummy(DummyNetworkConnection::new(a3.clone()));
let c4 = NetworkConnection::Dummy(DummyNetworkConnection::new(a4.clone()));
let c5 = NetworkConnection::Dummy(DummyNetworkConnection::new(a5));
assert_eq!(a1, c2.connection_descriptor());
assert_ne!(a3, c4.connection_descriptor());
assert_ne!(a4, c5.connection_descriptor());
assert_eq!(table.connection_count(), 0);
assert_eq!(table.get_connection(&a1), None);
let entry1 = table.add_connection(a1.clone(), c1.clone()).unwrap();
let entry1 = table.add_connection(c1.clone()).unwrap();
assert_eq!(table.connection_count(), 1);
assert_err!(table.remove_connection(&a3));
@ -70,8 +70,8 @@ pub async fn test_add_get_remove() {
assert_eq!(table.get_connection(&a1), Some(entry1.clone()));
assert_eq!(table.get_connection(&a1), Some(entry1.clone()));
assert_eq!(table.connection_count(), 1);
assert_err!(table.add_connection(a1.clone(), c1.clone()));
assert_err!(table.add_connection(a1.clone(), c2.clone()));
assert_err!(table.add_connection(c1.clone()));
assert_err!(table.add_connection(c2.clone()));
assert_eq!(table.connection_count(), 1);
assert_eq!(table.get_connection(&a1), Some(entry1.clone()));
assert_eq!(table.get_connection(&a1), Some(entry1.clone()));
@ -83,10 +83,10 @@ pub async fn test_add_get_remove() {
assert_eq!(table.get_connection(&a2), None);
assert_eq!(table.get_connection(&a1), None);
assert_eq!(table.connection_count(), 0);
let entry2 = table.add_connection(a1, c1.clone()).unwrap();
assert_err!(table.add_connection(a2.clone(), c1));
let entry3 = table.add_connection(a3.clone(), c2).unwrap();
let entry4 = table.add_connection(a4.clone(), c3).unwrap();
let entry2 = table.add_connection(c1).unwrap();
assert_err!(table.add_connection(c2));
let entry3 = table.add_connection(c3).unwrap();
let entry4 = table.add_connection(c4).unwrap();
assert_eq!(table.connection_count(), 3);
assert_eq!(table.remove_connection(&a2), Ok(entry2));
assert_eq!(table.remove_connection(&a3), Ok(entry3));