mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-02-08 10:55:31 -05:00
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> {
|
pub async fn load(routing_table: RoutingTable) -> EyreResult<RouteSpecStore> {
|
||||||
let config = routing_table.network_manager().config();
|
let (max_route_hop_count, default_route_hop_count) = {
|
||||||
let c = config.get();
|
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
|
// Get cbor blob from table store
|
||||||
let table_store = routing_table.network_manager().table_store();
|
let table_store = routing_table.network_manager().table_store();
|
||||||
let rsstdb = table_store.open("RouteSpecStore", 1).await?;
|
let rsstdb = table_store.open("RouteSpecStore", 1).await?;
|
||||||
@ -251,8 +258,8 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
let rss = RouteSpecStore {
|
let rss = RouteSpecStore {
|
||||||
unlocked_inner: Arc::new(RouteSpecStoreUnlockedInner {
|
unlocked_inner: Arc::new(RouteSpecStoreUnlockedInner {
|
||||||
max_route_hop_count: c.network.rpc.max_route_hop_count.into(),
|
max_route_hop_count,
|
||||||
default_route_hop_count: c.network.rpc.default_route_hop_count.into(),
|
default_route_hop_count,
|
||||||
routing_table,
|
routing_table,
|
||||||
}),
|
}),
|
||||||
inner: Arc::new(Mutex::new(inner)),
|
inner: Arc::new(Mutex::new(inner)),
|
||||||
|
@ -52,8 +52,16 @@ struct RPCMessageHeaderDetailDirect {
|
|||||||
routing_domain: RoutingDomain,
|
routing_domain: RoutingDomain,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Header details for rpc messages received over only a safety route but not a private route
|
||||||
#[derive(Debug, Clone)]
|
#[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
|
/// The private route we received the rpc over
|
||||||
private_route: DHTKey,
|
private_route: DHTKey,
|
||||||
// The safety selection for replying to this private routed rpc
|
// The safety selection for replying to this private routed rpc
|
||||||
@ -63,7 +71,8 @@ struct RPCMessageHeaderDetailPrivateRoute {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum RPCMessageHeaderDetail {
|
enum RPCMessageHeaderDetail {
|
||||||
Direct(RPCMessageHeaderDetailDirect),
|
Direct(RPCMessageHeaderDetailDirect),
|
||||||
PrivateRoute(RPCMessageHeaderDetailPrivateRoute),
|
SafetyRouted(RPCMessageHeaderDetailSafetyRouted),
|
||||||
|
PrivateRouted(RPCMessageHeaderDetailPrivateRouted),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The decoded header of an RPC message
|
/// The decoded header of an RPC message
|
||||||
@ -766,10 +775,11 @@ impl RPCProcessor {
|
|||||||
// Parse out the header detail from the question
|
// Parse out the header detail from the question
|
||||||
let detail = match &request.header.detail {
|
let detail = match &request.header.detail {
|
||||||
RPCMessageHeaderDetail::Direct(detail) => 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
|
// If this was sent via a private route, we don't know what the sender was, so drop this
|
||||||
return NetworkResult::invalid_message(
|
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) => {
|
RespondTo::PrivateRoute(pr) => {
|
||||||
let detail = match &request.header.detail {
|
match &request.header.detail {
|
||||||
RPCMessageHeaderDetail::Direct(_) => {
|
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(
|
return NetworkResult::invalid_message(
|
||||||
"not responding to private route from direct question",
|
"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(
|
NetworkResult::value(Destination::private_route(
|
||||||
pr.clone(),
|
pr.clone(),
|
||||||
detail.safety_selection.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,
|
opt_sender_nr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RPCMessageHeaderDetail::PrivateRoute(_) => {
|
RPCMessageHeaderDetail::SafetyRouted(_) | RPCMessageHeaderDetail::PrivateRouted(_) => {
|
||||||
// Decode the RPC message
|
// Decode the RPC message
|
||||||
let operation = {
|
let operation = {
|
||||||
let reader = capnp::message::Reader::new(encoded_msg.data, Default::default());
|
let reader = capnp::message::Reader::new(encoded_msg.data, Default::default());
|
||||||
@ -1047,7 +1066,38 @@ impl RPCProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self, body), err)]
|
#[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,
|
&self,
|
||||||
private_route: DHTKey,
|
private_route: DHTKey,
|
||||||
safety_selection: SafetySelection,
|
safety_selection: SafetySelection,
|
||||||
@ -1055,10 +1105,12 @@ impl RPCProcessor {
|
|||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
let msg = RPCMessageEncoded {
|
let msg = RPCMessageEncoded {
|
||||||
header: RPCMessageHeader {
|
header: RPCMessageHeader {
|
||||||
detail: RPCMessageHeaderDetail::PrivateRoute(RPCMessageHeaderDetailPrivateRoute {
|
detail: RPCMessageHeaderDetail::PrivateRouted(
|
||||||
private_route,
|
RPCMessageHeaderDetailPrivateRouted {
|
||||||
safety_selection,
|
private_route,
|
||||||
}),
|
safety_selection,
|
||||||
|
},
|
||||||
|
),
|
||||||
timestamp: intf::get_timestamp(),
|
timestamp: intf::get_timestamp(),
|
||||||
body_len: body.len() as u64,
|
body_len: body.len() as u64,
|
||||||
},
|
},
|
||||||
|
@ -1,14 +1,31 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl RPCProcessor {
|
impl RPCProcessor {
|
||||||
// Send FindNodeQ RPC request, receive FindNodeA answer
|
/// Send FindNodeQ RPC request, receive FindNodeA answer
|
||||||
// Can be sent via all methods including relays and routes
|
/// 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)]
|
#[instrument(level = "trace", skip(self), ret, err)]
|
||||||
pub async fn rpc_call_find_node(
|
pub async fn rpc_call_find_node(
|
||||||
self,
|
self,
|
||||||
dest: Destination,
|
dest: Destination,
|
||||||
key: DHTKey,
|
key: DHTKey,
|
||||||
) -> Result<NetworkResult<Answer<Vec<PeerInfo>>>, RPCError> {
|
) -> 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 =
|
let find_node_q_detail =
|
||||||
RPCQuestionDetail::FindNodeQ(RPCOperationFindNodeQ { node_id: key });
|
RPCQuestionDetail::FindNodeQ(RPCOperationFindNodeQ { node_id: key });
|
||||||
let find_node_q = RPCQuestion::new(RespondTo::Sender, find_node_q_detail);
|
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)]
|
#[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> {
|
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
|
// Get the question
|
||||||
let find_node_q = match msg.operation.kind() {
|
let find_node_q = match msg.operation.kind() {
|
||||||
RPCOperationKind::Question(q) => match q.detail() {
|
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> {
|
pub(crate) async fn process_node_info_update(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||||
let detail = match msg.header.detail {
|
let detail = match msg.header.detail {
|
||||||
RPCMessageHeaderDetail::Direct(detail) => detail,
|
RPCMessageHeaderDetail::Direct(detail) => detail,
|
||||||
RPCMessageHeaderDetail::PrivateRoute(_) => {
|
RPCMessageHeaderDetail::PrivateRouted(_) => {
|
||||||
return Err(RPCError::protocol("node_info_update must be direct"));
|
return Err(RPCError::protocol("node_info_update must be direct"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -42,7 +42,7 @@ impl RPCProcessor {
|
|||||||
.await => {}
|
.await => {}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
RPCMessageHeaderDetail::PrivateRoute(detail) => {
|
RPCMessageHeaderDetail::PrivateRouted(detail) => {
|
||||||
network_result_value_or_log!(debug
|
network_result_value_or_log!(debug
|
||||||
network_manager
|
network_manager
|
||||||
.handle_private_receipt(receipt, detail.private_route)
|
.handle_private_receipt(receipt, detail.private_route)
|
||||||
|
@ -227,7 +227,7 @@ impl RPCProcessor {
|
|||||||
))?;
|
))?;
|
||||||
|
|
||||||
// Pass message to RPC system
|
// 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)?;
|
.map_err(RPCError::internal)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -238,7 +238,7 @@ impl RPCProcessor {
|
|||||||
// Get header detail, must be direct and not inside a route itself
|
// Get header detail, must be direct and not inside a route itself
|
||||||
let detail = match msg.header.detail {
|
let detail = match msg.header.detail {
|
||||||
RPCMessageHeaderDetail::Direct(detail) => detail,
|
RPCMessageHeaderDetail::Direct(detail) => detail,
|
||||||
RPCMessageHeaderDetail::PrivateRoute(_) => {
|
RPCMessageHeaderDetail::SafetyRouted(_) | RPCMessageHeaderDetail::PrivateRouted(_) => {
|
||||||
return Err(RPCError::protocol(
|
return Err(RPCError::protocol(
|
||||||
"route operation can not be inside route",
|
"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> {
|
pub(crate) async fn process_status_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||||
let detail = match &msg.header.detail {
|
let detail = match &msg.header.detail {
|
||||||
RPCMessageHeaderDetail::Direct(detail) => detail,
|
RPCMessageHeaderDetail::Direct(detail) => detail,
|
||||||
RPCMessageHeaderDetail::PrivateRoute(_) => {
|
RPCMessageHeaderDetail::PrivateRouted(_) => {
|
||||||
return Err(RPCError::protocol("status_q must be direct"));
|
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> {
|
pub(crate) async fn process_validate_dial_info(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||||
let detail = match msg.header.detail {
|
let detail = match msg.header.detail {
|
||||||
RPCMessageHeaderDetail::Direct(detail) => detail,
|
RPCMessageHeaderDetail::Direct(detail) => detail,
|
||||||
RPCMessageHeaderDetail::PrivateRoute(_) => {
|
RPCMessageHeaderDetail::SafetyRouted(_) | RPCMessageHeaderDetail::PrivateRouted(_) => {
|
||||||
return Err(RPCError::protocol("validate_dial_info must be direct"));
|
return Err(RPCError::protocol("validate_dial_info must be direct"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user