331 lines
11 KiB
Rust
331 lines
11 KiB
Rust
use super::*;
|
|
|
|
#[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Ord)]
|
|
pub enum RPCError {
|
|
Timeout,
|
|
InvalidFormat(String),
|
|
Unreachable(DHTKey),
|
|
Unimplemented(String),
|
|
Protocol(String),
|
|
Internal(String),
|
|
}
|
|
|
|
pub fn rpc_error_internal<T: AsRef<str>>(x: T) -> RPCError {
|
|
error!("RPCError Internal: {}", x.as_ref());
|
|
RPCError::Internal(x.as_ref().to_owned())
|
|
}
|
|
pub fn rpc_error_invalid_format<T: AsRef<str>>(x: T) -> RPCError {
|
|
error!("RPCError Invalid Format: {}", x.as_ref());
|
|
RPCError::InvalidFormat(x.as_ref().to_owned())
|
|
}
|
|
pub fn rpc_error_protocol<T: AsRef<str>>(x: T) -> RPCError {
|
|
error!("RPCError Protocol: {}", x.as_ref());
|
|
RPCError::Protocol(x.as_ref().to_owned())
|
|
}
|
|
pub fn rpc_error_capnp_error(e: capnp::Error) -> RPCError {
|
|
error!("RPCError Protocol: capnp error: {}", &e.description);
|
|
RPCError::Protocol(e.description)
|
|
}
|
|
pub fn rpc_error_capnp_notinschema(e: capnp::NotInSchema) -> RPCError {
|
|
error!("RPCError Protocol: not in schema: {}", &e.0);
|
|
RPCError::Protocol(format!("not in schema: {}", &e.0))
|
|
}
|
|
pub fn rpc_error_unimplemented<T: AsRef<str>>(x: T) -> RPCError {
|
|
error!("RPCError Unimplemented: {}", x.as_ref());
|
|
RPCError::Unimplemented(x.as_ref().to_owned())
|
|
}
|
|
|
|
impl fmt::Display for RPCError {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
RPCError::Timeout => write!(f, "[RPCError: Timeout]"),
|
|
RPCError::InvalidFormat(s) => write!(f, "[RPCError: InvalidFormat({})]", s),
|
|
RPCError::Unreachable(k) => write!(f, "[RPCError: Unreachable({})]", k),
|
|
RPCError::Unimplemented(s) => write!(f, "[RPCError: Unimplemented({})]", s),
|
|
RPCError::Protocol(s) => write!(f, "[RPCError: Protocol({})]", s),
|
|
RPCError::Internal(s) => write!(f, "[RPCError: Internal({})]", s),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! map_error_internal {
|
|
($x:expr) => {
|
|
|_| rpc_error_internal($x)
|
|
};
|
|
}
|
|
#[macro_export]
|
|
macro_rules! map_error_protocol {
|
|
($x:expr) => {
|
|
|_| rpc_error_protocol($x)
|
|
};
|
|
}
|
|
#[macro_export]
|
|
macro_rules! map_error_string {
|
|
() => {
|
|
|s| rpc_error_internal(&s)
|
|
};
|
|
}
|
|
#[macro_export]
|
|
macro_rules! map_error_capnp_error {
|
|
() => {
|
|
|e| rpc_error_capnp_error(e)
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! map_error_capnp_notinschema {
|
|
() => {
|
|
|e| rpc_error_capnp_notinschema(e)
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! map_error_panic {
|
|
() => {
|
|
|_| panic!("oops")
|
|
};
|
|
}
|
|
|
|
impl RPCProcessor {
|
|
#[allow(dead_code)]
|
|
pub(super) fn get_rpc_request_debug_info<T: capnp::message::ReaderSegments>(
|
|
&self,
|
|
dest: &Destination,
|
|
message: &capnp::message::Reader<T>,
|
|
safety_route_spec: &Option<&SafetyRouteSpec>,
|
|
) -> String {
|
|
format!(
|
|
"REQ->{:?}{} {}",
|
|
dest,
|
|
match safety_route_spec {
|
|
None => "".to_owned(),
|
|
Some(srs) => format!("[{:?}]", srs),
|
|
},
|
|
self.get_rpc_message_debug_info(message)
|
|
)
|
|
}
|
|
#[allow(dead_code)]
|
|
pub(super) fn get_rpc_reply_debug_info<T: capnp::message::ReaderSegments>(
|
|
&self,
|
|
request_rpcreader: &RPCMessageReader,
|
|
reply_msg: &capnp::message::Reader<T>,
|
|
safety_route_spec: &Option<&SafetyRouteSpec>,
|
|
) -> String {
|
|
let request_operation = match request_rpcreader
|
|
.reader
|
|
.get_root::<veilid_capnp::operation::Reader>()
|
|
{
|
|
Ok(v) => v,
|
|
Err(e) => {
|
|
return format!("invalid operation: {}", e);
|
|
}
|
|
};
|
|
|
|
let respond_to = match request_operation.get_respond_to().which() {
|
|
Ok(v) => v,
|
|
Err(e) => {
|
|
return format!("(respond_to not in schema: {:?})", e);
|
|
}
|
|
};
|
|
let respond_to_str = match respond_to {
|
|
veilid_capnp::operation::respond_to::None(_) => "(None)".to_owned(),
|
|
veilid_capnp::operation::respond_to::Sender(_) => "Sender".to_owned(),
|
|
veilid_capnp::operation::respond_to::SenderWithInfo(sni) => {
|
|
let sni_reader = match sni {
|
|
Ok(snir) => snir,
|
|
Err(e) => {
|
|
return e.to_string();
|
|
}
|
|
};
|
|
let signed_node_info = match decode_signed_node_info(
|
|
&sni_reader,
|
|
&request_rpcreader.header.envelope.get_sender_id(),
|
|
true,
|
|
) {
|
|
Ok(ni) => ni,
|
|
Err(e) => {
|
|
return e.to_string();
|
|
}
|
|
};
|
|
format!("Sender({:?})", signed_node_info)
|
|
}
|
|
veilid_capnp::operation::respond_to::PrivateRoute(pr) => {
|
|
let pr_reader = match pr {
|
|
Ok(prr) => prr,
|
|
Err(e) => {
|
|
return e.to_string();
|
|
}
|
|
};
|
|
let private_route = match decode_private_route(&pr_reader) {
|
|
Ok(pr) => pr,
|
|
Err(e) => {
|
|
return e.to_string();
|
|
}
|
|
};
|
|
format!("[PR:{:?}]", private_route)
|
|
}
|
|
};
|
|
format!(
|
|
"REPLY->{:?}{} {}",
|
|
respond_to_str,
|
|
match safety_route_spec {
|
|
None => "".to_owned(),
|
|
Some(srs) => format!("[SR:{:?}]", srs),
|
|
},
|
|
self.get_rpc_message_debug_info(reply_msg)
|
|
)
|
|
}
|
|
|
|
pub(super) fn get_rpc_message_debug_info<T: capnp::message::ReaderSegments>(
|
|
&self,
|
|
message: &capnp::message::Reader<T>,
|
|
) -> String {
|
|
let operation = match message.get_root::<veilid_capnp::operation::Reader>() {
|
|
Ok(v) => v,
|
|
Err(e) => {
|
|
return format!("invalid operation: {}", e);
|
|
}
|
|
};
|
|
let op_id = operation.get_op_id();
|
|
let detail = match operation.get_detail().which() {
|
|
Ok(v) => v,
|
|
Err(e) => {
|
|
return format!("(operation detail not in schema: {})", e);
|
|
}
|
|
};
|
|
format!(
|
|
"#{} {}",
|
|
op_id,
|
|
self.get_rpc_operation_detail_debug_info(&detail)
|
|
)
|
|
}
|
|
|
|
#[allow(clippy::useless_format)]
|
|
pub(super) fn get_rpc_operation_detail_debug_info(
|
|
&self,
|
|
detail: &veilid_capnp::operation::detail::WhichReader,
|
|
) -> String {
|
|
match detail {
|
|
veilid_capnp::operation::detail::StatusQ(_) => {
|
|
format!("StatusQ")
|
|
}
|
|
veilid_capnp::operation::detail::StatusA(_) => {
|
|
format!("StatusA")
|
|
}
|
|
veilid_capnp::operation::detail::ValidateDialInfo(_) => {
|
|
format!("ValidateDialInfo")
|
|
}
|
|
veilid_capnp::operation::detail::FindNodeQ(d) => {
|
|
let fnqr = match d {
|
|
Ok(fnqr) => fnqr,
|
|
Err(e) => {
|
|
return format!("(invalid detail: {})", e);
|
|
}
|
|
};
|
|
let nidr = match fnqr.get_node_id() {
|
|
Ok(nidr) => nidr,
|
|
Err(e) => {
|
|
return format!("(invalid node id: {})", e);
|
|
}
|
|
};
|
|
let node_id = decode_public_key(&nidr);
|
|
format!("FindNodeQ: node_id={}", node_id.encode(),)
|
|
}
|
|
veilid_capnp::operation::detail::FindNodeA(d) => {
|
|
let fnar = match d {
|
|
Ok(fnar) => fnar,
|
|
Err(e) => {
|
|
return format!("(invalid detail: {})", e);
|
|
}
|
|
};
|
|
|
|
let p_reader = match fnar.reborrow().get_peers() {
|
|
Ok(pr) => pr,
|
|
Err(e) => {
|
|
return format!("(invalid peers: {})", e);
|
|
}
|
|
};
|
|
let mut peers = Vec::<PeerInfo>::with_capacity(match p_reader.len().try_into() {
|
|
Ok(v) => v,
|
|
Err(e) => return format!("invalid peer count: {}", e),
|
|
});
|
|
for p in p_reader.iter() {
|
|
let peer_info = match decode_peer_info(&p, true) {
|
|
Ok(v) => v,
|
|
Err(e) => {
|
|
return format!("(unable to decode peer info: {})", e);
|
|
}
|
|
};
|
|
peers.push(peer_info);
|
|
}
|
|
|
|
format!("FindNodeA: peers={:#?}", peers)
|
|
}
|
|
veilid_capnp::operation::detail::Route(_) => {
|
|
format!("Route")
|
|
}
|
|
veilid_capnp::operation::detail::NodeInfoUpdate(_) => {
|
|
format!("NodeInfoUpdate")
|
|
}
|
|
veilid_capnp::operation::detail::GetValueQ(_) => {
|
|
format!("GetValueQ")
|
|
}
|
|
veilid_capnp::operation::detail::GetValueA(_) => {
|
|
format!("GetValueA")
|
|
}
|
|
veilid_capnp::operation::detail::SetValueQ(_) => {
|
|
format!("SetValueQ")
|
|
}
|
|
veilid_capnp::operation::detail::SetValueA(_) => {
|
|
format!("SetValueA")
|
|
}
|
|
veilid_capnp::operation::detail::WatchValueQ(_) => {
|
|
format!("WatchValueQ")
|
|
}
|
|
veilid_capnp::operation::detail::WatchValueA(_) => {
|
|
format!("WatchValueA")
|
|
}
|
|
veilid_capnp::operation::detail::ValueChanged(_) => {
|
|
format!("ValueChanged")
|
|
}
|
|
veilid_capnp::operation::detail::SupplyBlockQ(_) => {
|
|
format!("SupplyBlockQ")
|
|
}
|
|
veilid_capnp::operation::detail::SupplyBlockA(_) => {
|
|
format!("SupplyBlockA")
|
|
}
|
|
veilid_capnp::operation::detail::FindBlockQ(_) => {
|
|
format!("FindBlockQ")
|
|
}
|
|
veilid_capnp::operation::detail::FindBlockA(_) => {
|
|
format!("FindBlockA")
|
|
}
|
|
veilid_capnp::operation::detail::Signal(_) => {
|
|
format!("Signal")
|
|
}
|
|
veilid_capnp::operation::detail::ReturnReceipt(_) => {
|
|
format!("ReturnReceipt")
|
|
}
|
|
veilid_capnp::operation::detail::StartTunnelQ(_) => {
|
|
format!("StartTunnelQ")
|
|
}
|
|
veilid_capnp::operation::detail::StartTunnelA(_) => {
|
|
format!("StartTunnelA")
|
|
}
|
|
veilid_capnp::operation::detail::CompleteTunnelQ(_) => {
|
|
format!("CompleteTunnelQ")
|
|
}
|
|
veilid_capnp::operation::detail::CompleteTunnelA(_) => {
|
|
format!("CompleteTunnelA")
|
|
}
|
|
veilid_capnp::operation::detail::CancelTunnelQ(_) => {
|
|
format!("CancelTunnelQ")
|
|
}
|
|
veilid_capnp::operation::detail::CancelTunnelA(_) => {
|
|
format!("CancelTunnelA")
|
|
}
|
|
}
|
|
}
|
|
}
|