fix private routing 1.0
This commit is contained in:
		@@ -106,11 +106,20 @@ pub fn encode_private_route(
 | 
			
		||||
        &mut builder.reborrow().init_public_key(),
 | 
			
		||||
    )?;
 | 
			
		||||
    builder.set_hop_count(private_route.hop_count);
 | 
			
		||||
    if let Some(rh) = &private_route.first_hop {
 | 
			
		||||
        let mut rh_builder = builder.reborrow().init_first_hop();
 | 
			
		||||
        encode_route_hop(rh, &mut rh_builder)?;
 | 
			
		||||
    let mut h_builder = builder.reborrow().init_hops();
 | 
			
		||||
    match &private_route.hops {
 | 
			
		||||
        PrivateRouteHops::FirstHop(first_hop) => {
 | 
			
		||||
            let mut rh_builder = h_builder.init_first_hop();
 | 
			
		||||
            encode_route_hop(first_hop, &mut rh_builder)?;
 | 
			
		||||
        }
 | 
			
		||||
        PrivateRouteHops::Data(data) => {
 | 
			
		||||
            let mut rhd_builder = h_builder.init_data();
 | 
			
		||||
            encode_route_hop_data(data, &mut rhd_builder)?;
 | 
			
		||||
        }
 | 
			
		||||
        PrivateRouteHops::Empty => {
 | 
			
		||||
            h_builder.set_empty(());
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -121,19 +130,23 @@ pub fn decode_private_route(
 | 
			
		||||
        "invalid public key in private route",
 | 
			
		||||
    ))?);
 | 
			
		||||
    let hop_count = reader.get_hop_count();
 | 
			
		||||
    let first_hop = if reader.has_first_hop() {
 | 
			
		||||
        let rh_reader = reader
 | 
			
		||||
            .get_first_hop()
 | 
			
		||||
            .map_err(RPCError::map_protocol("invalid first hop in private route"))?;
 | 
			
		||||
        Some(decode_route_hop(&rh_reader)?)
 | 
			
		||||
    } else {
 | 
			
		||||
        None
 | 
			
		||||
 | 
			
		||||
    let hops = match reader.get_hops().which().map_err(RPCError::protocol)? {
 | 
			
		||||
        veilid_capnp::private_route::hops::Which::FirstHop(rh_reader) => {
 | 
			
		||||
            let rh_reader = rh_reader.map_err(RPCError::protocol)?;
 | 
			
		||||
            PrivateRouteHops::FirstHop(decode_route_hop(&rh_reader)?)
 | 
			
		||||
        }
 | 
			
		||||
        veilid_capnp::private_route::hops::Which::Data(rhd_reader) => {
 | 
			
		||||
            let rhd_reader = rhd_reader.map_err(RPCError::protocol)?;
 | 
			
		||||
            PrivateRouteHops::Data(decode_route_hop_data(&rhd_reader)?)
 | 
			
		||||
        }
 | 
			
		||||
        veilid_capnp::private_route::hops::Which::Empty(_) => PrivateRouteHops::Empty,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Ok(PrivateRoute {
 | 
			
		||||
        public_key,
 | 
			
		||||
        hop_count,
 | 
			
		||||
        first_hop,
 | 
			
		||||
        hops,
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -205,8 +205,8 @@ impl RPCProcessor {
 | 
			
		||||
                private_route,
 | 
			
		||||
                safety_selection,
 | 
			
		||||
            } => {
 | 
			
		||||
                let Some(pr_first_hop) = &private_route.first_hop else {
 | 
			
		||||
                    return Err(RPCError::internal("destination private route must have first_hop"));
 | 
			
		||||
                let PrivateRouteHops::FirstHop(pr_first_hop) = &private_route.hops else {
 | 
			
		||||
                    return Err(RPCError::internal("destination private route must have first hop"));
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                match safety_selection {
 | 
			
		||||
 
 | 
			
		||||
@@ -72,26 +72,20 @@ impl RPCProcessor {
 | 
			
		||||
    #[instrument(level = "trace", skip_all, err)]
 | 
			
		||||
    async fn process_route_private_route_hop(
 | 
			
		||||
        &self,
 | 
			
		||||
        mut route: RPCOperationRoute,
 | 
			
		||||
        mut next_private_route: PrivateRoute,
 | 
			
		||||
        mut routed_operation: RoutedOperation,
 | 
			
		||||
        next_route_node: RouteNode,
 | 
			
		||||
        safety_route_public_key: DHTKey,
 | 
			
		||||
        next_private_route: PrivateRoute,
 | 
			
		||||
    ) -> Result<(), RPCError> {
 | 
			
		||||
        // Make sure hop count makes sense
 | 
			
		||||
        if route.safety_route.hop_count != 0 {
 | 
			
		||||
            return Err(RPCError::protocol(
 | 
			
		||||
                "Safety hop count should be zero if switched to private route",
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
        if next_private_route.hop_count as usize > self.unlocked_inner.max_route_hop_count {
 | 
			
		||||
            return Err(RPCError::protocol(
 | 
			
		||||
                "Private route hop count too high to process",
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Get private route first hop (this is validated to not be None before calling this function)
 | 
			
		||||
        let first_hop = next_private_route.first_hop.as_ref().unwrap();
 | 
			
		||||
 | 
			
		||||
        // Get next hop node ref
 | 
			
		||||
        let next_hop_nr = match &first_hop.node {
 | 
			
		||||
        let next_hop_nr = match &next_route_node {
 | 
			
		||||
            RouteNode::NodeId(id) => {
 | 
			
		||||
                //
 | 
			
		||||
                self.routing_table
 | 
			
		||||
@@ -116,27 +110,24 @@ impl RPCProcessor {
 | 
			
		||||
            }
 | 
			
		||||
        }?;
 | 
			
		||||
 | 
			
		||||
        if first_hop.next_hop.is_some() {
 | 
			
		||||
        if !matches!(next_private_route.hops, PrivateRouteHops::Empty) {
 | 
			
		||||
            // Sign the operation if this is not our last hop
 | 
			
		||||
            // as the last hop is already signed by the envelope
 | 
			
		||||
            let node_id = self.routing_table.node_id();
 | 
			
		||||
            let node_id_secret = self.routing_table.node_id_secret();
 | 
			
		||||
            let sig = sign(&node_id, &node_id_secret, &route.operation.data)
 | 
			
		||||
            let sig = sign(&node_id, &node_id_secret, &routed_operation.data)
 | 
			
		||||
                .map_err(RPCError::internal)?;
 | 
			
		||||
            route.operation.signatures.push(sig);
 | 
			
		||||
        } else {
 | 
			
		||||
            // If this is our last hop, then we drop the 'first_hop' from private route
 | 
			
		||||
            // XXX ? next_private_route.first_hop = None;
 | 
			
		||||
            routed_operation.signatures.push(sig);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Pass along the route
 | 
			
		||||
        let next_hop_route = RPCOperationRoute {
 | 
			
		||||
            safety_route: SafetyRoute {
 | 
			
		||||
                public_key: route.safety_route.public_key,
 | 
			
		||||
                public_key: safety_route_public_key,
 | 
			
		||||
                hop_count: 0,
 | 
			
		||||
                hops: SafetyRouteHops::Private(next_private_route),
 | 
			
		||||
            },
 | 
			
		||||
            operation: route.operation,
 | 
			
		||||
            operation: routed_operation,
 | 
			
		||||
        };
 | 
			
		||||
        let next_hop_route_stmt = RPCStatement::new(RPCStatementDetail::Route(next_hop_route));
 | 
			
		||||
 | 
			
		||||
@@ -342,19 +333,25 @@ impl RPCProcessor {
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    // Get the next hop node ref
 | 
			
		||||
                    if private_route.first_hop.is_some() {
 | 
			
		||||
                        // Switching to private route from safety route
 | 
			
		||||
                        self.process_route_private_route_hop(route, private_route)
 | 
			
		||||
                            .await?;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        // Private route is empty, process routed operation
 | 
			
		||||
                        self.process_routed_operation(
 | 
			
		||||
                            detail,
 | 
			
		||||
                            route.operation,
 | 
			
		||||
                            &route.safety_route,
 | 
			
		||||
                            &private_route,
 | 
			
		||||
                        )?;
 | 
			
		||||
                    }
 | 
			
		||||
                    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(
 | 
			
		||||
                        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),
 | 
			
		||||
                        },
 | 
			
		||||
                    )
 | 
			
		||||
                    .await?;
 | 
			
		||||
                } else if blob_tag == 0 {
 | 
			
		||||
                    // RouteHop
 | 
			
		||||
                    let route_hop = {
 | 
			
		||||
@@ -373,18 +370,24 @@ impl RPCProcessor {
 | 
			
		||||
            // No safety route left, now doing private route
 | 
			
		||||
            SafetyRouteHops::Private(ref private_route) => {
 | 
			
		||||
                // See if we have a hop, if not, we are at the end of the private route
 | 
			
		||||
                if let Some(first_hop) = &private_route.first_hop {
 | 
			
		||||
                    // See if we have next hop data
 | 
			
		||||
                    let opt_next_first_hop = if let Some(next_hop) = &first_hop.next_hop {
 | 
			
		||||
                match &private_route.hops {
 | 
			
		||||
                    PrivateRouteHops::FirstHop(_) => {
 | 
			
		||||
                        return Err(RPCError::protocol("should not have first hop here"));
 | 
			
		||||
                    }
 | 
			
		||||
                    PrivateRouteHops::Data(route_hop_data) => {
 | 
			
		||||
                        // Decrypt the blob with DEC(nonce, DH(the PR's public key, this hop's secret)
 | 
			
		||||
                        let node_id_secret = self.routing_table.node_id_secret();
 | 
			
		||||
                        let dh_secret = self
 | 
			
		||||
                            .crypto
 | 
			
		||||
                            .cached_dh(&private_route.public_key, &node_id_secret)
 | 
			
		||||
                            .map_err(RPCError::protocol)?;
 | 
			
		||||
                        let dec_blob_data =
 | 
			
		||||
                            Crypto::decrypt_aead(&next_hop.blob, &next_hop.nonce, &dh_secret, None)
 | 
			
		||||
                                .map_err(RPCError::protocol)?;
 | 
			
		||||
                        let dec_blob_data = Crypto::decrypt_aead(
 | 
			
		||||
                            &route_hop_data.blob,
 | 
			
		||||
                            &route_hop_data.nonce,
 | 
			
		||||
                            &dh_secret,
 | 
			
		||||
                            None,
 | 
			
		||||
                        )
 | 
			
		||||
                        .map_err(RPCError::protocol)?;
 | 
			
		||||
                        let dec_blob_reader = RPCMessageData::new(dec_blob_data).get_reader()?;
 | 
			
		||||
 | 
			
		||||
                        // Decode next RouteHop
 | 
			
		||||
@@ -394,40 +397,42 @@ impl RPCProcessor {
 | 
			
		||||
                                .map_err(RPCError::protocol)?;
 | 
			
		||||
                            decode_route_hop(&rh_reader)?
 | 
			
		||||
                        };
 | 
			
		||||
                        Some(route_hop)
 | 
			
		||||
                    } else {
 | 
			
		||||
                        // If the first hop has no RouteHopData, then this is a stub private route
 | 
			
		||||
                        // and we should just pass the operation to its final destination with
 | 
			
		||||
                        // an empty safety and private route
 | 
			
		||||
                        None
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    // Ensure hop count > 0
 | 
			
		||||
                    if private_route.hop_count == 0 {
 | 
			
		||||
                        return Err(RPCError::protocol("route should not be at the end"));
 | 
			
		||||
                    }
 | 
			
		||||
                        // Ensure hop count > 0
 | 
			
		||||
                        if private_route.hop_count == 0 {
 | 
			
		||||
                            return Err(RPCError::protocol("route should not be at the end"));
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    // Make next PrivateRoute and pass it on
 | 
			
		||||
                    let next_private_route = PrivateRoute {
 | 
			
		||||
                        public_key: private_route.public_key,
 | 
			
		||||
                        hop_count: private_route.hop_count - 1,
 | 
			
		||||
                        first_hop: opt_next_first_hop,
 | 
			
		||||
                    };
 | 
			
		||||
                    self.process_route_private_route_hop(route, next_private_route)
 | 
			
		||||
                        // Make next PrivateRoute and pass it on
 | 
			
		||||
                        self.process_route_private_route_hop(
 | 
			
		||||
                            route.operation,
 | 
			
		||||
                            route_hop.node,
 | 
			
		||||
                            route.safety_route.public_key,
 | 
			
		||||
                            PrivateRoute {
 | 
			
		||||
                                public_key: private_route.public_key,
 | 
			
		||||
                                hop_count: private_route.hop_count - 1,
 | 
			
		||||
                                hops: route_hop
 | 
			
		||||
                                    .next_hop
 | 
			
		||||
                                    .map(|rhd| PrivateRouteHops::Data(rhd))
 | 
			
		||||
                                    .unwrap_or(PrivateRouteHops::Empty),
 | 
			
		||||
                            },
 | 
			
		||||
                        )
 | 
			
		||||
                        .await?;
 | 
			
		||||
                } else {
 | 
			
		||||
                    // Ensure hop count == 0
 | 
			
		||||
                    if private_route.hop_count != 0 {
 | 
			
		||||
                        return Err(RPCError::protocol("route should be at the end"));
 | 
			
		||||
                    }
 | 
			
		||||
                    PrivateRouteHops::Empty => {
 | 
			
		||||
                        // Ensure hop count == 0
 | 
			
		||||
                        if private_route.hop_count != 0 {
 | 
			
		||||
                            return Err(RPCError::protocol("route should be at the end"));
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    // No hops left, time to process the routed operation
 | 
			
		||||
                    self.process_routed_operation(
 | 
			
		||||
                        detail,
 | 
			
		||||
                        route.operation,
 | 
			
		||||
                        &route.safety_route,
 | 
			
		||||
                        private_route,
 | 
			
		||||
                    )?;
 | 
			
		||||
                        // No hops left, time to process the routed operation
 | 
			
		||||
                        self.process_routed_operation(
 | 
			
		||||
                            detail,
 | 
			
		||||
                            route.operation,
 | 
			
		||||
                            &route.safety_route,
 | 
			
		||||
                            private_route,
 | 
			
		||||
                        )?;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user