checkpoint

This commit is contained in:
John Smith 2022-11-01 22:42:34 -04:00
parent d96b83fb4e
commit ec58574a5e
8 changed files with 124 additions and 31 deletions

View File

@ -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)),

View File

@ -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,
},

View File

@ -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() {

View File

@ -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"));
}
};

View File

@ -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)

View File

@ -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",
))

View File

@ -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"));
}
};

View File

@ -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"));
}
};