checkpoint
This commit is contained in:
		@@ -17,9 +17,9 @@ pub struct SafetySpec {
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct CompiledRoute {
 | 
			
		||||
    /// The safety route attached to the private route
 | 
			
		||||
    safety_route: SafetyRoute,
 | 
			
		||||
    pub safety_route: SafetyRoute,
 | 
			
		||||
    /// The secret used to encrypt the message payload
 | 
			
		||||
    secret: DHTKeySecret,
 | 
			
		||||
    pub secret: DHTKeySecret,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, Serialize, Deserialize)]
 | 
			
		||||
@@ -600,7 +600,7 @@ impl RouteSpecStore {
 | 
			
		||||
        &mut self,
 | 
			
		||||
        rti: &RoutingTableInner,
 | 
			
		||||
        routing_table: RoutingTable,
 | 
			
		||||
        safety_spec: SafetySpec,
 | 
			
		||||
        safety_spec: Option<SafetySpec>,
 | 
			
		||||
        private_route: PrivateRoute,
 | 
			
		||||
    ) -> Result<Option<CompiledRoute>, RPCError> {
 | 
			
		||||
        let pr_hopcount = private_route.hop_count as usize;
 | 
			
		||||
@@ -608,7 +608,18 @@ impl RouteSpecStore {
 | 
			
		||||
            return Err(RPCError::internal("private route hop count too long"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See if we are using a safety route, if not, short circuit this operation
 | 
			
		||||
        if safety_spec.is_none() {
 | 
			
		||||
            // Safety route stub with the node's public key as the safety route key since it's the 0th hop
 | 
			
		||||
            return Ok(Some(CompiledRoute {
 | 
			
		||||
                safety_route: SafetyRoute::new_stub(routing_table.node_id(), private_route),
 | 
			
		||||
                secret: routing_table.node_id_secret(),
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
        let safety_spec = safety_spec.unwrap();
 | 
			
		||||
 | 
			
		||||
        // See if the preferred route is here
 | 
			
		||||
        let safety_route_public_key;
 | 
			
		||||
        let opt_safety_rsd: Option<&mut RouteSpecDetail> =
 | 
			
		||||
            if let Some(preferred_route) = safety_spec.preferred_route {
 | 
			
		||||
                self.detail_mut(&preferred_route)
 | 
			
		||||
@@ -650,19 +661,21 @@ impl RouteSpecStore {
 | 
			
		||||
 | 
			
		||||
        // xxx implement caching first!
 | 
			
		||||
 | 
			
		||||
        // xxx implement, ensure we handle hops == 0 for our safetyspec
 | 
			
		||||
 | 
			
		||||
        // Ensure the total hop count isn't too long for our config
 | 
			
		||||
        let sr_hopcount = safety_spec.hop_count;
 | 
			
		||||
        if sr_hopcount > self.max_route_hop_count {
 | 
			
		||||
            return Err(RPCError::internal("private route hop count too long"));
 | 
			
		||||
        if sr_hopcount == 0 {
 | 
			
		||||
            return Err(RPCError::internal("safety route hop count is zero"));
 | 
			
		||||
        }
 | 
			
		||||
        let total_hopcount = sr_hopcount + pr_hopcount;
 | 
			
		||||
        if sr_hopcount > self.max_route_hop_count {
 | 
			
		||||
            return Err(RPCError::internal("safety route hop count too long"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See if we can optimize this compilation yet
 | 
			
		||||
        // We don't want to include full nodeinfo if we don't have to
 | 
			
		||||
        //let optimize = safety_rsd.
 | 
			
		||||
 | 
			
		||||
        // Create hops
 | 
			
		||||
        let hops = if sr_hopcount == 0 {
 | 
			
		||||
            SafetyRouteHops::Private(private_route)
 | 
			
		||||
        } else {
 | 
			
		||||
        let hops = {
 | 
			
		||||
            // start last blob-to-encrypt data off as private route
 | 
			
		||||
            let mut blob_data = {
 | 
			
		||||
                let mut pr_message = ::capnp::message::Builder::new_default();
 | 
			
		||||
@@ -681,16 +694,13 @@ impl RouteSpecStore {
 | 
			
		||||
            // (outer hop is a RouteHopData, not a RouteHop).
 | 
			
		||||
            // Each loop mutates 'nonce', and 'blob_data'
 | 
			
		||||
            let mut nonce = Crypto::get_random_nonce();
 | 
			
		||||
            let crypto = routing_table.network_manager().crypto();
 | 
			
		||||
            for h in (1..sr_hopcount).rev() {
 | 
			
		||||
                // Get blob to encrypt for next hop
 | 
			
		||||
                blob_data = {
 | 
			
		||||
                    // Encrypt the previous blob ENC(nonce, DH(PKhop,SKsr))
 | 
			
		||||
                    let dh_secret = self
 | 
			
		||||
                        .crypto
 | 
			
		||||
                        .cached_dh(
 | 
			
		||||
                            &safety_route_spec.hops[h].dial_info.node_id.key,
 | 
			
		||||
                            &safety_route_spec.secret_key,
 | 
			
		||||
                        )
 | 
			
		||||
                    let dh_secret = crypto
 | 
			
		||||
                        .cached_dh(&safety_rsd.hops[h], &safety_rsd.secret_key)
 | 
			
		||||
                        .map_err(RPCError::map_internal("dh failed"))?;
 | 
			
		||||
                    let enc_msg_data =
 | 
			
		||||
                        Crypto::encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
 | 
			
		||||
@@ -704,7 +714,7 @@ impl RouteSpecStore {
 | 
			
		||||
 | 
			
		||||
                    // Make route hop
 | 
			
		||||
                    let route_hop = RouteHop {
 | 
			
		||||
                        dial_info: safety_route_spec.hops[h].dial_info.clone(),
 | 
			
		||||
                        node: safety_route_spec.hops[h].dial_info.clone(),
 | 
			
		||||
                        next_hop: Some(route_hop_data),
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
@@ -744,12 +754,15 @@ impl RouteSpecStore {
 | 
			
		||||
 | 
			
		||||
        // Build safety route
 | 
			
		||||
        let safety_route = SafetyRoute {
 | 
			
		||||
            public_key: safety_route_spec.public_key,
 | 
			
		||||
            hop_count: safety_route_spec.hops.len() as u8,
 | 
			
		||||
            public_key: safety_rsd.
 | 
			
		||||
            hop_count: safety_spec.hop_count as u8,
 | 
			
		||||
            hops,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        Ok(safety_route)
 | 
			
		||||
        Ok(Some(CompiledRoute {
 | 
			
		||||
            safety_route,
 | 
			
		||||
            secret: todo!(),
 | 
			
		||||
        }))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Mark route as published
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ mod rpc_validate_dial_info;
 | 
			
		||||
mod rpc_value_changed;
 | 
			
		||||
mod rpc_watch_value;
 | 
			
		||||
 | 
			
		||||
pub use coders::*;
 | 
			
		||||
pub use destination::*;
 | 
			
		||||
pub use operation_waiter::*;
 | 
			
		||||
pub use rpc_error::*;
 | 
			
		||||
@@ -29,7 +30,6 @@ use super::*;
 | 
			
		||||
use crate::dht::*;
 | 
			
		||||
use crate::xx::*;
 | 
			
		||||
use capnp::message::ReaderSegments;
 | 
			
		||||
use coders::*;
 | 
			
		||||
use futures_util::StreamExt;
 | 
			
		||||
use network_manager::*;
 | 
			
		||||
use receipt_manager::*;
 | 
			
		||||
@@ -55,6 +55,8 @@ struct RPCMessageHeader {
 | 
			
		||||
    connection_descriptor: ConnectionDescriptor,
 | 
			
		||||
    /// The routing domain the message was sent through
 | 
			
		||||
    routing_domain: RoutingDomain,
 | 
			
		||||
    /// The private route the message was received through
 | 
			
		||||
    private_route: Option<DHTKey>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
@@ -134,7 +136,7 @@ struct RenderedOperation {
 | 
			
		||||
    message: Vec<u8>,  // The rendered operation bytes
 | 
			
		||||
    node_id: DHTKey,   // Destination node id we're sending to
 | 
			
		||||
    node_ref: NodeRef, // Node to send envelope to (may not be destination node id in case of relay)
 | 
			
		||||
    hop_count: usize,  // Total safety + private route hop count
 | 
			
		||||
    hop_count: usize,  // Total safety + private route hop count + 1 hop for the initial send
 | 
			
		||||
}
 | 
			
		||||
/////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
@@ -396,16 +398,25 @@ impl RPCProcessor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Wrap an operation with a private route inside a safety route
 | 
			
		||||
    pub(super) fn wrap_with_route(xxx continue here
 | 
			
		||||
    pub(super) fn wrap_with_route(
 | 
			
		||||
        &self,
 | 
			
		||||
        safety_spec: SafetySpec,
 | 
			
		||||
        safety_spec: Option<SafetySpec>,
 | 
			
		||||
        private_route: PrivateRoute,
 | 
			
		||||
        message_data: Vec<u8>,
 | 
			
		||||
    ) -> Result<RenderedOperation, RPCError> {
 | 
			
		||||
        let compiled_route: CompiledRoute = self.routing_table().with_route_spec_store(|rss| {
 | 
			
		||||
            // Compile the safety route with the private route
 | 
			
		||||
            rss.compile_safety_route(self.safety_spec, private_route)
 | 
			
		||||
        })?;
 | 
			
		||||
    ) -> Result<NetworkResult<RenderedOperation>, RPCError> {
 | 
			
		||||
        let routing_table = self.routing_table();
 | 
			
		||||
        let compiled_route: CompiledRoute =
 | 
			
		||||
            match self.routing_table().with_route_spec_store(|rss, rti| {
 | 
			
		||||
                // Compile the safety route with the private route
 | 
			
		||||
                rss.compile_safety_route(rti, routing_table, safety_spec, private_route)
 | 
			
		||||
            })? {
 | 
			
		||||
                Some(cr) => cr,
 | 
			
		||||
                None => {
 | 
			
		||||
                    return Ok(NetworkResult::no_connection_other(
 | 
			
		||||
                        "private route could not be compiled at this time",
 | 
			
		||||
                    ))
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        // Encrypt routed operation
 | 
			
		||||
        // Xmsg + ENC(Xmsg, DH(PKapr, SKbsr))
 | 
			
		||||
@@ -421,30 +432,42 @@ impl RPCProcessor {
 | 
			
		||||
        let operation = RoutedOperation::new(nonce, enc_msg_data);
 | 
			
		||||
 | 
			
		||||
        // Prepare route operation
 | 
			
		||||
        let route = RPCOperationRoute {
 | 
			
		||||
            safety_route,
 | 
			
		||||
        let route_operation = RPCOperationRoute {
 | 
			
		||||
            safety_route: compiled_route.safety_route,
 | 
			
		||||
            operation,
 | 
			
		||||
        };
 | 
			
		||||
        let operation =
 | 
			
		||||
            RPCOperation::new_statement(RPCStatement::new(RPCStatementDetail::Route(route)), None);
 | 
			
		||||
        let operation = RPCOperation::new_statement(
 | 
			
		||||
            RPCStatement::new(RPCStatementDetail::Route(route_operation)),
 | 
			
		||||
            None,
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // Convert message to bytes and return it
 | 
			
		||||
        let mut route_msg = ::capnp::message::Builder::new_default();
 | 
			
		||||
        let mut route_operation = route_msg.init_root::<veilid_capnp::operation::Builder>();
 | 
			
		||||
        operation.encode(&mut route_operation)?;
 | 
			
		||||
        let out = builder_to_vec(route_msg)?;
 | 
			
		||||
        let out_message = builder_to_vec(route_msg)?;
 | 
			
		||||
 | 
			
		||||
        // out_node_id = sr
 | 
			
		||||
        // .hops
 | 
			
		||||
        // .first()
 | 
			
		||||
        // .ok_or_else(RPCError::else_internal("no hop in safety route"))?
 | 
			
		||||
        // .dial_info
 | 
			
		||||
        // .node_id
 | 
			
		||||
        // .key;
 | 
			
		||||
        // Get the first hop this is going to
 | 
			
		||||
        let out_node_id = compiled_route
 | 
			
		||||
            .safety_route
 | 
			
		||||
            .hops
 | 
			
		||||
            .first()
 | 
			
		||||
            .ok_or_else(RPCError::else_internal("no hop in safety route"))?
 | 
			
		||||
            .dial_info
 | 
			
		||||
            .node_id
 | 
			
		||||
            .key;
 | 
			
		||||
 | 
			
		||||
        //out_hop_count = 1 + sr.hops.len();
 | 
			
		||||
        let out_hop_count =
 | 
			
		||||
            (1 + compiled_route.safety_route.hop_count + private_route.hop_count) as usize;
 | 
			
		||||
 | 
			
		||||
        Ok(out)
 | 
			
		||||
        let out = RenderedOperation {
 | 
			
		||||
            message: out_message,
 | 
			
		||||
            node_id: out_node_id,
 | 
			
		||||
            node_ref: compiled_route.first_hop,
 | 
			
		||||
            hop_count: out_hop_count,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        Ok(NetworkResult::value(out))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Produce a byte buffer that represents the wire encoding of the entire
 | 
			
		||||
@@ -455,8 +478,8 @@ impl RPCProcessor {
 | 
			
		||||
        &self,
 | 
			
		||||
        dest: Destination,
 | 
			
		||||
        operation: &RPCOperation,
 | 
			
		||||
    ) -> Result<RenderedOperation, RPCError> {
 | 
			
		||||
        let out: RenderedOperation;
 | 
			
		||||
    ) -> Result<NetworkResult<RenderedOperation>, RPCError> {
 | 
			
		||||
        let out: NetworkResult<RenderedOperation>;
 | 
			
		||||
 | 
			
		||||
        // Encode message to a builder and make a message reader for it
 | 
			
		||||
        // Then produce the message as an unencrypted byte buffer
 | 
			
		||||
@@ -471,12 +494,12 @@ impl RPCProcessor {
 | 
			
		||||
        match dest {
 | 
			
		||||
            Destination::Direct {
 | 
			
		||||
                target: ref node_ref,
 | 
			
		||||
                safety,
 | 
			
		||||
                safety_spec,
 | 
			
		||||
            }
 | 
			
		||||
            | Destination::Relay {
 | 
			
		||||
                relay: ref node_ref,
 | 
			
		||||
                target: _,
 | 
			
		||||
                safety,
 | 
			
		||||
                safety_spec,
 | 
			
		||||
            } => {
 | 
			
		||||
                // Send to a node without a private route
 | 
			
		||||
                // --------------------------------------
 | 
			
		||||
@@ -485,7 +508,7 @@ impl RPCProcessor {
 | 
			
		||||
                let (node_ref, node_id) = if let Destination::Relay {
 | 
			
		||||
                    relay: _,
 | 
			
		||||
                    target: ref dht_key,
 | 
			
		||||
                    safety: _,
 | 
			
		||||
                    safety_spec: _,
 | 
			
		||||
                } = dest
 | 
			
		||||
                {
 | 
			
		||||
                    (node_ref.clone(), dht_key.clone())
 | 
			
		||||
@@ -495,36 +518,36 @@ impl RPCProcessor {
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                // Handle the existence of safety route
 | 
			
		||||
                match safety {
 | 
			
		||||
                    false => {
 | 
			
		||||
                match safety_spec {
 | 
			
		||||
                    None => {
 | 
			
		||||
                        // If no safety route is being used, and we're not sending to a private
 | 
			
		||||
                        // route, we can use a direct envelope instead of routing
 | 
			
		||||
                        out = RenderedOperation {
 | 
			
		||||
                        out = NetworkResult::value(RenderedOperation {
 | 
			
		||||
                            message,
 | 
			
		||||
                            node_id,
 | 
			
		||||
                            node_ref,
 | 
			
		||||
                            hop_count: 1,
 | 
			
		||||
                        };
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                    true => {
 | 
			
		||||
                    Some(safety_spec) => {
 | 
			
		||||
                        // No private route was specified for the request
 | 
			
		||||
                        // but we are using a safety route, so we must create an empty private route
 | 
			
		||||
                        let private_route = PrivateRoute::new_stub(node_id);
 | 
			
		||||
 | 
			
		||||
                        // Wrap with safety route
 | 
			
		||||
                        out = self.wrap_with_route(true, private_route, message)?;
 | 
			
		||||
                        out = self.wrap_with_route(Some(safety_spec), private_route, message)?;
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
            Destination::PrivateRoute {
 | 
			
		||||
                private_route,
 | 
			
		||||
                safety,
 | 
			
		||||
                safety_spec,
 | 
			
		||||
                reliable,
 | 
			
		||||
            } => {
 | 
			
		||||
                // Send to private route
 | 
			
		||||
                // ---------------------
 | 
			
		||||
                // Reply with 'route' operation
 | 
			
		||||
                out = self.wrap_with_route(safety, private_route, message)?;
 | 
			
		||||
                out = self.wrap_with_route(safety_spec, private_route, message)?;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -602,7 +625,7 @@ impl RPCProcessor {
 | 
			
		||||
            node_id,
 | 
			
		||||
            node_ref,
 | 
			
		||||
            hop_count,
 | 
			
		||||
        } = self.render_operation(dest, &operation)?;
 | 
			
		||||
        } = network_result_try!(self.render_operation(dest, &operation)?);
 | 
			
		||||
 | 
			
		||||
        // Calculate answer timeout
 | 
			
		||||
        // Timeout is number of hops times the timeout per hop
 | 
			
		||||
@@ -665,7 +688,7 @@ impl RPCProcessor {
 | 
			
		||||
            node_id,
 | 
			
		||||
            node_ref,
 | 
			
		||||
            hop_count: _,
 | 
			
		||||
        } = self.render_operation(dest, &operation)?;
 | 
			
		||||
        } = network_result_try!(self.render_operation(dest, &operation)?);
 | 
			
		||||
 | 
			
		||||
        // Send statement
 | 
			
		||||
        let bytes = message.len() as u64;
 | 
			
		||||
@@ -749,7 +772,7 @@ impl RPCProcessor {
 | 
			
		||||
            node_id,
 | 
			
		||||
            node_ref,
 | 
			
		||||
            hop_count: _,
 | 
			
		||||
        } = self.render_operation(dest, &operation)?;
 | 
			
		||||
        } = network_result_try!(self.render_operation(dest, &operation)?);
 | 
			
		||||
 | 
			
		||||
        // Send the reply
 | 
			
		||||
        let bytes = message.len() as u64;
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,19 @@ impl PrivateRoute {
 | 
			
		||||
            first_hop: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    pub fn simplify(self) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            public_key: self.public_key,
 | 
			
		||||
            hop_count: self.hop_count,
 | 
			
		||||
            first_hop: self.first_hop.map(|h| RouteHop {
 | 
			
		||||
                node: match h.node {
 | 
			
		||||
                    RouteNode::NodeId(ni) => RouteNode::NodeId(ni),
 | 
			
		||||
                    RouteNode::PeerInfo(pi) => RouteNode::NodeId(pi.node_id),
 | 
			
		||||
                },
 | 
			
		||||
                next_hop: h.next_hop,
 | 
			
		||||
            }),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl fmt::Display for PrivateRoute {
 | 
			
		||||
@@ -79,6 +92,16 @@ pub struct SafetyRoute {
 | 
			
		||||
    pub hops: SafetyRouteHops,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl SafetyRoute {
 | 
			
		||||
    pub fn new_stub(public_key: DHTKey, private_route: PrivateRoute) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            public_key,
 | 
			
		||||
            hop_count: 0,
 | 
			
		||||
            hops: SafetyRouteHops::Private(private_route),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl fmt::Display for SafetyRoute {
 | 
			
		||||
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 | 
			
		||||
        write!(
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user