allow revert to invalid nodeinfo
This commit is contained in:
@@ -31,9 +31,19 @@ pub enum Destination {
|
||||
impl Destination {
|
||||
pub fn target(&self) -> Option<NodeRef> {
|
||||
match self {
|
||||
Destination::Direct { target, safety_selection: _ } => Some(target.clone()),
|
||||
Destination::Relay { relay:_, target, safety_selection: _ } => Some(target.clone()),
|
||||
Destination::PrivateRoute { private_route:_, safety_selection:_ } => None,
|
||||
Destination::Direct {
|
||||
target,
|
||||
safety_selection: _,
|
||||
} => Some(target.clone()),
|
||||
Destination::Relay {
|
||||
relay: _,
|
||||
target,
|
||||
safety_selection: _,
|
||||
} => Some(target.clone()),
|
||||
Destination::PrivateRoute {
|
||||
private_route: _,
|
||||
safety_selection: _,
|
||||
} => None,
|
||||
}
|
||||
}
|
||||
pub fn direct(target: NodeRef) -> Self {
|
||||
@@ -217,7 +227,6 @@ impl RPCProcessor {
|
||||
private_route,
|
||||
safety_selection,
|
||||
} => {
|
||||
|
||||
let Some(avoid_node_id) = private_route.first_hop_node_id() else {
|
||||
return Err(RPCError::internal("destination private route must have first hop"));
|
||||
};
|
||||
@@ -227,21 +236,21 @@ impl RPCProcessor {
|
||||
match safety_selection {
|
||||
SafetySelection::Unsafe(_) => {
|
||||
// Sent to a private route with no safety route, use a stub safety route for the response
|
||||
if !routing_table.has_valid_network_class(RoutingDomain::PublicInternet) {
|
||||
return Ok(NetworkResult::no_connection_other(
|
||||
"Own node info must be valid to use private route",
|
||||
));
|
||||
}
|
||||
|
||||
// Determine if we can use optimized nodeinfo
|
||||
let route_node = if rss
|
||||
.has_remote_private_route_seen_our_node_info(&private_route.public_key.value)
|
||||
{
|
||||
if !routing_table.has_valid_own_node_info(RoutingDomain::PublicInternet) {
|
||||
return Ok(NetworkResult::no_connection_other("Own node info must be valid to use private route"));
|
||||
}
|
||||
RouteNode::NodeId(routing_table.node_id(crypto_kind).value)
|
||||
} else {
|
||||
let Some(own_peer_info) =
|
||||
routing_table.get_own_peer_info(RoutingDomain::PublicInternet) else {
|
||||
return Ok(NetworkResult::no_connection_other("Own peer info must be valid to use private route"));
|
||||
};
|
||||
RouteNode::PeerInfo(own_peer_info)
|
||||
let route_node = if rss.has_remote_private_route_seen_our_node_info(
|
||||
&private_route.public_key.value,
|
||||
) {
|
||||
RouteNode::NodeId(routing_table.node_id(crypto_kind).value)
|
||||
} else {
|
||||
let own_peer_info =
|
||||
routing_table.get_own_peer_info(RoutingDomain::PublicInternet);
|
||||
RouteNode::PeerInfo(own_peer_info)
|
||||
};
|
||||
|
||||
Ok(NetworkResult::value(RespondTo::PrivateRoute(
|
||||
@@ -250,10 +259,12 @@ impl RPCProcessor {
|
||||
}
|
||||
SafetySelection::Safe(safety_spec) => {
|
||||
// Sent to a private route via a safety route, respond to private route
|
||||
|
||||
|
||||
// Check for loopback test
|
||||
let opt_private_route_id = rss.get_route_id_for_key(&private_route.public_key.value);
|
||||
let pr_key = if opt_private_route_id.is_some() && safety_spec.preferred_route == opt_private_route_id
|
||||
let opt_private_route_id =
|
||||
rss.get_route_id_for_key(&private_route.public_key.value);
|
||||
let pr_key = if opt_private_route_id.is_some()
|
||||
&& safety_spec.preferred_route == opt_private_route_id
|
||||
{
|
||||
// Private route is also safety route during loopback test
|
||||
private_route.public_key.value
|
||||
@@ -308,7 +319,10 @@ impl RPCProcessor {
|
||||
};
|
||||
|
||||
// Reply directly to the request's source
|
||||
let sender_node_id = TypedKey::new(detail.envelope.get_crypto_kind(), detail.envelope.get_sender_id());
|
||||
let sender_node_id = TypedKey::new(
|
||||
detail.envelope.get_crypto_kind(),
|
||||
detail.envelope.get_sender_id(),
|
||||
);
|
||||
|
||||
// This may be a different node's reference than the 'sender' in the case of a relay
|
||||
let peer_noderef = detail.peer_noderef.clone();
|
||||
@@ -320,18 +334,21 @@ impl RPCProcessor {
|
||||
} else {
|
||||
// Look up the sender node, we should have added it via senderNodeInfo before getting here.
|
||||
let res = match self.routing_table.lookup_node_ref(sender_node_id) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return NetworkResult::invalid_message(
|
||||
format!("failed to look up node info for respond to: {}", e)
|
||||
)};
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
return NetworkResult::invalid_message(format!(
|
||||
"failed to look up node info for respond to: {}",
|
||||
e
|
||||
))
|
||||
}
|
||||
};
|
||||
if let Some(sender_noderef) = res {
|
||||
NetworkResult::value(Destination::relay(peer_noderef, sender_noderef))
|
||||
NetworkResult::value(Destination::relay(peer_noderef, sender_noderef))
|
||||
} else {
|
||||
return NetworkResult::invalid_message(
|
||||
"not responding to sender that has no node info",
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
RespondTo::PrivateRoute(pr) => {
|
||||
|
@@ -888,10 +888,9 @@ impl RPCProcessor {
|
||||
// Get the target's node info timestamp
|
||||
let target_node_info_ts = target.node_info_ts(routing_domain);
|
||||
|
||||
// Don't return our node info if it's not valid yet
|
||||
let Some(own_peer_info) = routing_table.get_own_peer_info(routing_domain) else {
|
||||
return SenderPeerInfo::new_no_peer_info(target_node_info_ts);
|
||||
};
|
||||
// Return whatever peer info we have even if the network class is not yet valid
|
||||
// That away we overwrite any prior existing valid-network-class nodeinfo in the remote routing table
|
||||
let own_peer_info = routing_table.get_own_peer_info(routing_domain);
|
||||
|
||||
// Get our node info timestamp
|
||||
let our_node_info_ts = own_peer_info.signed_node_info().timestamp();
|
||||
@@ -1475,6 +1474,12 @@ impl RPCProcessor {
|
||||
let mut opt_sender_nr: Option<NodeRef> = None;
|
||||
if let Some(sender_peer_info) = operation.sender_peer_info() {
|
||||
// Ensure the sender peer info is for the actual sender specified in the envelope
|
||||
if !sender_peer_info.node_ids().contains(&sender_node_id) {
|
||||
// Attempted to update peer info for the wrong node id
|
||||
return Ok(NetworkResult::invalid_message(
|
||||
"attempt to update peer info for non-sender node id",
|
||||
));
|
||||
}
|
||||
|
||||
// Sender PeerInfo was specified, update our routing table with it
|
||||
if !self.verify_node_info(
|
||||
|
@@ -55,18 +55,16 @@ impl RPCProcessor {
|
||||
) -> Result<NetworkResult<()>, RPCError> {
|
||||
// Ignore if disabled
|
||||
let routing_table = self.routing_table();
|
||||
|
||||
let opi = routing_table.get_own_peer_info(msg.header.routing_domain());
|
||||
if !opi
|
||||
.signed_node_info()
|
||||
.node_info()
|
||||
.has_capability(CAP_APPMESSAGE)
|
||||
{
|
||||
if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) {
|
||||
if !opi
|
||||
.signed_node_info()
|
||||
.node_info()
|
||||
.has_capability(CAP_APPMESSAGE)
|
||||
{
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"app call is not available",
|
||||
));
|
||||
}
|
||||
}
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"app call is not available",
|
||||
));
|
||||
}
|
||||
|
||||
// Get the question
|
||||
|
@@ -26,18 +26,15 @@ impl RPCProcessor {
|
||||
) -> Result<NetworkResult<()>, RPCError> {
|
||||
// Ignore if disabled
|
||||
let routing_table = self.routing_table();
|
||||
let opi = routing_table.get_own_peer_info(msg.header.routing_domain());
|
||||
if !opi
|
||||
.signed_node_info()
|
||||
.node_info()
|
||||
.has_capability(CAP_APPMESSAGE)
|
||||
{
|
||||
if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) {
|
||||
if !opi
|
||||
.signed_node_info()
|
||||
.node_info()
|
||||
.has_capability(CAP_APPMESSAGE)
|
||||
{
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"app message is not available",
|
||||
));
|
||||
}
|
||||
}
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"app message is not available",
|
||||
));
|
||||
}
|
||||
|
||||
// Get the statement
|
||||
|
@@ -175,15 +175,17 @@ impl RPCProcessor {
|
||||
}
|
||||
// Ignore if disabled
|
||||
let routing_table = self.routing_table();
|
||||
let opi = routing_table.get_own_peer_info(msg.header.routing_domain());
|
||||
if !opi
|
||||
.signed_node_info()
|
||||
.node_info()
|
||||
.has_capability(CAP_DHT)
|
||||
{
|
||||
if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) {
|
||||
if !opi.signed_node_info().node_info().has_capability(CAP_DHT) {
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"dht is not available",
|
||||
));
|
||||
}
|
||||
}
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"dht is not available",
|
||||
));
|
||||
}
|
||||
|
||||
// Get the question
|
||||
let kind = msg.operation.kind().clone();
|
||||
let get_value_q = match kind {
|
||||
|
@@ -367,14 +367,21 @@ impl RPCProcessor {
|
||||
) -> Result<NetworkResult<()>, RPCError> {
|
||||
// Ignore if disabled
|
||||
let routing_table = self.routing_table();
|
||||
if !routing_table.has_valid_network_class(msg.header.routing_domain()) {
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"can't route without valid network class",
|
||||
));
|
||||
}
|
||||
|
||||
let opi = routing_table.get_own_peer_info(msg.header.routing_domain());
|
||||
if !opi
|
||||
.signed_node_info()
|
||||
.node_info()
|
||||
.has_capability(CAP_ROUTE)
|
||||
{
|
||||
if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) {
|
||||
if !opi.signed_node_info().node_info().has_capability(CAP_ROUTE) {
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"route is not available",
|
||||
));
|
||||
}
|
||||
}
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"route is not available",
|
||||
));
|
||||
}
|
||||
|
||||
// Get header detail, must be direct and not inside a route itself
|
||||
|
@@ -177,15 +177,17 @@ impl RPCProcessor {
|
||||
) -> Result<NetworkResult<()>, RPCError> {
|
||||
// Ignore if disabled
|
||||
let routing_table = self.routing_table();
|
||||
let opi = routing_table.get_own_peer_info(msg.header.routing_domain());
|
||||
if !opi
|
||||
.signed_node_info()
|
||||
.node_info()
|
||||
.has_capability(CAP_DHT)
|
||||
{
|
||||
if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) {
|
||||
if !opi.signed_node_info().node_info().has_capability(CAP_DHT) {
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"dht is not available",
|
||||
));
|
||||
}
|
||||
}
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"dht is not available",
|
||||
));
|
||||
}
|
||||
|
||||
// Ensure this never came over a private route, safety route is okay though
|
||||
match &msg.header.detail {
|
||||
RPCMessageHeaderDetail::Direct(_) | RPCMessageHeaderDetail::SafetyRouted(_) => {}
|
||||
|
@@ -39,15 +39,15 @@ impl RPCProcessor {
|
||||
) -> Result<NetworkResult<()>, RPCError> {
|
||||
// Ignore if disabled
|
||||
let routing_table = self.routing_table();
|
||||
let opi = routing_table.get_own_peer_info(msg.header.routing_domain());
|
||||
if !opi
|
||||
.signed_node_info()
|
||||
.node_info()
|
||||
.has_capability(CAP_SIGNAL)
|
||||
{
|
||||
if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) {
|
||||
let ni = opi.signed_node_info().node_info();
|
||||
if !ni.has_capability(CAP_SIGNAL) {
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"signal is not available",
|
||||
));
|
||||
}
|
||||
}
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"signal is not available",
|
||||
));
|
||||
}
|
||||
|
||||
// Can't allow anything other than direct packets here, as handling reverse connections
|
||||
|
@@ -58,6 +58,14 @@ impl RPCProcessor {
|
||||
&self,
|
||||
msg: RPCMessage,
|
||||
) -> Result<NetworkResult<()>, RPCError> {
|
||||
let routing_table = self.routing_table();
|
||||
if !routing_table.has_valid_network_class(msg.header.routing_domain()) {
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"can't validate dial info without valid network class",
|
||||
));
|
||||
}
|
||||
let opi = routing_table.get_own_peer_info(msg.header.routing_domain());
|
||||
|
||||
let detail = match msg.header.detail {
|
||||
RPCMessageHeaderDetail::Direct(detail) => detail,
|
||||
RPCMessageHeaderDetail::SafetyRouted(_) | RPCMessageHeaderDetail::PrivateRouted(_) => {
|
||||
@@ -68,16 +76,16 @@ impl RPCProcessor {
|
||||
};
|
||||
|
||||
// Ignore if disabled
|
||||
let routing_table = self.routing_table();
|
||||
let ni = opi.signed_node_info().node_info();
|
||||
if !opi
|
||||
.signed_node_info()
|
||||
.node_info()
|
||||
.has_capability(CAP_VALIDATE_DIAL_INFO)
|
||||
|| !ni.is_fully_direct_inbound()
|
||||
{
|
||||
if let Some(opi) = routing_table.get_own_peer_info(detail.routing_domain) {
|
||||
let ni = opi.signed_node_info().node_info();
|
||||
if !ni.has_capability(CAP_VALIDATE_DIAL_INFO) || !ni.is_fully_direct_inbound() {
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"validate dial info is not available",
|
||||
));
|
||||
}
|
||||
}
|
||||
return Ok(NetworkResult::service_unavailable(
|
||||
"validate dial info is not available",
|
||||
));
|
||||
}
|
||||
|
||||
// Get the statement
|
||||
|
@@ -8,12 +8,9 @@ impl RPCProcessor {
|
||||
) -> Result<NetworkResult<()>, RPCError> {
|
||||
// Ignore if disabled
|
||||
let routing_table = self.routing_table();
|
||||
{
|
||||
if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) {
|
||||
if !opi.signed_node_info().node_info().has_capability(CAP_DHT) {
|
||||
return Ok(NetworkResult::service_unavailable("dht is not available"));
|
||||
}
|
||||
}
|
||||
let opi = routing_table.get_own_peer_info(msg.header.routing_domain());
|
||||
if !opi.signed_node_info().node_info().has_capability(CAP_DHT) {
|
||||
return Ok(NetworkResult::service_unavailable("dht is not available"));
|
||||
}
|
||||
Err(RPCError::unimplemented("process_value_changed"))
|
||||
}
|
||||
|
@@ -8,12 +8,9 @@ impl RPCProcessor {
|
||||
) -> Result<NetworkResult<()>, RPCError> {
|
||||
// Ignore if disabled
|
||||
let routing_table = self.routing_table();
|
||||
{
|
||||
if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) {
|
||||
if !opi.signed_node_info().node_info().has_capability(CAP_DHT) {
|
||||
return Ok(NetworkResult::service_unavailable("dht is not available"));
|
||||
}
|
||||
}
|
||||
let opi = routing_table.get_own_peer_info(msg.header.routing_domain());
|
||||
if !opi.signed_node_info().node_info().has_capability(CAP_DHT) {
|
||||
return Ok(NetworkResult::service_unavailable("dht is not available"));
|
||||
}
|
||||
Err(RPCError::unimplemented("process_watch_value_q"))
|
||||
}
|
||||
|
Reference in New Issue
Block a user