refactor checkpoint
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
use crate::*;
|
||||
use rpc_processor::*;
|
||||
|
||||
pub fn encode_node_status(
|
||||
node_status: &NodeStatus,
|
||||
builder: &mut veilid_capnp::node_status::Builder,
|
||||
pub fn encode_public_internet_node_status(
|
||||
public_internet_node_status: &PublicInternetNodeStatus,
|
||||
builder: &mut veilid_capnp::public_internet_node_status::Builder,
|
||||
) -> Result<(), RPCError> {
|
||||
builder.set_will_route(node_status.will_route);
|
||||
builder.set_will_tunnel(node_status.will_tunnel);
|
||||
@@ -14,10 +14,10 @@ pub fn encode_node_status(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn decode_node_status(
|
||||
reader: &veilid_capnp::node_status::Reader,
|
||||
) -> Result<NodeStatus, RPCError> {
|
||||
Ok(NodeStatus {
|
||||
pub fn decode_public_internet_node_status(
|
||||
reader: &veilid_capnp::public_internet_node_status::Reader,
|
||||
) -> Result<PublicInternetNodeStatus, RPCError> {
|
||||
Ok(PublicInternetNodeStatus {
|
||||
will_route: reader.reborrow().get_will_route(),
|
||||
will_tunnel: reader.reborrow().get_will_tunnel(),
|
||||
will_signal: reader.reborrow().get_will_signal(),
|
||||
@@ -25,3 +25,62 @@ pub fn decode_node_status(
|
||||
will_validate_dial_info: reader.reborrow().get_will_validate_dial_info(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn encode_local_network_node_status(
|
||||
local_network_node_status: &LocalNetworkNodeStatus,
|
||||
builder: &mut veilid_capnp::local_network_node_status::Builder,
|
||||
) -> Result<(), RPCError> {
|
||||
builder.set_will_relay(node_status.will_relay);
|
||||
builder.set_will_validate_dial_info(node_status.will_validate_dial_info);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn decode_local_network_node_status(
|
||||
reader: &veilid_capnp::local_network_node_status::Reader,
|
||||
) -> Result<LocalNetworkNodeStatus, RPCError> {
|
||||
Ok(NodeStatus {
|
||||
will_relay: reader.reborrow().get_will_relay(),
|
||||
will_validate_dial_info: reader.reborrow().get_will_validate_dial_info(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn encode_node_status(
|
||||
node_status: &NodeStatus,
|
||||
builder: &mut veilid_capnp::node_status::Builder,
|
||||
) -> Result<(), RPCError> {
|
||||
match node_status {
|
||||
NodeStatus::PublicInternetNodeStatus(ns) => {
|
||||
let mut pi_builder = builder.reborrow().init_public_internet();
|
||||
encode_public_internet_node_status(&ns, &mut pi_builder)
|
||||
}
|
||||
NodeStatus::LocalNetworkNodeStatus(ns) => {
|
||||
let mut ln_builder = builder.reborrow().init_local_network();
|
||||
encode_local_network_node_status(&ns, &mut ln_builder)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn decode_node_status(
|
||||
reader: &veilid_capnp::node_status::Reader,
|
||||
) -> Result<NodeStatus, RPCError> {
|
||||
Ok(
|
||||
match reader
|
||||
.which()
|
||||
.map_err(RPCError::map_internal("invalid node status"))?
|
||||
{
|
||||
veilid_capnp::node_status::PublicInternet(pi) => {
|
||||
let r = r.map_err(RPCError::protocol)?;
|
||||
let pins = decode_public_internet_node_status(&r)?;
|
||||
NodeStatus::PublicInternet(pins)
|
||||
}
|
||||
veilid_capnp::node_status::LocalNetwork(ln) => {
|
||||
let r = ln.map_err(RPCError::protocol)?;
|
||||
let lnns = decode_local_network_node_status(&r)?;
|
||||
NodeStatus::LocalNetwork(lnns)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@@ -58,26 +58,34 @@ impl RPCOperationKind {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RPCOperation {
|
||||
op_id: u64,
|
||||
sender_info: Option<SignedNodeInfo>,
|
||||
kind: RPCOperationKind,
|
||||
}
|
||||
|
||||
impl RPCOperation {
|
||||
pub fn new_question(question: RPCQuestion) -> Self {
|
||||
pub fn new_question(question: RPCQuestion, sender_info: Option<SignedNodeInfo>) -> Self {
|
||||
Self {
|
||||
op_id: intf::get_random_u64(),
|
||||
sender_info,
|
||||
kind: RPCOperationKind::Question(question),
|
||||
}
|
||||
}
|
||||
pub fn new_statement(statement: RPCStatement) -> Self {
|
||||
pub fn new_statement(statement: RPCStatement, sender_info: Option<SignedNodeInfo>) -> Self {
|
||||
Self {
|
||||
op_id: intf::get_random_u64(),
|
||||
sender_info,
|
||||
kind: RPCOperationKind::Statement(statement),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_answer(request: &RPCOperation, answer: RPCAnswer) -> Self {
|
||||
pub fn new_answer(
|
||||
request: &RPCOperation,
|
||||
answer: RPCAnswer,
|
||||
sender_info: Option<SignedNodeInfo>,
|
||||
) -> Self {
|
||||
Self {
|
||||
op_id: request.op_id,
|
||||
sender_info,
|
||||
kind: RPCOperationKind::Answer(answer),
|
||||
}
|
||||
}
|
||||
@@ -86,6 +94,10 @@ impl RPCOperation {
|
||||
self.op_id
|
||||
}
|
||||
|
||||
pub fn sender_info(&self) -> Option<&SignedNodeInfo> {
|
||||
self.sender_info.as_ref()
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> &RPCOperationKind {
|
||||
&self.kind
|
||||
}
|
||||
@@ -100,16 +112,32 @@ impl RPCOperation {
|
||||
) -> Result<Self, RPCError> {
|
||||
let op_id = operation_reader.get_op_id();
|
||||
|
||||
let sender_info = if operation_reader.has_sender_info() {
|
||||
let sni_reader = operation_reader.get_sender_info();
|
||||
let sni = decode_signed_node_info(&sni_reader, sender_node_id, true)?;
|
||||
Some(sni)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let kind_reader = operation_reader.get_kind();
|
||||
let kind = RPCOperationKind::decode(&kind_reader, sender_node_id)?;
|
||||
|
||||
Ok(RPCOperation { op_id, kind })
|
||||
Ok(RPCOperation {
|
||||
op_id,
|
||||
sender_info,
|
||||
kind,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn encode(&self, builder: &mut veilid_capnp::operation::Builder) -> Result<(), RPCError> {
|
||||
builder.set_op_id(self.op_id);
|
||||
let mut k_builder = builder.reborrow().init_kind();
|
||||
self.kind.encode(&mut k_builder)?;
|
||||
if let Some(sender_info) = self.sender_info {
|
||||
let si_builder = builder.reborrow().init_sender_info();
|
||||
encode_signed_node_info(&self.sender_info, &mut si_builder)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@@ -18,12 +18,6 @@ impl RPCQuestion {
|
||||
pub fn detail(&self) -> &RPCQuestionDetail {
|
||||
&self.detail
|
||||
}
|
||||
// pub fn into_detail(self) -> RPCQuestionDetail {
|
||||
// self.detail
|
||||
// }
|
||||
// pub fn into_respond_to_detail(self) -> (RespondTo, RPCQuestionDetail) {
|
||||
// (self.respond_to, self.detail)
|
||||
// }
|
||||
pub fn desc(&self) -> &'static str {
|
||||
self.detail.desc()
|
||||
}
|
||||
@@ -32,7 +26,7 @@ impl RPCQuestion {
|
||||
sender_node_id: &DHTKey,
|
||||
) -> Result<RPCQuestion, RPCError> {
|
||||
let rt_reader = reader.get_respond_to();
|
||||
let respond_to = RespondTo::decode(&rt_reader, sender_node_id)?;
|
||||
let respond_to = RespondTo::decode(&rt_reader)?;
|
||||
let d_reader = reader.get_detail();
|
||||
let detail = RPCQuestionDetail::decode(&d_reader)?;
|
||||
Ok(RPCQuestion { respond_to, detail })
|
||||
|
@@ -3,7 +3,7 @@ use rpc_processor::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum RespondTo {
|
||||
Sender(Option<SignedNodeInfo>),
|
||||
Sender,
|
||||
PrivateRoute(PrivateRoute),
|
||||
}
|
||||
|
||||
@@ -13,11 +13,7 @@ impl RespondTo {
|
||||
builder: &mut veilid_capnp::question::respond_to::Builder,
|
||||
) -> Result<(), RPCError> {
|
||||
match self {
|
||||
Self::Sender(Some(sni)) => {
|
||||
let mut sni_builder = builder.reborrow().init_sender_with_info();
|
||||
encode_signed_node_info(sni, &mut sni_builder)?;
|
||||
}
|
||||
Self::Sender(None) => {
|
||||
Self::Sender => {
|
||||
builder.reborrow().set_sender(());
|
||||
}
|
||||
Self::PrivateRoute(pr) => {
|
||||
@@ -28,17 +24,9 @@ impl RespondTo {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::question::respond_to::Reader,
|
||||
sender_node_id: &DHTKey,
|
||||
) -> Result<Self, RPCError> {
|
||||
pub fn decode(reader: &veilid_capnp::question::respond_to::Reader) -> Result<Self, RPCError> {
|
||||
let respond_to = match reader.which().map_err(RPCError::protocol)? {
|
||||
veilid_capnp::question::respond_to::Sender(()) => RespondTo::Sender(None),
|
||||
veilid_capnp::question::respond_to::SenderWithInfo(sender_ni_reader) => {
|
||||
let sender_ni_reader = sender_ni_reader.map_err(RPCError::protocol)?;
|
||||
let sni = decode_signed_node_info(&sender_ni_reader, sender_node_id, true)?;
|
||||
RespondTo::Sender(Some(sni))
|
||||
}
|
||||
veilid_capnp::question::respond_to::Sender(()) => RespondTo::Sender,
|
||||
veilid_capnp::question::respond_to::PrivateRoute(pr_reader) => {
|
||||
let pr_reader = pr_reader.map_err(RPCError::protocol)?;
|
||||
let pr = decode_private_route(&pr_reader)?;
|
||||
|
135
veilid-core/src/rpc_processor/destination.rs
Normal file
135
veilid-core/src/rpc_processor/destination.rs
Normal file
@@ -0,0 +1,135 @@
|
||||
use super::*;
|
||||
|
||||
/// Where to send an RPC message
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Destination {
|
||||
/// Send to node directly
|
||||
Direct {
|
||||
/// The node to send to
|
||||
target: NodeRef,
|
||||
/// An optional safety route specification to send from for sender privacy
|
||||
safety_route_spec: Option<Arc<SafetyRouteSpec>>,
|
||||
},
|
||||
/// Send to node for relay purposes
|
||||
Relay {
|
||||
/// The relay to send to
|
||||
relay: NodeRef,
|
||||
/// The final destination the relay should send to
|
||||
target: DHTKey,
|
||||
/// An optional safety route specification to send from for sender privacy
|
||||
safety_route_spec: Option<Arc<SafetyRouteSpec>>,
|
||||
},
|
||||
/// Send to private route (privateroute)
|
||||
PrivateRoute {
|
||||
/// A private route to send to
|
||||
private_route: PrivateRoute,
|
||||
/// An optional safety route specification to send from for sender privacy
|
||||
safety_route_spec: Option<Arc<SafetyRouteSpec>>,
|
||||
},
|
||||
}
|
||||
|
||||
impl Destination {
|
||||
pub fn direct(target: NodeRef) -> Self {
|
||||
Self::Direct {
|
||||
target,
|
||||
safety_route_spec: None,
|
||||
}
|
||||
}
|
||||
pub fn relay(relay: NodeRef, target: DHTKey) -> Self {
|
||||
Self::Relay {
|
||||
relay,
|
||||
target,
|
||||
safety_route_spec: None,
|
||||
}
|
||||
}
|
||||
pub fn private_route(private_route: PrivateRoute) -> Self {
|
||||
Self::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn safety_route_spec(&self) -> Option<Arc<SafetyRouteSpec>> {
|
||||
match self {
|
||||
Destination::Direct {
|
||||
target,
|
||||
safety_route_spec,
|
||||
} => safety_route_spec.clone(),
|
||||
Destination::Relay {
|
||||
relay,
|
||||
target,
|
||||
safety_route_spec,
|
||||
} => safety_route_spec.clone(),
|
||||
Destination::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec,
|
||||
} => safety_route_spec.clone(),
|
||||
}
|
||||
}
|
||||
pub fn with_safety_route_spec(self, safety_route_spec: Arc<SafetyRouteSpec>) -> Self {
|
||||
match self {
|
||||
Destination::Direct {
|
||||
target,
|
||||
safety_route_spec: _,
|
||||
} => Self::Direct {
|
||||
target,
|
||||
safety_route_spec: Some(safety_route_spec),
|
||||
},
|
||||
Destination::Relay {
|
||||
relay,
|
||||
target,
|
||||
safety_route_spec: _,
|
||||
} => Self::Relay {
|
||||
relay,
|
||||
target,
|
||||
safety_route_spec: Some(safety_route_spec),
|
||||
},
|
||||
Destination::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec: _,
|
||||
} => Self::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec: Some(safety_route_spec),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Destination {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Destination::Direct {
|
||||
target,
|
||||
routing_domain,
|
||||
safety_route_spec,
|
||||
} => {
|
||||
let sr = safety_route_spec
|
||||
.map(|_sr| "+SR".to_owned())
|
||||
.unwrap_or_default();
|
||||
|
||||
write!(f, "{:?}{}", target, sr)
|
||||
}
|
||||
Destination::Relay {
|
||||
relay,
|
||||
target,
|
||||
safety_route_spec,
|
||||
} => {
|
||||
let sr = safety_route_spec
|
||||
.map(|_sr| "+SR".to_owned())
|
||||
.unwrap_or_default();
|
||||
|
||||
write!(f, "{:?}@{:?}{}", target.encode(), relay, sr)
|
||||
}
|
||||
Destination::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec,
|
||||
} => {
|
||||
let sr = safety_route_spec
|
||||
.map(|_sr| "+SR".to_owned())
|
||||
.unwrap_or_default();
|
||||
|
||||
write!(f, "{}{}", private_route, sr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
mod coders;
|
||||
mod destination;
|
||||
mod private_route;
|
||||
mod rpc_cancel_tunnel;
|
||||
mod rpc_complete_tunnel;
|
||||
@@ -18,6 +19,7 @@ mod rpc_validate_dial_info;
|
||||
mod rpc_value_changed;
|
||||
mod rpc_watch_value;
|
||||
|
||||
pub use destination::*;
|
||||
pub use private_route::*;
|
||||
pub use rpc_error::*;
|
||||
|
||||
@@ -36,208 +38,6 @@ use stop_token::future::FutureExt;
|
||||
|
||||
type OperationId = u64;
|
||||
|
||||
/// Where to send an RPC message
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Destination {
|
||||
/// Send to node directly
|
||||
Direct {
|
||||
/// The node to send to
|
||||
target: NodeRef,
|
||||
/// An optional routing domain to require
|
||||
routing_domain: Option<RoutingDomain>,
|
||||
/// An optional safety route specification to send from for sender privacy
|
||||
safety_route_spec: Option<Arc<SafetyRouteSpec>>,
|
||||
},
|
||||
/// Send to node for relay purposes
|
||||
Relay {
|
||||
/// The relay to send to
|
||||
relay: NodeRef,
|
||||
/// The final destination the relay should send to
|
||||
target: DHTKey,
|
||||
/// An optional routing domain to require
|
||||
routing_domain: Option<RoutingDomain>,
|
||||
/// An optional safety route specification to send from for sender privacy
|
||||
safety_route_spec: Option<Arc<SafetyRouteSpec>>,
|
||||
},
|
||||
/// Send to private route (privateroute)
|
||||
PrivateRoute {
|
||||
/// A private route to send to
|
||||
private_route: PrivateRoute,
|
||||
/// An optional safety route specification to send from for sender privacy
|
||||
safety_route_spec: Option<Arc<SafetyRouteSpec>>,
|
||||
},
|
||||
}
|
||||
|
||||
impl Destination {
|
||||
pub fn direct(target: NodeRef) -> Self {
|
||||
Self::Direct {
|
||||
target,
|
||||
routing_domain: None,
|
||||
safety_route_spec: None,
|
||||
}
|
||||
}
|
||||
pub fn relay(relay: NodeRef, target: DHTKey) -> Self {
|
||||
Self::Relay {
|
||||
relay,
|
||||
target,
|
||||
routing_domain: None,
|
||||
safety_route_spec: None,
|
||||
}
|
||||
}
|
||||
pub fn private_route(private_route: PrivateRoute) -> Self {
|
||||
Self::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn
|
||||
|
||||
pub fn routing_domain(&self) -> Option<RoutingDomain> {
|
||||
match self {
|
||||
Destination::Direct {
|
||||
target,
|
||||
routing_domain,
|
||||
safety_route_spec,
|
||||
} => *routing_domain,
|
||||
Destination::Relay {
|
||||
relay,
|
||||
target,
|
||||
routing_domain,
|
||||
safety_route_spec,
|
||||
} => *routing_domain,
|
||||
Destination::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec,
|
||||
} => Some(RoutingDomain::PublicInternet),
|
||||
}
|
||||
}
|
||||
pub fn safety_route_spec(&self) -> Option<Arc<SafetyRouteSpec>> {
|
||||
match self {
|
||||
Destination::Direct {
|
||||
target,
|
||||
routing_domain,
|
||||
safety_route_spec,
|
||||
} => safety_route_spec.clone(),
|
||||
Destination::Relay {
|
||||
relay,
|
||||
target,
|
||||
routing_domain,
|
||||
safety_route_spec,
|
||||
} => safety_route_spec.clone(),
|
||||
Destination::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec,
|
||||
} => safety_route_spec.clone(),
|
||||
}
|
||||
}
|
||||
pub fn with_routing_domain(self, routing_domain: RoutingDomain) -> Self {
|
||||
match self {
|
||||
Destination::Direct {
|
||||
target,
|
||||
routing_domain: _,
|
||||
safety_route_spec,
|
||||
} => Self::Direct {
|
||||
target,
|
||||
routing_domain: Some(routing_domain),
|
||||
safety_route_spec,
|
||||
},
|
||||
Destination::Relay {
|
||||
relay,
|
||||
target,
|
||||
routing_domain: _,
|
||||
safety_route_spec,
|
||||
} => Self::Relay {
|
||||
relay,
|
||||
target,
|
||||
routing_domain: Some(routing_domain),
|
||||
safety_route_spec,
|
||||
},
|
||||
Destination::PrivateRoute {
|
||||
private_route: _,
|
||||
safety_route_spec: _,
|
||||
} => panic!("Private route is only valid in PublicInternet routing domain"),
|
||||
}
|
||||
}
|
||||
pub fn with_safety_route_spec(self, safety_route_spec: Arc<SafetyRouteSpec>) -> Self {
|
||||
match self {
|
||||
Destination::Direct {
|
||||
target,
|
||||
routing_domain,
|
||||
safety_route_spec: _,
|
||||
} => Self::Direct {
|
||||
target,
|
||||
routing_domain,
|
||||
safety_route_spec: Some(safety_route_spec),
|
||||
},
|
||||
Destination::Relay {
|
||||
relay,
|
||||
target,
|
||||
routing_domain,
|
||||
safety_route_spec: _,
|
||||
} => Self::Relay {
|
||||
relay,
|
||||
target,
|
||||
routing_domain,
|
||||
safety_route_spec: Some(safety_route_spec),
|
||||
},
|
||||
Destination::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec: _,
|
||||
} => Self::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec: Some(safety_route_spec),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Destination {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Destination::Direct {
|
||||
target,
|
||||
routing_domain,
|
||||
safety_route_spec,
|
||||
} => {
|
||||
let rd = routing_domain
|
||||
.map(|rd| format!("#{:?}", rd))
|
||||
.unwrap_or_default();
|
||||
let sr = safety_route_spec
|
||||
.map(|_sr| "+SR".to_owned())
|
||||
.unwrap_or_default();
|
||||
|
||||
write!(f, "{:?}{}{}", target, rd, sr)
|
||||
}
|
||||
Destination::Relay {
|
||||
relay,
|
||||
target,
|
||||
routing_domain,
|
||||
safety_route_spec,
|
||||
} => {
|
||||
let rd = routing_domain
|
||||
.map(|rd| format!("#{:?}", rd))
|
||||
.unwrap_or_default();
|
||||
let sr = safety_route_spec
|
||||
.map(|_sr| "+SR".to_owned())
|
||||
.unwrap_or_default();
|
||||
|
||||
write!(f, "{:?}@{:?}{}{}", target.encode(), relay, rd, sr)
|
||||
}
|
||||
Destination::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec,
|
||||
} => {
|
||||
let sr = safety_route_spec
|
||||
.map(|_sr| "+SR".to_owned())
|
||||
.unwrap_or_default();
|
||||
|
||||
write!(f, "{}{}", private_route, sr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The decoded header of an RPC message
|
||||
#[derive(Debug, Clone)]
|
||||
struct RPCMessageHeader {
|
||||
@@ -251,6 +51,8 @@ struct RPCMessageHeader {
|
||||
peer_noderef: NodeRef,
|
||||
/// The connection from the peer sent the message (not the original sender)
|
||||
connection_descriptor: ConnectionDescriptor,
|
||||
/// The routing domain the message was sent through
|
||||
routing_domain: RoutingDomain,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -352,7 +154,6 @@ pub struct RPCProcessorInner {
|
||||
pub struct RPCProcessor {
|
||||
crypto: Crypto,
|
||||
config: VeilidConfig,
|
||||
enable_local_peer_scope: bool,
|
||||
inner: Arc<Mutex<RPCProcessorInner>>,
|
||||
}
|
||||
|
||||
@@ -375,11 +176,6 @@ impl RPCProcessor {
|
||||
Self {
|
||||
crypto: network_manager.crypto(),
|
||||
config: network_manager.config(),
|
||||
enable_local_peer_scope: network_manager
|
||||
.config()
|
||||
.get()
|
||||
.network
|
||||
.enable_local_peer_scope,
|
||||
inner: Arc::new(Mutex::new(Self::new_inner(network_manager))),
|
||||
}
|
||||
}
|
||||
@@ -402,12 +198,8 @@ impl RPCProcessor {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
fn filter_peer_scope(&self, node_info: &NodeInfo) -> bool {
|
||||
// if local peer scope is enabled, then don't reject any peer info
|
||||
if self.enable_local_peer_scope {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Determine if a NodeInfo can be placed into the specified routing domain
|
||||
fn filter_node_info(&self, routing_domain: RoutingDomain, node_info: &NodeInfo) -> bool {
|
||||
// reject attempts to include non-public addresses in results
|
||||
for did in &node_info.dial_info_detail_list {
|
||||
if !did.dial_info.is_global() {
|
||||
@@ -584,31 +376,6 @@ impl RPCProcessor {
|
||||
out
|
||||
}
|
||||
|
||||
/// Gets a 'RespondTo::Sender' that contains either our dial info,
|
||||
/// or None if the peer has seen our dial info before or our node info is not yet valid
|
||||
/// because of an unknown network class
|
||||
pub fn make_respond_to_sender(
|
||||
&self,
|
||||
routing_domain: RoutingDomain,
|
||||
peer: NodeRef,
|
||||
) -> RespondTo {
|
||||
if peer.has_seen_our_node_info(routing_domain)
|
||||
|| matches!(
|
||||
self.network_manager()
|
||||
.get_network_class(routing_domain)
|
||||
.unwrap_or(NetworkClass::Invalid),
|
||||
NetworkClass::Invalid
|
||||
)
|
||||
{
|
||||
RespondTo::Sender(None)
|
||||
} else {
|
||||
let our_sni = self
|
||||
.routing_table()
|
||||
.get_own_signed_node_info(routing_domain);
|
||||
RespondTo::Sender(Some(our_sni))
|
||||
}
|
||||
}
|
||||
|
||||
/// Produce a byte buffer that represents the wire encoding of the entire
|
||||
/// unencrypted envelope body for a RPC message. This incorporates
|
||||
/// wrapping a private and/or safety route if they are specified.
|
||||
@@ -617,7 +384,7 @@ impl RPCProcessor {
|
||||
&self,
|
||||
dest: Destination,
|
||||
operation: &RPCOperation,
|
||||
) -> Result<RenderedOperation, RPCError> { xxx continue propagating safetyroutespec
|
||||
) -> Result<RenderedOperation, RPCError> {
|
||||
let out_node_id; // Envelope Node Id
|
||||
let mut out_node_ref: Option<NodeRef> = None; // Node to send envelope to
|
||||
let out_hop_count: usize; // Total safety + private route hop count
|
||||
@@ -634,12 +401,28 @@ impl RPCProcessor {
|
||||
|
||||
// To where are we sending the request
|
||||
match dest {
|
||||
Destination::Direct(ref node_ref) | Destination::Relay(ref node_ref, _) => {
|
||||
Destination::Direct {
|
||||
target: node_ref,
|
||||
routing_domain,
|
||||
safety_route_spec,
|
||||
}
|
||||
| Destination::Relay {
|
||||
relay: node_ref,
|
||||
target: _,
|
||||
routing_domain,
|
||||
safety_route_spec,
|
||||
} => {
|
||||
// Send to a node without a private route
|
||||
// --------------------------------------
|
||||
|
||||
// Get the actual destination node id accounting for relays
|
||||
let (node_ref, node_id) = if let Destination::Relay(_, dht_key) = dest {
|
||||
let (node_ref, node_id) = if let Destination::Relay {
|
||||
relay: _,
|
||||
target: dht_key,
|
||||
routing_domain: _,
|
||||
safety_route_spec: _,
|
||||
} = dest
|
||||
{
|
||||
(node_ref.clone(), dht_key.clone())
|
||||
} else {
|
||||
let node_id = node_ref.node_id();
|
||||
@@ -676,7 +459,10 @@ impl RPCProcessor {
|
||||
}
|
||||
};
|
||||
}
|
||||
Destination::PrivateRoute(private_route) => {
|
||||
Destination::PrivateRoute {
|
||||
private_route,
|
||||
safety_route_spec,
|
||||
} => {
|
||||
// Send to private route
|
||||
// ---------------------
|
||||
// Reply with 'route' operation
|
||||
@@ -723,12 +509,22 @@ impl RPCProcessor {
|
||||
}
|
||||
|
||||
// Issue a question over the network, possibly using an anonymized route
|
||||
#[instrument(level = "debug", skip(self, question, safety_route_spec), err)]
|
||||
#[instrument(level = "debug", skip(self, question), err)]
|
||||
async fn question(
|
||||
&self,
|
||||
dest: Destination,
|
||||
question: RPCQuestion,
|
||||
) -> Result<NetworkResult<WaitableReply>, RPCError> {
|
||||
|
||||
// Get sender info if we should send that
|
||||
let opt_sender_info = if dest.safety_route_spec().is_none() && matches!(question.respond_to(), RespondTo::Sender) {
|
||||
// Sender is not private, send sender info if needed
|
||||
// Get the noderef of the eventual destination or first route hop
|
||||
if let Some(target_nr) = self.routing_table().lookup_node_ref(dest.get_target_id()) {
|
||||
if target_nr.has_seen_our_node_info(R)
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap question in operation
|
||||
let operation = RPCOperation::new_question(question);
|
||||
let op_id = operation.op_id();
|
||||
@@ -951,6 +747,10 @@ impl RPCProcessor {
|
||||
&self,
|
||||
encoded_msg: RPCMessageEncoded,
|
||||
) -> Result<(), RPCError> {
|
||||
|
||||
// Get the routing domain
|
||||
let routing_domain = encoded_msg.header.routing_domain;
|
||||
|
||||
// Decode the operation
|
||||
let sender_node_id = encoded_msg.header.envelope.get_sender_id();
|
||||
|
||||
@@ -971,12 +771,13 @@ impl RPCProcessor {
|
||||
match q.respond_to() {
|
||||
RespondTo::Sender(Some(sender_ni)) => {
|
||||
// Sender NodeInfo was specified, update our routing table with it
|
||||
if !self.filter_peer_scope(&sender_ni.node_info) {
|
||||
if !self.filter_node_info(&sender_ni.node_info) {
|
||||
return Err(RPCError::invalid_format(
|
||||
"respond_to_sender_signed_node_info has invalid peer scope",
|
||||
));
|
||||
}
|
||||
opt_sender_nr = self.routing_table().register_node_with_signed_node_info(
|
||||
routing_domain,
|
||||
sender_node_id,
|
||||
sender_ni.clone(),
|
||||
false,
|
||||
@@ -1168,6 +969,7 @@ impl RPCProcessor {
|
||||
body: Vec<u8>,
|
||||
peer_noderef: NodeRef,
|
||||
connection_descriptor: ConnectionDescriptor,
|
||||
routing_domain: RoutingDomain,
|
||||
) -> EyreResult<()> {
|
||||
let msg = RPCMessageEncoded {
|
||||
header: RPCMessageHeader {
|
||||
@@ -1176,6 +978,7 @@ impl RPCProcessor {
|
||||
body_len: body.len() as u64,
|
||||
peer_noderef,
|
||||
connection_descriptor,
|
||||
routing_domain,
|
||||
},
|
||||
data: RPCMessageData { contents: body },
|
||||
};
|
||||
|
@@ -4,7 +4,7 @@ impl RPCProcessor {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
fn compile_safety_route(
|
||||
&self,
|
||||
safety_route_spec: &SafetyRouteSpec,
|
||||
safety_route_spec: Arc<SafetyRouteSpec>,
|
||||
private_route: PrivateRoute,
|
||||
) -> Result<SafetyRoute, RPCError> {
|
||||
// Ensure the total hop count isn't too long for our config
|
||||
@@ -111,15 +111,15 @@ impl RPCProcessor {
|
||||
// Wrap an operation inside a route
|
||||
pub(super) fn wrap_with_route(
|
||||
&self,
|
||||
safety_route_spec: Option<&SafetyRouteSpec>,
|
||||
safety_route_spec: Option<Arc<SafetyRouteSpec>>,
|
||||
private_route: PrivateRoute,
|
||||
message_data: Vec<u8>,
|
||||
) -> Result<Vec<u8>, RPCError> {
|
||||
// Encrypt routed operation
|
||||
// Xmsg + ENC(Xmsg, DH(PKapr, SKbsr))
|
||||
let nonce = Crypto::get_random_nonce();
|
||||
let stub_safety_route_spec = SafetyRouteSpec::new();
|
||||
let safety_route_spec = safety_route_spec.unwrap_or(&stub_safety_route_spec);
|
||||
let safety_route_spec =
|
||||
safety_route_spec.unwrap_or_else(|| Arc::new(SafetyRouteSpec::new()));
|
||||
let dh_secret = self
|
||||
.crypto
|
||||
.cached_dh(&private_route.public_key, &safety_route_spec.secret_key)
|
||||
|
@@ -8,15 +8,11 @@ impl RPCProcessor {
|
||||
self,
|
||||
dest: Destination,
|
||||
key: DHTKey,
|
||||
safety_route: Option<&SafetyRouteSpec>,
|
||||
respond_to: RespondTo,
|
||||
) -> Result<NetworkResult<Answer<Vec<PeerInfo>>>, RPCError> {
|
||||
let find_node_q = RPCOperationFindNodeQ { node_id: key };
|
||||
let question = RPCQuestion::new(respond_to, RPCQuestionDetail::FindNodeQ(find_node_q));
|
||||
let find_node_q = RPCQuestionDetail::FindNodeQ(RPCOperationFindNodeQ { node_id: key });
|
||||
|
||||
// Send the find_node request
|
||||
let waitable_reply =
|
||||
network_result_try!(self.question(dest, question, safety_route).await?);
|
||||
let waitable_reply = network_result_try!(self.question(dest, find_node_q).await?);
|
||||
|
||||
// Wait for reply
|
||||
let (msg, latency) = match self.wait_for_reply(waitable_reply).await? {
|
||||
@@ -35,7 +31,7 @@ impl RPCProcessor {
|
||||
|
||||
// Verify peers are in the correct peer scope
|
||||
for peer_info in &find_node_a.peers {
|
||||
if !self.filter_peer_scope(&peer_info.signed_node_info.node_info) {
|
||||
if !self.filter_node_info(&peer_info.signed_node_info.node_info) {
|
||||
return Err(RPCError::invalid_format(
|
||||
"find_node response has invalid peer scope",
|
||||
));
|
||||
|
@@ -2,20 +2,20 @@ use super::*;
|
||||
|
||||
impl RPCProcessor {
|
||||
// Sends a our node info to another node
|
||||
// Can be sent via all methods including relays and routes
|
||||
#[instrument(level = "trace", skip(self), ret, err)]
|
||||
pub async fn rpc_call_node_info_update(
|
||||
self,
|
||||
target: NodeRef,
|
||||
routing_domain: RoutingDomain,
|
||||
) -> Result<NetworkResult<()>, RPCError> {
|
||||
// Get the signed node info for the desired routing domain to send update with
|
||||
let signed_node_info = self
|
||||
.routing_table()
|
||||
.get_own_signed_node_info(routing_domain);
|
||||
let node_info_update = RPCOperationNodeInfoUpdate { signed_node_info };
|
||||
let statement = RPCStatement::new(RPCStatementDetail::NodeInfoUpdate(node_info_update));
|
||||
|
||||
// Send the node_info_update request
|
||||
// Send the node_info_update request to the specific routing domain requested
|
||||
network_result_try!(
|
||||
self.statement(
|
||||
Destination::direct(target).with_routing_domain(routing_domain),
|
||||
@@ -41,7 +41,7 @@ impl RPCProcessor {
|
||||
};
|
||||
|
||||
// Update our routing table with signed node info
|
||||
if !self.filter_peer_scope(&node_info_update.signed_node_info.node_info) {
|
||||
if !self.filter_node_info(&node_info_update.signed_node_info.node_info) {
|
||||
log_rpc!(debug
|
||||
"node_info_update has invalid peer scope from {}", sender_node_id
|
||||
);
|
||||
|
@@ -8,14 +8,21 @@ impl RPCProcessor {
|
||||
self,
|
||||
peer: NodeRef,
|
||||
) -> Result<NetworkResult<Answer<SenderInfo>>, RPCError> {
|
||||
let node_status = self.network_manager().generate_node_status();
|
||||
let routing_domain = match peer.best_routing_domain() {
|
||||
Some(rd) => rd,
|
||||
None => {
|
||||
return Ok(NetworkResult::no_connection_other(
|
||||
"no routing domain for peer",
|
||||
))
|
||||
}
|
||||
};
|
||||
let node_status = self.network_manager().generate_node_status(routing_domain);
|
||||
let status_q = RPCOperationStatusQ { node_status };
|
||||
let respond_to = self.make_respond_to_sender(peer.clone());
|
||||
let question = RPCQuestion::new(respond_to, RPCQuestionDetail::StatusQ(status_q));
|
||||
let question = RPCQuestion::new(RespondTo::Sender, RPCQuestionDetail::StatusQ(status_q));
|
||||
|
||||
// Send the info request
|
||||
let waitable_reply = network_result_try!(
|
||||
self.question(Destination::Direct(peer.clone()), question, None)
|
||||
self.question(Destination::direct(peer.clone()), question)
|
||||
.await?
|
||||
);
|
||||
|
||||
@@ -37,26 +44,48 @@ impl RPCProcessor {
|
||||
_ => return Err(RPCError::invalid_format("not an answer")),
|
||||
};
|
||||
|
||||
// Ensure the returned node status is the kind for the routing domain we asked for
|
||||
match routing_domain {
|
||||
RoutingDomain::PublicInternet => {
|
||||
if !matches!(status_a.node_status, NodeStatus::PublicInternet(_)) {
|
||||
return Ok(NetworkResult::invalid_message(
|
||||
"node status doesn't match PublicInternet routing domain",
|
||||
));
|
||||
}
|
||||
}
|
||||
RoutingDomain::LocalNetwork => {
|
||||
if !matches!(status_a.node_status, NodeStatus::LocalNetwork(_)) {
|
||||
return Ok(NetworkResult::invalid_message(
|
||||
"node status doesn't match LocalNetwork routing domain",
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update latest node status in routing table
|
||||
peer.update_node_status(status_a.node_status.clone());
|
||||
peer.update_node_status(status_a.node_status);
|
||||
|
||||
// Report sender_info IP addresses to network manager
|
||||
// Don't need to validate these addresses for the current routing domain
|
||||
// the address itself is irrelevant, and the remote node can lie anyway
|
||||
if let Some(socket_address) = status_a.sender_info.socket_address {
|
||||
match send_data_kind {
|
||||
SendDataKind::Direct(connection_descriptor) => {
|
||||
match connection_descriptor.peer_scope() {
|
||||
PeerScope::Global => self.network_manager().report_global_socket_address(
|
||||
SendDataKind::Direct(connection_descriptor) => match routing_domain {
|
||||
RoutingDomain::PublicInternet => self
|
||||
.network_manager()
|
||||
.report_public_internet_socket_address(
|
||||
socket_address,
|
||||
connection_descriptor,
|
||||
peer,
|
||||
),
|
||||
PeerScope::Local => self.network_manager().report_local_socket_address(
|
||||
RoutingDomain::LocalNetwork => {
|
||||
self.network_manager().report_local_network_socket_address(
|
||||
socket_address,
|
||||
connection_descriptor,
|
||||
peer,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
SendDataKind::Indirect => {
|
||||
// Do nothing in this case, as the socket address returned here would be for any node other than ours
|
||||
}
|
||||
@@ -75,6 +104,7 @@ impl RPCProcessor {
|
||||
#[instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id, res), err)]
|
||||
pub(crate) async fn process_status_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||
let connection_descriptor = msg.header.connection_descriptor;
|
||||
let routing_domain = msg.header.routing_domain;
|
||||
|
||||
// Get the question
|
||||
let status_q = match msg.operation.kind() {
|
||||
@@ -85,6 +115,24 @@ impl RPCProcessor {
|
||||
_ => panic!("not a question"),
|
||||
};
|
||||
|
||||
// Ensure the node status from the question is the kind for the routing domain we received the request in
|
||||
match routing_domain {
|
||||
RoutingDomain::PublicInternet => {
|
||||
if !matches!(status_a.node_status, NodeStatus::PublicInternet(_)) {
|
||||
return Ok(NetworkResult::invalid_message(
|
||||
"node status doesn't match PublicInternet routing domain",
|
||||
));
|
||||
}
|
||||
}
|
||||
RoutingDomain::LocalNetwork => {
|
||||
if !matches!(status_a.node_status, NodeStatus::LocalNetwork(_)) {
|
||||
return Ok(NetworkResult::invalid_message(
|
||||
"node status doesn't match LocalNetwork routing domain",
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update node status for the requesting node to our routing table
|
||||
if let Some(sender_nr) = msg.opt_sender_nr.clone() {
|
||||
// Update latest node status in routing table for the statusq sender
|
||||
@@ -92,7 +140,7 @@ impl RPCProcessor {
|
||||
}
|
||||
|
||||
// Make status answer
|
||||
let node_status = self.network_manager().generate_node_status();
|
||||
let node_status = self.network_manager().generate_node_status(routing_domain);
|
||||
|
||||
// Get the peer address in the returned sender info
|
||||
let sender_info = SenderInfo {
|
||||
@@ -106,11 +154,7 @@ impl RPCProcessor {
|
||||
|
||||
// Send status answer
|
||||
let res = self
|
||||
.answer(
|
||||
msg,
|
||||
RPCAnswer::new(RPCAnswerDetail::StatusA(status_a)),
|
||||
None,
|
||||
)
|
||||
.answer(msg, RPCAnswer::new(RPCAnswerDetail::StatusA(status_a)))
|
||||
.await?;
|
||||
tracing::Span::current().record("res", &tracing::field::display(res));
|
||||
Ok(())
|
||||
|
Reference in New Issue
Block a user