checkpoint
This commit is contained in:
parent
d96b83fb4e
commit
ec58574a5e
@ -208,8 +208,15 @@ impl RouteSpecStore {
|
||||
}
|
||||
|
||||
pub async fn load(routing_table: RoutingTable) -> EyreResult<RouteSpecStore> {
|
||||
let config = routing_table.network_manager().config();
|
||||
let c = config.get();
|
||||
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,20 +799,29 @@ 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,
|
||||
};
|
||||
|
||||
NetworkResult::value(Destination::private_route(
|
||||
pr.clone(),
|
||||
detail.safety_selection.clone(),
|
||||
))
|
||||
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(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
private_route,
|
||||
safety_selection,
|
||||
}),
|
||||
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"));
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user