switch out capabilities

This commit is contained in:
John Smith 2023-07-03 15:10:28 -04:00
parent cf9d8cf7c2
commit dfb4eefd92
22 changed files with 172 additions and 205 deletions

View File

@ -50,6 +50,7 @@ core:
reverse_connection_receipt_time_ms: 5000 reverse_connection_receipt_time_ms: 5000
hole_punch_receipt_time_ms: 5000 hole_punch_receipt_time_ms: 5000
network_key_password: null network_key_password: null
disable_capabilites: []
routing_table: routing_table:
node_id: null node_id: null
node_id_secret: null node_id_secret: null

View File

@ -189,6 +189,7 @@ network:
reverse_connection_receipt_time_ms: 5000 reverse_connection_receipt_time_ms: 5000
hole_punch_receipt_time_ms: 5000 hole_punch_receipt_time_ms: 5000
network_key_password: null network_key_password: null
disable_capabilites: []
node_id: null node_id: null
node_id_secret: null node_id_secret: null
bootstrap: ['bootstrap.veilid.net'] bootstrap: ['bootstrap.veilid.net']

View File

@ -34,6 +34,7 @@ using TunnelID = UInt64; # Id for tunnels
using CryptoKind = UInt32; # FOURCC code for cryptography type using CryptoKind = UInt32; # FOURCC code for cryptography type
using ValueSeqNum = UInt32; # sequence numbers for values using ValueSeqNum = UInt32; # sequence numbers for values
using Subkey = UInt32; # subkey index for dht using Subkey = UInt32; # subkey index for dht
using Capability = UInt32; # FOURCC code for capability
struct TypedKey @0xe2d567a9f1e61b29 { struct TypedKey @0xe2d567a9f1e61b29 {
kind @0 :CryptoKind; kind @0 :CryptoKind;
@ -190,22 +191,17 @@ struct DialInfoDetail @0x96423aa1d67b74d8 {
} }
struct PublicInternetNodeStatus @0x9c9d7f1f12eb088f { struct PublicInternetNodeStatus @0x9c9d7f1f12eb088f {
willRoute @0 :Bool; capabilities @0 :List(Capability); # List of Capability FOURCC codes that this node is advertising it is capable of in the publicinternet routing domain
willTunnel @1 :Bool;
willSignal @2 :Bool;
willRelay @3 :Bool;
willValidateDialInfo @4 :Bool;
} }
struct LocalNetworkNodeStatus @0x957f5bfed2d0b5a5 { struct LocalNetworkNodeStatus @0x957f5bfed2d0b5a5 {
willRelay @0 :Bool; capabilities @0 :List(Capability); # List of Capability FOURCC codes that this node is advertising it is capable of in the localnetwork routing domain
willValidateDialInfo @1 :Bool;
} }
struct NodeStatus @0xd36b9e7a3bf3330d { struct NodeStatus @0xd36b9e7a3bf3330d {
union { union {
publicInternet @0 :PublicInternetNodeStatus; publicInternet @0 :PublicInternetNodeStatus;
localNetwork @1 :LocalNetworkNodeStatus; localNetwork @1 :LocalNetworkNodeStatus;
} }
} }

View File

@ -4,7 +4,7 @@ use data_encoding::BASE64URL_NOPAD;
use digest::Digest; use digest::Digest;
use rand::RngCore; use rand::RngCore;
const AEAD_OVERHEAD: usize = PUBLIC_KEY_LENGTH; const AEAD_OVERHEAD: usize = PUBLIC_KEY_LENGTH;
pub const CRYPTO_KIND_NONE: CryptoKind = FourCC([b'N', b'O', b'N', b'E']); pub const CRYPTO_KIND_NONE: CryptoKind = FourCC(*b"NONE");
pub fn none_generate_keypair() -> KeyPair { pub fn none_generate_keypair() -> KeyPair {
let mut csprng = VeilidRng {}; let mut csprng = VeilidRng {};

View File

@ -15,7 +15,7 @@ use ed25519_dalek as ed;
use x25519_dalek as xd; use x25519_dalek as xd;
const AEAD_OVERHEAD: usize = 16; const AEAD_OVERHEAD: usize = 16;
pub const CRYPTO_KIND_VLD0: CryptoKind = FourCC([b'V', b'L', b'D', b'0']); pub const CRYPTO_KIND_VLD0: CryptoKind = FourCC(*b"VLD0");
fn ed25519_to_x25519_pk(key: &ed::PublicKey) -> VeilidAPIResult<xd::PublicKey> { fn ed25519_to_x25519_pk(key: &ed::PublicKey) -> VeilidAPIResult<xd::PublicKey> {
let bytes = key.to_bytes(); let bytes = key.to_bytes();

View File

@ -495,31 +495,42 @@ impl NetworkManager {
/// Get our node's capabilities in the PublicInternet routing domain /// Get our node's capabilities in the PublicInternet routing domain
fn generate_public_internet_node_status(&self) -> PublicInternetNodeStatus { fn generate_public_internet_node_status(&self) -> PublicInternetNodeStatus {
let Some(own_peer_info) = self let Some(own_peer_info) = self
.routing_table() .routing_table()
.get_own_peer_info(RoutingDomain::PublicInternet) else { .get_own_peer_info(RoutingDomain::PublicInternet) else {
return PublicInternetNodeStatus { return PublicInternetNodeStatus::default();
will_route: false,
will_tunnel: false,
will_signal: false,
will_relay: false,
will_validate_dial_info: false,
};
}; };
let own_node_info = own_peer_info.signed_node_info().node_info(); let own_node_info = own_peer_info.signed_node_info().node_info();
let config = self.config();
let c = config.get();
let will_route = own_node_info.can_inbound_relay(); // xxx: eventually this may have more criteria added let will_route = own_node_info.can_inbound_relay(); // xxx: eventually this may have more criteria added
let will_tunnel = own_node_info.can_inbound_relay(); // xxx: we may want to restrict by battery life and network bandwidth at some point let will_tunnel = own_node_info.can_inbound_relay(); // xxx: we may want to restrict by battery life and network bandwidth at some point
let will_signal = own_node_info.can_signal(); let will_signal = own_node_info.can_signal();
let will_relay = own_node_info.can_inbound_relay(); let will_relay = own_node_info.can_inbound_relay();
let will_validate_dial_info = own_node_info.can_validate_dial_info(); let will_validate_dial_info = own_node_info.can_validate_dial_info();
let mut capabilities = Vec::new();
if will_route && !c.capabilities.disable.contains(&CAP_WILL_ROUTE) {
capabilities.push(CAP_WILL_ROUTE);
}
if will_tunnel && !c.capabilities.disable.contains(&CAP_WILL_TUNNEL) {
capabilities.push(CAP_WILL_TUNNEL);
}
if will_signal && !c.capabilities.disable.contains(&CAP_WILL_SIGNAL) {
capabilities.push(CAP_WILL_SIGNAL);
}
if will_relay && !c.capabilities.disable.contains(&CAP_WILL_RELAY){
capabilities.push(CAP_WILL_RELAY);
}
if will_validate_dial_info && !c.capabilities.disable.contains(&CAP_WILL_VALIDATE_DIAL_INFO) {
capabilities.push(CAP_WILL_VALIDATE_DIAL_INFO);
}
PublicInternetNodeStatus { PublicInternetNodeStatus {
will_route, capabilities
will_tunnel,
will_signal,
will_relay,
will_validate_dial_info,
} }
} }
/// Get our node's capabilities in the LocalNetwork routing domain /// Get our node's capabilities in the LocalNetwork routing domain
@ -527,20 +538,26 @@ impl NetworkManager {
let Some(own_peer_info) = self let Some(own_peer_info) = self
.routing_table() .routing_table()
.get_own_peer_info(RoutingDomain::LocalNetwork) else { .get_own_peer_info(RoutingDomain::LocalNetwork) else {
return LocalNetworkNodeStatus { return LocalNetworkNodeStatus::default();
will_relay: false,
will_validate_dial_info: false,
};
}; };
let own_node_info = own_peer_info.signed_node_info().node_info(); let own_node_info = own_peer_info.signed_node_info().node_info();
let config = self.config();
let c = config.get();
let will_relay = own_node_info.can_inbound_relay(); let will_relay = own_node_info.can_inbound_relay();
let will_validate_dial_info = own_node_info.can_validate_dial_info(); let will_validate_dial_info = own_node_info.can_validate_dial_info();
let mut capabilities = Vec::new();
if will_relay && !c.capabilities.disable.contains(&CAP_WILL_RELAY) {
capabilities.push(CAP_WILL_RELAY);
}
if will_validate_dial_info && !c.capabilities.disable.contains(&CAP_WILL_VALIDATE_DIAL_INFO) {
capabilities.push(CAP_WILL_VALIDATE_DIAL_INFO);
}
LocalNetworkNodeStatus { LocalNetworkNodeStatus {
will_relay, capabilities
will_validate_dial_info,
} }
} }

View File

@ -686,30 +686,30 @@ impl Network {
let c = self.config.get(); let c = self.config.get();
let mut inbound = ProtocolTypeSet::new(); let mut inbound = ProtocolTypeSet::new();
if c.network.protocol.udp.enabled && c.capabilities.protocol_udp { if c.network.protocol.udp.enabled {
inbound.insert(ProtocolType::UDP); inbound.insert(ProtocolType::UDP);
} }
if c.network.protocol.tcp.listen && c.capabilities.protocol_accept_tcp { if c.network.protocol.tcp.listen {
inbound.insert(ProtocolType::TCP); inbound.insert(ProtocolType::TCP);
} }
if c.network.protocol.ws.listen && c.capabilities.protocol_accept_ws { if c.network.protocol.ws.listen {
inbound.insert(ProtocolType::WS); inbound.insert(ProtocolType::WS);
} }
if c.network.protocol.wss.listen && c.capabilities.protocol_accept_wss { if c.network.protocol.wss.listen {
inbound.insert(ProtocolType::WSS); inbound.insert(ProtocolType::WSS);
} }
let mut outbound = ProtocolTypeSet::new(); let mut outbound = ProtocolTypeSet::new();
if c.network.protocol.udp.enabled && c.capabilities.protocol_udp { if c.network.protocol.udp.enabled {
outbound.insert(ProtocolType::UDP); outbound.insert(ProtocolType::UDP);
} }
if c.network.protocol.tcp.connect && c.capabilities.protocol_connect_tcp { if c.network.protocol.tcp.connect {
outbound.insert(ProtocolType::TCP); outbound.insert(ProtocolType::TCP);
} }
if c.network.protocol.ws.connect && c.capabilities.protocol_connect_ws { if c.network.protocol.ws.connect {
outbound.insert(ProtocolType::WS); outbound.insert(ProtocolType::WS);
} }
if c.network.protocol.wss.connect && c.capabilities.protocol_connect_wss { if c.network.protocol.wss.connect {
outbound.insert(ProtocolType::WSS); outbound.insert(ProtocolType::WSS);
} }

View File

@ -265,7 +265,7 @@ impl RouteSpecStore {
}; };
let node_status_ok = let node_status_ok =
if let Some(ns) = e.node_status(RoutingDomain::PublicInternet) { if let Some(ns) = e.node_status(RoutingDomain::PublicInternet) {
ns.will_route() ns.has_capability(CAP_WILL_ROUTE)
} else { } else {
false false
}; };

View File

@ -148,7 +148,7 @@ impl RoutingTable {
// Ensure we have the node's status // Ensure we have the node's status
if let Some(node_status) = e.node_status(routing_domain) { if let Some(node_status) = e.node_status(routing_domain) {
// Ensure the node will relay // Ensure the node will relay
if node_status.will_relay() { if node_status.has_capability(CAP_WILL_RELAY) {
// Compare against previous candidate // Compare against previous candidate
if let Some(best_inbound_relay) = best_inbound_relay.as_mut() { if let Some(best_inbound_relay) = best_inbound_relay.as_mut() {
// Less is faster // Less is faster

View File

@ -3,17 +3,21 @@ use super::*;
/// RoutingDomain-specific status for each node /// RoutingDomain-specific status for each node
/// is returned by the StatusA call /// is returned by the StatusA call
pub type Capability = FourCC;
pub const CAP_WILL_ROUTE: Capability = FourCC(*b"ROUT");
pub const CAP_WILL_TUNNEL: Capability = FourCC(*b"TUNL");
pub const CAP_WILL_SIGNAL: Capability = FourCC(*b"SGNL");
pub const CAP_WILL_RELAY: Capability = FourCC(*b"RLAY");
pub const CAP_WILL_VALIDATE_DIAL_INFO: Capability = FourCC(*b"DIAL");
pub const MAX_CAPABILITIES: usize = 64;
/// PublicInternet RoutingDomain Status /// PublicInternet RoutingDomain Status
#[derive( #[derive(
Clone, Debug, Default, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize, Clone, Debug, Default, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)] )]
#[archive_attr(repr(C), derive(CheckBytes))] #[archive_attr(repr(C), derive(CheckBytes))]
pub struct PublicInternetNodeStatus { pub struct PublicInternetNodeStatus {
pub will_route: bool, pub capabilities: Vec<Capability>,
pub will_tunnel: bool,
pub will_signal: bool,
pub will_relay: bool,
pub will_validate_dial_info: bool,
} }
#[derive( #[derive(
@ -21,8 +25,7 @@ pub struct PublicInternetNodeStatus {
)] )]
#[archive_attr(repr(C), derive(CheckBytes))] #[archive_attr(repr(C), derive(CheckBytes))]
pub struct LocalNetworkNodeStatus { pub struct LocalNetworkNodeStatus {
pub will_relay: bool, pub capabilities: Vec<Capability>,
pub will_validate_dial_info: bool,
} }
#[derive(Clone, Debug, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)] #[derive(Clone, Debug, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
@ -33,34 +36,10 @@ pub enum NodeStatus {
} }
impl NodeStatus { impl NodeStatus {
pub fn will_route(&self) -> bool { pub fn has_capability(&self, cap: Capability) -> bool {
match self { match self {
NodeStatus::PublicInternet(pi) => pi.will_route, NodeStatus::PublicInternet(pi) => pi.capabilities.contains(&cap),
NodeStatus::LocalNetwork(_) => false, NodeStatus::LocalNetwork(ln) => ln.capabilities.contains(&cap),
}
}
pub fn will_tunnel(&self) -> bool {
match self {
NodeStatus::PublicInternet(pi) => pi.will_tunnel,
NodeStatus::LocalNetwork(_) => false,
}
}
pub fn will_signal(&self) -> bool {
match self {
NodeStatus::PublicInternet(pi) => pi.will_signal,
NodeStatus::LocalNetwork(_) => false,
}
}
pub fn will_relay(&self) -> bool {
match self {
NodeStatus::PublicInternet(pi) => pi.will_relay,
NodeStatus::LocalNetwork(ln) => ln.will_relay,
}
}
pub fn will_validate_dial_info(&self) -> bool {
match self {
NodeStatus::PublicInternet(pi) => pi.will_validate_dial_info,
NodeStatus::LocalNetwork(ln) => ln.will_validate_dial_info,
} }
} }
} }

View File

@ -71,13 +71,11 @@ pub fn decode_node_info(reader: &veilid_capnp::node_info::Reader) -> Result<Node
.map_err(RPCError::protocol)?, .map_err(RPCError::protocol)?,
)?; )?;
let envelope_support = reader let es_reader = reader
.reborrow() .reborrow()
.get_envelope_support() .get_envelope_support()
.map_err(RPCError::protocol)? .map_err(RPCError::protocol)?;
.as_slice() let envelope_support = es_reader.as_slice().map(|s| s.to_vec()).unwrap_or_default();
.map(|s| s.to_vec())
.unwrap_or_default();
// Ensure envelope versions are not duplicated // Ensure envelope versions are not duplicated
// Unsorted is okay, some nodes may have a different envelope order preference // Unsorted is okay, some nodes may have a different envelope order preference
@ -94,10 +92,16 @@ pub fn decode_node_info(reader: &veilid_capnp::node_info::Reader) -> Result<Node
return Err(RPCError::protocol("no envelope versions")); return Err(RPCError::protocol("no envelope versions"));
} }
let crypto_support: Vec<CryptoKind> = reader let cs_reader = reader
.reborrow() .reborrow()
.get_crypto_support() .get_crypto_support()
.map_err(RPCError::protocol)? .map_err(RPCError::protocol)?;
if cs_reader.len() as usize > MAX_CRYPTO_KINDS {
return Err(RPCError::protocol("too many crypto kinds"));
}
let crypto_support: Vec<CryptoKind> = cs_reader
.as_slice() .as_slice()
.map(|s| s.iter().map(|x| FourCC::from(x.to_be_bytes())).collect()) .map(|s| s.iter().map(|x| FourCC::from(x.to_be_bytes())).collect())
.unwrap_or_default(); .unwrap_or_default();

