checkpoint
This commit is contained in:
		@@ -208,8 +208,15 @@ impl RouteSpecStore {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn load(routing_table: RoutingTable) -> EyreResult<RouteSpecStore> {
 | 
			
		||||
        let (max_route_hop_count, default_route_hop_count) = {
 | 
			
		||||
            let config = routing_table.network_manager().config();
 | 
			
		||||
            let c = config.get();
 | 
			
		||||
            (
 | 
			
		||||
                c.network.rpc.max_route_hop_count as usize,
 | 
			
		||||
                c.network.rpc.default_route_hop_count as usize,
 | 
			
		||||
            )
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Get cbor blob from table store
 | 
			
		||||
        let table_store = routing_table.network_manager().table_store();
 | 
			
		||||
        let rsstdb = table_store.open("RouteSpecStore", 1).await?;
 | 
			
		||||
@@ -251,8 +258,8 @@ impl RouteSpecStore {
 | 
			
		||||
 | 
			
		||||
        let rss = RouteSpecStore {
 | 
			
		||||
            unlocked_inner: Arc::new(RouteSpecStoreUnlockedInner {
 | 
			
		||||
                max_route_hop_count: c.network.rpc.max_route_hop_count.into(),
 | 
			
		||||
                default_route_hop_count: c.network.rpc.default_route_hop_count.into(),
 | 
			
		||||
                max_route_hop_count,
 | 
			
		||||
                default_route_hop_count,
 | 
			
		||||
                routing_table,
 | 
			
		||||
            }),
 | 
			
		||||
            inner: Arc::new(Mutex::new(inner)),
 | 
			
		||||
 
 | 
			
		||||
@@ -52,8 +52,16 @@ struct RPCMessageHeaderDetailDirect {
 | 
			
		||||
    routing_domain: RoutingDomain,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Header details for rpc messages received over only a safety route but not a private route
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
struct RPCMessageHeaderDetailPrivateRoute {
 | 
			
		||||
struct RPCMessageHeaderDetailSafetyRouted {
 | 
			
		||||
    /// The sequencing used for this route
 | 
			
		||||
    sequencing: Sequencing,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Header details for rpc messages received over a private route
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
struct RPCMessageHeaderDetailPrivateRouted {
 | 
			
		||||
    /// The private route we received the rpc over
 | 
			
		||||
    private_route: DHTKey,
 | 
			
		||||
    // The safety selection for replying to this private routed rpc
 | 
			
		||||
@@ -63,7 +71,8 @@ struct RPCMessageHeaderDetailPrivateRoute {
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
enum RPCMessageHeaderDetail {
 | 
			
		||||
    Direct(RPCMessageHeaderDetailDirect),
 | 
			
		||||
    PrivateRoute(RPCMessageHeaderDetailPrivateRoute),
 | 
			
		||||
    SafetyRouted(RPCMessageHeaderDetailSafetyRouted),
 | 
			
		||||
    PrivateRouted(RPCMessageHeaderDetailPrivateRouted),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The decoded header of an RPC message
 | 
			
		||||
@@ -766,10 +775,11 @@ impl RPCProcessor {
 | 
			
		||||
                // Parse out the header detail from the question
 | 
			
		||||
                let detail = match &request.header.detail {
 | 
			
		||||
                    RPCMessageHeaderDetail::Direct(detail) => detail,
 | 
			
		||||
                    RPCMessageHeaderDetail::PrivateRoute(_) => {
 | 
			
		||||
                    RPCMessageHeaderDetail::SafetyRouted(_)
 | 
			
		||||
                    | RPCMessageHeaderDetail::PrivateRouted(_) => {
 | 
			
		||||
                        // If this was sent via a private route, we don't know what the sender was, so drop this
 | 
			
		||||
                        return NetworkResult::invalid_message(
 | 
			
		||||
                            "not responding directly to question from private route",
 | 
			
		||||
                            "can't respond directly to non-direct question",
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
@@ -789,16 +799,23 @@ impl RPCProcessor {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            RespondTo::PrivateRoute(pr) => {
 | 
			
		||||
                let detail = match &request.header.detail {
 | 
			
		||||
                match &request.header.detail {
 | 
			
		||||
                    RPCMessageHeaderDetail::Direct(_) => {
 | 
			
		||||
                        // If this was sent directly, don't respond to a private route as this could give away this node's safety routes
 | 
			
		||||
                        // If this was sent directly, we should only ever respond directly
 | 
			
		||||
                        return NetworkResult::invalid_message(
 | 
			
		||||
                            "not responding to private route from direct question",
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    RPCMessageHeaderDetail::PrivateRoute(detail) => detail,
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                    RPCMessageHeaderDetail::SafetyRouted(detail) => {
 | 
			
		||||
                        // If this was sent via a safety route, but no received over our private route, don't respond with a safety route,
 | 
			
		||||
                        // it would give away which safety routes belong to this node
 | 
			
		||||
                        NetworkResult::value(Destination::private_route(
 | 
			
		||||
                            pr.clone(),
 | 
			
		||||
                            SafetySelection::Unsafe(detail.sequencing),
 | 
			
		||||
                        ))
 | 
			
		||||
                    }
 | 
			
		||||
                    RPCMessageHeaderDetail::PrivateRouted(detail) => {
 | 
			
		||||
                        // If this was received over our private route, it's okay to respond to a private route via our safety route
 | 
			
		||||
                        NetworkResult::value(Destination::private_route(
 | 
			
		||||
                            pr.clone(),
 | 
			
		||||
                            detail.safety_selection.clone(),
 | 
			
		||||
@@ -806,6 +823,8 @@ impl RPCProcessor {
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Issue a reply over the network, possibly using an anonymized route
 | 
			
		||||
    // The request must want a response, or this routine fails
 | 
			
		||||
@@ -916,7 +935,7 @@ impl RPCProcessor {
 | 
			
		||||
                    opt_sender_nr,
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            RPCMessageHeaderDetail::PrivateRoute(_) => {
 | 
			
		||||
            RPCMessageHeaderDetail::SafetyRouted(_) | RPCMessageHeaderDetail::PrivateRouted(_) => {
 | 
			
		||||
                // Decode the RPC message
 | 
			
		||||
                let operation = {
 | 
			
		||||
                    let reader = capnp::message::Reader::new(encoded_msg.data, Default::default());
 | 
			
		||||
@@ -1047,7 +1066,38 @@ impl RPCProcessor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[instrument(level = "trace", skip(self, body), err)]
 | 
			
		||||
    pub fn enqueue_private_route_message(
 | 
			
		||||
    pub fn enqueue_safety_routed_message(
 | 
			
		||||
        &self, xxx keep pushing this through
 | 
			
		||||
        private_route: DHTKey,
 | 
			
		||||
        safety_selection: SafetySelection,
 | 
			
		||||
        body: Vec<u8>,
 | 
			
		||||
    ) -> EyreResult<()> {
 | 
			
		||||
        let msg = RPCMessageEncoded {
 | 
			
		||||
            header: RPCMessageHeader {
 | 
			
		||||
                detail: RPCMessageHeaderDetail::PrivateRouted(
 | 
			
		||||
                    RPCMessageHeaderDetailPrivateRouted {
 | 
			
		||||
                        private_route,
 | 
			
		||||
                        safety_selection,
 | 
			
		||||
                    },
 | 
			
		||||
                ),
 | 
			
		||||
                timestamp: intf::get_timestamp(),
 | 
			
		||||
                body_len: body.len() as u64,
 | 
			
		||||
            },
 | 
			
		||||
            data: RPCMessageData { contents: body },
 | 
			
		||||
        };
 | 
			
		||||
        let send_channel = {
 | 
			
		||||
            let inner = self.inner.lock();
 | 
			
		||||
            inner.send_channel.as_ref().unwrap().clone()
 | 
			
		||||
        };
 | 
			
		||||
        let span_id = Span::current().id();
 | 
			
		||||
        send_channel
 | 
			
		||||
            .try_send((span_id, msg))
 | 
			
		||||
            .wrap_err("failed to enqueue received RPC message")?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[instrument(level = "trace", skip(self, body), err)]
 | 
			
		||||
    pub fn enqueue_private_routed_message(
 | 
			
		||||
        &self,
 | 
			
		||||
        private_route: DHTKey,
 | 
			
		||||
        safety_selection: SafetySelection,
 | 
			
		||||
@@ -1055,10 +1105,12 @@ impl RPCProcessor {
 | 
			
		||||
    ) -> EyreResult<()> {
 | 
			
		||||
        let msg = RPCMessageEncoded {
 | 
			
		||||
            header: RPCMessageHeader {
 | 
			
		||||
                detail: RPCMessageHeaderDetail::PrivateRoute(RPCMessageHeaderDetailPrivateRoute {
 | 
			
		||||
                detail: RPCMessageHeaderDetail::PrivateRouted(
 | 
			
		||||
                    RPCMessageHeaderDetailPrivateRouted {
 | 
			
		||||
                        private_route,
 | 
			
		||||
                        safety_selection,
 | 
			
		||||
                }),
 | 
			
		||||
                    },
 | 
			
		||||
                ),
 | 
			
		||||
                timestamp: intf::get_timestamp(),
 | 
			
		||||
                body_len: body.len() as u64,
 | 
			
		||||
            },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,31 @@
 | 
			
		||||
use super::*;
 | 
			
		||||
 | 
			
		||||
impl RPCProcessor {
 | 
			
		||||
    // Send FindNodeQ RPC request, receive FindNodeA answer
 | 
			
		||||
    // Can be sent via all methods including relays and routes
 | 
			
		||||
    /// Send FindNodeQ RPC request, receive FindNodeA answer
 | 
			
		||||
    /// Can be sent via all methods including relays
 | 
			
		||||
    /// Safety routes may be used, but never private routes.
 | 
			
		||||
    /// Because this leaks information about the identity of the node itself,
 | 
			
		||||
    /// replying to this request received over a private route will leak
 | 
			
		||||
    /// the identity of the node and defeat the private route.
 | 
			
		||||
    #[instrument(level = "trace", skip(self), ret, err)]
 | 
			
		||||
    pub async fn rpc_call_find_node(
 | 
			
		||||
        self,
 | 
			
		||||
        dest: Destination,
 | 
			
		||||
        key: DHTKey,
 | 
			
		||||
    ) -> Result<NetworkResult<Answer<Vec<PeerInfo>>>, RPCError> {
 | 
			
		||||
        // Ensure destination never has a private route
 | 
			
		||||
        if matches!(
 | 
			
		||||
            dest,
 | 
			
		||||
            Destination::PrivateRoute {
 | 
			
		||||
                private_route: _,
 | 
			
		||||
                safety_selection: _
 | 
			
		||||
            }
 | 
			
		||||
        ) {
 | 
			
		||||
            return Err(RPCError::internal(
 | 
			
		||||
                "Never send find node requests over private routes",
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let find_node_q_detail =
 | 
			
		||||
            RPCQuestionDetail::FindNodeQ(RPCOperationFindNodeQ { node_id: key });
 | 
			
		||||
        let find_node_q = RPCQuestion::new(RespondTo::Sender, find_node_q_detail);
 | 
			
		||||
@@ -51,6 +68,23 @@ impl RPCProcessor {
 | 
			
		||||
 | 
			
		||||
    #[instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id, res), err)]
 | 
			
		||||
    pub(crate) async fn process_find_node_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
 | 
			
		||||
        // Ensure this never came over a private route
 | 
			
		||||
        match msg.header.detail {
 | 
			
		||||
            RPCMessageHeaderDetail::Direct(_) => todo!(),
 | 
			
		||||
            RPCMessageHeaderDetail::PrivateRouted(_) => todo!(),
 | 
			
		||||
        }
 | 
			
		||||
        if matches!(
 | 
			
		||||
            dest,
 | 
			
		||||
            Destination::PrivateRoute {
 | 
			
		||||
                private_route: _,
 | 
			
		||||
                safety_selection: _
 | 
			
		||||
            }
 | 
			
		||||
        ) {
 | 
			
		||||
            return Err(RPCError::internal(
 | 
			
		||||
                "Never send find node requests over private routes",
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Get the question
 | 
			
		||||
        let find_node_q = match msg.operation.kind() {
 | 
			
		||||
            RPCOperationKind::Question(q) => match q.detail() {
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ impl RPCProcessor {
 | 
			
		||||
    pub(crate) async fn process_node_info_update(&self, msg: RPCMessage) -> Result<(), RPCError> {
 | 
			
		||||
        let detail = match msg.header.detail {
 | 
			
		||||
            RPCMessageHeaderDetail::Direct(detail) => detail,
 | 
			
		||||
            RPCMessageHeaderDetail::PrivateRoute(_) => {
 | 
			
		||||
            RPCMessageHeaderDetail::PrivateRouted(_) => {
 | 
			
		||||
                return Err(RPCError::protocol("node_info_update must be direct"));
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ impl RPCProcessor {
 | 
			
		||||
                        .await => {}
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            RPCMessageHeaderDetail::PrivateRoute(detail) => {
 | 
			
		||||
            RPCMessageHeaderDetail::PrivateRouted(detail) => {
 | 
			
		||||
                network_result_value_or_log!(debug
 | 
			
		||||
                    network_manager
 | 
			
		||||
                        .handle_private_receipt(receipt, detail.private_route)
 | 
			
		||||
 
 | 
			
		||||
@@ -227,7 +227,7 @@ impl RPCProcessor {
 | 
			
		||||
        ))?;
 | 
			
		||||
 | 
			
		||||
        // Pass message to RPC system
 | 
			
		||||
        self.enqueue_private_route_message(private_route.public_key, safety_selection, body)
 | 
			
		||||
        self.enqueue_private_routed_message(private_route.public_key, safety_selection, body)
 | 
			
		||||
            .map_err(RPCError::internal)?;
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
@@ -238,7 +238,7 @@ impl RPCProcessor {
 | 
			
		||||
        // Get header detail, must be direct and not inside a route itself
 | 
			
		||||
        let detail = match msg.header.detail {
 | 
			
		||||
            RPCMessageHeaderDetail::Direct(detail) => detail,
 | 
			
		||||
            RPCMessageHeaderDetail::PrivateRoute(_) => {
 | 
			
		||||
            RPCMessageHeaderDetail::SafetyRouted(_) | RPCMessageHeaderDetail::PrivateRouted(_) => {
 | 
			
		||||
                return Err(RPCError::protocol(
 | 
			
		||||
                    "route operation can not be inside route",
 | 
			
		||||
                ))
 | 
			
		||||
 
 | 
			
		||||
@@ -105,7 +105,7 @@ impl RPCProcessor {
 | 
			
		||||
    pub(crate) async fn process_status_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
 | 
			
		||||
        let detail = match &msg.header.detail {
 | 
			
		||||
            RPCMessageHeaderDetail::Direct(detail) => detail,
 | 
			
		||||
            RPCMessageHeaderDetail::PrivateRoute(_) => {
 | 
			
		||||
            RPCMessageHeaderDetail::PrivateRouted(_) => {
 | 
			
		||||
                return Err(RPCError::protocol("status_q must be direct"));
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ impl RPCProcessor {
 | 
			
		||||
    pub(crate) async fn process_validate_dial_info(&self, msg: RPCMessage) -> Result<(), RPCError> {
 | 
			
		||||
        let detail = match msg.header.detail {
 | 
			
		||||
            RPCMessageHeaderDetail::Direct(detail) => detail,
 | 
			
		||||
            RPCMessageHeaderDetail::PrivateRoute(_) => {
 | 
			
		||||
            RPCMessageHeaderDetail::SafetyRouted(_) | RPCMessageHeaderDetail::PrivateRouted(_) => {
 | 
			
		||||
                return Err(RPCError::protocol("validate_dial_info must be direct"));
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user