checkpoint

This commit is contained in:
John Smith 2023-02-17 17:47:21 -05:00
parent ca3ce91365
commit 05be3099c8
17 changed files with 205 additions and 152 deletions

View File

@ -529,7 +529,7 @@ struct Answer @0xacacb8b6988c1058 {
struct Operation @0xbf2811c435403c3b { struct Operation @0xbf2811c435403c3b {
opId @0 :UInt64; # Random RPC ID. Must be random to foil reply forgery attacks. opId @0 :UInt64; # Random RPC ID. Must be random to foil reply forgery attacks.
senderNodeInfo @1 :SignedNodeInfo; # (optional) SignedNodeInfo for the sender to be cached by the receiver. senderPeerInfo @1 :PeerInfo; # (optional) PeerInfo for the sender to be cached by the receiver.
targetNodeInfoTs @2 :UInt64; # Timestamp the sender believes the target's node info to be at or zero if not sent targetNodeInfoTs @2 :UInt64; # Timestamp the sender believes the target's node info to be at or zero if not sent
kind :union { kind :union {
question @3 :Question; question @3 :Question;

View File

@ -159,6 +159,13 @@ impl TypedKeySet {
out.sort_by(compare_crypto_kind); out.sort_by(compare_crypto_kind);
out out
} }
pub fn keys(&self) -> Vec<PublicKey> {
let mut out = Vec::new();
for tk in &self.items {
out.push(tk.key);
}
out
}
pub fn get(&self, kind: CryptoKind) -> Option<TypedKey> { pub fn get(&self, kind: CryptoKind) -> Option<TypedKey> {
self.items.iter().find(|x| x.kind == kind).copied() self.items.iter().find(|x| x.kind == kind).copied()
} }

View File

@ -765,34 +765,33 @@ impl NetworkManager {
/// Called by the RPC handler when we want to issue an RPC request or response /// Called by the RPC handler when we want to issue an RPC request or response
/// node_ref is the direct destination to which the envelope will be sent /// node_ref is the direct destination to which the envelope will be sent
/// If 'envelope_node_id' is specified, it can be different than the node_ref being sent to /// If 'envelope_node_ref' is specified, it can be different than the node_ref being sent to
/// which will cause the envelope to be relayed /// which will cause the envelope to be relayed
#[instrument(level = "trace", skip(self, body), ret, err)] #[instrument(level = "trace", skip(self, body), ret, err)]
pub async fn send_envelope<B: AsRef<[u8]>>( pub async fn send_envelope<B: AsRef<[u8]>>(
&self, &self,
node_ref: NodeRef, node_ref: NodeRef,
envelope_node_id: Option<TypedKey>, envelope_node_ref: Option<NodeRef>,
body: B, body: B,
) -> EyreResult<NetworkResult<SendDataKind>> { ) -> EyreResult<NetworkResult<SendDataKind>> {
let via_node_ids = node_ref.node_ids();
let Some(best_via_node_id) = via_node_ids.best() else {
bail!("should have a best node id");
};
let envelope_node_id = envelope_node_id.unwrap_or(best_via_node_id);
if !via_node_ids.contains(&envelope_node_id) { let end_node_ref = envelope_node_ref.as_ref().unwrap_or(&node_ref).clone();
if !node_ref.same_entry(&end_node_ref) {
log_net!( log_net!(
"sending envelope to {:?} via {:?}", "sending envelope to {:?} via {:?}",
envelope_node_id, end_node_ref,
node_ref node_ref
); );
} else { } else {
log_net!("sending envelope to {:?}", node_ref); log_net!("sending envelope to {:?}", node_ref);
} }
let best_node_id = end_node_ref.best_node_id();
// Get node's envelope versions and see if we can send to it // Get node's envelope versions and see if we can send to it
// and if so, get the max version we can use // and if so, get the max version we can use
let Some(envelope_version) = node_ref.envelope_support().into_iter().rev().find(|x| VALID_ENVELOPE_VERSIONS.contains(x)) else { let Some(envelope_version) = end_node_ref.best_envelope_version() else {
bail!( bail!(
"can't talk to this node {} because we dont support its envelope versions", "can't talk to this node {} because we dont support its envelope versions",
node_ref node_ref
@ -800,10 +799,10 @@ impl NetworkManager {
}; };
// Build the envelope to send // Build the envelope to send
let out = self.build_envelope(envelope_node_id, envelope_version, body)?; let out = self.build_envelope(best_node_id, envelope_version, body)?;
// Send the envelope via whatever means necessary // Send the envelope via whatever means necessary
self.send_data(node_ref.clone(), out).await self.send_data(node_ref, out).await
} }
/// Called by the RPC handler when we want to issue an direct receipt /// Called by the RPC handler when we want to issue an direct receipt
@ -867,7 +866,7 @@ impl NetworkManager {
let rpc = self.rpc_processor(); let rpc = self.rpc_processor();
network_result_try!(rpc network_result_try!(rpc
.rpc_call_signal( .rpc_call_signal(
Destination::relay(relay_nr, target_nr.node_id()), Destination::relay(relay_nr, target_nr.clone()),
SignalInfo::ReverseConnect { receipt, peer_info }, SignalInfo::ReverseConnect { receipt, peer_info },
) )
.await .await
@ -972,7 +971,7 @@ impl NetworkManager {
let rpc = self.rpc_processor(); let rpc = self.rpc_processor();
network_result_try!(rpc network_result_try!(rpc
.rpc_call_signal( .rpc_call_signal(
Destination::relay(relay_nr, target_nr.node_id()), Destination::relay(relay_nr, target_nr.clone()),
SignalInfo::HolePunch { receipt, peer_info }, SignalInfo::HolePunch { receipt, peer_info },
) )
.await .await
@ -1076,7 +1075,7 @@ impl NetworkManager {
let relay_nr = routing_table let relay_nr = routing_table
.lookup_and_filter_noderef(relay_key, routing_domain.into(), dial_info_filter) .lookup_and_filter_noderef(relay_key, routing_domain.into(), dial_info_filter)
.ok_or_else(|| eyre!("couldn't look up relay"))?; .ok_or_else(|| eyre!("couldn't look up relay"))?;
if target_node_ref.node_id() != target_key { if !target_node_ref.node_ids().contains(&target_key) {
bail!("target noderef didn't match target key"); bail!("target noderef didn't match target key");
} }
NodeContactMethod::SignalReverse(relay_nr, target_node_ref) NodeContactMethod::SignalReverse(relay_nr, target_node_ref)
@ -1085,7 +1084,7 @@ impl NetworkManager {
let relay_nr = routing_table let relay_nr = routing_table
.lookup_and_filter_noderef(relay_key, routing_domain.into(), dial_info_filter) .lookup_and_filter_noderef(relay_key, routing_domain.into(), dial_info_filter)
.ok_or_else(|| eyre!("couldn't look up relay"))?; .ok_or_else(|| eyre!("couldn't look up relay"))?;
if target_node_ref.node_id() != target_key { if target_node_ref.node_ids().contains(&target_key) {
bail!("target noderef didn't match target key"); bail!("target noderef didn't match target key");
} }
NodeContactMethod::SignalHolePunch(relay_nr, target_node_ref) NodeContactMethod::SignalHolePunch(relay_nr, target_node_ref)
@ -1386,7 +1385,7 @@ impl NetworkManager {
let some_relay_nr = if self.check_client_whitelist(sender_id) { let some_relay_nr = if self.check_client_whitelist(sender_id) {
// Full relay allowed, do a full resolve_node // Full relay allowed, do a full resolve_node
match rpc.resolve_node(recipient_id).await { match rpc.resolve_node(recipient_id.key).await {
Ok(v) => v, Ok(v) => v,
Err(e) => { Err(e) => {
log_net!(debug "failed to resolve recipient node for relay, dropping outbound relayed packet: {}" ,e); log_net!(debug "failed to resolve recipient node for relay, dropping outbound relayed packet: {}" ,e);

View File

@ -476,6 +476,10 @@ impl BucketEntryInner {
self.envelope_support.clone() self.envelope_support.clone()
} }
pub fn best_envelope_version(&self) -> Option<u8> {
self.envelope_support.iter().rev().find(|x| VALID_ENVELOPE_VERSIONS.contains(x)).copied()
}
pub fn state(&self, cur_ts: Timestamp) -> BucketEntryState { pub fn state(&self, cur_ts: Timestamp) -> BucketEntryState {
if self.check_reliable(cur_ts) { if self.check_reliable(cur_ts) {
BucketEntryState::Reliable BucketEntryState::Reliable

View File

@ -132,6 +132,9 @@ pub trait NodeRefBase: Sized {
fn set_envelope_support(&self, envelope_support: Vec<u8>) { fn set_envelope_support(&self, envelope_support: Vec<u8>) {
self.operate_mut(|_rti, e| e.set_envelope_support(envelope_support)) self.operate_mut(|_rti, e| e.set_envelope_support(envelope_support))
} }
fn best_envelope_version(&self) -> Option<u8> {
self.operate(|_rti, e| e.best_envelope_version())
}
fn state(&self, cur_ts: Timestamp) -> BucketEntryState { fn state(&self, cur_ts: Timestamp) -> BucketEntryState {
self.operate(|_rti, e| e.state(cur_ts)) self.operate(|_rti, e| e.state(cur_ts))
} }

View File

@ -16,7 +16,7 @@ pub struct RouteHopData {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum RouteNode { pub enum RouteNode {
/// Route node is optimized, no contact method information as this node id has been seen before /// Route node is optimized, no contact method information as this node id has been seen before
NodeId(TypedKey), NodeId(PublicKey),
/// Route node with full contact method information to ensure the peer is reachable /// Route node with full contact method information to ensure the peer is reachable
PeerInfo(PeerInfo), PeerInfo(PeerInfo),
} }
@ -79,6 +79,11 @@ impl PrivateRoute {
false false
} }
/// Get the crypto kind in use for this route
pub fn crypto_kind(&self) -> CryptoKind {
self.public_key.kind
}
/// Remove the first unencrypted hop if possible /// Remove the first unencrypted hop if possible
pub fn pop_first_hop(&mut self) -> Option<RouteNode> { pub fn pop_first_hop(&mut self) -> Option<RouteNode> {
match &mut self.hops { match &mut self.hops {
@ -112,8 +117,8 @@ impl PrivateRoute {
// Get the safety route to use from the spec // Get the safety route to use from the spec
Some(match &pr_first_hop.node { Some(match &pr_first_hop.node {
RouteNode::NodeId(n) => n, RouteNode::NodeId(n) => TypedKey::new(self.public_key.kind, *n),
RouteNode::PeerInfo(p) => p.node_id.key, RouteNode::PeerInfo(p) => p.node_ids.get(self.public_key.kind).unwrap(),
}) })
} }
} }
@ -126,8 +131,13 @@ impl fmt::Display for PrivateRoute {
self.public_key, self.public_key,
self.hop_count, self.hop_count,
match &self.hops { match &self.hops {
PrivateRouteHops::FirstHop(fh) => { PrivateRouteHops::FirstHop(_) => {
format!("->{}", fh.node) format!(
"->{}",
self.first_hop_node_id()
.map(|n| n.to_string())
.unwrap_or_else(|| "None".to_owned())
)
} }
PrivateRouteHops::Data(_) => { PrivateRouteHops::Data(_) => {
"->?".to_owned() "->?".to_owned()
@ -156,6 +166,7 @@ pub struct SafetyRoute {
} }
impl SafetyRoute { impl SafetyRoute {
/// Stub route is the form used when no privacy is required, but you need to directly contact a private route
pub fn new_stub(public_key: TypedKey, private_route: PrivateRoute) -> Self { pub fn new_stub(public_key: TypedKey, private_route: PrivateRoute) -> Self {
// First hop should have already been popped off for stubbed safety routes since // First hop should have already been popped off for stubbed safety routes since
// we are sending directly to the first hop // we are sending directly to the first hop
@ -166,9 +177,16 @@ impl SafetyRoute {
hops: SafetyRouteHops::Private(private_route), hops: SafetyRouteHops::Private(private_route),
} }
} }
/// Check if this is a stub route
pub fn is_stub(&self) -> bool { pub fn is_stub(&self) -> bool {
matches!(self.hops, SafetyRouteHops::Private(_)) matches!(self.hops, SafetyRouteHops::Private(_))
} }
/// Get the crypto kind in use for this route
pub fn crypto_kind(&self) -> CryptoKind {
self.public_key.kind
}
} }
impl fmt::Display for SafetyRoute { impl fmt::Display for SafetyRoute {

View File

@ -163,6 +163,8 @@ impl RouteStats {
#[derive(Clone, Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)] #[derive(Clone, Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
#[archive_attr(repr(C), derive(CheckBytes))] #[archive_attr(repr(C), derive(CheckBytes))]
pub struct RouteSpecDetail { pub struct RouteSpecDetail {
/// Crypto kind
crypto_kind: CryptoKind,
/// Secret key /// Secret key
#[with(Skip)] #[with(Skip)]
secret_key: SecretKey, secret_key: SecretKey,
@ -187,6 +189,9 @@ pub struct RouteSpecDetail {
} }
impl RouteSpecDetail { impl RouteSpecDetail {
pub fn get_crypto_kind(&self) -> CryptoKind {
self.crypto_kind
}
pub fn get_stats(&self) -> &RouteStats { pub fn get_stats(&self) -> &RouteStats {
&self.stats &self.stats
} }
@ -221,13 +226,13 @@ impl RouteSpecDetail {
#[archive_attr(repr(C, align(8)), derive(CheckBytes))] #[archive_attr(repr(C, align(8)), derive(CheckBytes))]
pub struct RouteSpecStoreContent { pub struct RouteSpecStoreContent {
/// All of the routes we have allocated so far /// All of the routes we have allocated so far
details: HashMap<TypedKey, RouteSpecDetail>, details: HashMap<PublicKey, RouteSpecDetail>,
} }
/// What remote private routes have seen /// What remote private routes have seen
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct RemotePrivateRouteInfo { pub struct RemotePrivateRouteInfo {
// The private route itself /// The private route itself
private_route: Option<PrivateRoute>, private_route: Option<PrivateRoute>,
/// Did this remote private route see our node info due to no safety route in use /// Did this remote private route see our node info due to no safety route in use
last_seen_our_node_info_ts: Timestamp, last_seen_our_node_info_ts: Timestamp,
@ -256,13 +261,13 @@ pub struct RouteSpecStoreCache {
/// Route spec hop cache, used to quickly disqualify routes /// Route spec hop cache, used to quickly disqualify routes
hop_cache: HashSet<Vec<u8>>, hop_cache: HashSet<Vec<u8>>,
/// Has a remote private route responded to a question and when /// Has a remote private route responded to a question and when
remote_private_route_cache: LruCache<TypedKey, RemotePrivateRouteInfo>, remote_private_route_cache: LruCache<PublicKey, RemotePrivateRouteInfo>,
/// Compiled route cache /// Compiled route cache
compiled_route_cache: LruCache<CompiledRouteCacheKey, SafetyRoute>, compiled_route_cache: LruCache<CompiledRouteCacheKey, SafetyRoute>,
/// List of dead allocated routes /// List of dead allocated routes
dead_routes: Vec<TypedKey>, dead_routes: Vec<PublicKey>,
/// List of dead remote routes /// List of dead remote routes
dead_remote_routes: Vec<TypedKey>, dead_remote_routes: Vec<PublicKey>,
} }
impl Default for RouteSpecStoreCache { impl Default for RouteSpecStoreCache {
@ -602,6 +607,7 @@ impl RouteSpecStore {
/// Prefers nodes that are not currently in use by another route /// Prefers nodes that are not currently in use by another route
/// The route is not yet tested for its reachability /// The route is not yet tested for its reachability
/// Returns None if no route could be allocated at this time /// Returns None if no route could be allocated at this time
/// Returns Some list of public keys for the requested set of crypto kinds
#[instrument(level = "trace", skip(self), ret, err)] #[instrument(level = "trace", skip(self), ret, err)]
pub fn allocate_route( pub fn allocate_route(
&self, &self,
@ -1590,8 +1596,8 @@ impl RouteSpecStore {
rti: &RoutingTableInner, rti: &RoutingTableInner,
safety_spec: &SafetySpec, safety_spec: &SafetySpec,
direction: DirectionSet, direction: DirectionSet,
avoid_nodes: &[TypedKey], avoid_nodes: &[PublicKey],
) -> EyreResult<Option<TypedKeySet>> { ) -> EyreResult<Option<PublicKey>> {
// Ensure the total hop count isn't too long for our config // Ensure the total hop count isn't too long for our config
let max_route_hop_count = self.unlocked_inner.max_route_hop_count; let max_route_hop_count = self.unlocked_inner.max_route_hop_count;
if safety_spec.hop_count == 0 { if safety_spec.hop_count == 0 {
@ -1645,13 +1651,14 @@ impl RouteSpecStore {
Ok(Some(sr_pubkey)) Ok(Some(sr_pubkey))
} }
/// Get a private sroute to use for the answer to question /// Get a private route to use for the answer to question
#[instrument(level = "trace", skip(self), ret, err)] #[instrument(level = "trace", skip(self), ret, err)]
pub fn get_private_route_for_safety_spec( pub fn get_private_route_for_safety_spec(
&self, &self,
crypto_kind: CryptoKind,
safety_spec: &SafetySpec, safety_spec: &SafetySpec,
avoid_nodes: &[TypedKey], avoid_nodes: &[PublicKey],
) -> EyreResult<Option<TypedKey>> { ) -> EyreResult<Option<PublicKey>> {
let inner = &mut *self.inner.lock(); let inner = &mut *self.inner.lock();
let routing_table = self.unlocked_inner.routing_table.clone(); let routing_table = self.unlocked_inner.routing_table.clone();
let rti = &*routing_table.inner.read(); let rti = &*routing_table.inner.read();
@ -1669,7 +1676,7 @@ impl RouteSpecStore {
#[instrument(level = "trace", skip(self), err)] #[instrument(level = "trace", skip(self), err)]
pub fn assemble_private_route( pub fn assemble_private_route(
&self, &self,
key: &TypedKey, key: &PublicKey,
optimized: Option<bool>, optimized: Option<bool>,
) -> EyreResult<PrivateRoute> { ) -> EyreResult<PrivateRoute> {
let inner = &*self.inner.lock(); let inner = &*self.inner.lock();
@ -1758,7 +1765,7 @@ impl RouteSpecStore {
/// Import a remote private route for compilation /// Import a remote private route for compilation
#[instrument(level = "trace", skip(self, blob), ret, err)] #[instrument(level = "trace", skip(self, blob), ret, err)]
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> EyreResult<TypedKey> { pub fn import_remote_private_route(&self, blob: Vec<u8>) -> EyreResult<PublicKey> {
// decode the pr blob // decode the pr blob
let private_route = RouteSpecStore::blob_to_private_route(blob)?; let private_route = RouteSpecStore::blob_to_private_route(blob)?;
@ -1783,7 +1790,7 @@ impl RouteSpecStore {
/// Release a remote private route that is no longer in use /// Release a remote private route that is no longer in use
#[instrument(level = "trace", skip(self), ret)] #[instrument(level = "trace", skip(self), ret)]
fn release_remote_private_route(&self, key: &TypedKey) -> bool { fn release_remote_private_route(&self, key: &PublicKey) -> bool {
let inner = &mut *self.inner.lock(); let inner = &mut *self.inner.lock();
if inner.cache.remote_private_route_cache.remove(key).is_some() { if inner.cache.remote_private_route_cache.remove(key).is_some() {
// Mark it as dead for the update // Mark it as dead for the update
@ -1795,7 +1802,7 @@ impl RouteSpecStore {
} }
/// Retrieve an imported remote private route by its public key /// Retrieve an imported remote private route by its public key
pub fn get_remote_private_route(&self, key: &TypedKey) -> Option<PrivateRoute> { pub fn get_remote_private_route(&self, key: &PublicKey) -> Option<PrivateRoute> {
let inner = &mut *self.inner.lock(); let inner = &mut *self.inner.lock();
let cur_ts = get_aligned_timestamp(); let cur_ts = get_aligned_timestamp();
Self::with_get_remote_private_route(inner, cur_ts, key, |r| { Self::with_get_remote_private_route(inner, cur_ts, key, |r| {
@ -1804,7 +1811,7 @@ impl RouteSpecStore {
} }
/// Retrieve an imported remote private route by its public key but don't 'touch' it /// Retrieve an imported remote private route by its public key but don't 'touch' it
pub fn peek_remote_private_route(&self, key: &TypedKey) -> Option<PrivateRoute> { pub fn peek_remote_private_route(&self, key: &PublicKey) -> Option<PrivateRoute> {
let inner = &mut *self.inner.lock(); let inner = &mut *self.inner.lock();
let cur_ts = get_aligned_timestamp(); let cur_ts = get_aligned_timestamp();
Self::with_peek_remote_private_route(inner, cur_ts, key, |r| { Self::with_peek_remote_private_route(inner, cur_ts, key, |r| {
@ -1865,7 +1872,7 @@ impl RouteSpecStore {
fn with_get_remote_private_route<F, R>( fn with_get_remote_private_route<F, R>(
inner: &mut RouteSpecStoreInner, inner: &mut RouteSpecStoreInner,
cur_ts: Timestamp, cur_ts: Timestamp,
remote_private_route: &TypedKey, key: &PublicKey,
f: F, f: F,
) -> Option<R> ) -> Option<R>
where where
@ -1885,7 +1892,7 @@ impl RouteSpecStore {
fn with_peek_remote_private_route<F, R>( fn with_peek_remote_private_route<F, R>(
inner: &mut RouteSpecStoreInner, inner: &mut RouteSpecStoreInner,
cur_ts: Timestamp, cur_ts: Timestamp,
remote_private_route: &TypedKey, key: &PublicKey,
f: F, f: F,
) -> Option<R> ) -> Option<R>
where where
@ -1907,7 +1914,7 @@ impl RouteSpecStore {
/// Check to see if this remote (not ours) private route has seen our current node info yet /// Check to see if this remote (not ours) private route has seen our current node info yet
/// This happens when you communicate with a private route without a safety route /// This happens when you communicate with a private route without a safety route
pub fn has_remote_private_route_seen_our_node_info(&self, remote_private_route: &TypedKey) -> bool { pub fn has_remote_private_route_seen_our_node_info(&self, key: &PublicKey) -> bool {
let our_node_info_ts = { let our_node_info_ts = {
let rti = &*self.unlocked_inner.routing_table.inner.read(); let rti = &*self.unlocked_inner.routing_table.inner.read();
let Some(ts) = rti.get_own_node_info_ts(RoutingDomain::PublicInternet) else { let Some(ts) = rti.get_own_node_info_ts(RoutingDomain::PublicInternet) else {
@ -1919,7 +1926,7 @@ impl RouteSpecStore {
let opt_rpr_node_info_ts = { let opt_rpr_node_info_ts = {
let inner = &mut *self.inner.lock(); let inner = &mut *self.inner.lock();
let cur_ts = get_aligned_timestamp(); let cur_ts = get_aligned_timestamp();
Self::with_peek_remote_private_route(inner, cur_ts, remote_private_route, |rpr| { Self::with_peek_remote_private_route(inner, cur_ts, key, |rpr| {
rpr.last_seen_our_node_info_ts rpr.last_seen_our_node_info_ts
}) })
}; };

View File

@ -16,12 +16,15 @@ impl RPCOperationKind {
} }
} }
pub fn decode(kind_reader: &veilid_capnp::operation::kind::Reader) -> Result<Self, RPCError> { pub fn decode(
kind_reader: &veilid_capnp::operation::kind::Reader,
crypto: Crypto,
) -> Result<Self, RPCError> {
let which_reader = kind_reader.which().map_err(RPCError::protocol)?; let which_reader = kind_reader.which().map_err(RPCError::protocol)?;
let out = match which_reader { let out = match which_reader {
veilid_capnp::operation::kind::Which::Question(r) => { veilid_capnp::operation::kind::Which::Question(r) => {
let q_reader = r.map_err(RPCError::protocol)?; let q_reader = r.map_err(RPCError::protocol)?;
let out = RPCQuestion::decode(&q_reader)?; let out = RPCQuestion::decode(&q_reader, crypto)?;
RPCOperationKind::Question(out) RPCOperationKind::Question(out)
} }
veilid_capnp::operation::kind::Which::Statement(r) => { veilid_capnp::operation::kind::Which::Statement(r) => {
@ -54,31 +57,25 @@ impl RPCOperationKind {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct RPCOperation { pub struct RPCOperation {
op_id: OperationId, op_id: OperationId,
sender_node_info: Option<SignedNodeInfo>, opt_sender_peer_info: Option<PeerInfo>,
target_node_info_ts: Timestamp, target_node_info_ts: Timestamp,
kind: RPCOperationKind, kind: RPCOperationKind,
} }
impl RPCOperation { impl RPCOperation {
pub fn new_question( pub fn new_question(question: RPCQuestion, sender_peer_info: SenderPeerInfo) -> Self {
question: RPCQuestion,
sender_signed_node_info: SenderSignedNodeInfo,
) -> Self {
Self { Self {
op_id: OperationId::new(get_random_u64()), op_id: OperationId::new(get_random_u64()),
sender_node_info: sender_signed_node_info.signed_node_info, opt_sender_peer_info: sender_peer_info.opt_sender_peer_info,
target_node_info_ts: sender_signed_node_info.target_node_info_ts, target_node_info_ts: sender_peer_info.target_node_info_ts,
kind: RPCOperationKind::Question(question), kind: RPCOperationKind::Question(question),
} }
} }
pub fn new_statement( pub fn new_statement(statement: RPCStatement, sender_peer_info: SenderPeerInfo) -> Self {
statement: RPCStatement,
sender_signed_node_info: SenderSignedNodeInfo,
) -> Self {
Self { Self {
op_id: OperationId::new(get_random_u64()), op_id: OperationId::new(get_random_u64()),
sender_node_info: sender_signed_node_info.signed_node_info, opt_sender_peer_info: sender_peer_info.opt_sender_peer_info,
target_node_info_ts: sender_signed_node_info.target_node_info_ts, target_node_info_ts: sender_peer_info.target_node_info_ts,
kind: RPCOperationKind::Statement(statement), kind: RPCOperationKind::Statement(statement),
} }
} }
@ -86,12 +83,12 @@ impl RPCOperation {
pub fn new_answer( pub fn new_answer(
request: &RPCOperation, request: &RPCOperation,
answer: RPCAnswer, answer: RPCAnswer,
sender_signed_node_info: SenderSignedNodeInfo, sender_peer_info: SenderPeerInfo,
) -> Self { ) -> Self {
Self { Self {
op_id: request.op_id, op_id: request.op_id,
sender_node_info: sender_signed_node_info.signed_node_info, opt_sender_peer_info: sender_peer_info.opt_sender_peer_info,
target_node_info_ts: sender_signed_node_info.target_node_info_ts, target_node_info_ts: sender_peer_info.target_node_info_ts,
kind: RPCOperationKind::Answer(answer), kind: RPCOperationKind::Answer(answer),
} }
} }
@ -100,8 +97,8 @@ impl RPCOperation {
self.op_id self.op_id
} }
pub fn sender_node_info(&self) -> Option<&SignedNodeInfo> { pub fn sender_peer_info(&self) -> Option<&PeerInfo> {
self.sender_node_info.as_ref() self.opt_sender_peer_info.as_ref()
} }
pub fn target_node_info_ts(&self) -> Timestamp { pub fn target_node_info_ts(&self) -> Timestamp {
self.target_node_info_ts self.target_node_info_ts
@ -117,20 +114,16 @@ impl RPCOperation {
pub fn decode( pub fn decode(
operation_reader: &veilid_capnp::operation::Reader, operation_reader: &veilid_capnp::operation::Reader,
opt_sender_node_id: Option<&TypedKey>, crypto: Crypto,
) -> Result<Self, RPCError> { ) -> Result<Self, RPCError> {
let op_id = OperationId::new(operation_reader.get_op_id()); let op_id = OperationId::new(operation_reader.get_op_id());
let sender_node_info = if operation_reader.has_sender_node_info() { let sender_peer_info = if operation_reader.has_sender_peer_info() {
if let Some(sender_node_id) = opt_sender_node_id { let pi_reader = operation_reader
let sni_reader = operation_reader .get_sender_peer_info()
.get_sender_node_info() .map_err(RPCError::protocol)?;
.map_err(RPCError::protocol)?; let pi = decode_peer_info(&pi_reader, crypto.clone())?;
let sni = decode_signed_node_info(&sni_reader, sender_node_id)?; Some(pi)
Some(sni)
} else {
None
}
} else { } else {
None None
}; };
@ -138,11 +131,11 @@ impl RPCOperation {
let target_node_info_ts = Timestamp::new(operation_reader.get_target_node_info_ts()); let target_node_info_ts = Timestamp::new(operation_reader.get_target_node_info_ts());
let kind_reader = operation_reader.get_kind(); let kind_reader = operation_reader.get_kind();
let kind = RPCOperationKind::decode(&kind_reader)?; let kind = RPCOperationKind::decode(&kind_reader, crypto)?;
Ok(RPCOperation { Ok(RPCOperation {
op_id, op_id,
sender_node_info, opt_sender_peer_info: sender_peer_info,
target_node_info_ts, target_node_info_ts,
kind, kind,
}) })
@ -150,9 +143,9 @@ impl RPCOperation {
pub fn encode(&self, builder: &mut veilid_capnp::operation::Builder) -> Result<(), RPCError> { pub fn encode(&self, builder: &mut veilid_capnp::operation::Builder) -> Result<(), RPCError> {
builder.set_op_id(self.op_id.as_u64()); builder.set_op_id(self.op_id.as_u64());
if let Some(sender_info) = &self.sender_node_info { if let Some(sender_peer_info) = &self.opt_sender_peer_info {
let mut si_builder = builder.reborrow().init_sender_node_info(); let mut pi_builder = builder.reborrow().init_sender_peer_info();
encode_signed_node_info(&sender_info, &mut si_builder)?; encode_peer_info(&sender_peer_info, &mut pi_builder)?;
} }
builder.set_target_node_info_ts(self.target_node_info_ts.as_u64()); builder.set_target_node_info_ts(self.target_node_info_ts.as_u64());
let mut k_builder = builder.reborrow().init_kind(); let mut k_builder = builder.reborrow().init_kind();

View File

@ -19,9 +19,12 @@ impl RPCQuestion {
pub fn desc(&self) -> &'static str { pub fn desc(&self) -> &'static str {
self.detail.desc() self.detail.desc()
} }
pub fn decode(reader: &veilid_capnp::question::Reader) -> Result<RPCQuestion, RPCError> { pub fn decode(
reader: &veilid_capnp::question::Reader,
crypto: Crypto,
) -> Result<RPCQuestion, RPCError> {
let rt_reader = reader.get_respond_to(); let rt_reader = reader.get_respond_to();
let respond_to = RespondTo::decode(&rt_reader)?; let respond_to = RespondTo::decode(&rt_reader, crypto)?;
let d_reader = reader.get_detail(); let d_reader = reader.get_detail();
let detail = RPCQuestionDetail::decode(&d_reader)?; let detail = RPCQuestionDetail::decode(&d_reader)?;
Ok(RPCQuestion { respond_to, detail }) Ok(RPCQuestion { respond_to, detail })

View File

@ -23,12 +23,15 @@ impl RespondTo {
Ok(()) Ok(())
} }
pub fn decode(reader: &veilid_capnp::question::respond_to::Reader) -> Result<Self, RPCError> { pub fn decode(
reader: &veilid_capnp::question::respond_to::Reader,
crypto: Crypto,
) -> Result<Self, RPCError> {
let respond_to = match reader.which().map_err(RPCError::protocol)? { let respond_to = match reader.which().map_err(RPCError::protocol)? {
veilid_capnp::question::respond_to::Sender(()) => RespondTo::Sender, veilid_capnp::question::respond_to::Sender(()) => RespondTo::Sender,
veilid_capnp::question::respond_to::PrivateRoute(pr_reader) => { veilid_capnp::question::respond_to::PrivateRoute(pr_reader) => {
let pr_reader = pr_reader.map_err(RPCError::protocol)?; let pr_reader = pr_reader.map_err(RPCError::protocol)?;
let pr = decode_private_route(&pr_reader)?; let pr = decode_private_route(&pr_reader, crypto)?;
RespondTo::PrivateRoute(pr) RespondTo::PrivateRoute(pr)
} }
}; };

View File

@ -53,7 +53,7 @@ pub fn encode_route_hop(
match &route_hop.node { match &route_hop.node {
RouteNode::NodeId(ni) => { RouteNode::NodeId(ni) => {
let mut ni_builder = node_builder.init_node_id(); let mut ni_builder = node_builder.init_node_id();
encode_key256(&ni.key, &mut ni_builder)?; encode_key256(&ni, &mut ni_builder);
} }
RouteNode::PeerInfo(pi) => { RouteNode::PeerInfo(pi) => {
let mut pi_builder = node_builder.init_peer_info(); let mut pi_builder = node_builder.init_peer_info();
@ -67,17 +67,20 @@ pub fn encode_route_hop(
Ok(()) Ok(())
} }
pub fn decode_route_hop(reader: &veilid_capnp::route_hop::Reader) -> Result<RouteHop, RPCError> { pub fn decode_route_hop(
reader: &veilid_capnp::route_hop::Reader,
crypto: Crypto,
) -> Result<RouteHop, RPCError> {
let n_reader = reader.reborrow().get_node(); let n_reader = reader.reborrow().get_node();
let node = match n_reader.which().map_err(RPCError::protocol)? { let node = match n_reader.which().map_err(RPCError::protocol)? {
veilid_capnp::route_hop::node::Which::NodeId(ni) => { veilid_capnp::route_hop::node::Which::NodeId(ni) => {
let ni_reader = ni.map_err(RPCError::protocol)?; let ni_reader = ni.map_err(RPCError::protocol)?;
RouteNode::NodeId(NodeId::new(decode_key256(&ni_reader))) RouteNode::NodeId(decode_key256(&ni_reader))
} }
veilid_capnp::route_hop::node::Which::PeerInfo(pi) => { veilid_capnp::route_hop::node::Which::PeerInfo(pi) => {
let pi_reader = pi.map_err(RPCError::protocol)?; let pi_reader = pi.map_err(RPCError::protocol)?;
RouteNode::PeerInfo( RouteNode::PeerInfo(
decode_peer_info(&pi_reader) decode_peer_info(&pi_reader, crypto)
.map_err(RPCError::map_protocol("invalid peer info in route hop"))?, .map_err(RPCError::map_protocol("invalid peer info in route hop"))?,
) )
} }
@ -101,10 +104,10 @@ pub fn encode_private_route(
private_route: &PrivateRoute, private_route: &PrivateRoute,
builder: &mut veilid_capnp::private_route::Builder, builder: &mut veilid_capnp::private_route::Builder,
) -> Result<(), RPCError> { ) -> Result<(), RPCError> {
encode_key256( encode_typed_key(
&private_route.public_key, &private_route.public_key,
&mut builder.reborrow().init_public_key(), &mut builder.reborrow().init_public_key(),
)?; );
builder.set_hop_count(private_route.hop_count); builder.set_hop_count(private_route.hop_count);
let mut h_builder = builder.reborrow().init_hops(); let mut h_builder = builder.reborrow().init_hops();
match &private_route.hops { match &private_route.hops {
@ -125,16 +128,17 @@ pub fn encode_private_route(
pub fn decode_private_route( pub fn decode_private_route(
reader: &veilid_capnp::private_route::Reader, reader: &veilid_capnp::private_route::Reader,
crypto: Crypto,
) -> Result<PrivateRoute, RPCError> { ) -> Result<PrivateRoute, RPCError> {
let public_key = decode_key256(&reader.get_public_key().map_err(RPCError::map_protocol( let public_key = decode_typed_key(&reader.get_public_key().map_err(
"invalid public key in private route", RPCError::map_protocol("invalid public key in private route"),
))?); )?)?;
let hop_count = reader.get_hop_count(); let hop_count = reader.get_hop_count();
let hops = match reader.get_hops().which().map_err(RPCError::protocol)? { let hops = match reader.get_hops().which().map_err(RPCError::protocol)? {
veilid_capnp::private_route::hops::Which::FirstHop(rh_reader) => { veilid_capnp::private_route::hops::Which::FirstHop(rh_reader) => {
let rh_reader = rh_reader.map_err(RPCError::protocol)?; let rh_reader = rh_reader.map_err(RPCError::protocol)?;
PrivateRouteHops::FirstHop(decode_route_hop(&rh_reader)?) PrivateRouteHops::FirstHop(decode_route_hop(&rh_reader, crypto)?)
} }
veilid_capnp::private_route::hops::Which::Data(rhd_reader) => { veilid_capnp::private_route::hops::Which::Data(rhd_reader) => {
let rhd_reader = rhd_reader.map_err(RPCError::protocol)?; let rhd_reader = rhd_reader.map_err(RPCError::protocol)?;
@ -156,10 +160,10 @@ pub fn encode_safety_route(
safety_route: &SafetyRoute, safety_route: &SafetyRoute,
builder: &mut veilid_capnp::safety_route::Builder, builder: &mut veilid_capnp::safety_route::Builder,
) -> Result<(), RPCError> { ) -> Result<(), RPCError> {
encode_key256( encode_typed_key(
&safety_route.public_key, &safety_route.public_key,
&mut builder.reborrow().init_public_key(), &mut builder.reborrow().init_public_key(),
)?; );
builder.set_hop_count(safety_route.hop_count); builder.set_hop_count(safety_route.hop_count);
let h_builder = builder.reborrow().init_hops(); let h_builder = builder.reborrow().init_hops();
match &safety_route.hops { match &safety_route.hops {
@ -178,12 +182,13 @@ pub fn encode_safety_route(
pub fn decode_safety_route( pub fn decode_safety_route(
reader: &veilid_capnp::safety_route::Reader, reader: &veilid_capnp::safety_route::Reader,
crypto: Crypto,
) -> Result<SafetyRoute, RPCError> { ) -> Result<SafetyRoute, RPCError> {
let public_key = decode_key256( let public_key = decode_typed_key(
&reader &reader
.get_public_key() .get_public_key()
.map_err(RPCError::map_protocol("invalid public key in safety route"))?, .map_err(RPCError::map_protocol("invalid public key in safety route"))?,
); )?;
let hop_count = reader.get_hop_count(); let hop_count = reader.get_hop_count();
let hops = match reader.get_hops().which().map_err(RPCError::protocol)? { let hops = match reader.get_hops().which().map_err(RPCError::protocol)? {
veilid_capnp::safety_route::hops::Which::Data(rhd_reader) => { veilid_capnp::safety_route::hops::Which::Data(rhd_reader) => {
@ -192,7 +197,7 @@ pub fn decode_safety_route(
} }
veilid_capnp::safety_route::hops::Which::Private(pr_reader) => { veilid_capnp::safety_route::hops::Which::Private(pr_reader) => {
let pr_reader = pr_reader.map_err(RPCError::protocol)?; let pr_reader = pr_reader.map_err(RPCError::protocol)?;
SafetyRouteHops::Private(decode_private_route(&pr_reader)?) SafetyRouteHops::Private(decode_private_route(&pr_reader, crypto)?)
} }
}; };

View File

@ -162,8 +162,9 @@ impl RPCProcessor {
} }
SafetySelection::Safe(safety_spec) => { SafetySelection::Safe(safety_spec) => {
// Sent directly but with a safety route, respond to private route // Sent directly but with a safety route, respond to private route
let ck = target.best_node_id().kind;
let Some(pr_key) = rss let Some(pr_key) = rss
.get_private_route_for_safety_spec(safety_spec, &target.node_ids()) .get_private_route_for_safety_spec(ck, safety_spec, &target.node_ids().keys())
.map_err(RPCError::internal)? else { .map_err(RPCError::internal)? else {
return Ok(NetworkResult::no_connection_other("no private route for response at this time")); return Ok(NetworkResult::no_connection_other("no private route for response at this time"));
}; };
@ -187,10 +188,12 @@ impl RPCProcessor {
} }
SafetySelection::Safe(safety_spec) => { SafetySelection::Safe(safety_spec) => {
// Sent via a relay but with a safety route, respond to private route // Sent via a relay but with a safety route, respond to private route
let ck = target.best_node_id().kind;
let mut avoid_nodes = relay.node_ids(); let mut avoid_nodes = relay.node_ids();
avoid_nodes.add_all(&target.node_ids()); avoid_nodes.add_all(&target.node_ids());
let Some(pr_key) = rss let Some(pr_key) = rss
.get_private_route_for_safety_spec(safety_spec, &avoid_nodes) .get_private_route_for_safety_spec(ck, safety_spec, &avoid_nodes.keys())
.map_err(RPCError::internal)? else { .map_err(RPCError::internal)? else {
return Ok(NetworkResult::no_connection_other("no private route for response at this time")); return Ok(NetworkResult::no_connection_other("no private route for response at this time"));
}; };
@ -219,13 +222,13 @@ impl RPCProcessor {
// Determine if we can use optimized nodeinfo // Determine if we can use optimized nodeinfo
let route_node = match rss let route_node = match rss
.has_remote_private_route_seen_our_node_info(&private_route.public_key) .has_remote_private_route_seen_our_node_info(&private_route.public_key.key)
{ {
true => { true => {
if !routing_table.has_valid_own_node_info(RoutingDomain::PublicInternet) { 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")); return Ok(NetworkResult::no_connection_other("Own node info must be valid to use private route"));
} }
RouteNode::NodeId(routing_table.node_id(crypto_kind)) RouteNode::NodeId(routing_table.node_id(crypto_kind).key)
} }
false => { false => {
let Some(own_peer_info) = let Some(own_peer_info) =
@ -245,14 +248,14 @@ impl RPCProcessor {
// Check for loopback test // Check for loopback test
let pr_key = if safety_spec.preferred_route let pr_key = if safety_spec.preferred_route
== Some(private_route.public_key) == Some(private_route.public_key.key)
{ {
// Private route is also safety route during loopback test // Private route is also safety route during loopback test
private_route.public_key private_route.public_key.key
} else { } else {
// Get the privat route to respond to that matches the safety route spec we sent the request with // Get the private route to respond to that matches the safety route spec we sent the request with
let Some(pr_key) = rss let Some(pr_key) = rss
.get_private_route_for_safety_spec(safety_spec, &[avoid_node_id]) .get_private_route_for_safety_spec(crypto_kind, safety_spec, &[avoid_node_id])
.map_err(RPCError::internal)? else { .map_err(RPCError::internal)? else {
return Ok(NetworkResult::no_connection_other("no private route for response at this time")); return Ok(NetworkResult::no_connection_other("no private route for response at this time"));
}; };
@ -300,18 +303,25 @@ impl RPCProcessor {
}; };
// Reply directly to the request's source // Reply directly to the request's source
let sender_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 // This may be a different node's reference than the 'sender' in the case of a relay
let peer_noderef = detail.peer_noderef.clone(); let peer_noderef = detail.peer_noderef.clone();
// If the sender_id is that of the peer, then this is a direct reply // If the sender_id is that of the peer, then this is a direct reply
// else it is a relayed reply through the peer // else it is a relayed reply through the peer
xxx continue here, make sure respond to semantics are correct if peer_noderef.node_ids().contains(&sender_node_id) {
if peer_noderef.node_id() == sender_id {
NetworkResult::value(Destination::direct(peer_noderef)) NetworkResult::value(Destination::direct(peer_noderef))
} else { } else {
NetworkResult::value(Destination::relay(peer_noderef, sender_id)) // Look up the sender node, we should have added it via senderNodeInfo before getting here.
if let Some(sender_noderef) = self.routing_table.lookup_node_ref(sender_node_id) {
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) => { RespondTo::PrivateRoute(pr) => {

View File

@ -179,22 +179,22 @@ struct RenderedOperation {
/// Node information exchanged during every RPC message /// Node information exchanged during every RPC message
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct SenderSignedNodeInfo { pub struct SenderPeerInfo {
/// The current signed node info of the sender if required /// The current peer info of the sender if required
signed_node_info: Option<SignedNodeInfo>, opt_sender_peer_info: Option<PeerInfo>,
/// The last timestamp of the target's node info to assist remote node with sending its latest node info /// The last timestamp of the target's node info to assist remote node with sending its latest node info
target_node_info_ts: Timestamp, target_node_info_ts: Timestamp,
} }
impl SenderSignedNodeInfo { impl SenderPeerInfo {
pub fn new_no_sni(target_node_info_ts: Timestamp) -> Self { pub fn new_no_peer_info(target_node_info_ts: Timestamp) -> Self {
Self { Self {
signed_node_info: None, opt_sender_peer_info: None,
target_node_info_ts, target_node_info_ts,
} }
} }
pub fn new(sender_signed_node_info: SignedNodeInfo, target_node_info_ts: Timestamp) -> Self { pub fn new(sender_peer_info: PeerInfo, target_node_info_ts: Timestamp) -> Self {
Self { Self {
signed_node_info: Some(sender_signed_node_info), opt_sender_peer_info: Some(sender_peer_info),
target_node_info_ts, target_node_info_ts,
} }
} }
@ -686,17 +686,14 @@ impl RPCProcessor {
/// Get signed node info to package with RPC messages to improve /// Get signed node info to package with RPC messages to improve
/// routing table caching when it is okay to do so /// routing table caching when it is okay to do so
#[instrument(level = "trace", skip(self), ret, err)] #[instrument(level = "trace", skip(self), ret, err)]
fn get_sender_signed_node_info( fn get_sender_signed_node_info(&self, dest: &Destination) -> Result<SenderPeerInfo, RPCError> {
&self,
dest: &Destination,
) -> Result<SenderSignedNodeInfo, RPCError> {
// Don't do this if the sender is to remain private // Don't do this if the sender is to remain private
// Otherwise we would be attaching the original sender's identity to the final destination, // Otherwise we would be attaching the original sender's identity to the final destination,
// thus defeating the purpose of the safety route entirely :P // thus defeating the purpose of the safety route entirely :P
match dest.get_safety_selection() { match dest.get_safety_selection() {
SafetySelection::Unsafe(_) => {} SafetySelection::Unsafe(_) => {}
SafetySelection::Safe(_) => { SafetySelection::Safe(_) => {
return Ok(SenderSignedNodeInfo::default()); return Ok(SenderPeerInfo::default());
} }
} }
@ -716,14 +713,14 @@ impl RPCProcessor {
target target
} else { } else {
// Target was not in our routing table // Target was not in our routing table
return Ok(SenderSignedNodeInfo::default()); return Ok(SenderPeerInfo::default());
} }
} }
Destination::PrivateRoute { Destination::PrivateRoute {
private_route: _, private_route: _,
safety_selection: _, safety_selection: _,
} => { } => {
return Ok(SenderSignedNodeInfo::default()); return Ok(SenderPeerInfo::default());
} }
}; };
@ -737,7 +734,7 @@ impl RPCProcessor {
// Don't return our node info if it's not valid yet // 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 { let Some(own_peer_info) = routing_table.get_own_peer_info(routing_domain) else {
return Ok(SenderSignedNodeInfo::new_no_sni(target_node_info_ts)); return Ok(SenderPeerInfo::new_no_peer_info(target_node_info_ts));
}; };
// Get our node info timestamp // Get our node info timestamp
@ -745,10 +742,10 @@ impl RPCProcessor {
// If the target has seen our node info already don't send it again // If the target has seen our node info already don't send it again
if target.has_seen_our_node_info_ts(routing_domain, our_node_info_ts) { if target.has_seen_our_node_info_ts(routing_domain, our_node_info_ts) {
return Ok(SenderSignedNodeInfo::new_no_sni(target_node_info_ts)); return Ok(SenderPeerInfo::new_no_peer_info(target_node_info_ts));
} }
Ok(SenderSignedNodeInfo::new( Ok(SenderPeerInfo::new(
own_peer_info.signed_node_info, own_peer_info.signed_node_info,
target_node_info_ts, target_node_info_ts,
)) ))
@ -1205,19 +1202,20 @@ impl RPCProcessor {
RPCOperation::decode(&op_reader, Some(&sender_node_id))? RPCOperation::decode(&op_reader, Some(&sender_node_id))?
}; };
// Get the sender noderef, incorporating and 'sender node info' // Get the sender noderef, incorporating sender's peer info
let mut opt_sender_nr: Option<NodeRef> = None; let mut opt_sender_nr: Option<NodeRef> = None;
if let Some(sender_node_info) = operation.sender_node_info() { if let Some(sender_peer_info) = operation.sender_peer_info() {
// Sender NodeInfo was specified, update our routing table with it // Ensure the sender peer info is for the actual sender specified in the envelope
if !self.filter_node_info(routing_domain, &sender_node_info) {
// Sender PeerInfo was specified, update our routing table with it
if !self.filter_node_info(routing_domain, &sender_peer_info) {
return Err(RPCError::invalid_format( return Err(RPCError::invalid_format(
"sender signednodeinfo has invalid peer scope", "sender peerinfo has invalid peer scope",
)); ));
} }
opt_sender_nr = self.routing_table().register_node_with_signed_node_info( opt_sender_nr = self.routing_table().register_node_with_peer_info(
routing_domain, routing_domain,
sender_node_id, sender_peer_info,
sender_node_info.clone(),
false, false,
); );
} }

View File

@ -116,7 +116,7 @@ impl VeilidAPI {
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Attach/Detach // Attach/Detach
// get a full copy of the current state /// Get a full copy of the current state
pub async fn get_state(&self) -> Result<VeilidState, VeilidAPIError> { pub async fn get_state(&self) -> Result<VeilidState, VeilidAPIError> {
let attachment_manager = self.attachment_manager()?; let attachment_manager = self.attachment_manager()?;
let network_manager = attachment_manager.network_manager(); let network_manager = attachment_manager.network_manager();
@ -133,9 +133,7 @@ impl VeilidAPI {
}) })
} }
// get network connectedness /// Connect to the network
// connect to the network
#[instrument(level = "debug", err, skip_all)] #[instrument(level = "debug", err, skip_all)]
pub async fn attach(&self) -> Result<(), VeilidAPIError> { pub async fn attach(&self) -> Result<(), VeilidAPIError> {
let attachment_manager = self.attachment_manager()?; let attachment_manager = self.attachment_manager()?;
@ -145,7 +143,7 @@ impl VeilidAPI {
Ok(()) Ok(())
} }
// disconnect from the network /// Disconnect from the network
#[instrument(level = "debug", err, skip_all)] #[instrument(level = "debug", err, skip_all)]
pub async fn detach(&self) -> Result<(), VeilidAPIError> { pub async fn detach(&self) -> Result<(), VeilidAPIError> {
let attachment_manager = self.attachment_manager()?; let attachment_manager = self.attachment_manager()?;
@ -166,8 +164,12 @@ impl VeilidAPI {
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Private route allocation // Private route allocation
/// Allocate a new private route set with default cryptography and network options
/// Returns a list of the public key and published 'blob' pairs. Publishing as many of these
/// pairs as possible to the network is desirable as support for multiple cryptography
/// systems will require choosing a compatible route
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
pub async fn new_private_route(&self) -> Result<(TypedKeySet, Vec<u8>), VeilidAPIError> { pub async fn new_private_route(&self) -> Result<Vec<(PublicKey, Vec<u8>)>, VeilidAPIError> {
self.new_custom_private_route( self.new_custom_private_route(
&VALID_CRYPTO_KINDS, &VALID_CRYPTO_KINDS,
Stability::default(), Stability::default(),
@ -176,13 +178,14 @@ impl VeilidAPI {
.await .await
} }
///
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
pub async fn new_custom_private_route( pub async fn new_custom_private_route(
&self, &self,
crypto_kinds: &[CryptoKind], crypto_kinds: &[CryptoKind],
stability: Stability, stability: Stability,
sequencing: Sequencing, sequencing: Sequencing,
) -> Result<(TypedKeySet, Vec<u8>), VeilidAPIError> { ) -> Result<Vec<(PublicKey, Vec<u8>)>, VeilidAPIError> {
let default_route_hop_count: usize = { let default_route_hop_count: usize = {
let config = self.config()?; let config = self.config()?;
let c = config.get(); let c = config.get();
@ -229,14 +232,14 @@ impl VeilidAPI {
} }
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> Result<TypedKey, VeilidAPIError> { pub fn import_remote_private_route(&self, blob: Vec<u8>) -> Result<PublicKey, VeilidAPIError> {
let rss = self.routing_table()?.route_spec_store(); let rss = self.routing_table()?.route_spec_store();
rss.import_remote_private_route(blob) rss.import_remote_private_route(blob)
.map_err(|e| VeilidAPIError::invalid_argument(e, "blob", "private route blob")) .map_err(|e| VeilidAPIError::invalid_argument(e, "blob", "private route blob"))
} }
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
pub fn release_private_route(&self, key: &TypedKey) -> Result<(), VeilidAPIError> { pub fn release_private_route(&self, key: &PublicKey) -> Result<(), VeilidAPIError> {
let rss = self.routing_table()?.route_spec_store(); let rss = self.routing_table()?.route_spec_store();
if rss.release_route(key) { if rss.release_route(key) {
Ok(()) Ok(())

View File

@ -147,7 +147,7 @@ impl VeilidAPIError {
pub fn shutdown() -> Self { pub fn shutdown() -> Self {
Self::Shutdown Self::Shutdown
} }
pub fn key_not_found(key: TypedKey) -> Self { pub fn key_not_found(key: PublicKey) -> Self {
Self::KeyNotFound { key } Self::KeyNotFound { key }
} }
pub fn no_connection<T: ToString>(msg: T) -> Self { pub fn no_connection<T: ToString>(msg: T) -> Self {

View File

@ -4,8 +4,8 @@ use super::*;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Target { pub enum Target {
NodeId(TypedKey), NodeId(PublicKey),
PrivateRoute(TypedKey), PrivateRoute(PublicKey),
} }
pub struct RoutingContextInner {} pub struct RoutingContextInner {}
@ -225,11 +225,11 @@ impl RoutingContext {
/////////////////////////////////// ///////////////////////////////////
/// Block Store /// Block Store
pub async fn find_block(&self, _block_id: TypedKey) -> Result<Vec<u8>, VeilidAPIError> { pub async fn find_block(&self, _block_id: PublicKey) -> Result<Vec<u8>, VeilidAPIError> {
panic!("unimplemented"); panic!("unimplemented");
} }
pub async fn supply_block(&self, _block_id: TypedKey) -> Result<bool, VeilidAPIError> { pub async fn supply_block(&self, _block_id: PublicKey) -> Result<bool, VeilidAPIError> {
panic!("unimplemented"); panic!("unimplemented");
} }
} }

View File

@ -159,7 +159,7 @@ pub struct VeilidLog {
pub struct VeilidAppMessage { pub struct VeilidAppMessage {
/// Some(sender) if the message was sent directly, None if received via a private/safety route /// Some(sender) if the message was sent directly, None if received via a private/safety route
#[serde(with = "opt_json_as_string")] #[serde(with = "opt_json_as_string")]
pub sender: Option<TypedKey>, pub sender: Option<PublicKey>,
/// The content of the message to deliver to the application /// The content of the message to deliver to the application
#[serde(with = "json_as_base64")] #[serde(with = "json_as_base64")]
pub message: Vec<u8>, pub message: Vec<u8>,
@ -173,7 +173,7 @@ pub struct VeilidAppMessage {
pub struct VeilidAppCall { pub struct VeilidAppCall {
/// Some(sender) if the request was sent directly, None if received via a private/safety route /// Some(sender) if the request was sent directly, None if received via a private/safety route
#[serde(with = "opt_json_as_string")] #[serde(with = "opt_json_as_string")]
pub sender: Option<TypedKey>, pub sender: Option<PublicKey>,
/// The content of the request to deliver to the application /// The content of the request to deliver to the application
#[serde(with = "json_as_base64")] #[serde(with = "json_as_base64")]
pub message: Vec<u8>, pub message: Vec<u8>,
@ -513,7 +513,7 @@ impl SafetySelection {
#[archive_attr(repr(C), derive(CheckBytes))] #[archive_attr(repr(C), derive(CheckBytes))]
pub struct SafetySpec { pub struct SafetySpec {
/// preferred safety route if it still exists /// preferred safety route if it still exists
pub preferred_route: Option<TypedKey>, pub preferred_route: Option<PublicKey>,
/// must be greater than 0 /// must be greater than 0
pub hop_count: usize, pub hop_count: usize,
/// prefer reliability over speed /// prefer reliability over speed