View File

@ -4,44 +4,74 @@ pub fn encode_public_internet_node_status(
public_internet_node_status: &PublicInternetNodeStatus, public_internet_node_status: &PublicInternetNodeStatus,
builder: &mut veilid_capnp::public_internet_node_status::Builder, builder: &mut veilid_capnp::public_internet_node_status::Builder,
) -> Result<(), RPCError> { ) -> Result<(), RPCError> {
builder.set_will_route(public_internet_node_status.will_route); let mut cap_builder = builder
builder.set_will_tunnel(public_internet_node_status.will_tunnel); .reborrow()
builder.set_will_signal(public_internet_node_status.will_signal); .init_capabilities(public_internet_node_status.capabilities.len() as u32);
builder.set_will_relay(public_internet_node_status.will_relay); if let Some(s) = cap_builder.as_slice() {
builder.set_will_validate_dial_info(public_internet_node_status.will_validate_dial_info); let capvec: Vec<u32> = public_internet_node_status
.capabilities
.iter()
.map(|x| u32::from_be_bytes(x.0))
.collect();
s.clone_from_slice(&capvec);
}
Ok(()) Ok(())
} }
pub fn decode_public_internet_node_status( pub fn decode_public_internet_node_status(
reader: &veilid_capnp::public_internet_node_status::Reader, reader: &veilid_capnp::public_internet_node_status::Reader,
) -> Result<PublicInternetNodeStatus, RPCError> { ) -> Result<PublicInternetNodeStatus, RPCError> {
Ok(PublicInternetNodeStatus { let cap_reader = reader
will_route: reader.reborrow().get_will_route(), .reborrow()
will_tunnel: reader.reborrow().get_will_tunnel(), .get_capabilities()
will_signal: reader.reborrow().get_will_signal(), .map_err(RPCError::protocol)?;
will_relay: reader.reborrow().get_will_relay(), if cap_reader.len() as usize > MAX_CAPABILITIES {
will_validate_dial_info: reader.reborrow().get_will_validate_dial_info(), return Err(RPCError::protocol("too many capabilities"));
}) }
let capabilities = cap_reader
.as_slice()
.map(|s| s.iter().map(|x| FourCC::from(x.to_be_bytes())).collect())
.unwrap_or_default();
Ok(PublicInternetNodeStatus { capabilities })
} }
pub fn encode_local_network_node_status( pub fn encode_local_network_node_status(
local_network_node_status: &LocalNetworkNodeStatus, local_network_node_status: &LocalNetworkNodeStatus,
builder: &mut veilid_capnp::local_network_node_status::Builder, builder: &mut veilid_capnp::local_network_node_status::Builder,
) -> Result<(), RPCError> { ) -> Result<(), RPCError> {
builder.set_will_relay(local_network_node_status.will_relay); let mut cap_builder = builder
builder.set_will_validate_dial_info(local_network_node_status.will_validate_dial_info); .reborrow()
.init_capabilities(local_network_node_status.capabilities.len() as u32);
if let Some(s) = cap_builder.as_slice() {
let capvec: Vec<u32> = local_network_node_status
.capabilities
.iter()
.map(|x| u32::from_be_bytes(x.0))
.collect();
s.clone_from_slice(&capvec);
}
Ok(()) Ok(())
} }
pub fn decode_local_network_node_status( pub fn decode_local_network_node_status(
reader: &veilid_capnp::local_network_node_status::Reader, reader: &veilid_capnp::local_network_node_status::Reader,
) -> Result<LocalNetworkNodeStatus, RPCError> { ) -> Result<LocalNetworkNodeStatus, RPCError> {
Ok(LocalNetworkNodeStatus { let cap_reader = reader
will_relay: reader.reborrow().get_will_relay(), .reborrow()
will_validate_dial_info: reader.reborrow().get_will_validate_dial_info(), .get_capabilities()
}) .map_err(RPCError::protocol)?;
if cap_reader.len() as usize > MAX_CAPABILITIES {
return Err(RPCError::protocol("too many capabilities"));
}
let capabilities = cap_reader
.as_slice()
.map(|s| s.iter().map(|x| FourCC::from(x.to_be_bytes())).collect())
.unwrap_or_default();
Ok(LocalNetworkNodeStatus { capabilities })
} }
pub fn encode_node_status( pub fn encode_node_status(

View File

@ -105,7 +105,7 @@ impl RPCProcessor {
let entry = v.unwrap(); let entry = v.unwrap();
entry.with(rti, move |_rti, e| { entry.with(rti, move |_rti, e| {
if let Some(status) = &e.node_status(routing_domain) { if let Some(status) = &e.node_status(routing_domain) {
status.will_validate_dial_info() status.has_capability(CAP_WILL_VALIDATE_DIAL_INFO)
} else { } else {
true true
} }

View File

@ -168,13 +168,7 @@ fn config_callback(key: String) -> ConfigCallbackReturn {
match key.as_str() { match key.as_str() {
"program_name" => Ok(Box::new(String::from("VeilidCoreTests"))), "program_name" => Ok(Box::new(String::from("VeilidCoreTests"))),
"namespace" => Ok(Box::new(String::from(""))), "namespace" => Ok(Box::new(String::from(""))),
"capabilities.protocol_udp" => Ok(Box::new(true)), "capabilities.disable" => Ok(Box::new(Vec::<FourCC>::new())),
"capabilities.protocol_connect_tcp" => Ok(Box::new(true)),
"capabilities.protocol_accept_tcp" => Ok(Box::new(true)),
"capabilities.protocol_connect_ws" => Ok(Box::new(true)),
"capabilities.protocol_accept_ws" => Ok(Box::new(true)),
"capabilities.protocol_connect_wss" => Ok(Box::new(true)),
"capabilities.protocol_accept_wss" => Ok(Box::new(true)),
"table_store.directory" => Ok(Box::new(get_table_store_path())), "table_store.directory" => Ok(Box::new(get_table_store_path())),
"table_store.delete" => Ok(Box::new(true)), "table_store.delete" => Ok(Box::new(true)),
"block_store.directory" => Ok(Box::new(get_block_store_path())), "block_store.directory" => Ok(Box::new(get_block_store_path())),
@ -299,13 +293,7 @@ pub async fn test_config() {
let inner = vc.get(); let inner = vc.get();
assert_eq!(inner.program_name, String::from("VeilidCoreTests")); assert_eq!(inner.program_name, String::from("VeilidCoreTests"));
assert_eq!(inner.namespace, String::from("")); assert_eq!(inner.namespace, String::from(""));
assert_eq!(inner.capabilities.protocol_udp, true); assert_eq!(inner.capabilities.disable, Vec::<FourCC>::new());
assert_eq!(inner.capabilities.protocol_connect_tcp, true);
assert_eq!(inner.capabilities.protocol_accept_tcp, true);
assert_eq!(inner.capabilities.protocol_connect_ws, true);
assert_eq!(inner.capabilities.protocol_accept_ws, true);
assert_eq!(inner.capabilities.protocol_connect_wss, true);
assert_eq!(inner.capabilities.protocol_accept_wss, true);
assert_eq!(inner.table_store.directory, get_table_store_path()); assert_eq!(inner.table_store.directory, get_table_store_path());
assert_eq!(inner.table_store.delete, true); assert_eq!(inner.table_store.delete, true);
assert_eq!(inner.block_store.directory, get_block_store_path()); assert_eq!(inner.block_store.directory, get_block_store_path());

View File

@ -76,13 +76,7 @@ pub fn fix_veilidconfiginner() -> VeilidConfigInner {
program_name: "Bob".to_string(), program_name: "Bob".to_string(),
namespace: "Internets".to_string(), namespace: "Internets".to_string(),
capabilities: VeilidConfigCapabilities { capabilities: VeilidConfigCapabilities {
protocol_udp: false, disable: Vec::new(),
protocol_connect_tcp: true,
protocol_accept_tcp: false,
protocol_connect_ws: true,
protocol_accept_ws: false,
protocol_connect_wss: true,
protocol_accept_wss: false,
}, },
protected_store: VeilidConfigProtectedStore { protected_store: VeilidConfigProtectedStore {
allow_insecure_fallback: true, allow_insecure_fallback: true,

View File

@ -468,13 +468,7 @@ pub struct VeilidConfigProtectedStore {
JsonSchema, JsonSchema,
)] )]
pub struct VeilidConfigCapabilities { pub struct VeilidConfigCapabilities {
pub protocol_udp: bool, pub disable: Vec<FourCC>,
pub protocol_connect_tcp: bool,
pub protocol_accept_tcp: bool,
pub protocol_connect_ws: bool,
pub protocol_accept_ws: bool,
pub protocol_connect_wss: bool,
pub protocol_accept_wss: bool,
} }
#[derive( #[derive(
@ -670,13 +664,7 @@ impl VeilidConfig {
get_config!(inner.program_name); get_config!(inner.program_name);
get_config!(inner.namespace); get_config!(inner.namespace);
get_config!(inner.capabilities.protocol_udp); get_config!(inner.capabilities.disable);
get_config!(inner.capabilities.protocol_connect_tcp);
get_config!(inner.capabilities.protocol_accept_tcp);
get_config!(inner.capabilities.protocol_connect_ws);
get_config!(inner.capabilities.protocol_accept_ws);
get_config!(inner.capabilities.protocol_connect_wss);
get_config!(inner.capabilities.protocol_accept_wss);
get_config!(inner.table_store.directory); get_config!(inner.table_store.directory);
get_config!(inner.table_store.delete); get_config!(inner.table_store.delete);
get_config!(inner.block_store.directory); get_config!(inner.block_store.directory);

View File

@ -52,15 +52,7 @@ Future<VeilidConfig> getDefaultVeilidConfig(String programName) async {
return VeilidConfig( return VeilidConfig(
programName: programName, programName: programName,
namespace: "", namespace: "",
capabilities: VeilidConfigCapabilities( capabilities: VeilidConfigCapabilities(disable: []),
protocolUDP: !kIsWeb,
protocolConnectTCP: !kIsWeb,
protocolAcceptTCP: !kIsWeb,
protocolConnectWS: true,
protocolAcceptWS: !kIsWeb,
protocolConnectWSS: true,
protocolAcceptWSS: false,
),
protectedStore: VeilidConfigProtectedStore( protectedStore: VeilidConfigProtectedStore(
allowInsecureFallback: false, allowInsecureFallback: false,
alwaysUseInsecureStorage: false, alwaysUseInsecureStorage: false,

View File

@ -867,44 +867,19 @@ class VeilidConfigProtectedStore {
//////////// ////////////
class VeilidConfigCapabilities { class VeilidConfigCapabilities {
bool protocolUDP; List<String> disable;
bool protocolConnectTCP;
bool protocolAcceptTCP;
bool protocolConnectWS;
bool protocolAcceptWS;
bool protocolConnectWSS;
bool protocolAcceptWSS;
VeilidConfigCapabilities({ VeilidConfigCapabilities({
required this.protocolUDP, required this.disable,
required this.protocolConnectTCP,
required this.protocolAcceptTCP,
required this.protocolConnectWS,
required this.protocolAcceptWS,
required this.protocolConnectWSS,
required this.protocolAcceptWSS,
}); });
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {
'protocol_udp': protocolUDP, 'disable': disable,
'protocol_connect_tcp': protocolConnectTCP,
'protocol_accept_tcp': protocolAcceptTCP,
'protocol_connect_ws': protocolConnectWS,
'protocol_accept_ws': protocolAcceptWS,
'protocol_connect_wss': protocolConnectWSS,
'protocol_accept_wss': protocolAcceptWSS,
}; };
} }
VeilidConfigCapabilities.fromJson(dynamic json) VeilidConfigCapabilities.fromJson(dynamic json) : disable = json['disable'];
: protocolUDP = json['protocol_udp'],
protocolConnectTCP = json['protocol_connect_tcp'],
protocolAcceptTCP = json['protocol_accept_tcp'],
protocolConnectWS = json['protocol_connect_ws'],
protocolAcceptWS = json['protocol_accept_ws'],
protocolConnectWSS = json['protocol_connect_wss'],
protocolAcceptWSS = json['protocol_accept_wss'];
} }
//////////// ////////////

View File

@ -2,7 +2,7 @@ from dataclasses import dataclass, fields
from enum import StrEnum from enum import StrEnum
from typing import Optional, Self from typing import Optional, Self
from .types import TypedKey, TypedSecret from .types import TypedKey, TypedSecret, Capability
class VeilidConfigLogLevel(StrEnum): class VeilidConfigLogLevel(StrEnum):
@ -41,13 +41,7 @@ class ConfigBase:
@dataclass @dataclass
class VeilidConfigCapabilities(ConfigBase): class VeilidConfigCapabilities(ConfigBase):
protocol_udp: bool disable: list[Capability]
protocol_connect_tcp: bool
protocol_accept_tcp: bool
protocol_connect_ws: bool
protocol_accept_ws: bool
protocol_connect_wss: bool
protocol_accept_wss: bool
@dataclass @dataclass

View File

@ -52,6 +52,14 @@ class CryptoKind(StrEnum):
CRYPTO_KIND_VLD0 = "VLD0" CRYPTO_KIND_VLD0 = "VLD0"
class Capability(StrEnum):
CAP_WILL_ROUTE = "ROUT"
CAP_WILL_TUNNEL = "TUNL"
CAP_WILL_SIGNAL = "SGNL"
CAP_WILL_RELAY = "RLAY"
CAP_WILL_VALIDATE_DIAL_INFO = "DIAL"
class Stability(StrEnum): class Stability(StrEnum):
LOW_LATENCY = "LowLatency" LOW_LATENCY = "LowLatency"
RELIABLE = "Reliable" RELIABLE = "Reliable"
@ -67,6 +75,7 @@ class DHTSchemaKind(StrEnum):
DFLT = "DFLT" DFLT = "DFLT"
SMPL = "SMPL" SMPL = "SMPL"
class SafetySelectionKind(StrEnum): class SafetySelectionKind(StrEnum):
UNSAFE = "Unsafe" UNSAFE = "Unsafe"
SAFE = "Safe" SAFE = "Safe"
@ -235,11 +244,10 @@ class VeilidVersion:
if self._patch < other._patch: if self._patch < other._patch:
return True return True
return False return False
def __eq__(self, other): def __eq__(self, other):
return isinstance(other, VeilidVersion) and self.data == other.data and self.seq == other.seq and self.writer == other.writer return isinstance(other, VeilidVersion) and self.data == other.data and self.seq == other.seq and self.writer == other.writer
@property @property
def major(self): def major(self):
return self._major return self._major
@ -308,7 +316,8 @@ class DHTSchema:
if DHTSchemaKind(j["kind"]) == DHTSchemaKind.SMPL: if DHTSchemaKind(j["kind"]) == DHTSchemaKind.SMPL:
return cls.smpl( return cls.smpl(
j["o_cnt"], j["o_cnt"],
[DHTSchemaSMPLMember.from_json(member) for member in j["members"]], [DHTSchemaSMPLMember.from_json(member)
for member in j["members"]],
) )
raise Exception("Unknown DHTSchema kind", j["kind"]) raise Exception("Unknown DHTSchema kind", j["kind"])
@ -339,7 +348,8 @@ class DHTRecordDescriptor:
return cls( return cls(
TypedKey(j["key"]), TypedKey(j["key"]),
PublicKey(j["owner"]), PublicKey(j["owner"]),
None if j["owner_secret"] is None else SecretKey(j["owner_secret"]), None if j["owner_secret"] is None else SecretKey(
j["owner_secret"]),
DHTSchema.from_json(j["schema"]), DHTSchema.from_json(j["schema"]),
) )
@ -404,14 +414,15 @@ class SafetySpec:
@classmethod @classmethod
def from_json(cls, j: dict) -> Self: def from_json(cls, j: dict) -> Self:
return cls(RouteId(j["preferred_route"]) if "preferred_route" in j else None, return cls(RouteId(j["preferred_route"]) if "preferred_route" in j else None,
j["hop_count"], j["hop_count"],
Stability(j["stability"]), Stability(j["stability"]),
Sequencing(j["sequencing"])) Sequencing(j["sequencing"]))
def to_json(self) -> dict: def to_json(self) -> dict:
return self.__dict__ return self.__dict__
class SafetySelection: class SafetySelection:
kind: SafetySelectionKind kind: SafetySelectionKind
@ -438,9 +449,8 @@ class SafetySelection:
def to_json(self) -> dict: def to_json(self) -> dict:
if self.kind == SafetySelectionKind.UNSAFE: if self.kind == SafetySelectionKind.UNSAFE:
return {"Unsafe": self.sequencing } return {"Unsafe": self.sequencing}
elif self.kind == SafetySelectionKind.SAFE: elif self.kind == SafetySelectionKind.SAFE:
return {"Safe": self.safety_spec.to_json() } return {"Safe": self.safety_spec.to_json()}
else: else:
raise Exception("Invalid SafetySelection") raise Exception("Invalid SafetySelection")

View File

@ -46,6 +46,8 @@ logging:
testing: testing:
subnode_index: 0 subnode_index: 0
core: core:
capabilities:
disable: []
protected_store: protected_store:
allow_insecure_fallback: true allow_insecure_fallback: true
always_use_insecure_storage: true always_use_insecure_storage: true
@ -70,6 +72,7 @@ core:
reverse_connection_receipt_time_ms: 5000 reverse_connection_receipt_time_ms: 5000
hole_punch_receipt_time_ms: 5000 hole_punch_receipt_time_ms: 5000
network_key_password: null network_key_password: null
disable_capabilites: []
routing_table: routing_table:
node_id: null node_id: null
node_id_secret: null node_id_secret: null
@ -622,8 +625,14 @@ pub struct ProtectedStore {
pub new_device_encryption_key_password: Option<String>, pub new_device_encryption_key_password: Option<String>,
} }
#[derive(Debug, Deserialize, Serialize)]
pub struct Capabilities {
pub disable: Vec<String>,
}
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
pub struct Core { pub struct Core {
pub capabilities: Capabilities,
pub protected_store: ProtectedStore, pub protected_store: ProtectedStore,
pub table_store: TableStore, pub table_store: TableStore,
pub block_store: BlockStore, pub block_store: BlockStore,
@ -962,6 +971,7 @@ impl Settings {
set_config_value!(inner.logging.otlp.grpc_endpoint, value); set_config_value!(inner.logging.otlp.grpc_endpoint, value);
set_config_value!(inner.logging.console.enabled, value); set_config_value!(inner.logging.console.enabled, value);
set_config_value!(inner.testing.subnode_index, value); set_config_value!(inner.testing.subnode_index, value);
set_config_value!(inner.core.capabilities.disable, value);
set_config_value!(inner.core.protected_store.allow_insecure_fallback, value); set_config_value!(inner.core.protected_store.allow_insecure_fallback, value);
set_config_value!( set_config_value!(
inner.core.protected_store.always_use_insecure_storage, inner.core.protected_store.always_use_insecure_storage,
@ -1093,13 +1103,7 @@ impl Settings {
} else { } else {
format!("subnode{}", inner.testing.subnode_index) format!("subnode{}", inner.testing.subnode_index)
})), })),
"capabilities.protocol_udp" => Ok(Box::new(true)), "capabilities.disable" => Ok(Box::new(Vec::<FourCC>::new())),
"capabilities.protocol_connect_tcp" => Ok(Box::new(true)),
"capabilities.protocol_accept_tcp" => Ok(Box::new(true)),
"capabilities.protocol_connect_ws" => Ok(Box::new(true)),
"capabilities.protocol_accept_ws" => Ok(Box::new(true)),
"capabilities.protocol_connect_wss" => Ok(Box::new(true)),
"capabilities.protocol_accept_wss" => Ok(Box::new(true)),
"protected_store.allow_insecure_fallback" => { "protected_store.allow_insecure_fallback" => {
Ok(Box::new(inner.core.protected_store.allow_insecure_fallback)) Ok(Box::new(inner.core.protected_store.allow_insecure_fallback))
} }

View File

@ -33,13 +33,7 @@ fn init_callbacks() {
window.configCallback = (configKey) => { window.configCallback = (configKey) => {
switch(configKey) { switch(configKey) {
case "namespace": return ""; case "namespace": return "";
case "capabilities.protocol_udp": return false; case "capabilities.disable": return [];
case "capabilities.protocol_connect_tcp": return false;
case "capabilities.protocol_accept_tcp": return false;
case "capabilities.protocol_connect_ws": return true;
case "capabilities.protocol_accept_ws": return false;
case "capabilities.protocol_connect_wss": return true;
case "capabilities.protocol_accept_wss": return false;
case "tablestore.directory": return ""; case "tablestore.directory": return "";
case "network.routing_table.node_id": return []; case "network.routing_table.node_id": return [];
case "network.routing_table.node_id_secret": return []; case "network.routing_table.node_id_secret": return [];