pr work
This commit is contained in:
		@@ -177,7 +177,7 @@ impl VeilidCoreContext {
 | 
			
		||||
        // Set up config from callback
 | 
			
		||||
        trace!("setup config with callback");
 | 
			
		||||
        let mut config = VeilidConfig::new();
 | 
			
		||||
        config.setup(config_callback)?;
 | 
			
		||||
        config.setup(config_callback, update_callback.clone())?;
 | 
			
		||||
 | 
			
		||||
        Self::new_common(update_callback, config).await
 | 
			
		||||
    }
 | 
			
		||||
@@ -190,7 +190,7 @@ impl VeilidCoreContext {
 | 
			
		||||
        // Set up config from callback
 | 
			
		||||
        trace!("setup config with json");
 | 
			
		||||
        let mut config = VeilidConfig::new();
 | 
			
		||||
        config.setup_from_json(config_json)?;
 | 
			
		||||
        config.setup_from_json(config_json, update_callback.clone())?;
 | 
			
		||||
        Self::new_common(update_callback, config).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -271,6 +271,34 @@ impl RPCProcessor {
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #[instrument(level = "trace", skip_all, err)]
 | 
			
		||||
    pub(crate) async fn process_private_route_first_hop(
 | 
			
		||||
        &self,
 | 
			
		||||
        operation: RoutedOperation,
 | 
			
		||||
        sr_pubkey: DHTKey,
 | 
			
		||||
        private_route: &PrivateRoute,
 | 
			
		||||
    ) -> Result<(), RPCError> {
 | 
			
		||||
        let PrivateRouteHops::FirstHop(pr_first_hop) = &private_route.hops else {
 | 
			
		||||
            return Err(RPCError::protocol("switching from safety route to private route requires first hop"));
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Switching to private route from safety route
 | 
			
		||||
        self.process_route_private_route_hop(
 | 
			
		||||
            operation,
 | 
			
		||||
            pr_first_hop.node.clone(),
 | 
			
		||||
            sr_pubkey,
 | 
			
		||||
            PrivateRoute {
 | 
			
		||||
                public_key: private_route.public_key,
 | 
			
		||||
                hop_count: private_route.hop_count - 1,
 | 
			
		||||
                hops: pr_first_hop
 | 
			
		||||
                    .next_hop
 | 
			
		||||
                    .clone()
 | 
			
		||||
                    .map(|rhd| PrivateRouteHops::Data(rhd))
 | 
			
		||||
                    .unwrap_or(PrivateRouteHops::Empty),
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
        .await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[instrument(level = "trace", skip(self, msg), err)]
 | 
			
		||||
    pub(crate) async fn process_route(&self, msg: RPCMessage) -> Result<(), RPCError> {
 | 
			
		||||
@@ -332,24 +360,11 @@ impl RPCProcessor {
 | 
			
		||||
                        decode_private_route(&pr_reader)?
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    // Get the next hop node ref
 | 
			
		||||
                    let PrivateRouteHops::FirstHop(pr_first_hop) = private_route.hops else {
 | 
			
		||||
                        return Err(RPCError::protocol("switching from safety route to private route requires first hop"));
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    // Switching to private route from safety route
 | 
			
		||||
                    self.process_route_private_route_hop(
 | 
			
		||||
                    // Switching from full safety route to private route first hop
 | 
			
		||||
                    self.process_private_route_first_hop(
 | 
			
		||||
                        route.operation,
 | 
			
		||||
                        pr_first_hop.node,
 | 
			
		||||
                        route.safety_route.public_key,
 | 
			
		||||
                        PrivateRoute {
 | 
			
		||||
                            public_key: private_route.public_key,
 | 
			
		||||
                            hop_count: private_route.hop_count - 1,
 | 
			
		||||
                            hops: pr_first_hop
 | 
			
		||||
                                .next_hop
 | 
			
		||||
                                .map(|rhd| PrivateRouteHops::Data(rhd))
 | 
			
		||||
                                .unwrap_or(PrivateRouteHops::Empty),
 | 
			
		||||
                        },
 | 
			
		||||
                        &private_route,
 | 
			
		||||
                    )
 | 
			
		||||
                    .await?;
 | 
			
		||||
                } else if blob_tag == 0 {
 | 
			
		||||
@@ -361,6 +376,7 @@ impl RPCProcessor {
 | 
			
		||||
                        decode_route_hop(&rh_reader)?
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    // Continue the full safety route with another hop
 | 
			
		||||
                    self.process_route_safety_route_hop(route, route_hop)
 | 
			
		||||
                        .await?;
 | 
			
		||||
                } else {
 | 
			
		||||
@@ -372,7 +388,13 @@ impl RPCProcessor {
 | 
			
		||||
                // See if we have a hop, if not, we are at the end of the private route
 | 
			
		||||
                match &private_route.hops {
 | 
			
		||||
                    PrivateRouteHops::FirstHop(_) => {
 | 
			
		||||
                        return Err(RPCError::protocol("should not have first hop here"));
 | 
			
		||||
                        // Safety route was a stub, start with the beginning of the private route
 | 
			
		||||
                        self.process_private_route_first_hop(
 | 
			
		||||
                            route.operation,
 | 
			
		||||
                            route.safety_route.public_key,
 | 
			
		||||
                            private_route,
 | 
			
		||||
                        )
 | 
			
		||||
                        .await?;
 | 
			
		||||
                    }
 | 
			
		||||
                    PrivateRouteHops::Data(route_hop_data) => {
 | 
			
		||||
                        // Decrypt the blob with DEC(nonce, DH(the PR's public key, this hop's secret)
 | 
			
		||||
 
 | 
			
		||||
@@ -156,13 +156,12 @@ cfg_if! {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn update_callback(update: VeilidUpdate) {
 | 
			
		||||
    println!("update_callback: {:?}", update);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn setup_veilid_core() -> (UpdateCallback, ConfigCallback) {
 | 
			
		||||
    (
 | 
			
		||||
        Arc::new(move |veilid_update: VeilidUpdate| {
 | 
			
		||||
            println!("update_callback: {:?}", veilid_update);
 | 
			
		||||
        }),
 | 
			
		||||
        Arc::new(config_callback),
 | 
			
		||||
    )
 | 
			
		||||
    (Arc::new(update_callback), Arc::new(config_callback))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn config_callback(key: String) -> ConfigCallbackReturn {
 | 
			
		||||
@@ -268,7 +267,7 @@ fn config_callback(key: String) -> ConfigCallbackReturn {
 | 
			
		||||
 | 
			
		||||
pub fn get_config() -> VeilidConfig {
 | 
			
		||||
    let mut vc = VeilidConfig::new();
 | 
			
		||||
    match vc.setup(Arc::new(config_callback)) {
 | 
			
		||||
    match vc.setup(Arc::new(config_callback), Arc::new(update_callback)) {
 | 
			
		||||
        Ok(()) => (),
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            error!("Error: {}", e);
 | 
			
		||||
@@ -280,7 +279,7 @@ pub fn get_config() -> VeilidConfig {
 | 
			
		||||
 | 
			
		||||
pub async fn test_config() {
 | 
			
		||||
    let mut vc = VeilidConfig::new();
 | 
			
		||||
    match vc.setup(Arc::new(config_callback)) {
 | 
			
		||||
    match vc.setup(Arc::new(config_callback), Arc::new(update_callback)) {
 | 
			
		||||
        Ok(()) => (),
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            error!("Error: {}", e);
 | 
			
		||||
 
 | 
			
		||||
@@ -319,6 +319,14 @@ pub struct VeilidStateNetwork {
 | 
			
		||||
    pub peers: Vec<PeerTableData>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(
 | 
			
		||||
    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
#[archive_attr(repr(C), derive(CheckBytes))]
 | 
			
		||||
pub struct VeilidStateConfig {
 | 
			
		||||
    pub config: VeilidConfigInner,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
 | 
			
		||||
#[archive_attr(repr(u8), derive(CheckBytes))]
 | 
			
		||||
#[serde(tag = "kind")]
 | 
			
		||||
@@ -328,6 +336,7 @@ pub enum VeilidUpdate {
 | 
			
		||||
    AppCall(VeilidAppCall),
 | 
			
		||||
    Attachment(VeilidStateAttachment),
 | 
			
		||||
    Network(VeilidStateNetwork),
 | 
			
		||||
    Config(VeilidStateConfig),
 | 
			
		||||
    Shutdown,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -336,6 +345,7 @@ pub enum VeilidUpdate {
 | 
			
		||||
pub struct VeilidState {
 | 
			
		||||
    pub attachment: VeilidStateAttachment,
 | 
			
		||||
    pub network: VeilidStateNetwork,
 | 
			
		||||
    pub config: VeilidStateConfig,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -2679,13 +2689,16 @@ impl VeilidAPI {
 | 
			
		||||
    pub async fn get_state(&self) -> Result<VeilidState, VeilidAPIError> {
 | 
			
		||||
        let attachment_manager = self.attachment_manager()?;
 | 
			
		||||
        let network_manager = attachment_manager.network_manager();
 | 
			
		||||
        let config = self.config()?;
 | 
			
		||||
 | 
			
		||||
        let attachment = attachment_manager.get_veilid_state();
 | 
			
		||||
        let network = network_manager.get_veilid_state();
 | 
			
		||||
        let config = config.get_veilid_state();
 | 
			
		||||
 | 
			
		||||
        Ok(VeilidState {
 | 
			
		||||
            attachment,
 | 
			
		||||
            network,
 | 
			
		||||
            config,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
use crate::xx::*;
 | 
			
		||||
use crate::*;
 | 
			
		||||
use rkyv::{Archive as RkyvArchive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
 | 
			
		||||
use serde::*;
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -16,7 +17,18 @@ pub type ConfigCallback = Arc<dyn Fn(String) -> ConfigCallbackReturn + Send + Sy
 | 
			
		||||
///     url: 'https://localhost:5150'
 | 
			
		||||
/// ```
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigHTTPS {
 | 
			
		||||
    pub enabled: bool,
 | 
			
		||||
    pub listen_address: String,
 | 
			
		||||
@@ -34,7 +46,18 @@ pub struct VeilidConfigHTTPS {
 | 
			
		||||
///     url: 'https://localhost:5150'
 | 
			
		||||
/// ```
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigHTTP {
 | 
			
		||||
    pub enabled: bool,
 | 
			
		||||
    pub listen_address: String,
 | 
			
		||||
@@ -48,7 +71,18 @@ pub struct VeilidConfigHTTP {
 | 
			
		||||
///
 | 
			
		||||
/// To be implemented...
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigApplication {
 | 
			
		||||
    pub https: VeilidConfigHTTPS,
 | 
			
		||||
    pub http: VeilidConfigHTTP,
 | 
			
		||||
@@ -64,7 +98,18 @@ pub struct VeilidConfigApplication {
 | 
			
		||||
///     public_address: ''
 | 
			
		||||
/// ```
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigUDP {
 | 
			
		||||
    pub enabled: bool,
 | 
			
		||||
    pub socket_pool_size: u32,
 | 
			
		||||
@@ -82,7 +127,18 @@ pub struct VeilidConfigUDP {
 | 
			
		||||
///     listen_address: ':5150'
 | 
			
		||||
///     public_address: ''
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigTCP {
 | 
			
		||||
    pub connect: bool,
 | 
			
		||||
    pub listen: bool,
 | 
			
		||||
@@ -102,7 +158,18 @@ pub struct VeilidConfigTCP {
 | 
			
		||||
///     path: 'ws'
 | 
			
		||||
///     url: 'ws://localhost:5150/ws'
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigWS {
 | 
			
		||||
    pub connect: bool,
 | 
			
		||||
    pub listen: bool,
 | 
			
		||||
@@ -123,7 +190,18 @@ pub struct VeilidConfigWS {
 | 
			
		||||
///     path: 'ws'
 | 
			
		||||
///     url: ''
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigWSS {
 | 
			
		||||
    pub connect: bool,
 | 
			
		||||
    pub listen: bool,
 | 
			
		||||
@@ -140,7 +218,18 @@ pub struct VeilidConfigWSS {
 | 
			
		||||
/// All protocols are available by default, and the Veilid node will
 | 
			
		||||
/// sort out which protocol is used for each peer connection.
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigProtocol {
 | 
			
		||||
    pub udp: VeilidConfigUDP,
 | 
			
		||||
    pub tcp: VeilidConfigTCP,
 | 
			
		||||
@@ -156,7 +245,18 @@ pub struct VeilidConfigProtocol {
 | 
			
		||||
///     private_key_path: /path/to/private/key
 | 
			
		||||
///     connection_initial_timeout_ms: 2000
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigTLS {
 | 
			
		||||
    pub certificate_path: String,
 | 
			
		||||
    pub private_key_path: String,
 | 
			
		||||
@@ -165,7 +265,18 @@ pub struct VeilidConfigTLS {
 | 
			
		||||
 | 
			
		||||
/// Configure the Distributed Hash Table (DHT)
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigDHT {
 | 
			
		||||
    pub resolve_node_timeout_ms: Option<u32>,
 | 
			
		||||
    pub resolve_node_count: u32,
 | 
			
		||||
@@ -184,7 +295,18 @@ pub struct VeilidConfigDHT {
 | 
			
		||||
 | 
			
		||||
/// Configure RPC
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigRPC {
 | 
			
		||||
    pub concurrency: u32,
 | 
			
		||||
    pub queue_size: u32,
 | 
			
		||||
@@ -197,7 +319,18 @@ pub struct VeilidConfigRPC {
 | 
			
		||||
 | 
			
		||||
/// Configure the network routing table
 | 
			
		||||
///
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigRoutingTable {
 | 
			
		||||
    pub limit_over_attached: u32,
 | 
			
		||||
    pub limit_fully_attached: u32,
 | 
			
		||||
@@ -206,7 +339,18 @@ pub struct VeilidConfigRoutingTable {
 | 
			
		||||
    pub limit_attached_weak: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigNetwork {
 | 
			
		||||
    pub connection_initial_timeout_ms: u32,
 | 
			
		||||
    pub connection_inactivity_timeout_ms: u32,
 | 
			
		||||
@@ -233,19 +377,52 @@ pub struct VeilidConfigNetwork {
 | 
			
		||||
    pub protocol: VeilidConfigProtocol,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigTableStore {
 | 
			
		||||
    pub directory: String,
 | 
			
		||||
    pub delete: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigBlockStore {
 | 
			
		||||
    pub directory: String,
 | 
			
		||||
    pub delete: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigProtectedStore {
 | 
			
		||||
    pub allow_insecure_fallback: bool,
 | 
			
		||||
    pub always_use_insecure_storage: bool,
 | 
			
		||||
@@ -253,7 +430,18 @@ pub struct VeilidConfigProtectedStore {
 | 
			
		||||
    pub delete: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigCapabilities {
 | 
			
		||||
    pub protocol_udp: bool,
 | 
			
		||||
    pub protocol_connect_tcp: bool,
 | 
			
		||||
@@ -264,7 +452,18 @@ pub struct VeilidConfigCapabilities {
 | 
			
		||||
    pub protocol_accept_wss: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Clone,
 | 
			
		||||
    Copy,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub enum VeilidConfigLogLevel {
 | 
			
		||||
    Off,
 | 
			
		||||
    Error,
 | 
			
		||||
@@ -322,7 +521,18 @@ impl Default for VeilidConfigLogLevel {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Default,
 | 
			
		||||
    Debug,
 | 
			
		||||
    Clone,
 | 
			
		||||
    PartialEq,
 | 
			
		||||
    Eq,
 | 
			
		||||
    Serialize,
 | 
			
		||||
    Deserialize,
 | 
			
		||||
    RkyvArchive,
 | 
			
		||||
    RkyvSerialize,
 | 
			
		||||
    RkyvDeserialize,
 | 
			
		||||
)]
 | 
			
		||||
pub struct VeilidConfigInner {
 | 
			
		||||
    pub program_name: String,
 | 
			
		||||
    pub namespace: String,
 | 
			
		||||
@@ -338,6 +548,7 @@ pub struct VeilidConfigInner {
 | 
			
		||||
/// Veilid is configured
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
pub struct VeilidConfig {
 | 
			
		||||
    update_cb: Option<UpdateCallback>,
 | 
			
		||||
    inner: Arc<RwLock<VeilidConfigInner>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -362,23 +573,29 @@ impl VeilidConfig {
 | 
			
		||||
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            update_cb: None,
 | 
			
		||||
            inner: Arc::new(RwLock::new(Self::new_inner())),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setup_from_json(&mut self, config: String) -> Result<(), VeilidAPIError> {
 | 
			
		||||
        {
 | 
			
		||||
            let mut inner = self.inner.write();
 | 
			
		||||
    pub fn setup_from_json(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        config: String,
 | 
			
		||||
        update_cb: UpdateCallback,
 | 
			
		||||
    ) -> Result<(), VeilidAPIError> {
 | 
			
		||||
        self.update_cb = Some(update_cb);
 | 
			
		||||
 | 
			
		||||
        self.with_mut(|inner| {
 | 
			
		||||
            *inner = serde_json::from_str(&config).map_err(VeilidAPIError::generic)?;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Validate settings
 | 
			
		||||
        self.validate()?;
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
            Ok(())
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setup(&mut self, cb: ConfigCallback) -> Result<(), VeilidAPIError> {
 | 
			
		||||
    pub fn setup(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        cb: ConfigCallback,
 | 
			
		||||
        update_cb: UpdateCallback,
 | 
			
		||||
    ) -> Result<(), VeilidAPIError> {
 | 
			
		||||
        macro_rules! get_config {
 | 
			
		||||
            ($key:expr) => {
 | 
			
		||||
                let keyname = &stringify!($key)[6..];
 | 
			
		||||
@@ -389,8 +606,9 @@ impl VeilidConfig {
 | 
			
		||||
                })?;
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        {
 | 
			
		||||
            let mut inner = self.inner.write();
 | 
			
		||||
 | 
			
		||||
        self.update_cb = Some(update_cb);
 | 
			
		||||
        self.with_mut(|inner| {
 | 
			
		||||
            get_config!(inner.program_name);
 | 
			
		||||
            get_config!(inner.namespace);
 | 
			
		||||
            get_config!(inner.capabilities.protocol_udp);
 | 
			
		||||
@@ -482,19 +700,44 @@ impl VeilidConfig {
 | 
			
		||||
            get_config!(inner.network.protocol.wss.listen_address);
 | 
			
		||||
            get_config!(inner.network.protocol.wss.path);
 | 
			
		||||
            get_config!(inner.network.protocol.wss.url);
 | 
			
		||||
        }
 | 
			
		||||
        // Validate settings
 | 
			
		||||
        self.validate()?;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    pub fn get_veilid_state(&self) -> VeilidStateConfig {
 | 
			
		||||
        let inner = self.inner.read();
 | 
			
		||||
        VeilidStateConfig {
 | 
			
		||||
            config: inner.clone(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get(&self) -> RwLockReadGuard<VeilidConfigInner> {
 | 
			
		||||
        self.inner.read()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_mut(&self) -> RwLockWriteGuard<VeilidConfigInner> {
 | 
			
		||||
        self.inner.write()
 | 
			
		||||
    pub fn with_mut<F, R>(&self, f: F) -> Result<R, VeilidAPIError>
 | 
			
		||||
    where
 | 
			
		||||
        F: FnOnce(&mut VeilidConfigInner) -> Result<R, VeilidAPIError>,
 | 
			
		||||
    {
 | 
			
		||||
        let (out, config) = {
 | 
			
		||||
            let inner = &mut *self.inner.write();
 | 
			
		||||
            // Edit a copy
 | 
			
		||||
            let mut editedinner = inner.clone();
 | 
			
		||||
            // Make changes
 | 
			
		||||
            let out = f(&mut editedinner)?;
 | 
			
		||||
            // Validate
 | 
			
		||||
            Self::validate(&mut editedinner)?;
 | 
			
		||||
            // Commit changes
 | 
			
		||||
            *inner = editedinner.clone();
 | 
			
		||||
            (out, editedinner)
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Send configuration update to clients
 | 
			
		||||
        if let Some(update_cb) = &self.update_cb {
 | 
			
		||||
            update_cb(VeilidUpdate::Config(VeilidStateConfig { config }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(out)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_key_json(&self, key: &str) -> Result<String, VeilidAPIError> {
 | 
			
		||||
@@ -521,47 +764,43 @@ impl VeilidConfig {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    pub fn set_key_json(&self, key: &str, value: &str) -> Result<(), VeilidAPIError> {
 | 
			
		||||
        let mut c = self.get_mut();
 | 
			
		||||
        self.with_mut(|c| {
 | 
			
		||||
            // Split key into path parts
 | 
			
		||||
            let keypath: Vec<&str> = key.split('.').collect();
 | 
			
		||||
 | 
			
		||||
        // Split key into path parts
 | 
			
		||||
        let keypath: Vec<&str> = key.split('.').collect();
 | 
			
		||||
            // Convert value into jsonvalue
 | 
			
		||||
            let newval = json::parse(value).map_err(VeilidAPIError::generic)?;
 | 
			
		||||
 | 
			
		||||
        // Convert value into jsonvalue
 | 
			
		||||
        let newval = json::parse(value).map_err(VeilidAPIError::generic)?;
 | 
			
		||||
            // Generate json from whole config
 | 
			
		||||
            let jc = serde_json::to_string(&*c).map_err(VeilidAPIError::generic)?;
 | 
			
		||||
            let mut jvc = json::parse(&jc).map_err(VeilidAPIError::generic)?;
 | 
			
		||||
 | 
			
		||||
        // Generate json from whole config
 | 
			
		||||
        let jc = serde_json::to_string(&*c).map_err(VeilidAPIError::generic)?;
 | 
			
		||||
        let mut jvc = json::parse(&jc).map_err(VeilidAPIError::generic)?;
 | 
			
		||||
 | 
			
		||||
        // Find requested subkey
 | 
			
		||||
        let newconfigstring = if let Some((objkeyname, objkeypath)) = keypath.split_last() {
 | 
			
		||||
            // Replace subkey
 | 
			
		||||
            let mut out = &mut jvc;
 | 
			
		||||
            for k in objkeypath {
 | 
			
		||||
                if !out.has_key(*k) {
 | 
			
		||||
                    apibail_parse!(format!("invalid subkey in key '{}'", key), k);
 | 
			
		||||
            // Find requested subkey
 | 
			
		||||
            let newconfigstring = if let Some((objkeyname, objkeypath)) = keypath.split_last() {
 | 
			
		||||
                // Replace subkey
 | 
			
		||||
                let mut out = &mut jvc;
 | 
			
		||||
                for k in objkeypath {
 | 
			
		||||
                    if !out.has_key(*k) {
 | 
			
		||||
                        apibail_parse!(format!("invalid subkey in key '{}'", key), k);
 | 
			
		||||
                    }
 | 
			
		||||
                    out = &mut out[*k];
 | 
			
		||||
                }
 | 
			
		||||
                out = &mut out[*k];
 | 
			
		||||
            }
 | 
			
		||||
            if !out.has_key(objkeyname) {
 | 
			
		||||
                apibail_parse!(format!("invalid subkey in key '{}'", key), objkeyname);
 | 
			
		||||
            }
 | 
			
		||||
            out[*objkeyname] = newval;
 | 
			
		||||
            jvc.to_string()
 | 
			
		||||
        } else {
 | 
			
		||||
            newval.to_string()
 | 
			
		||||
        };
 | 
			
		||||
        // Generate and validate new config
 | 
			
		||||
        let mut newconfig = VeilidConfig::new();
 | 
			
		||||
        newconfig.setup_from_json(newconfigstring)?;
 | 
			
		||||
        //  Replace whole config
 | 
			
		||||
        *c = newconfig.get().clone();
 | 
			
		||||
        Ok(())
 | 
			
		||||
                if !out.has_key(objkeyname) {
 | 
			
		||||
                    apibail_parse!(format!("invalid subkey in key '{}'", key), objkeyname);
 | 
			
		||||
                }
 | 
			
		||||
                out[*objkeyname] = newval;
 | 
			
		||||
                jvc.to_string()
 | 
			
		||||
            } else {
 | 
			
		||||
                newval.to_string()
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Generate new config
 | 
			
		||||
            *c = serde_json::from_str(&newconfigstring).map_err(VeilidAPIError::generic)?;
 | 
			
		||||
            Ok(())
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn validate(&self) -> Result<(), VeilidAPIError> {
 | 
			
		||||
        let inner = self.inner.read();
 | 
			
		||||
 | 
			
		||||
    fn validate(inner: &VeilidConfigInner) -> Result<(), VeilidAPIError> {
 | 
			
		||||
        if inner.program_name.is_empty() {
 | 
			
		||||
            apibail_generic!("Program name must not be empty in 'program_name'");
 | 
			
		||||
        }
 | 
			
		||||
@@ -731,8 +970,11 @@ impl VeilidConfig {
 | 
			
		||||
            .await
 | 
			
		||||
            .map_err(VeilidAPIError::internal)?;
 | 
			
		||||
 | 
			
		||||
        self.inner.write().network.node_id = Some(node_id);
 | 
			
		||||
        self.inner.write().network.node_id_secret = Some(node_id_secret);
 | 
			
		||||
        self.with_mut(|c| {
 | 
			
		||||
            c.network.node_id = Some(node_id);
 | 
			
		||||
            c.network.node_id_secret = Some(node_id_secret);
 | 
			
		||||
            Ok(())
 | 
			
		||||
        })?;
 | 
			
		||||
 | 
			
		||||
        trace!("init_node_id complete");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user