Deprecate WSS via feature flag

This commit is contained in:
Christien Rioux 2025-09-07 17:25:25 -04:00
parent 88e0d420b4
commit dbc5bd495b
34 changed files with 441 additions and 1517 deletions

View file

@ -24,6 +24,7 @@
- Crypto / CryptoSystem functions now use typed keys everywhere (#483) - Crypto / CryptoSystem functions now use typed keys everywhere (#483)
- Eliminated 'best' CryptoKind concept, crypto kinds must now be explicitly stated, otherwise upgrades of veilid-core that change the 'best' CryptoKind could break functionality silently. - Eliminated 'best' CryptoKind concept, crypto kinds must now be explicitly stated, otherwise upgrades of veilid-core that change the 'best' CryptoKind could break functionality silently.
- Encryption is enabled by default for all DHT operations, closes [#300](https://gitlab.com/veilid/veilid/-/issues/300) (@neequ57) - Encryption is enabled by default for all DHT operations, closes [#300](https://gitlab.com/veilid/veilid/-/issues/300) (@neequ57)
- Deprecation of WSS config and removal of Application config
- veilid-core: - veilid-core:
- Add private route example - Add private route example
@ -40,6 +41,7 @@
- Update keyring-manager to eliminate licensing issue - Update keyring-manager to eliminate licensing issue
- Added 'tick lag' detection to check for missed watch updates - Added 'tick lag' detection to check for missed watch updates
- Added 'DHT Widening', separates consensus width (server side dht operation acceptance) from consensus count (client side), fixes [#435](https://gitlab.com/veilid/veilid/-/issues/435) - Added 'DHT Widening', separates consensus width (server side dht operation acceptance) from consensus count (client side), fixes [#435](https://gitlab.com/veilid/veilid/-/issues/435)
- Deprecation of WSS protocol, closes [#487](https://gitlab.com/veilid/veilid/-/issues/487)
- veilid-python: - veilid-python:
- Correction of type hints - Correction of type hints

View file

@ -64,6 +64,9 @@ enable-crypto-none = [
"digest", "digest",
] ]
# Protocol support features
enable-protocol-wss = []
# Debugging and testing features # Debugging and testing features
verbose-tracing = [] verbose-tracing = []
tracking = [] tracking = []

View file

@ -47,6 +47,7 @@ where
"W" => { "W" => {
format!("ws://{}:{}", hostname, &short[1..]) format!("ws://{}:{}", hostname, &short[1..])
} }
#[cfg(feature = "enable-protocol-wss")]
"S" => { "S" => {
format!("wss://{}:{}", hostname, &short[1..]) format!("wss://{}:{}", hostname, &short[1..])
} }
@ -66,6 +67,7 @@ where
.port .port
.ok_or_else(|| VeilidAPIError::parse_error("Missing port in udp url", url))?, .ok_or_else(|| VeilidAPIError::parse_error("Missing port in udp url", url))?,
"ws" => split_url.port.unwrap_or(80u16), "ws" => split_url.port.unwrap_or(80u16),
#[cfg(feature = "enable-protocol-wss")]
"wss" => split_url.port.unwrap_or(443u16), "wss" => split_url.port.unwrap_or(443u16),
_ => { _ => {
apibail_parse_error!("Invalid dial info url scheme", split_url.scheme); apibail_parse_error!("Invalid dial info url scheme", split_url.scheme);
@ -92,6 +94,7 @@ where
SocketAddress::from_socket_addr(sa).canonical(), SocketAddress::from_socket_addr(sa).canonical(),
url.to_string(), url.to_string(),
)?, )?,
#[cfg(feature = "enable-protocol-wss")]
"wss" => DialInfo::try_wss( "wss" => DialInfo::try_wss(
SocketAddress::from_socket_addr(sa).canonical(), SocketAddress::from_socket_addr(sa).canonical(),
url.to_string(), url.to_string(),
@ -141,6 +144,7 @@ where
hostname: split_url.host.to_string(), hostname: split_url.host.to_string(),
} }
} }
#[cfg(feature = "enable-protocol-wss")]
DialInfo::WSS(di) => { DialInfo::WSS(di) => {
let mut split_url = let mut split_url =
SplitUrl::from_str(&format!("wss://{}", di.request)).unwrap(); SplitUrl::from_str(&format!("wss://{}", di.request)).unwrap();
@ -188,6 +192,7 @@ where
} }
split_url.to_string() split_url.to_string()
} }
#[cfg(feature = "enable-protocol-wss")]
DialInfo::WSS(di) => { DialInfo::WSS(di) => {
let mut split_url = let mut split_url =
SplitUrl::from_str(&format!("wss://{}", di.request)).unwrap(); SplitUrl::from_str(&format!("wss://{}", di.request)).unwrap();

View file

@ -41,6 +41,7 @@ impl NetworkManager {
ProtocolType::UDP, ProtocolType::UDP,
ProtocolType::TCP, ProtocolType::TCP,
ProtocolType::WS, ProtocolType::WS,
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS, ProtocolType::WSS,
]; ];

View file

@ -41,12 +41,12 @@ pub enum ConnectionRefKind {
#[derive(Debug)] #[derive(Debug)]
struct ConnectionTableInner { struct ConnectionTableInner {
max_connections: Vec<usize>, max_connections: BTreeMap<ProtocolType, usize>,
conn_by_id: Vec<LruCache<NetworkConnectionId, NetworkConnection>>, conn_by_id: BTreeMap<ProtocolType, LruCache<NetworkConnectionId, NetworkConnection>>,
protocol_index_by_id: BTreeMap<NetworkConnectionId, usize>, protocol_type_by_id: BTreeMap<NetworkConnectionId, ProtocolType>,
id_by_flow: BTreeMap<Flow, NetworkConnectionId>, id_by_flow: BTreeMap<Flow, NetworkConnectionId>,
ids_by_remote: BTreeMap<PeerAddress, Vec<NetworkConnectionId>>, ids_by_remote: BTreeMap<PeerAddress, Vec<NetworkConnectionId>>,
priority_flows: Vec<LruCache<Flow, ()>>, priority_flows: BTreeMap<ProtocolType, LruCache<Flow, ()>>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -62,62 +62,57 @@ impl ConnectionTable {
let config = registry.config(); let config = registry.config();
let max_connections = { let max_connections = {
let c = config.get(); let c = config.get();
vec![
let mut max_connections = BTreeMap::<ProtocolType, usize>::new();
max_connections.insert(
ProtocolType::TCP,
c.network.protocol.tcp.max_connections as usize, c.network.protocol.tcp.max_connections as usize,
);
max_connections.insert(
ProtocolType::WS,
c.network.protocol.ws.max_connections as usize, c.network.protocol.ws.max_connections as usize,
);
#[cfg(feature = "enable-protocol-wss")]
max_connections.insert(
ProtocolType::WSS,
c.network.protocol.wss.max_connections as usize, c.network.protocol.wss.max_connections as usize,
] );
max_connections
}; };
Self { Self {
registry, registry,
inner: Mutex::new(ConnectionTableInner { inner: Mutex::new(ConnectionTableInner {
conn_by_id: max_connections conn_by_id: max_connections
.iter() .keys()
.map(|_| LruCache::new_unbounded()) .map(|pt| (*pt, LruCache::new_unbounded()))
.collect(), .collect(),
protocol_index_by_id: BTreeMap::new(), protocol_type_by_id: BTreeMap::new(),
id_by_flow: BTreeMap::new(), id_by_flow: BTreeMap::new(),
ids_by_remote: BTreeMap::new(), ids_by_remote: BTreeMap::new(),
priority_flows: max_connections priority_flows: max_connections
.iter() .iter()
.map(|x| LruCache::new(x * PRIORITY_FLOW_PERCENTAGE / 100)) .map(|(pt, x)| (*pt, LruCache::new(*x * PRIORITY_FLOW_PERCENTAGE / 100)))
.collect(), .collect(),
max_connections, max_connections,
}), }),
} }
} }
fn protocol_to_index(protocol: ProtocolType) -> usize {
match protocol {
ProtocolType::TCP => 0,
ProtocolType::WS => 1,
ProtocolType::WSS => 2,
ProtocolType::UDP => panic!("not a connection-oriented protocol"),
}
}
fn index_to_protocol(idx: usize) -> ProtocolType {
match idx {
0 => ProtocolType::TCP,
1 => ProtocolType::WS,
2 => ProtocolType::WSS,
_ => panic!("not a connection-oriented protocol"),
}
}
#[instrument(level = "trace", skip(self))] #[instrument(level = "trace", skip(self))]
pub async fn join(&self) { pub async fn join(&self) {
let mut unord = { let mut unord = {
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
let unord = FuturesUnordered::new(); let unord = FuturesUnordered::new();
for table in &mut inner.conn_by_id { for (pt, table) in &mut inner.conn_by_id {
for (_, mut v) in table.drain() { for (_, mut v) in table.drain() {
veilid_log!(self trace "connection table join: {:?}", v); veilid_log!(self trace "connection table {} join: {:?}", pt, v);
v.close(); v.close();
unord.push(v); unord.push(v);
} }
} }
inner.protocol_index_by_id.clear(); inner.protocol_type_by_id.clear();
inner.id_by_flow.clear(); inner.id_by_flow.clear();
inner.ids_by_remote.clear(); inner.ids_by_remote.clear();
unord unord
@ -165,8 +160,12 @@ impl ConnectionTable {
/// If connections 'must' stay alive, use 'NetworkConnection::protect'. /// If connections 'must' stay alive, use 'NetworkConnection::protect'.
pub fn add_priority_flow(&self, flow: Flow) { pub fn add_priority_flow(&self, flow: Flow) {
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
let protocol_index = Self::protocol_to_index(flow.protocol_type()); let protocol_type = flow.protocol_type();
inner.priority_flows[protocol_index].insert(flow, ()); if let Some(pf) = inner.priority_flows.get_mut(&protocol_type) {
pf.insert(flow, ());
} else {
veilid_log!(self error "Missing priority flow table for protocol type: {}", protocol_type);
}
} }
/// The mechanism for selecting which connections get evicted from the connection table /// The mechanism for selecting which connections get evicted from the connection table
@ -175,22 +174,22 @@ impl ConnectionTable {
fn lru_out_connection_inner( fn lru_out_connection_inner(
&self, &self,
inner: &mut ConnectionTableInner, inner: &mut ConnectionTableInner,
protocol_index: usize, protocol_type: ProtocolType,
) -> Result<Option<NetworkConnection>, ()> { ) -> Result<Option<NetworkConnection>, ()> {
// If nothing needs to be LRUd out right now, then just return // If nothing needs to be LRUd out right now, then just return
if inner.conn_by_id[protocol_index].len() < inner.max_connections[protocol_index] { if inner.conn_by_id[&protocol_type].len() < inner.max_connections[&protocol_type] {
return Ok(None); return Ok(None);
} }
// Find a free connection to terminate to make room // Find a free connection to terminate to make room
let dead_k = { let dead_k = {
let Some(lruk) = inner.conn_by_id[protocol_index].iter().find_map(|(k, v)| { let Some(lruk) = inner.conn_by_id[&protocol_type].iter().find_map(|(k, v)| {
// Ensure anything being LRU evicted isn't protected somehow // Ensure anything being LRU evicted isn't protected somehow
// 1. connections that are 'in-use' are kept // 1. connections that are 'in-use' are kept
// 2. connections with flows in the priority list are kept // 2. connections with flows in the priority list are kept
// 3. connections that are protected are kept // 3. connections that are protected are kept
if !v.is_in_use() if !v.is_in_use()
&& !inner.priority_flows[protocol_index].contains_key(&v.flow()) && !inner.priority_flows[&protocol_type].contains_key(&v.flow())
&& v.protected_node_ref().is_none() && v.protected_node_ref().is_none()
{ {
Some(*k) Some(*k)
@ -216,7 +215,7 @@ impl ConnectionTable {
// Get indices for network connection table // Get indices for network connection table
let id = network_connection.connection_id(); let id = network_connection.connection_id();
let flow = network_connection.flow(); let flow = network_connection.flow();
let protocol_index = Self::protocol_to_index(flow.protocol_type()); let protocol_type = flow.protocol_type();
let remote = flow.remote(); let remote = flow.remote();
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
@ -227,10 +226,10 @@ impl ConnectionTable {
} }
// Sanity checking this implementation (hard fails that would invalidate the representation) // Sanity checking this implementation (hard fails that would invalidate the representation)
if inner.conn_by_id[protocol_index].contains_key(&id) { if inner.conn_by_id[&protocol_type].contains_key(&id) {
panic!("duplicate connection id: {:#?}", network_connection); panic!("duplicate connection id: {:#?}", network_connection);
} }
if inner.protocol_index_by_id.contains_key(&id) { if inner.protocol_type_by_id.contains_key(&id) {
panic!("duplicate id to protocol index: {:#?}", network_connection); panic!("duplicate id to protocol index: {:#?}", network_connection);
} }
if let Some(ids) = inner.ids_by_remote.get(&flow.remote()) { if let Some(ids) = inner.ids_by_remote.get(&flow.remote()) {
@ -255,7 +254,7 @@ impl ConnectionTable {
// if we have reached the maximum number of connections per protocol type // if we have reached the maximum number of connections per protocol type
// then drop the least recently used connection that is not protected or referenced // then drop the least recently used connection that is not protected or referenced
let out_conn = match self.lru_out_connection_inner(&mut inner, protocol_index) { let out_conn = match self.lru_out_connection_inner(&mut inner, protocol_type) {
Ok(v) => v, Ok(v) => v,
Err(()) => { Err(()) => {
return Err(ConnectionTableAddError::table_full(network_connection)); return Err(ConnectionTableAddError::table_full(network_connection));
@ -263,11 +262,12 @@ impl ConnectionTable {
}; };
// Add the connection to the table // Add the connection to the table
let res = inner.conn_by_id[protocol_index].insert(id, network_connection); let conn_by_id_table = inner.conn_by_id.get_mut(&protocol_type).unwrap();
let res = conn_by_id_table.insert(id, network_connection);
assert!(res.is_none()); assert!(res.is_none());
// add connection records // add connection records
inner.protocol_index_by_id.insert(id, protocol_index); inner.protocol_type_by_id.insert(id, protocol_type);
inner.id_by_flow.insert(flow, id); inner.id_by_flow.insert(flow, id);
inner.ids_by_remote.entry(remote).or_default().push(id); inner.ids_by_remote.entry(remote).or_default().push(id);
@ -283,18 +283,19 @@ impl ConnectionTable {
let inner = self.inner.lock(); let inner = self.inner.lock();
let id = *inner.id_by_flow.get(&flow)?; let id = *inner.id_by_flow.get(&flow)?;
let protocol_index = Self::protocol_to_index(flow.protocol_type()); let protocol_type = flow.protocol_type();
let out = inner.conn_by_id[protocol_index].peek(&id).unwrap(); let out = inner.conn_by_id[&protocol_type].peek(&id).unwrap();
Some(out.get_handle()) Some(out.get_handle())
} }
//#[instrument(level = "trace", skip(self), ret)] //#[instrument(level = "trace", skip(self), ret)]
pub fn touch_connection_by_id(&self, id: NetworkConnectionId) { pub fn touch_connection_by_id(&self, id: NetworkConnectionId) {
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
let Some(protocol_index) = inner.protocol_index_by_id.get(&id).copied() else { let Some(protocol_type) = inner.protocol_type_by_id.get(&id).copied() else {
return; return;
}; };
let _ = inner.conn_by_id[protocol_index].get(&id).unwrap(); let conn_by_id_table = inner.conn_by_id.get_mut(&protocol_type).unwrap();
let _ = conn_by_id_table.get(&id);
} }
#[expect(dead_code)] #[expect(dead_code)]
@ -310,8 +311,8 @@ impl ConnectionTable {
let inner = self.inner.lock(); let inner = self.inner.lock();
let id = *inner.id_by_flow.get(&flow)?; let id = *inner.id_by_flow.get(&flow)?;
let protocol_index = Self::protocol_to_index(flow.protocol_type()); let protocol_type = flow.protocol_type();
let out = inner.conn_by_id[protocol_index].peek(&id).unwrap(); let out = inner.conn_by_id[&protocol_type].peek(&id).unwrap();
Some(closure(out)) Some(closure(out))
} }
@ -328,8 +329,9 @@ impl ConnectionTable {
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
let id = *inner.id_by_flow.get(&flow)?; let id = *inner.id_by_flow.get(&flow)?;
let protocol_index = Self::protocol_to_index(flow.protocol_type()); let protocol_type = flow.protocol_type();
let out = inner.conn_by_id[protocol_index].peek_mut(&id).unwrap(); let conn_by_id_table = inner.conn_by_id.get_mut(&protocol_type).unwrap();
let out = conn_by_id_table.peek_mut(&id).unwrap();
Some(closure(out)) Some(closure(out))
} }
@ -339,8 +341,9 @@ impl ConnectionTable {
) -> Option<R> { ) -> Option<R> {
let mut inner_lock = self.inner.lock(); let mut inner_lock = self.inner.lock();
let inner = &mut *inner_lock; let inner = &mut *inner_lock;
for (id, idx) in inner.protocol_index_by_id.iter() { for (id, pt) in inner.protocol_type_by_id.iter() {
if let Some(conn) = inner.conn_by_id[*idx].peek_mut(id) { let conn_by_id_table = inner.conn_by_id.get_mut(pt).unwrap();
if let Some(conn) = conn_by_id_table.peek_mut(id) {
if let Some(out) = closure(conn) { if let Some(out) = closure(conn) {
return Some(out); return Some(out);
} }
@ -356,11 +359,12 @@ impl ConnectionTable {
ref_type: ConnectionRefKind, ref_type: ConnectionRefKind,
) -> bool { ) -> bool {
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
let Some(protocol_index) = inner.protocol_index_by_id.get(&id).copied() else { let Some(protocol_type) = inner.protocol_type_by_id.get(&id).copied() else {
// Sometimes network connections die before we can ref/unref them // Sometimes network connections die before we can ref/unref them
return false; return false;
}; };
let out = inner.conn_by_id[protocol_index].get_mut(&id).unwrap(); let conn_by_id_table = inner.conn_by_id.get_mut(&protocol_type).unwrap();
let out = conn_by_id_table.get_mut(&id).unwrap();
match ref_type { match ref_type {
ConnectionRefKind::AddRef => out.add_ref(), ConnectionRefKind::AddRef => out.add_ref(),
ConnectionRefKind::RemoveRef => out.remove_ref(), ConnectionRefKind::RemoveRef => out.remove_ref(),
@ -377,7 +381,9 @@ impl ConnectionTable {
let inner = &mut *self.inner.lock(); let inner = &mut *self.inner.lock();
let all_ids_by_remote = inner.ids_by_remote.get(&remote)?; let all_ids_by_remote = inner.ids_by_remote.get(&remote)?;
let protocol_index = Self::protocol_to_index(remote.protocol_type()); let protocol_type = remote.protocol_type();
let conn_by_id_table = inner.conn_by_id.get_mut(&protocol_type).unwrap();
if all_ids_by_remote.is_empty() { if all_ids_by_remote.is_empty() {
// no connections // no connections
return None; return None;
@ -385,16 +391,16 @@ impl ConnectionTable {
if all_ids_by_remote.len() == 1 { if all_ids_by_remote.len() == 1 {
// only one connection // only one connection
let id = all_ids_by_remote[0]; let id = all_ids_by_remote[0];
let nc = inner.conn_by_id[protocol_index].get(&id).unwrap(); let nc = conn_by_id_table.get(&id).unwrap();
return Some(nc.get_handle()); return Some(nc.get_handle());
} }
// multiple connections, find the one that matches the best port, or the most recent // multiple connections, find the one that matches the best port, or the most recent
if let Some(best_port) = best_port { if let Some(best_port) = best_port {
for id in all_ids_by_remote { for id in all_ids_by_remote {
let nc = inner.conn_by_id[protocol_index].peek(id).unwrap(); let nc = conn_by_id_table.peek(id).unwrap();
if let Some(local_addr) = nc.flow().local() { if let Some(local_addr) = nc.flow().local() {
if local_addr.port() == best_port { if local_addr.port() == best_port {
let nc = inner.conn_by_id[protocol_index].get(id).unwrap(); let nc = conn_by_id_table.get(id).unwrap();
return Some(nc.get_handle()); return Some(nc.get_handle());
} }
} }
@ -402,7 +408,7 @@ impl ConnectionTable {
} }
// just return most recent network connection if a best port match can not be found // just return most recent network connection if a best port match can not be found
let best_id = *all_ids_by_remote.last().unwrap(); let best_id = *all_ids_by_remote.last().unwrap();
let nc = inner.conn_by_id[protocol_index].get(&best_id).unwrap(); let nc = conn_by_id_table.get(&best_id).unwrap();
Some(nc.get_handle()) Some(nc.get_handle())
} }
@ -440,7 +446,10 @@ impl ConnectionTable {
pub fn connection_count(&self) -> usize { pub fn connection_count(&self) -> usize {
let inner = self.inner.lock(); let inner = self.inner.lock();
inner.conn_by_id.iter().fold(0, |acc, c| acc + c.len()) inner
.conn_by_id
.iter()
.fold(0, |acc, (_pt, c)| acc + c.len())
} }
#[instrument(level = "trace", skip(inner), ret)] #[instrument(level = "trace", skip(inner), ret)]
@ -449,10 +458,11 @@ impl ConnectionTable {
inner: &mut ConnectionTableInner, inner: &mut ConnectionTableInner,
id: NetworkConnectionId, id: NetworkConnectionId,
) -> NetworkConnection { ) -> NetworkConnection {
// protocol_index_by_id // protocol_type_by_id
let protocol_index = inner.protocol_index_by_id.remove(&id).unwrap(); let protocol_type = inner.protocol_type_by_id.remove(&id).unwrap();
// conn_by_id // conn_by_id
let conn = inner.conn_by_id[protocol_index].remove(&id).unwrap(); let conn_by_id_table = inner.conn_by_id.get_mut(&protocol_type).unwrap();
let conn = conn_by_id_table.remove(&id).unwrap();
// id_by_flow // id_by_flow
let flow = conn.flow(); let flow = conn.flow();
let _ = inner let _ = inner
@ -484,8 +494,8 @@ impl ConnectionTable {
pub fn remove_connection_by_id(&self, id: NetworkConnectionId) -> Option<NetworkConnection> { pub fn remove_connection_by_id(&self, id: NetworkConnectionId) -> Option<NetworkConnection> {
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
let protocol_index = *inner.protocol_index_by_id.get(&id)?; let protocol_type = *inner.protocol_type_by_id.get(&id)?;
if !inner.conn_by_id[protocol_index].contains_key(&id) { if !inner.conn_by_id[&protocol_type].contains_key(&id) {
return None; return None;
} }
let conn = self.remove_connection_records_inner(&mut inner, id); let conn = self.remove_connection_records_inner(&mut inner, id);
@ -496,16 +506,16 @@ impl ConnectionTable {
let mut out = String::new(); let mut out = String::new();
let inner = self.inner.lock(); let inner = self.inner.lock();
let cur_ts = Timestamp::now(); let cur_ts = Timestamp::now();
for t in 0..inner.conn_by_id.len() { for pt in inner.conn_by_id.keys() {
out += &format!( out += &format!(
" {} Connections: ({}/{})\n", " {} Connections: ({}/{})\n",
Self::index_to_protocol(t), pt,
inner.conn_by_id[t].len(), inner.conn_by_id[pt].len(),
inner.max_connections[t] inner.max_connections[pt]
); );
for (_, conn) in &inner.conn_by_id[t] { for (_, conn) in &inner.conn_by_id[pt] {
let is_priority_flow = inner.priority_flows[t].contains_key(&conn.flow()); let is_priority_flow = inner.priority_flows[pt].contains_key(&conn.flow());
out += &format!( out += &format!(
" {}{}\n", " {}{}\n",
@ -515,15 +525,15 @@ impl ConnectionTable {
} }
} }
for t in 0..inner.priority_flows.len() { for pt in inner.priority_flows.keys() {
out += &format!( out += &format!(
" {} Priority Flows: ({}/{})\n", " {} Priority Flows: ({}/{})\n",
Self::index_to_protocol(t), pt,
inner.priority_flows[t].len(), inner.priority_flows[pt].len(),
inner.priority_flows[t].capacity(), inner.priority_flows[pt].capacity(),
); );
for (flow, _) in &inner.priority_flows[t] { for (flow, _) in &inner.priority_flows[pt] {
out += &format!(" {}\n", flow); out += &format!(" {}\n", flow);
} }
} }

View file

@ -404,7 +404,19 @@ impl Network {
.wrap_err("connect failure")?); .wrap_err("connect failure")?);
network_result_try!(pnc.send(data).await.wrap_err("send failure")?); network_result_try!(pnc.send(data).await.wrap_err("send failure")?);
} }
ProtocolType::WS | ProtocolType::WSS => { ProtocolType::WS => {
let pnc = network_result_try!(WebsocketProtocolHandler::connect(
self.registry(),
None,
&dial_info,
connect_timeout_ms
)
.await
.wrap_err("connect failure")?);
network_result_try!(pnc.send(data).await.wrap_err("send failure")?);
}
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => {
let pnc = network_result_try!(WebsocketProtocolHandler::connect( let pnc = network_result_try!(WebsocketProtocolHandler::connect(
self.registry(), self.registry(),
None, None,
@ -458,6 +470,7 @@ impl Network {
} }
match dial_info.protocol_type() { match dial_info.protocol_type() {
// Connectionless protocols
ProtocolType::UDP => { ProtocolType::UDP => {
let peer_socket_addr = dial_info.to_socket_addr(); let peer_socket_addr = dial_info.to_socket_addr();
let h = RawUdpProtocolHandler::new_unspecified_bound_handler( let h = RawUdpProtocolHandler::new_unspecified_bound_handler(
@ -498,7 +511,8 @@ impl Network {
out.resize(recv_len, 0u8); out.resize(recv_len, 0u8);
Ok(NetworkResult::Value(out)) Ok(NetworkResult::Value(out))
} }
ProtocolType::TCP | ProtocolType::WS | ProtocolType::WSS => { // Connection-oriented protocols
_ => {
let pnc = network_result_try!(match dial_info.protocol_type() { let pnc = network_result_try!(match dial_info.protocol_type() {
ProtocolType::UDP => unreachable!(), ProtocolType::UDP => unreachable!(),
ProtocolType::TCP => { ProtocolType::TCP => {
@ -512,7 +526,18 @@ impl Network {
.await .await
.wrap_err("connect failure")? .wrap_err("connect failure")?
} }
ProtocolType::WS | ProtocolType::WSS => { ProtocolType::WS => {
WebsocketProtocolHandler::connect(
self.registry(),
None,
&dial_info,
connect_timeout_ms,
)
.await
.wrap_err("connect failure")?
}
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => {
WebsocketProtocolHandler::connect( WebsocketProtocolHandler::connect(
self.registry(), self.registry(),
None, None,
@ -843,6 +868,8 @@ impl Network {
return res; return res;
} }
} }
#[cfg(feature = "enable-protocol-wss")]
if network_state if network_state
.protocol_config .protocol_config
.inbound .inbound
@ -927,6 +954,7 @@ impl Network {
self.register_ws_dial_info(editor_public_internet, editor_local_network) self.register_ws_dial_info(editor_public_internet, editor_local_network)
.await?; .await?;
} }
#[cfg(feature = "enable-protocol-wss")]
if protocol_config.inbound.contains(ProtocolType::WSS) { if protocol_config.inbound.contains(ProtocolType::WSS) {
self.register_wss_dial_info(editor_public_internet, editor_local_network) self.register_wss_dial_info(editor_public_internet, editor_local_network)
.await?; .await?;

View file

@ -99,6 +99,7 @@ impl Network {
if c.network.protocol.ws.listen { if c.network.protocol.ws.listen {
inbound.insert(ProtocolType::WS); inbound.insert(ProtocolType::WS);
} }
#[cfg(feature = "enable-protocol-wss")]
if c.network.protocol.wss.listen { if c.network.protocol.wss.listen {
inbound.insert(ProtocolType::WSS); inbound.insert(ProtocolType::WSS);
} }
@ -113,6 +114,7 @@ impl Network {
if c.network.protocol.ws.connect { if c.network.protocol.ws.connect {
outbound.insert(ProtocolType::WS); outbound.insert(ProtocolType::WS);
} }
#[cfg(feature = "enable-protocol-wss")]
if c.network.protocol.wss.connect { if c.network.protocol.wss.connect {
outbound.insert(ProtocolType::WSS); outbound.insert(ProtocolType::WSS);
} }

View file

@ -12,6 +12,7 @@ pub(crate) enum ProtocolNetworkConnection {
RawTcp(tcp::RawTcpNetworkConnection), RawTcp(tcp::RawTcpNetworkConnection),
WsAccepted(ws::WebSocketNetworkConnectionAccepted), WsAccepted(ws::WebSocketNetworkConnectionAccepted),
Ws(ws::WebsocketNetworkConnectionWS), Ws(ws::WebsocketNetworkConnectionWS),
#[cfg(feature = "enable-protocol-wss")]
Wss(ws::WebsocketNetworkConnectionWSS), Wss(ws::WebsocketNetworkConnectionWSS),
//WebRTC(wrtc::WebRTCNetworkConnection), //WebRTC(wrtc::WebRTCNetworkConnection),
} }
@ -40,7 +41,17 @@ impl ProtocolNetworkConnection {
) )
.await .await
} }
ProtocolType::WS | ProtocolType::WSS => { ProtocolType::WS => {
ws::WebsocketProtocolHandler::connect(
registry,
local_address,
dial_info,
timeout_ms,
)
.await
}
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => {
ws::WebsocketProtocolHandler::connect( ws::WebsocketProtocolHandler::connect(
registry, registry,
local_address, local_address,
@ -58,6 +69,7 @@ impl ProtocolNetworkConnection {
Self::RawTcp(t) => t.flow(), Self::RawTcp(t) => t.flow(),
Self::WsAccepted(w) => w.flow(), Self::WsAccepted(w) => w.flow(),
Self::Ws(w) => w.flow(), Self::Ws(w) => w.flow(),
#[cfg(feature = "enable-protocol-wss")]
Self::Wss(w) => w.flow(), Self::Wss(w) => w.flow(),
} }
} }
@ -68,6 +80,7 @@ impl ProtocolNetworkConnection {
Self::RawTcp(t) => t.close().await, Self::RawTcp(t) => t.close().await,
Self::WsAccepted(w) => w.close().await, Self::WsAccepted(w) => w.close().await,
Self::Ws(w) => w.close().await, Self::Ws(w) => w.close().await,
#[cfg(feature = "enable-protocol-wss")]
Self::Wss(w) => w.close().await, Self::Wss(w) => w.close().await,
} }
} }
@ -78,6 +91,7 @@ impl ProtocolNetworkConnection {
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,
#[cfg(feature = "enable-protocol-wss")]
Self::Wss(w) => w.send(message).await, Self::Wss(w) => w.send(message).await,
} }
} }
@ -87,6 +101,7 @@ impl ProtocolNetworkConnection {
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,
#[cfg(feature = "enable-protocol-wss")]
Self::Wss(w) => w.recv().await, Self::Wss(w) => w.recv().await,
} }
} }

View file

@ -1,6 +1,8 @@
use super::*; use super::*;
#[cfg(feature = "enable-protocol-wss")]
use async_tls::TlsConnector; use async_tls::TlsConnector;
use async_tungstenite::tungstenite::error::ProtocolError; use async_tungstenite::tungstenite::error::ProtocolError;
use async_tungstenite::tungstenite::handshake::server::{ use async_tungstenite::tungstenite::handshake::server::{
Callback, ErrorResponse, Request, Response, Callback, ErrorResponse, Request, Response,
@ -22,10 +24,12 @@ const MAX_WS_BEFORE_BODY: usize = 2048;
cfg_if! { cfg_if! {
if #[cfg(feature="rt-async-std")] { if #[cfg(feature="rt-async-std")] {
#[cfg(feature="enable-protocol-wss")]
pub type WebsocketNetworkConnectionWSS = pub type WebsocketNetworkConnectionWSS =
WebsocketNetworkConnection<async_tls::client::TlsStream<TcpStream>>; WebsocketNetworkConnection<async_tls::client::TlsStream<TcpStream>>;
pub type WebsocketNetworkConnectionWS = WebsocketNetworkConnection<TcpStream>; pub type WebsocketNetworkConnectionWS = WebsocketNetworkConnection<TcpStream>;
} else if #[cfg(feature="rt-tokio")] { } else if #[cfg(feature="rt-tokio")] {
#[cfg(feature="enable-protocol-wss")]
pub type WebsocketNetworkConnectionWSS = pub type WebsocketNetworkConnectionWSS =
WebsocketNetworkConnection<async_tls::client::TlsStream<Compat<TcpStream>>>; WebsocketNetworkConnection<async_tls::client::TlsStream<Compat<TcpStream>>>;
pub type WebsocketNetworkConnectionWS = WebsocketNetworkConnection<Compat<TcpStream>>; pub type WebsocketNetworkConnectionWS = WebsocketNetworkConnection<Compat<TcpStream>>;
@ -192,7 +196,13 @@ impl WebsocketProtocolHandler {
let config = registry.config(); let config = registry.config();
let c = config.get(); let c = config.get();
let path = if tls { let path = if tls {
format!("GET /{}", c.network.protocol.wss.path.trim_end_matches('/')) cfg_if::cfg_if! {
if #[cfg(feature="enable-protocol-wss")] {
format!("GET /{}", c.network.protocol.wss.path.trim_end_matches('/'))
} else {
unreachable!("no tls protocols are enabled");
}
}
} else { } else {
format!("GET /{}", c.network.protocol.ws.path.trim_end_matches('/')) format!("GET /{}", c.network.protocol.ws.path.trim_end_matches('/'))
}; };
@ -276,7 +286,13 @@ impl WebsocketProtocolHandler {
// Wrap the websocket in a NetworkConnection and register it // Wrap the websocket in a NetworkConnection and register it
let protocol_type = if self.arc.tls { let protocol_type = if self.arc.tls {
ProtocolType::WSS cfg_if::cfg_if! {
if #[cfg(feature="enable-protocol-wss")] {
ProtocolType::WSS
} else {
return Ok(None);
}
}
} else { } else {
ProtocolType::WS ProtocolType::WS
}; };
@ -309,15 +325,15 @@ impl WebsocketProtocolHandler {
// Split dial info up // Split dial info up
let (tls, scheme) = match dial_info { let (tls, scheme) = match dial_info {
DialInfo::WS(_) => (false, "ws"), DialInfo::WS(_) => (false, "ws"),
#[cfg(feature = "enable-protocol-wss")]
DialInfo::WSS(_) => (true, "wss"), DialInfo::WSS(_) => (true, "wss"),
_ => panic!("invalid dialinfo for WS/WSS protocol"), _ => panic!("invalid dialinfo for websocket protocol"),
}; };
let request = dial_info.request().unwrap(); let request = dial_info.request().unwrap();
let split_url = SplitUrl::from_str(&request).map_err(to_io_error_other)?; let split_url = SplitUrl::from_str(&request).map_err(to_io_error_other)?;
if split_url.scheme != scheme { if split_url.scheme != scheme {
bail_io_error_other!("invalid websocket url scheme"); bail_io_error_other!("invalid websocket url scheme");
} }
let domain = split_url.host.clone();
// Resolve remote address // Resolve remote address
let remote_address = dial_info.to_socket_addr(); let remote_address = dial_info.to_socket_addr();
@ -346,18 +362,26 @@ impl WebsocketProtocolHandler {
// Negotiate TLS if this is WSS // Negotiate TLS if this is WSS
if tls { if tls {
let connector = TlsConnector::default(); cfg_if::cfg_if! {
let tls_stream = network_result_try!(connector if #[cfg(feature="enable-protocol-wss")] {
.connect(domain.to_string(), tcp_stream) let domain = split_url.host.clone();
.await
.into_network_result()?);
let (ws_stream, _response) = client_async(request, tls_stream)
.await
.map_err(to_io_error_other)?;
Ok(NetworkResult::Value(ProtocolNetworkConnection::Wss( let connector = TlsConnector::default();
WebsocketNetworkConnection::new(registry, flow, ws_stream), let tls_stream = network_result_try!(connector
))) .connect(domain.to_string(), tcp_stream)
.await
.into_network_result()?);
let (ws_stream, _response) = client_async(request, tls_stream)
.await
.map_err(to_io_error_other)?;
Ok(NetworkResult::Value(ProtocolNetworkConnection::Wss(
WebsocketNetworkConnection::new(registry, flow, ws_stream),
)))
} else {
unreachable!("no tls support for websockets enabled");
}
}
} else { } else {
let (ws_stream, _response) = client_async(request, tcp_stream) let (ws_stream, _response) = client_async(request, tcp_stream)
.await .await

View file

@ -419,6 +419,7 @@ impl Network {
Ok(()) Ok(())
} }
#[cfg(feature = "enable-protocol-wss")]
#[instrument(level = "trace", skip_all)] #[instrument(level = "trace", skip_all)]
pub(super) async fn start_wss_listeners(&self) -> EyreResult<StartupDisposition> { pub(super) async fn start_wss_listeners(&self) -> EyreResult<StartupDisposition> {
veilid_log!(self trace "WSS: binding protocol handlers"); veilid_log!(self trace "WSS: binding protocol handlers");
@ -472,6 +473,7 @@ impl Network {
Ok(StartupDisposition::Success) Ok(StartupDisposition::Success)
} }
#[cfg(feature = "enable-protocol-wss")]
#[instrument(level = "trace", skip_all)] #[instrument(level = "trace", skip_all)]
pub(super) async fn register_wss_dial_info( pub(super) async fn register_wss_dial_info(
&self, &self,

View file

@ -252,6 +252,7 @@ impl Network {
.with(|c| format!("ws://{}/{}", addr, c.network.protocol.ws.path)), .with(|c| format!("ws://{}/{}", addr, c.network.protocol.ws.path)),
) )
.unwrap(), .unwrap(),
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => DialInfo::try_wss( ProtocolType::WSS => DialInfo::try_wss(
addr, addr,
self.config() self.config()

View file

@ -15,6 +15,7 @@ fn make_mock_bootstrap_record(include_timestamp: bool) -> BootstrapRecord {
) )
.expect("should make ws dialinfo"), .expect("should make ws dialinfo"),
}, },
#[cfg(feature = "enable-protocol-wss")]
DialInfoDetail { DialInfoDetail {
class: DialInfoClass::Direct, class: DialInfoClass::Direct,
dial_info: DialInfo::try_wss( dial_info: DialInfo::try_wss(

View file

@ -39,7 +39,7 @@ pub async fn test_add_get_remove() {
let a5 = Flow::new( let a5 = Flow::new(
PeerAddress::new( PeerAddress::new(
SocketAddress::new(Address::IPV6(Ipv6Addr::new(192, 0, 0, 0, 0, 0, 0, 1)), 8090), SocketAddress::new(Address::IPV6(Ipv6Addr::new(192, 0, 0, 0, 0, 0, 0, 1)), 8090),
ProtocolType::WSS, ProtocolType::WS,
), ),
SocketAddress::from_socket_addr(SocketAddr::V6(SocketAddrV6::new( SocketAddress::from_socket_addr(SocketAddr::V6(SocketAddrV6::new(
Ipv6Addr::new(193, 0, 0, 0, 0, 0, 0, 1), Ipv6Addr::new(193, 0, 0, 0, 0, 0, 0, 1),

View file

@ -1,6 +1,7 @@
mod tcp; mod tcp;
mod udp; mod udp;
mod ws; mod ws;
#[cfg(feature = "enable-protocol-wss")]
mod wss; mod wss;
use super::*; use super::*;
@ -8,6 +9,7 @@ use super::*;
pub(crate) use tcp::*; pub(crate) use tcp::*;
pub(crate) use udp::*; pub(crate) use udp::*;
pub(crate) use ws::*; pub(crate) use ws::*;
#[cfg(feature = "enable-protocol-wss")]
pub(crate) use wss::*; pub(crate) use wss::*;
// Keep member order appropriate for sorting < preference // Keep member order appropriate for sorting < preference
@ -18,6 +20,7 @@ pub(crate) enum DialInfo {
UDP(DialInfoUDP), UDP(DialInfoUDP),
TCP(DialInfoTCP), TCP(DialInfoTCP),
WS(DialInfoWS), WS(DialInfoWS),
#[cfg(feature = "enable-protocol-wss")]
WSS(DialInfoWSS), WSS(DialInfoWSS),
} }
impl Default for DialInfo { impl Default for DialInfo {
@ -47,6 +50,7 @@ impl fmt::Display for DialInfo {
} }
} }
} }
#[cfg(feature = "enable-protocol-wss")]
DialInfo::WSS(di) => { DialInfo::WSS(di) => {
let url = format!("wss://{}", di.request); let url = format!("wss://{}", di.request);
let split_url = SplitUrl::from_str(&url).unwrap(); let split_url = SplitUrl::from_str(&url).unwrap();
@ -110,6 +114,7 @@ impl FromStr for DialInfo {
} }
} }
} }
#[cfg(feature = "enable-protocol-wss")]
"wss" => { "wss" => {
let url = format!("wss://{}", rest); let url = format!("wss://{}", rest);
let split_url = SplitUrl::from_str(&url).map_err(|e| { let split_url = SplitUrl::from_str(&url).map_err(|e| {
@ -191,6 +196,7 @@ impl DialInfo {
request: url[5..].to_string(), request: url[5..].to_string(),
})) }))
} }
#[cfg(feature = "enable-protocol-wss")]
pub fn try_wss(socket_address: SocketAddress, url: String) -> VeilidAPIResult<Self> { pub fn try_wss(socket_address: SocketAddress, url: String) -> VeilidAPIResult<Self> {
let split_url = SplitUrl::from_str(&url).map_err(|e| { let split_url = SplitUrl::from_str(&url).map_err(|e| {
VeilidAPIError::parse_error(format!("unable to split WSS url: {}", e), &url) VeilidAPIError::parse_error(format!("unable to split WSS url: {}", e), &url)
@ -220,6 +226,7 @@ impl DialInfo {
Self::UDP(_) => ProtocolType::UDP, Self::UDP(_) => ProtocolType::UDP,
Self::TCP(_) => ProtocolType::TCP, Self::TCP(_) => ProtocolType::TCP,
Self::WS(_) => ProtocolType::WS, Self::WS(_) => ProtocolType::WS,
#[cfg(feature = "enable-protocol-wss")]
Self::WSS(_) => ProtocolType::WSS, Self::WSS(_) => ProtocolType::WSS,
} }
} }
@ -231,6 +238,7 @@ impl DialInfo {
Self::UDP(di) => di.socket_address.address(), Self::UDP(di) => di.socket_address.address(),
Self::TCP(di) => di.socket_address.address(), Self::TCP(di) => di.socket_address.address(),
Self::WS(di) => di.socket_address.address(), Self::WS(di) => di.socket_address.address(),
#[cfg(feature = "enable-protocol-wss")]
Self::WSS(di) => di.socket_address.address(), Self::WSS(di) => di.socket_address.address(),
} }
} }
@ -240,6 +248,7 @@ impl DialInfo {
Self::UDP(di) => di.socket_address.set_address(address), Self::UDP(di) => di.socket_address.set_address(address),
Self::TCP(di) => di.socket_address.set_address(address), Self::TCP(di) => di.socket_address.set_address(address),
Self::WS(di) => di.socket_address.set_address(address), Self::WS(di) => di.socket_address.set_address(address),
#[cfg(feature = "enable-protocol-wss")]
Self::WSS(di) => di.socket_address.set_address(address), Self::WSS(di) => di.socket_address.set_address(address),
} }
} }
@ -248,6 +257,7 @@ impl DialInfo {
Self::UDP(di) => di.socket_address, Self::UDP(di) => di.socket_address,
Self::TCP(di) => di.socket_address, Self::TCP(di) => di.socket_address,
Self::WS(di) => di.socket_address, Self::WS(di) => di.socket_address,
#[cfg(feature = "enable-protocol-wss")]
Self::WSS(di) => di.socket_address, Self::WSS(di) => di.socket_address,
} }
} }
@ -256,6 +266,7 @@ impl DialInfo {
Self::UDP(di) => di.socket_address.ip_addr(), Self::UDP(di) => di.socket_address.ip_addr(),
Self::TCP(di) => di.socket_address.ip_addr(), Self::TCP(di) => di.socket_address.ip_addr(),
Self::WS(di) => di.socket_address.ip_addr(), Self::WS(di) => di.socket_address.ip_addr(),
#[cfg(feature = "enable-protocol-wss")]
Self::WSS(di) => di.socket_address.ip_addr(), Self::WSS(di) => di.socket_address.ip_addr(),
} }
} }
@ -264,6 +275,7 @@ impl DialInfo {
Self::UDP(di) => di.socket_address.port(), Self::UDP(di) => di.socket_address.port(),
Self::TCP(di) => di.socket_address.port(), Self::TCP(di) => di.socket_address.port(),
Self::WS(di) => di.socket_address.port(), Self::WS(di) => di.socket_address.port(),
#[cfg(feature = "enable-protocol-wss")]
Self::WSS(di) => di.socket_address.port(), Self::WSS(di) => di.socket_address.port(),
} }
} }
@ -273,6 +285,7 @@ impl DialInfo {
Self::UDP(di) => di.socket_address.set_port(port), Self::UDP(di) => di.socket_address.set_port(port),
Self::TCP(di) => di.socket_address.set_port(port), Self::TCP(di) => di.socket_address.set_port(port),
Self::WS(di) => di.socket_address.set_port(port), Self::WS(di) => di.socket_address.set_port(port),
#[cfg(feature = "enable-protocol-wss")]
Self::WSS(di) => di.socket_address.set_port(port), Self::WSS(di) => di.socket_address.set_port(port),
} }
} }
@ -281,6 +294,7 @@ impl DialInfo {
Self::UDP(di) => di.socket_address.socket_addr(), Self::UDP(di) => di.socket_address.socket_addr(),
Self::TCP(di) => di.socket_address.socket_addr(), Self::TCP(di) => di.socket_address.socket_addr(),
Self::WS(di) => di.socket_address.socket_addr(), Self::WS(di) => di.socket_address.socket_addr(),
#[cfg(feature = "enable-protocol-wss")]
Self::WSS(di) => di.socket_address.socket_addr(), Self::WSS(di) => di.socket_address.socket_addr(),
} }
} }
@ -289,6 +303,7 @@ impl DialInfo {
Self::UDP(di) => PeerAddress::new(di.socket_address, ProtocolType::UDP), Self::UDP(di) => PeerAddress::new(di.socket_address, ProtocolType::UDP),
Self::TCP(di) => PeerAddress::new(di.socket_address, ProtocolType::TCP), Self::TCP(di) => PeerAddress::new(di.socket_address, ProtocolType::TCP),
Self::WS(di) => PeerAddress::new(di.socket_address, ProtocolType::WS), Self::WS(di) => PeerAddress::new(di.socket_address, ProtocolType::WS),
#[cfg(feature = "enable-protocol-wss")]
Self::WSS(di) => PeerAddress::new(di.socket_address, ProtocolType::WSS), Self::WSS(di) => PeerAddress::new(di.socket_address, ProtocolType::WSS),
} }
} }
@ -297,6 +312,7 @@ impl DialInfo {
Self::UDP(_) => None, Self::UDP(_) => None,
Self::TCP(_) => None, Self::TCP(_) => None,
Self::WS(di) => Some(format!("ws://{}", di.request)), Self::WS(di) => Some(format!("ws://{}", di.request)),
#[cfg(feature = "enable-protocol-wss")]
Self::WSS(di) => Some(format!("wss://{}", di.request)), Self::WSS(di) => Some(format!("wss://{}", di.request)),
} }
} }
@ -323,6 +339,7 @@ impl DialInfo {
(DialInfo::UDP(a), DialInfo::UDP(b)) => a.cmp(b), (DialInfo::UDP(a), DialInfo::UDP(b)) => a.cmp(b),
(DialInfo::TCP(a), DialInfo::TCP(b)) => a.cmp(b), (DialInfo::TCP(a), DialInfo::TCP(b)) => a.cmp(b),
(DialInfo::WS(a), DialInfo::WS(b)) => a.cmp(b), (DialInfo::WS(a), DialInfo::WS(b)) => a.cmp(b),
#[cfg(feature = "enable-protocol-wss")]
(DialInfo::WSS(a), DialInfo::WSS(b)) => a.cmp(b), (DialInfo::WSS(a), DialInfo::WSS(b)) => a.cmp(b),
_ => unreachable!(), _ => unreachable!(),
} }

View file

@ -1,6 +1,65 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use super::*; use super::*;
lazy_static::lazy_static! {
static ref PROTOCOL_TYPE_ORDERING: BTreeMap<(Sequencing, ProtocolType), usize>= {
let mut out = BTreeMap::<(Sequencing, ProtocolType), usize>::new();
// Sequencing::NoPreference
{
let pref = Sequencing::NoPreference;
let mut order = 0;
out.insert((pref, ProtocolType::UDP), order);
order += 1;
out.insert((pref, ProtocolType::TCP), order);
order += 1;
out.insert((pref, ProtocolType::WS), order);
cfg_if::cfg_if! {
if #[cfg(feature="enable-protocol-wss")] {
order += 1;
out.insert((pref, ProtocolType::WSS), order);
}
}
}
// Sequencing::PreferOrdered | Sequencing::EnsureOrdered
for pref in [Sequencing::PreferOrdered, Sequencing::EnsureOrdered]
{
let mut order = 0;
out.insert((pref, ProtocolType::TCP), order);
order += 1;
out.insert((pref, ProtocolType::WS), order);
cfg_if::cfg_if! {
if #[cfg(feature="enable-protocol-wss")] {
order += 1;
out.insert((pref, ProtocolType::WSS), order);
}
}
order += 1;
out.insert((pref, ProtocolType::UDP), order);
}
out
};
static ref PROTOCOL_TYPE_ALL_ORDERED_SET: ProtocolTypeSet = {
let mut out = ProtocolTypeSet::new();
out.insert(ProtocolType::TCP);
out.insert(ProtocolType::WS);
#[cfg(feature="enable-protocol-wss")]
out.insert(ProtocolType::WSS);
out
};
}
// Keep member order appropriate for sorting < preference // Keep member order appropriate for sorting < preference
// Must match DialInfo order // Must match DialInfo order
#[allow(clippy::derived_hash_with_manual_eq)] #[allow(clippy::derived_hash_with_manual_eq)]
@ -10,6 +69,7 @@ pub(crate) enum ProtocolType {
UDP = 0, UDP = 0,
TCP = 1, TCP = 1,
WS = 2, WS = 2,
#[cfg(feature = "enable-protocol-wss")]
WSS = 3, WSS = 3,
} }
@ -19,6 +79,7 @@ impl ProtocolType {
ProtocolType::UDP => SequenceOrdering::Unordered, ProtocolType::UDP => SequenceOrdering::Unordered,
ProtocolType::TCP => SequenceOrdering::Ordered, ProtocolType::TCP => SequenceOrdering::Ordered,
ProtocolType::WS => SequenceOrdering::Ordered, ProtocolType::WS => SequenceOrdering::Ordered,
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => SequenceOrdering::Ordered, ProtocolType::WSS => SequenceOrdering::Ordered,
} }
} }
@ -26,43 +87,16 @@ impl ProtocolType {
pub fn low_level_protocol_type(&self) -> LowLevelProtocolType { pub fn low_level_protocol_type(&self) -> LowLevelProtocolType {
match self { match self {
ProtocolType::UDP => LowLevelProtocolType::UDP, ProtocolType::UDP => LowLevelProtocolType::UDP,
ProtocolType::TCP | ProtocolType::WS | ProtocolType::WSS => LowLevelProtocolType::TCP, ProtocolType::TCP | ProtocolType::WS => LowLevelProtocolType::TCP,
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => LowLevelProtocolType::TCP,
} }
} }
pub fn sort_order(&self, sequencing: Sequencing) -> usize { pub fn sort_order(&self, sequencing: Sequencing) -> usize {
match self { *PROTOCOL_TYPE_ORDERING.get(&(sequencing, *self)).unwrap()
ProtocolType::UDP => {
if sequencing != Sequencing::NoPreference {
3
} else {
0
}
}
ProtocolType::TCP => {
if sequencing != Sequencing::NoPreference {
0
} else {
1
}
}
ProtocolType::WS => {
if sequencing != Sequencing::NoPreference {
1
} else {
2
}
}
ProtocolType::WSS => {
if sequencing != Sequencing::NoPreference {
2
} else {
3
}
}
}
} }
pub fn all_ordered_set() -> ProtocolTypeSet { pub fn all_ordered_set() -> ProtocolTypeSet {
ProtocolType::TCP | ProtocolType::WS | ProtocolType::WSS *PROTOCOL_TYPE_ALL_ORDERED_SET
} }
pub fn ordered_sequencing_sort(a: Self, b: Self) -> core::cmp::Ordering { pub fn ordered_sequencing_sort(a: Self, b: Self) -> core::cmp::Ordering {
@ -84,6 +118,7 @@ impl fmt::Display for ProtocolType {
ProtocolType::UDP => write!(f, "UDP"), ProtocolType::UDP => write!(f, "UDP"),
ProtocolType::TCP => write!(f, "TCP"), ProtocolType::TCP => write!(f, "TCP"),
ProtocolType::WS => write!(f, "WS"), ProtocolType::WS => write!(f, "WS"),
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => write!(f, "WSS"), ProtocolType::WSS => write!(f, "WSS"),
} }
} }
@ -96,6 +131,7 @@ impl FromStr for ProtocolType {
"UDP" => Ok(ProtocolType::UDP), "UDP" => Ok(ProtocolType::UDP),
"TCP" => Ok(ProtocolType::TCP), "TCP" => Ok(ProtocolType::TCP),
"WS" => Ok(ProtocolType::WS), "WS" => Ok(ProtocolType::WS),
#[cfg(feature = "enable-protocol-wss")]
"WSS" => Ok(ProtocolType::WSS), "WSS" => Ok(ProtocolType::WSS),
_ => Err(VeilidAPIError::parse_error( _ => Err(VeilidAPIError::parse_error(
"ProtocolType::from_str failed", "ProtocolType::from_str failed",

View file

@ -156,7 +156,18 @@ impl Network {
ProtocolType::TCP => { ProtocolType::TCP => {
bail!("no support for TCP protocol") bail!("no support for TCP protocol")
} }
ProtocolType::WS | ProtocolType::WSS => { ProtocolType::WS => {
let pnc = network_result_try!(ws::WebsocketProtocolHandler::connect(
self.registry(),
&dial_info,
timeout_ms
)
.await
.wrap_err("connect failure")?);
network_result_try!(pnc.send(data).await.wrap_err("send failure")?);
}
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => {
let pnc = network_result_try!(ws::WebsocketProtocolHandler::connect( let pnc = network_result_try!(ws::WebsocketProtocolHandler::connect(
self.registry(), self.registry(),
&dial_info, &dial_info,
@ -212,11 +223,21 @@ impl Network {
ProtocolType::TCP => { ProtocolType::TCP => {
bail!("no support for TCP protocol") bail!("no support for TCP protocol")
} }
ProtocolType::WS | ProtocolType::WSS => { _ => {
let pnc = network_result_try!(match dial_info.protocol_type() { let pnc = network_result_try!(match dial_info.protocol_type() {
ProtocolType::UDP => unreachable!(), ProtocolType::UDP => unreachable!(),
ProtocolType::TCP => unreachable!(), ProtocolType::TCP => unreachable!(),
ProtocolType::WS | ProtocolType::WSS => { ProtocolType::WS => {
ws::WebsocketProtocolHandler::connect(
self.registry(),
&dial_info,
connect_timeout_ms,
)
.await
.wrap_err("connect failure")?
}
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => {
ws::WebsocketProtocolHandler::connect( ws::WebsocketProtocolHandler::connect(
self.registry(), self.registry(),
&dial_info, &dial_info,
@ -368,6 +389,7 @@ impl Network {
if c.network.protocol.ws.connect { if c.network.protocol.ws.connect {
outbound.insert(ProtocolType::WS); outbound.insert(ProtocolType::WS);
} }
#[cfg(feature = "enable-protocol-wss")]
if c.network.protocol.wss.connect { if c.network.protocol.wss.connect {
outbound.insert(ProtocolType::WSS); outbound.insert(ProtocolType::WSS);
} }

View file

@ -29,7 +29,11 @@ impl ProtocolNetworkConnection {
ProtocolType::TCP => { ProtocolType::TCP => {
panic!("TCP dial info is not supported on WASM targets"); panic!("TCP dial info is not supported on WASM targets");
} }
ProtocolType::WS | ProtocolType::WSS => { ProtocolType::WS => {
ws::WebsocketProtocolHandler::connect(registry, dial_info, timeout_ms).await
}
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => {
ws::WebsocketProtocolHandler::connect(registry, dial_info, timeout_ms).await ws::WebsocketProtocolHandler::connect(registry, dial_info, timeout_ms).await
} }
} }

View file

@ -127,6 +127,7 @@ impl WebsocketProtocolHandler {
// Split dial info up // Split dial info up
let (_tls, scheme) = match dial_info { let (_tls, scheme) = match dial_info {
DialInfo::WS(_) => (false, "ws"), DialInfo::WS(_) => (false, "ws"),
#[cfg(feature = "enable-protocol-wss")]
DialInfo::WSS(_) => (true, "wss"), DialInfo::WSS(_) => (true, "wss"),
_ => panic!("invalid dialinfo for WS/WSS protocol"), _ => panic!("invalid dialinfo for WS/WSS protocol"),
}; };

View file

@ -43,6 +43,7 @@ pub fn decode_dial_info(reader: &veilid_capnp::dial_info::Reader) -> Result<Dial
) )
.map_err(RPCError::map_protocol("invalid WS dial info")) .map_err(RPCError::map_protocol("invalid WS dial info"))
} }
#[cfg(feature = "enable-protocol-wss")]
FOURCC_PROTOCOL_TYPE_WSS => { FOURCC_PROTOCOL_TYPE_WSS => {
let wss = reader let wss = reader
.get_detail() .get_detail()
@ -119,6 +120,7 @@ pub fn encode_dial_info(
); );
requestb.push_str(request.as_str()); requestb.push_str(request.as_str());
} }
#[cfg(feature = "enable-protocol-wss")]
DialInfo::WSS(wss) => { DialInfo::WSS(wss) => {
builder.set_protocol_type(FOURCC_PROTOCOL_TYPE_WSS); builder.set_protocol_type(FOURCC_PROTOCOL_TYPE_WSS);
let mut di_wss_builder = builder let mut di_wss_builder = builder

View file

@ -3,6 +3,7 @@ use super::*;
pub const FOURCC_PROTOCOL_TYPE_UDP: u32 = u32::from_be_bytes(*b"pUDP"); pub const FOURCC_PROTOCOL_TYPE_UDP: u32 = u32::from_be_bytes(*b"pUDP");
pub const FOURCC_PROTOCOL_TYPE_TCP: u32 = u32::from_be_bytes(*b"pTCP"); pub const FOURCC_PROTOCOL_TYPE_TCP: u32 = u32::from_be_bytes(*b"pTCP");
pub const FOURCC_PROTOCOL_TYPE_WS: u32 = u32::from_be_bytes(*b"p_WS"); pub const FOURCC_PROTOCOL_TYPE_WS: u32 = u32::from_be_bytes(*b"p_WS");
#[cfg(feature = "enable-protocol-wss")]
pub const FOURCC_PROTOCOL_TYPE_WSS: u32 = u32::from_be_bytes(*b"pWSS"); pub const FOURCC_PROTOCOL_TYPE_WSS: u32 = u32::from_be_bytes(*b"pWSS");
pub fn decode_protocol_type_set( pub fn decode_protocol_type_set(
@ -21,6 +22,7 @@ pub fn decode_protocol_type_set(
FOURCC_PROTOCOL_TYPE_WS => { FOURCC_PROTOCOL_TYPE_WS => {
out.insert(ProtocolType::WS); out.insert(ProtocolType::WS);
} }
#[cfg(feature = "enable-protocol-wss")]
FOURCC_PROTOCOL_TYPE_WSS => { FOURCC_PROTOCOL_TYPE_WSS => {
out.insert(ProtocolType::WSS); out.insert(ProtocolType::WSS);
} }
@ -44,6 +46,7 @@ pub fn encode_protocol_type_set(
ProtocolType::UDP => FOURCC_PROTOCOL_TYPE_UDP, ProtocolType::UDP => FOURCC_PROTOCOL_TYPE_UDP,
ProtocolType::TCP => FOURCC_PROTOCOL_TYPE_TCP, ProtocolType::TCP => FOURCC_PROTOCOL_TYPE_TCP,
ProtocolType::WS => FOURCC_PROTOCOL_TYPE_WS, ProtocolType::WS => FOURCC_PROTOCOL_TYPE_WS,
#[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => FOURCC_PROTOCOL_TYPE_WSS, ProtocolType::WSS => FOURCC_PROTOCOL_TYPE_WSS,
}, },
); );

View file

@ -89,15 +89,6 @@ fn test_config() {
assert_eq!(inner.network.tls.private_key_path, get_keyfile_path()); assert_eq!(inner.network.tls.private_key_path, get_keyfile_path());
assert_eq!(inner.network.tls.connection_initial_timeout_ms, 2_000u32); assert_eq!(inner.network.tls.connection_initial_timeout_ms, 2_000u32);
assert!(!inner.network.application.https.enabled);
assert_eq!(inner.network.application.https.listen_address, "");
assert_eq!(inner.network.application.https.path, "app");
assert_eq!(inner.network.application.https.url, None);
assert!(!inner.network.application.http.enabled);
assert_eq!(inner.network.application.http.listen_address, "");
assert_eq!(inner.network.application.http.path, "app");
assert_eq!(inner.network.application.http.url, None);
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] #[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
assert!(!inner.network.protocol.udp.enabled); assert!(!inner.network.protocol.udp.enabled);
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
@ -131,12 +122,17 @@ fn test_config() {
assert_eq!(inner.network.protocol.ws.listen_address, ""); assert_eq!(inner.network.protocol.ws.listen_address, "");
assert_eq!(inner.network.protocol.ws.path, "ws"); assert_eq!(inner.network.protocol.ws.path, "ws");
assert_eq!(inner.network.protocol.ws.url, None); assert_eq!(inner.network.protocol.ws.url, None);
assert!(inner.network.protocol.wss.connect);
assert!(!inner.network.protocol.wss.listen); cfg_if::cfg_if! {
assert_eq!(inner.network.protocol.wss.max_connections, 32u32); if #[cfg(feature="enable-protocol-wss")] {
assert_eq!(inner.network.protocol.wss.listen_address, ""); assert!(inner.network.protocol.wss.connect);
assert_eq!(inner.network.protocol.wss.path, "ws"); assert!(!inner.network.protocol.wss.listen);
assert_eq!(inner.network.protocol.wss.url, None); assert_eq!(inner.network.protocol.wss.max_connections, 32u32);
assert_eq!(inner.network.protocol.wss.listen_address, "");
assert_eq!(inner.network.protocol.wss.path, "ws");
assert_eq!(inner.network.protocol.wss.url, None);
}
}
assert!(!inner.network.privacy.require_inbound_relay); assert!(!inner.network.privacy.require_inbound_relay);
#[cfg(feature = "geolocation")] #[cfg(feature = "geolocation")]

View file

@ -268,20 +268,6 @@ pub fn fix_fake_veilid_config() -> VeilidConfig {
private_key_path: "/etc/ssl/keys/key.pem".to_string(), private_key_path: "/etc/ssl/keys/key.pem".to_string(),
connection_initial_timeout_ms: 1000, connection_initial_timeout_ms: 1000,
}, },
application: VeilidConfigApplication {
https: VeilidConfigHTTPS {
enabled: true,
listen_address: "10.0.0.3".to_string(),
path: "/https_path/".to_string(),
url: Some("https://veilid.com/".to_string()),
},
http: VeilidConfigHTTP {
enabled: true,
listen_address: "10.0.0.4".to_string(),
path: "/http_path/".to_string(),
url: Some("http://veilid.com/".to_string()),
},
},
protocol: VeilidConfigProtocol { protocol: VeilidConfigProtocol {
udp: VeilidConfigUDP { udp: VeilidConfigUDP {
enabled: false, enabled: false,
@ -304,6 +290,7 @@ pub fn fix_fake_veilid_config() -> VeilidConfig {
path: "Straight".to_string(), path: "Straight".to_string(),
url: Some("https://veilid.com/ws".to_string()), url: Some("https://veilid.com/ws".to_string()),
}, },
#[cfg(feature = "enable-protocol-wss")]
wss: VeilidConfigWSS { wss: VeilidConfigWSS {
connect: true, connect: true,
listen: false, listen: false,

View file

@ -411,16 +411,20 @@ fn get_filtered_node_ref(
fn get_protocol_type(text: &str) -> Option<ProtocolType> { fn get_protocol_type(text: &str) -> Option<ProtocolType> {
let lctext = text.to_ascii_lowercase(); let lctext = text.to_ascii_lowercase();
if lctext == "udp" { if lctext == "udp" {
Some(ProtocolType::UDP) return Some(ProtocolType::UDP);
} else if lctext == "tcp" {
Some(ProtocolType::TCP)
} else if lctext == "ws" {
Some(ProtocolType::WS)
} else if lctext == "wss" {
Some(ProtocolType::WSS)
} else {
None
} }
if lctext == "tcp" {
return Some(ProtocolType::TCP);
}
if lctext == "ws" {
return Some(ProtocolType::WS);
}
#[cfg(feature = "enable-protocol-wss")]
if lctext == "wss" {
return Some(ProtocolType::WSS);
}
None
} }
fn get_sequencing(text: &str) -> Option<Sequencing> { fn get_sequencing(text: &str) -> Option<Sequencing> {
let seqtext = text.to_ascii_lowercase(); let seqtext = text.to_ascii_lowercase();

View file

@ -89,24 +89,6 @@ impl Default for VeilidConfigHTTP {
} }
} }
/// Application configuration.
///
/// Configure web access to the Progressive Web App (PWA).
///
/// To be implemented...
///
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[cfg_attr(
all(target_arch = "wasm32", target_os = "unknown"),
derive(Tsify),
tsify(into_wasm_abi, from_wasm_abi)
)]
#[must_use]
pub struct VeilidConfigApplication {
pub https: VeilidConfigHTTPS,
pub http: VeilidConfigHTTP,
}
/// Enable and configure UDP. /// Enable and configure UDP.
/// ///
/// ```yaml /// ```yaml
@ -265,6 +247,7 @@ impl Default for VeilidConfigWS {
tsify(into_wasm_abi, from_wasm_abi) tsify(into_wasm_abi, from_wasm_abi)
)] )]
#[must_use] #[must_use]
#[cfg(feature = "enable-protocol-wss")]
pub struct VeilidConfigWSS { pub struct VeilidConfigWSS {
pub connect: bool, pub connect: bool,
pub listen: bool, pub listen: bool,
@ -275,6 +258,7 @@ pub struct VeilidConfigWSS {
pub url: Option<String>, // Fixed URL is not optional for TLS-based protocols and is dynamically validated pub url: Option<String>, // Fixed URL is not optional for TLS-based protocols and is dynamically validated
} }
#[cfg(feature = "enable-protocol-wss")]
impl Default for VeilidConfigWSS { impl Default for VeilidConfigWSS {
fn default() -> Self { fn default() -> Self {
Self { Self {
@ -306,6 +290,7 @@ pub struct VeilidConfigProtocol {
pub udp: VeilidConfigUDP, pub udp: VeilidConfigUDP,
pub tcp: VeilidConfigTCP, pub tcp: VeilidConfigTCP,
pub ws: VeilidConfigWS, pub ws: VeilidConfigWS,
#[cfg(feature = "enable-protocol-wss")]
pub wss: VeilidConfigWSS, pub wss: VeilidConfigWSS,
} }
@ -629,7 +614,6 @@ pub struct VeilidConfigNetwork {
pub detect_address_changes: Option<bool>, pub detect_address_changes: Option<bool>,
pub restricted_nat_retries: u32, pub restricted_nat_retries: u32,
pub tls: VeilidConfigTLS, pub tls: VeilidConfigTLS,
pub application: VeilidConfigApplication,
pub protocol: VeilidConfigProtocol, pub protocol: VeilidConfigProtocol,
pub privacy: VeilidConfigPrivacy, pub privacy: VeilidConfigPrivacy,
#[cfg(feature = "virtual-network")] #[cfg(feature = "virtual-network")]
@ -656,7 +640,6 @@ impl Default for VeilidConfigNetwork {
detect_address_changes: Some(true), detect_address_changes: Some(true),
restricted_nat_retries: 0, restricted_nat_retries: 0,
tls: VeilidConfigTLS::default(), tls: VeilidConfigTLS::default(),
application: VeilidConfigApplication::default(),
protocol: VeilidConfigProtocol::default(), protocol: VeilidConfigProtocol::default(),
privacy: VeilidConfigPrivacy::default(), privacy: VeilidConfigPrivacy::default(),
#[cfg(feature = "virtual-network")] #[cfg(feature = "virtual-network")]
@ -1197,17 +1180,8 @@ impl VeilidStartupOptions {
if inner.network.protocol.ws.max_connections == 0 { if inner.network.protocol.ws.max_connections == 0 {
apibail_generic!("WS max connections must be > 0 in config key 'network.protocol.ws.max_connections'"); apibail_generic!("WS max connections must be > 0 in config key 'network.protocol.ws.max_connections'");
} }
if inner.network.application.https.enabled
&& inner.network.application.https.path == inner.network.protocol.ws.path
{
apibail_generic!("WS path conflicts with HTTPS application path in config key 'network.protocol.ws.path'");
}
if inner.network.application.http.enabled
&& inner.network.application.http.path == inner.network.protocol.ws.path
{
apibail_generic!("WS path conflicts with HTTP application path in config key 'network.protocol.ws.path'");
}
} }
#[cfg(feature = "enable-protocol-wss")]
if inner.network.protocol.wss.listen { if inner.network.protocol.wss.listen {
// Validate WSS settings // Validate WSS settings
if inner.network.protocol.wss.max_connections == 0 { if inner.network.protocol.wss.max_connections == 0 {
@ -1226,32 +1200,6 @@ impl VeilidStartupOptions {
"WSS URL must be specified in config key 'network.protocol.wss.url'" "WSS URL must be specified in config key 'network.protocol.wss.url'"
); );
} }
if inner.network.application.https.enabled
&& inner.network.application.https.path == inner.network.protocol.wss.path
{
apibail_generic!("WSS path conflicts with HTTPS application path in config key 'network.protocol.ws.path'");
}
if inner.network.application.http.enabled
&& inner.network.application.http.path == inner.network.protocol.wss.path
{
apibail_generic!("WSS path conflicts with HTTP application path in config key 'network.protocol.ws.path'");
}
}
if inner.network.application.https.enabled {
// Validate HTTPS settings
if inner
.network
.application
.https
.url
.as_ref()
.map(|u| u.is_empty())
.unwrap_or_default()
{
apibail_generic!(
"HTTPS URL must be specified in config key 'network.application.https.url'"
);
}
} }
if inner.network.rpc.max_route_hop_count == 0 { if inner.network.rpc.max_route_hop_count == 0 {
apibail_generic!( apibail_generic!(

View file

@ -149,50 +149,6 @@ enum VeilidConfigLogLevel {
String toJson() => name.toPascalCase(); String toJson() => name.toPascalCase();
} }
//////////////////////////////////////
/// VeilidConfig
@freezed
sealed class VeilidConfigHTTPS with _$VeilidConfigHTTPS {
const factory VeilidConfigHTTPS({
required bool enabled,
required String listenAddress,
required String path,
String? url,
}) = _VeilidConfigHTTPS;
factory VeilidConfigHTTPS.fromJson(dynamic json) =>
_$VeilidConfigHTTPSFromJson(json as Map<String, dynamic>);
}
////////////
@freezed
sealed class VeilidConfigHTTP with _$VeilidConfigHTTP {
const factory VeilidConfigHTTP({
required bool enabled,
required String listenAddress,
required String path,
String? url,
}) = _VeilidConfigHTTP;
factory VeilidConfigHTTP.fromJson(dynamic json) =>
_$VeilidConfigHTTPFromJson(json as Map<String, dynamic>);
}
////////////
@freezed
sealed class VeilidConfigApplication with _$VeilidConfigApplication {
const factory VeilidConfigApplication({
required VeilidConfigHTTPS https,
required VeilidConfigHTTP http,
}) = _VeilidConfigApplication;
factory VeilidConfigApplication.fromJson(dynamic json) =>
_$VeilidConfigApplicationFromJson(json as Map<String, dynamic>);
}
//////////// ////////////
@freezed @freezed
sealed class VeilidConfigUDP with _$VeilidConfigUDP { sealed class VeilidConfigUDP with _$VeilidConfigUDP {
@ -239,8 +195,10 @@ sealed class VeilidConfigWS with _$VeilidConfigWS {
} }
//////////// ////////////
@Deprecated('WSS is disabled by default in veilid-flutter')
@freezed @freezed
sealed class VeilidConfigWSS with _$VeilidConfigWSS { sealed class VeilidConfigWSS with _$VeilidConfigWSS {
@Deprecated('WSS is disabled by default in veilid-flutter')
const factory VeilidConfigWSS({ const factory VeilidConfigWSS({
required bool connect, required bool connect,
required bool listen, required bool listen,
@ -250,6 +208,7 @@ sealed class VeilidConfigWSS with _$VeilidConfigWSS {
String? url, String? url,
}) = _VeilidConfigWSS; }) = _VeilidConfigWSS;
@Deprecated('WSS is disabled by default in veilid-flutter')
factory VeilidConfigWSS.fromJson(dynamic json) => factory VeilidConfigWSS.fromJson(dynamic json) =>
_$VeilidConfigWSSFromJson(json as Map<String, dynamic>); _$VeilidConfigWSSFromJson(json as Map<String, dynamic>);
} }
@ -262,6 +221,7 @@ sealed class VeilidConfigProtocol with _$VeilidConfigProtocol {
required VeilidConfigUDP udp, required VeilidConfigUDP udp,
required VeilidConfigTCP tcp, required VeilidConfigTCP tcp,
required VeilidConfigWS ws, required VeilidConfigWS ws,
@Deprecated('WSS is disabled by default in veilid-flutter')
required VeilidConfigWSS wss, required VeilidConfigWSS wss,
}) = _VeilidConfigProtocol; }) = _VeilidConfigProtocol;
@ -386,7 +346,6 @@ sealed class VeilidConfigNetwork with _$VeilidConfigNetwork {
required bool? detectAddressChanges, required bool? detectAddressChanges,
required int restrictedNatRetries, required int restrictedNatRetries,
required VeilidConfigTLS tls, required VeilidConfigTLS tls,
required VeilidConfigApplication application,
required VeilidConfigProtocol protocol, required VeilidConfigProtocol protocol,
required VeilidConfigPrivacy privacy, required VeilidConfigPrivacy privacy,
String? networkKeyPassword, String? networkKeyPassword,

File diff suppressed because it is too large Load diff

View file

@ -171,52 +171,6 @@ _VeilidWASMConfig _$VeilidWASMConfigFromJson(Map<String, dynamic> json) =>
Map<String, dynamic> _$VeilidWASMConfigToJson(_VeilidWASMConfig instance) => Map<String, dynamic> _$VeilidWASMConfigToJson(_VeilidWASMConfig instance) =>
<String, dynamic>{'logging': instance.logging.toJson()}; <String, dynamic>{'logging': instance.logging.toJson()};
_VeilidConfigHTTPS _$VeilidConfigHTTPSFromJson(Map<String, dynamic> json) =>
_VeilidConfigHTTPS(
enabled: json['enabled'] as bool,
listenAddress: json['listen_address'] as String,
path: json['path'] as String,
url: json['url'] as String?,
);
Map<String, dynamic> _$VeilidConfigHTTPSToJson(_VeilidConfigHTTPS instance) =>
<String, dynamic>{
'enabled': instance.enabled,
'listen_address': instance.listenAddress,
'path': instance.path,
'url': instance.url,
};
_VeilidConfigHTTP _$VeilidConfigHTTPFromJson(Map<String, dynamic> json) =>
_VeilidConfigHTTP(
enabled: json['enabled'] as bool,
listenAddress: json['listen_address'] as String,
path: json['path'] as String,
url: json['url'] as String?,
);
Map<String, dynamic> _$VeilidConfigHTTPToJson(_VeilidConfigHTTP instance) =>
<String, dynamic>{
'enabled': instance.enabled,
'listen_address': instance.listenAddress,
'path': instance.path,
'url': instance.url,
};
_VeilidConfigApplication _$VeilidConfigApplicationFromJson(
Map<String, dynamic> json,
) => _VeilidConfigApplication(
https: VeilidConfigHTTPS.fromJson(json['https']),
http: VeilidConfigHTTP.fromJson(json['http']),
);
Map<String, dynamic> _$VeilidConfigApplicationToJson(
_VeilidConfigApplication instance,
) => <String, dynamic>{
'https': instance.https.toJson(),
'http': instance.http.toJson(),
};
_VeilidConfigUDP _$VeilidConfigUDPFromJson(Map<String, dynamic> json) => _VeilidConfigUDP _$VeilidConfigUDPFromJson(Map<String, dynamic> json) =>
_VeilidConfigUDP( _VeilidConfigUDP(
enabled: json['enabled'] as bool, enabled: json['enabled'] as bool,
@ -476,7 +430,6 @@ _VeilidConfigNetwork _$VeilidConfigNetworkFromJson(Map<String, dynamic> json) =>
detectAddressChanges: json['detect_address_changes'] as bool?, detectAddressChanges: json['detect_address_changes'] as bool?,
restrictedNatRetries: (json['restricted_nat_retries'] as num).toInt(), restrictedNatRetries: (json['restricted_nat_retries'] as num).toInt(),
tls: VeilidConfigTLS.fromJson(json['tls']), tls: VeilidConfigTLS.fromJson(json['tls']),
application: VeilidConfigApplication.fromJson(json['application']),
protocol: VeilidConfigProtocol.fromJson(json['protocol']), protocol: VeilidConfigProtocol.fromJson(json['protocol']),
privacy: VeilidConfigPrivacy.fromJson(json['privacy']), privacy: VeilidConfigPrivacy.fromJson(json['privacy']),
networkKeyPassword: json['network_key_password'] as String?, networkKeyPassword: json['network_key_password'] as String?,
@ -502,7 +455,6 @@ Map<String, dynamic> _$VeilidConfigNetworkToJson(
'detect_address_changes': instance.detectAddressChanges, 'detect_address_changes': instance.detectAddressChanges,
'restricted_nat_retries': instance.restrictedNatRetries, 'restricted_nat_retries': instance.restrictedNatRetries,
'tls': instance.tls.toJson(), 'tls': instance.tls.toJson(),
'application': instance.application.toJson(),
'protocol': instance.protocol.toJson(), 'protocol': instance.protocol.toJson(),
'privacy': instance.privacy.toJson(), 'privacy': instance.privacy.toJson(),
'network_key_password': instance.networkKeyPassword, 'network_key_password': instance.networkKeyPassword,

View file

@ -33,6 +33,7 @@ rt-tokio = [
"opentelemetry/rt-tokio", "opentelemetry/rt-tokio",
] ]
debug-load = ["dep:ctor", "dep:libc-print", "dep:android_log-sys", "dep:oslog"] debug-load = ["dep:ctor", "dep:libc-print", "dep:android_log-sys", "dep:oslog"]
enable-protocol-wss = ["veilid-core/enable-protocol-wss"]
footgun = ["veilid-core/footgun"] footgun = ["veilid-core/footgun"]
[dependencies] [dependencies]

View file

@ -123,28 +123,6 @@ class VeilidConfigTLS(ConfigBase):
connection_initial_timeout_ms: int connection_initial_timeout_ms: int
@dataclass
class VeilidConfigHTTPS(ConfigBase):
enabled: bool
listen_address: str
path: str
url: Optional[str]
@dataclass
class VeilidConfigHTTP(ConfigBase):
enabled: bool
listen_address: str
path: str
url: Optional[str]
@dataclass
class VeilidConfigApplication(ConfigBase):
https: VeilidConfigHTTPS
http: VeilidConfigHTTP
@dataclass @dataclass
class VeilidConfigUDP(ConfigBase): class VeilidConfigUDP(ConfigBase):
enabled: bool enabled: bool
@ -172,14 +150,14 @@ class VeilidConfigWS(ConfigBase):
url: Optional[str] url: Optional[str]
@dataclass # @dataclass
class VeilidConfigWSS(ConfigBase): # class VeilidConfigWSS(ConfigBase):
connect: bool # connect: bool
listen: bool # listen: bool
max_connections: int # max_connections: int
listen_address: str # listen_address: str
path: str # path: str
url: Optional[str] # url: Optional[str]
@dataclass @dataclass
@ -187,7 +165,7 @@ class VeilidConfigProtocol(ConfigBase):
udp: VeilidConfigUDP udp: VeilidConfigUDP
tcp: VeilidConfigTCP tcp: VeilidConfigTCP
ws: VeilidConfigWS ws: VeilidConfigWS
wss: VeilidConfigWSS # wss: VeilidConfigWSS
@dataclass @dataclass
@ -214,7 +192,6 @@ class VeilidConfigNetwork(ConfigBase):
detect_address_changes: Optional[bool] detect_address_changes: Optional[bool]
restricted_nat_retries: int restricted_nat_retries: int
tls: VeilidConfigTLS tls: VeilidConfigTLS
application: VeilidConfigApplication
protocol: VeilidConfigProtocol protocol: VeilidConfigProtocol
privacy: VeilidConfigPrivacy privacy: VeilidConfigPrivacy

View file

@ -4015,22 +4015,6 @@
"network" "network"
] ]
}, },
"VeilidConfigApplication": {
"description": "Application configuration.\n\nConfigure web access to the Progressive Web App (PWA).\n\nTo be implemented...",
"type": "object",
"properties": {
"http": {
"$ref": "#/$defs/VeilidConfigHTTP"
},
"https": {
"$ref": "#/$defs/VeilidConfigHTTPS"
}
},
"required": [
"https",
"http"
]
},
"VeilidConfigBlockStore": { "VeilidConfigBlockStore": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -4206,64 +4190,9 @@
"max_watch_expiration_ms" "max_watch_expiration_ms"
] ]
}, },
"VeilidConfigHTTP": {
"description": "Enable and configure HTTP access to the Veilid node.\n\n```yaml\nhttp:\n enabled: false\n listen_address: ':5150'\n path: 'app\"\n url: 'https://localhost:5150'\n```",
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"listen_address": {
"type": "string"
},
"path": {
"type": "string"
},
"url": {
"type": [
"string",
"null"
]
}
},
"required": [
"enabled",
"listen_address",
"path"
]
},
"VeilidConfigHTTPS": {
"description": "Enable and configure HTTPS access to the Veilid node.\n\n```yaml\nhttps:\n enabled: false\n listen_address: ':5150'\n path: 'app'\n url: 'https://localhost:5150'\n```",
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"listen_address": {
"type": "string"
},
"path": {
"type": "string"
},
"url": {
"type": [
"string",
"null"
]
}
},
"required": [
"enabled",
"listen_address",
"path"
]
},
"VeilidConfigNetwork": { "VeilidConfigNetwork": {
"type": "object", "type": "object",
"properties": { "properties": {
"application": {
"$ref": "#/$defs/VeilidConfigApplication"
},
"client_allowlist_timeout_ms": { "client_allowlist_timeout_ms": {
"type": "integer", "type": "integer",
"format": "uint32", "format": "uint32",
@ -4364,7 +4293,6 @@
"upnp", "upnp",
"restricted_nat_retries", "restricted_nat_retries",
"tls", "tls",
"application",
"protocol", "protocol",
"privacy" "privacy"
] ]
@ -4426,16 +4354,12 @@
}, },
"ws": { "ws": {
"$ref": "#/$defs/VeilidConfigWS" "$ref": "#/$defs/VeilidConfigWS"
},
"wss": {
"$ref": "#/$defs/VeilidConfigWSS"
} }
}, },
"required": [ "required": [
"udp", "udp",
"tcp", "tcp",
"ws", "ws"
"wss"
] ]
}, },
"VeilidConfigRPC": { "VeilidConfigRPC": {
@ -4693,42 +4617,6 @@
"path" "path"
] ]
}, },
"VeilidConfigWSS": {
"description": "Enable and configure Secure Web Sockets.\n\n```yaml\nwss:\n connect: true\n listen: false\n max_connections: 32\n listen_address: ':5150'\n path: 'ws'\n url: ''",
"type": "object",
"properties": {
"connect": {
"type": "boolean"
},
"listen": {
"type": "boolean"
},
"listen_address": {
"type": "string"
},
"max_connections": {
"type": "integer",
"format": "uint32",
"minimum": 0
},
"path": {
"type": "string"
},
"url": {
"type": [
"string",
"null"
]
}
},
"required": [
"connect",
"listen",
"max_connections",
"listen_address",
"path"
]
},
"VeilidLog": { "VeilidLog": {
"description": "A VeilidCore log message with optional backtrace.", "description": "A VeilidCore log message with optional backtrace.",
"type": "object", "type": "object",

View file

@ -30,6 +30,7 @@ default-async-std = [
"veilid-remote-api/default-async-std", "veilid-remote-api/default-async-std",
] ]
enable-protocol-wss = ["veilid-core/enable-protocol-wss"]
footgun = ["veilid-core/footgun"] footgun = ["veilid-core/footgun"]
rt-tokio = [ rt-tokio = [

View file

@ -392,7 +392,10 @@ fn main() -> EyreResult<()> {
settingsrw.core.network.protocol.udp.listen_address = listen_address.clone(); settingsrw.core.network.protocol.udp.listen_address = listen_address.clone();
settingsrw.core.network.protocol.tcp.listen_address = listen_address.clone(); settingsrw.core.network.protocol.tcp.listen_address = listen_address.clone();
settingsrw.core.network.protocol.ws.listen_address = listen_address.clone(); settingsrw.core.network.protocol.ws.listen_address = listen_address.clone();
settingsrw.core.network.protocol.wss.listen_address = listen_address; #[cfg(feature = "enable-protocol-wss")]
{
settingsrw.core.network.protocol.wss.listen_address = listen_address;
}
} }
drop(settingsrw); drop(settingsrw);

View file

@ -64,6 +64,17 @@ pub fn load_default_config() -> EyreResult<config::Config> {
listen_address: 'localhost:5148' listen_address: 'localhost:5148'
"#; "#;
#[cfg(not(feature = "enable-protocol-wss"))]
let protocol_wss_section = "";
#[cfg(feature = "enable-protocol-wss")]
let protocol_wss_section = r#"wss:
connect: true
listen: false
max_connections: 256
listen_address: ':5150'
path: 'ws'
# url: ''"#;
let mut default_config = String::from( let mut default_config = String::from(
r#"--- r#"---
daemon: daemon:
@ -187,17 +198,6 @@ core:
certificate_path: '%CERTIFICATE_PATH%' certificate_path: '%CERTIFICATE_PATH%'
private_key_path: '%PRIVATE_KEY_PATH%' private_key_path: '%PRIVATE_KEY_PATH%'
connection_initial_timeout_ms: 2000 connection_initial_timeout_ms: 2000
application:
https:
enabled: false
listen_address: ':443'
path: 'app'
# url: 'https://localhost'
http:
enabled: false
listen_address: ':80'
path: 'app'
# url: 'http://localhost'
protocol: protocol:
udp: udp:
enabled: true enabled: true
@ -217,13 +217,7 @@ core:
listen_address: ':5150' listen_address: ':5150'
path: 'ws' path: 'ws'
# url: 'ws://localhost:5150/ws' # url: 'ws://localhost:5150/ws'
wss: %PROTOCOL_WSS_SECTION%
connect: true
listen: false
max_connections: 256
listen_address: ':5150'
path: 'ws'
# url: ''
privacy: privacy:
require_inbound_relay: false require_inbound_relay: false
%PRIVACY_GEOLOCATION_SECTION% %PRIVACY_GEOLOCATION_SECTION%
@ -263,6 +257,10 @@ core:
.replace( .replace(
"%VIRTUAL_NETWORK_SERVER_SECTION%", "%VIRTUAL_NETWORK_SERVER_SECTION%",
virtual_network_server_section, virtual_network_server_section,
)
.replace(
"%PROTOCOL_WSS_SECTION%",
protocol_wss_section,
); );
let dek_password = if let Some(dek_password) = std::env::var_os("DEK_PASSWORD") { let dek_password = if let Some(dek_password) = std::env::var_os("DEK_PASSWORD") {
@ -597,12 +595,6 @@ pub struct Http {
pub url: Option<ParsedUrl>, pub url: Option<ParsedUrl>,
} }
#[derive(Debug, Deserialize, Serialize)]
pub struct Application {
pub https: Https,
pub http: Http,
}
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
pub struct Udp { pub struct Udp {
pub enabled: bool, pub enabled: bool,
@ -630,6 +622,7 @@ pub struct Ws {
pub url: Option<ParsedUrl>, pub url: Option<ParsedUrl>,
} }
#[cfg(feature = "enable-protocol-wss")]
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
pub struct Wss { pub struct Wss {
pub connect: bool, pub connect: bool,
@ -645,6 +638,7 @@ pub struct Protocol {
pub udp: Udp, pub udp: Udp,
pub tcp: Tcp, pub tcp: Tcp,
pub ws: Ws, pub ws: Ws,
#[cfg(feature = "enable-protocol-wss")]
pub wss: Wss, pub wss: Wss,
} }
@ -839,7 +833,6 @@ pub struct Network {
pub detect_address_changes: Option<bool>, pub detect_address_changes: Option<bool>,
pub restricted_nat_retries: u32, pub restricted_nat_retries: u32,
pub tls: Tls, pub tls: Tls,
pub application: Application,
pub protocol: Protocol, pub protocol: Protocol,
pub privacy: Privacy, pub privacy: Privacy,
#[cfg(feature = "virtual-network")] #[cfg(feature = "virtual-network")]
@ -1360,14 +1353,6 @@ impl Settings {
set_config_value!(inner.core.network.tls.certificate_path, value); set_config_value!(inner.core.network.tls.certificate_path, value);
set_config_value!(inner.core.network.tls.private_key_path, value); set_config_value!(inner.core.network.tls.private_key_path, value);
set_config_value!(inner.core.network.tls.connection_initial_timeout_ms, value); set_config_value!(inner.core.network.tls.connection_initial_timeout_ms, value);
set_config_value!(inner.core.network.application.https.enabled, value);
set_config_value!(inner.core.network.application.https.listen_address, value);
set_config_value!(inner.core.network.application.https.path, value);
set_config_value!(inner.core.network.application.https.url, value);
set_config_value!(inner.core.network.application.http.enabled, value);
set_config_value!(inner.core.network.application.http.listen_address, value);
set_config_value!(inner.core.network.application.http.path, value);
set_config_value!(inner.core.network.application.http.url, value);
set_config_value!(inner.core.network.protocol.udp.enabled, value); set_config_value!(inner.core.network.protocol.udp.enabled, value);
set_config_value!(inner.core.network.protocol.udp.socket_pool_size, value); set_config_value!(inner.core.network.protocol.udp.socket_pool_size, value);
set_config_value!(inner.core.network.protocol.udp.listen_address, value); set_config_value!(inner.core.network.protocol.udp.listen_address, value);
@ -1383,12 +1368,17 @@ impl Settings {
set_config_value!(inner.core.network.protocol.ws.listen_address, value); set_config_value!(inner.core.network.protocol.ws.listen_address, value);
set_config_value!(inner.core.network.protocol.ws.path, value); set_config_value!(inner.core.network.protocol.ws.path, value);
set_config_value!(inner.core.network.protocol.ws.url, value); set_config_value!(inner.core.network.protocol.ws.url, value);
set_config_value!(inner.core.network.protocol.wss.connect, value);
set_config_value!(inner.core.network.protocol.wss.listen, value); cfg_if::cfg_if! {
set_config_value!(inner.core.network.protocol.wss.max_connections, value); if #[cfg(feature="enable-protocol-wss")] {
set_config_value!(inner.core.network.protocol.wss.listen_address, value); set_config_value!(inner.core.network.protocol.wss.connect, value);
set_config_value!(inner.core.network.protocol.wss.path, value); set_config_value!(inner.core.network.protocol.wss.listen, value);
set_config_value!(inner.core.network.protocol.wss.url, value); set_config_value!(inner.core.network.protocol.wss.max_connections, value);
set_config_value!(inner.core.network.protocol.wss.listen_address, value);
set_config_value!(inner.core.network.protocol.wss.path, value);
set_config_value!(inner.core.network.protocol.wss.url, value);
}
}
set_config_value!(inner.core.network.privacy.require_inbound_relay, value); set_config_value!(inner.core.network.privacy.require_inbound_relay, value);
#[cfg(feature = "geolocation")] #[cfg(feature = "geolocation")]
set_config_value!(inner.core.network.privacy.country_code_denylist, value); set_config_value!(inner.core.network.privacy.country_code_denylist, value);
@ -1552,66 +1542,6 @@ impl Settings {
.tls .tls
.connection_initial_timeout_ms, .connection_initial_timeout_ms,
}, },
application: VeilidConfigApplication {
https: VeilidConfigHTTPS {
enabled: inner.core.network.application.https.enabled,
listen_address: inner
.core
.network
.application
.https
.listen_address
.with_offset_port(subnode_offset)
.map_err(VeilidAPIError::internal)?
.name
.clone(),
path: inner
.core
.network
.application
.https
.path
.to_string_lossy()
.to_string(),
url: match inner.core.network.application.https.url {
Some(ref a) => Some(
a.with_offset_port(subnode_offset)
.map_err(VeilidAPIError::internal)
.map(|x| x.urlstring.clone())?,
),
None => None,
},
},
http: VeilidConfigHTTP {
enabled: inner.core.network.application.http.enabled,
listen_address: inner
.core
.network
.application
.http
.listen_address
.with_offset_port(subnode_offset)
.map_err(VeilidAPIError::internal)?
.name
.clone(),
path: inner
.core
.network
.application
.http
.path
.to_string_lossy()
.to_string(),
url: match inner.core.network.application.http.url {
Some(ref a) => Some(
a.with_offset_port(subnode_offset)
.map_err(VeilidAPIError::internal)
.map(|x| x.urlstring.clone())?,
),
None => None,
},
},
},
protocol: VeilidConfigProtocol { protocol: VeilidConfigProtocol {
udp: VeilidConfigUDP { udp: VeilidConfigUDP {
enabled: inner.core.network.protocol.udp.enabled, enabled: inner.core.network.protocol.udp.enabled,
@ -1689,6 +1619,7 @@ impl Settings {
None => None, None => None,
}, },
}, },
#[cfg(feature = "enable-protocol-wss")]
wss: VeilidConfigWSS { wss: VeilidConfigWSS {
connect: inner.core.network.protocol.wss.connect, connect: inner.core.network.protocol.wss.connect,
listen: inner.core.network.protocol.wss.listen, listen: inner.core.network.protocol.wss.listen,
@ -1928,28 +1859,6 @@ mod tests {
); );
assert_eq!(s.core.network.tls.connection_initial_timeout_ms, 2_000u32); assert_eq!(s.core.network.tls.connection_initial_timeout_ms, 2_000u32);
// //
assert!(!s.core.network.application.https.enabled);
assert_eq!(s.core.network.application.https.listen_address.name, ":443");
assert_eq!(
s.core.network.application.https.listen_address.addrs,
listen_address_to_socket_addrs(":443").unwrap()
);
assert_eq!(
s.core.network.application.https.path,
std::path::PathBuf::from("app")
);
assert_eq!(s.core.network.application.https.url, None);
assert!(!s.core.network.application.http.enabled);
assert_eq!(s.core.network.application.http.listen_address.name, ":80");
assert_eq!(
s.core.network.application.http.listen_address.addrs,
listen_address_to_socket_addrs(":80").unwrap()
);
assert_eq!(
s.core.network.application.http.path,
std::path::PathBuf::from("app")
);
assert_eq!(s.core.network.application.http.url, None);
// //
let valid_socket_addrs = [ let valid_socket_addrs = [
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 5150), SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 5150),
@ -1991,19 +1900,23 @@ mod tests {
); );
assert_eq!(s.core.network.protocol.ws.url, None); assert_eq!(s.core.network.protocol.ws.url, None);
// //
assert!(s.core.network.protocol.wss.connect); cfg_if::cfg_if! {
assert!(!s.core.network.protocol.wss.listen); if #[cfg(feature="enable-protocol-wss")] {
assert_eq!(s.core.network.protocol.wss.max_connections, 256); assert!(s.core.network.protocol.wss.connect);
assert_eq!(s.core.network.protocol.wss.listen_address.name, ":5150"); assert!(!s.core.network.protocol.wss.listen);
for addr in &s.core.network.protocol.wss.listen_address.addrs { assert_eq!(s.core.network.protocol.wss.max_connections, 256);
assert!(valid_socket_addrs.contains(addr)); assert_eq!(s.core.network.protocol.wss.listen_address.name, ":5150");
for addr in &s.core.network.protocol.wss.listen_address.addrs {
assert!(valid_socket_addrs.contains(addr));
}
assert!(!s.core.network.protocol.wss.listen_address.addrs.is_empty());
assert_eq!(
s.core.network.protocol.wss.path,
std::path::PathBuf::from("ws")
);
assert_eq!(s.core.network.protocol.wss.url, None);
}
} }
assert!(!s.core.network.protocol.wss.listen_address.addrs.is_empty());
assert_eq!(
s.core.network.protocol.wss.path,
std::path::PathBuf::from("ws")
);
assert_eq!(s.core.network.protocol.wss.url, None);
// //
assert!(!s.core.network.privacy.require_inbound_relay); assert!(!s.core.network.privacy.require_inbound_relay);
#[cfg(feature = "geolocation")] #[cfg(feature = "geolocation")]

View file

@ -26,6 +26,7 @@ enable-crypto-vld0 = ["veilid-core/enable-crypto-vld0"]
enable-crypto-none = ["veilid-core/enable-crypto-none"] enable-crypto-none = ["veilid-core/enable-crypto-none"]
crypto-test = ["enable-crypto-vld0", "enable-crypto-none"] crypto-test = ["enable-crypto-vld0", "enable-crypto-none"]
crypto-test-none = ["enable-crypto-none"] crypto-test-none = ["enable-crypto-none"]
enable-protocol-wss = ["veilid-core/enable-protocol-wss"]
footgun = ["veilid-core/footgun"] footgun = ["veilid-core/footgun"]
[dependencies] [dependencies]