mirror of
https://gitlab.com/veilid/veilid.git
synced 2024-12-12 09:14:25 -05:00
clippy work
This commit is contained in:
parent
6438a64fc7
commit
e4ee093951
@ -396,7 +396,7 @@ impl NetworkManager {
|
|||||||
dial_info_failures_map.insert(did.dial_info, ts);
|
dial_info_failures_map.insert(did.dial_info, ts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let dif_sort: Option<Arc<dyn Fn(&DialInfoDetail, &DialInfoDetail) -> core::cmp::Ordering>> = if dial_info_failures_map.is_empty() {
|
let dif_sort: Option<Arc<DialInfoDetailSort>> = if dial_info_failures_map.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Arc::new(move |a: &DialInfoDetail, b: &DialInfoDetail| {
|
Some(Arc::new(move |a: &DialInfoDetail, b: &DialInfoDetail| {
|
||||||
|
@ -75,8 +75,8 @@ impl Bucket {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
let bucket_data = SerializedBucketData { entries };
|
let bucket_data = SerializedBucketData { entries };
|
||||||
let out = serialize_json_bytes(&bucket_data);
|
|
||||||
out
|
serialize_json_bytes(bucket_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new entry with a node_id of this crypto kind and return it
|
/// Create a new entry with a node_id of this crypto kind and return it
|
||||||
@ -129,11 +129,8 @@ impl Bucket {
|
|||||||
let mut extra_entries = bucket_len - bucket_depth;
|
let mut extra_entries = bucket_len - bucket_depth;
|
||||||
|
|
||||||
// Get the sorted list of entries by their kick order
|
// Get the sorted list of entries by their kick order
|
||||||
let mut sorted_entries: Vec<(PublicKey, Arc<BucketEntry>)> = self
|
let mut sorted_entries: Vec<(PublicKey, Arc<BucketEntry>)> =
|
||||||
.entries
|
self.entries.iter().map(|(k, v)| (*k, v.clone())).collect();
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (k.clone(), v.clone()))
|
|
||||||
.collect();
|
|
||||||
let cur_ts = get_aligned_timestamp();
|
let cur_ts = get_aligned_timestamp();
|
||||||
sorted_entries.sort_by(|a, b| -> core::cmp::Ordering {
|
sorted_entries.sort_by(|a, b| -> core::cmp::Ordering {
|
||||||
if a.0 == b.0 {
|
if a.0 == b.0 {
|
||||||
|
@ -492,7 +492,7 @@ impl BucketEntryInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !only_live {
|
if !only_live {
|
||||||
return Some(v.clone());
|
return Some(*v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the connection is still considered live
|
// Check if the connection is still considered live
|
||||||
@ -509,7 +509,7 @@ impl BucketEntryInner {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if alive {
|
if alive {
|
||||||
Some(v.clone())
|
Some(*v)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -583,13 +583,11 @@ impl BucketEntryInner {
|
|||||||
RoutingDomain::LocalNetwork => self
|
RoutingDomain::LocalNetwork => self
|
||||||
.local_network
|
.local_network
|
||||||
.node_status
|
.node_status
|
||||||
.as_ref()
|
.as_ref().cloned(),
|
||||||
.map(|ns| ns.clone()),
|
|
||||||
RoutingDomain::PublicInternet => self
|
RoutingDomain::PublicInternet => self
|
||||||
.public_internet
|
.public_internet
|
||||||
.node_status
|
.node_status
|
||||||
.as_ref()
|
.as_ref().cloned()
|
||||||
.map(|ns| ns.clone()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -892,7 +890,7 @@ impl BucketEntry {
|
|||||||
F: FnOnce(&RoutingTableInner, &BucketEntryInner) -> R,
|
F: FnOnce(&RoutingTableInner, &BucketEntryInner) -> R,
|
||||||
{
|
{
|
||||||
let inner = self.inner.read();
|
let inner = self.inner.read();
|
||||||
f(rti, &*inner)
|
f(rti, &inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note, that this requires -also- holding the RoutingTable write lock, as a
|
// Note, that this requires -also- holding the RoutingTable write lock, as a
|
||||||
@ -902,7 +900,7 @@ impl BucketEntry {
|
|||||||
F: FnOnce(&mut RoutingTableInner, &mut BucketEntryInner) -> R,
|
F: FnOnce(&mut RoutingTableInner, &mut BucketEntryInner) -> R,
|
||||||
{
|
{
|
||||||
let mut inner = self.inner.write();
|
let mut inner = self.inner.write();
|
||||||
f(rti, &mut *inner)
|
f(rti, &mut inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal inner access for RoutingTableInner only
|
// Internal inner access for RoutingTableInner only
|
||||||
@ -911,7 +909,7 @@ impl BucketEntry {
|
|||||||
F: FnOnce(&BucketEntryInner) -> R,
|
F: FnOnce(&BucketEntryInner) -> R,
|
||||||
{
|
{
|
||||||
let inner = self.inner.read();
|
let inner = self.inner.read();
|
||||||
f(&*inner)
|
f(&inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal inner access for RoutingTableInner only
|
// Internal inner access for RoutingTableInner only
|
||||||
@ -920,7 +918,7 @@ impl BucketEntry {
|
|||||||
F: FnOnce(&mut BucketEntryInner) -> R,
|
F: FnOnce(&mut BucketEntryInner) -> R,
|
||||||
{
|
{
|
||||||
let mut inner = self.inner.write();
|
let mut inner = self.inner.write();
|
||||||
f(&mut *inner)
|
f(&mut inner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ impl RoutingTable {
|
|||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
|
|
||||||
out += &format!("Entries: {}\n", inner.bucket_entry_count());
|
out += &format!("Entries: {}\n", inner.bucket_entry_count());
|
||||||
out += &format!(" Live:\n");
|
out += " Live:\n";
|
||||||
for ec in inner.cached_entry_counts() {
|
for ec in inner.cached_entry_counts() {
|
||||||
let routing_domain = ec.0 .0;
|
let routing_domain = ec.0 .0;
|
||||||
let crypto_kind = ec.0 .1;
|
let crypto_kind = ec.0 .1;
|
||||||
|
@ -129,7 +129,7 @@ impl RoutingTableUnlockedInner {
|
|||||||
where
|
where
|
||||||
F: FnOnce(&VeilidConfigInner) -> R,
|
F: FnOnce(&VeilidConfigInner) -> R,
|
||||||
{
|
{
|
||||||
f(&*self.config.get())
|
f(&self.config.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_id(&self, kind: CryptoKind) -> TypedKey {
|
pub fn node_id(&self, kind: CryptoKind) -> TypedKey {
|
||||||
@ -541,7 +541,7 @@ impl RoutingTable {
|
|||||||
peer_b: &PeerInfo,
|
peer_b: &PeerInfo,
|
||||||
dial_info_filter: DialInfoFilter,
|
dial_info_filter: DialInfoFilter,
|
||||||
sequencing: Sequencing,
|
sequencing: Sequencing,
|
||||||
dif_sort: Option<Arc<dyn Fn(&DialInfoDetail, &DialInfoDetail) -> core::cmp::Ordering>>,
|
dif_sort: Option<Arc<DialInfoDetailSort>>,
|
||||||
) -> ContactMethod {
|
) -> ContactMethod {
|
||||||
self.inner.read().get_contact_method(
|
self.inner.read().get_contact_method(
|
||||||
routing_domain,
|
routing_domain,
|
||||||
@ -885,7 +885,7 @@ impl RoutingTable {
|
|||||||
crypto_kind: CryptoKind,
|
crypto_kind: CryptoKind,
|
||||||
max_per_type: usize,
|
max_per_type: usize,
|
||||||
) -> Vec<NodeRef> {
|
) -> Vec<NodeRef> {
|
||||||
let protocol_types = vec![
|
let protocol_types = [
|
||||||
ProtocolType::UDP,
|
ProtocolType::UDP,
|
||||||
ProtocolType::TCP,
|
ProtocolType::TCP,
|
||||||
ProtocolType::WS,
|
ProtocolType::WS,
|
||||||
@ -893,8 +893,8 @@ impl RoutingTable {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let protocol_types_len = protocol_types.len();
|
let protocol_types_len = protocol_types.len();
|
||||||
let mut nodes_proto_v4 = vec![0usize, 0usize, 0usize, 0usize];
|
let mut nodes_proto_v4 = [0usize, 0usize, 0usize, 0usize];
|
||||||
let mut nodes_proto_v6 = vec![0usize, 0usize, 0usize, 0usize];
|
let mut nodes_proto_v6 = [0usize, 0usize, 0usize, 0usize];
|
||||||
|
|
||||||
let filter = Box::new(
|
let filter = Box::new(
|
||||||
move |rti: &RoutingTableInner, entry: Option<Arc<BucketEntry>>| {
|
move |rti: &RoutingTableInner, entry: Option<Arc<BucketEntry>>| {
|
||||||
|
@ -85,7 +85,7 @@ pub trait NodeRefBase: Sized {
|
|||||||
self.common()
|
self.common()
|
||||||
.filter
|
.filter
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|f| f.dial_info_filter.clone())
|
.map(|f| f.dial_info_filter)
|
||||||
.unwrap_or(DialInfoFilter::all())
|
.unwrap_or(DialInfoFilter::all())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +283,7 @@ pub trait NodeRefBase: Sized {
|
|||||||
self.operate(|rti, e| {
|
self.operate(|rti, e| {
|
||||||
// apply sequencing to filter and get sort
|
// apply sequencing to filter and get sort
|
||||||
let sequencing = self.common().sequencing;
|
let sequencing = self.common().sequencing;
|
||||||
let filter = self.common().filter.clone().unwrap_or_default();
|
let filter = self.common().filter.unwrap_or_default();
|
||||||
let (ordered, filter) = filter.with_sequencing(sequencing);
|
let (ordered, filter) = filter.with_sequencing(sequencing);
|
||||||
let mut last_connections = e.last_connections(rti, true, filter);
|
let mut last_connections = e.last_connections(rti, true, filter);
|
||||||
|
|
||||||
@ -444,7 +444,7 @@ impl Clone for NodeRef {
|
|||||||
common: NodeRefBaseCommon {
|
common: NodeRefBaseCommon {
|
||||||
routing_table: self.common.routing_table.clone(),
|
routing_table: self.common.routing_table.clone(),
|
||||||
entry: self.common.entry.clone(),
|
entry: self.common.entry.clone(),
|
||||||
filter: self.common.filter.clone(),
|
filter: self.common.filter,
|
||||||
sequencing: self.common.sequencing,
|
sequencing: self.common.sequencing,
|
||||||
#[cfg(feature = "tracking")]
|
#[cfg(feature = "tracking")]
|
||||||
track_id: self.common.entry.write().track(),
|
track_id: self.common.entry.write().track(),
|
||||||
|
@ -18,7 +18,7 @@ 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(PublicKey),
|
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(Box<PeerInfo>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RouteNode {
|
impl RouteNode {
|
||||||
@ -41,7 +41,7 @@ impl RouteNode {
|
|||||||
Ok(nr) => nr,
|
Ok(nr) => nr,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log_rtab!(debug "failed to look up route node: {}", e);
|
log_rtab!(debug "failed to look up route node: {}", e);
|
||||||
return None;
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,13 +49,13 @@ impl RouteNode {
|
|||||||
//
|
//
|
||||||
match routing_table.register_node_with_peer_info(
|
match routing_table.register_node_with_peer_info(
|
||||||
RoutingDomain::PublicInternet,
|
RoutingDomain::PublicInternet,
|
||||||
pi.clone(),
|
*pi.clone(),
|
||||||
false,
|
false,
|
||||||
) {
|
) {
|
||||||
Ok(nr) => Some(nr),
|
Ok(nr) => Some(nr),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log_rtab!(debug "failed to register route node: {}", e);
|
log_rtab!(debug "failed to register route node: {}", e);
|
||||||
return None;
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ impl RouteHop {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum PrivateRouteHops {
|
pub enum PrivateRouteHops {
|
||||||
/// The first hop of a private route, unencrypted, route_hops == total hop count
|
/// The first hop of a private route, unencrypted, route_hops == total hop count
|
||||||
FirstHop(RouteHop),
|
FirstHop(Box<RouteHop>),
|
||||||
/// Private route internal node. Has > 0 private route hops left but < total hop count
|
/// Private route internal node. Has > 0 private route hops left but < total hop count
|
||||||
Data(RouteHopData),
|
Data(RouteHopData),
|
||||||
/// Private route has ended (hop count = 0)
|
/// Private route has ended (hop count = 0)
|
||||||
@ -134,10 +134,10 @@ impl PrivateRoute {
|
|||||||
Self {
|
Self {
|
||||||
public_key,
|
public_key,
|
||||||
hop_count: 1,
|
hop_count: 1,
|
||||||
hops: PrivateRouteHops::FirstHop(RouteHop {
|
hops: PrivateRouteHops::FirstHop(Box::new(RouteHop {
|
||||||
node,
|
node,
|
||||||
next_hop: None,
|
next_hop: None,
|
||||||
}),
|
})),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ fn _get_route_permutation_count(hop_count: usize) -> usize {
|
|||||||
// more than two nodes has factorial permutation
|
// more than two nodes has factorial permutation
|
||||||
// hop_count = 3 -> 2! -> 2
|
// hop_count = 3 -> 2! -> 2
|
||||||
// hop_count = 4 -> 3! -> 6
|
// hop_count = 4 -> 3! -> 6
|
||||||
(3..hop_count).into_iter().fold(2usize, |acc, x| acc * x)
|
(3..hop_count).fold(2usize, |acc, x| acc * x)
|
||||||
}
|
}
|
||||||
pub type PermReturnType = (Vec<usize>, bool);
|
pub type PermReturnType = (Vec<usize>, bool);
|
||||||
pub type PermFunc<'t> = Box<dyn FnMut(&[usize]) -> Option<PermReturnType> + Send + 't>;
|
pub type PermFunc<'t> = Box<dyn FnMut(&[usize]) -> Option<PermReturnType> + Send + 't>;
|
||||||
@ -47,7 +47,7 @@ pub fn with_route_permutations(
|
|||||||
f: &mut PermFunc,
|
f: &mut PermFunc,
|
||||||
) -> Option<PermReturnType> {
|
) -> Option<PermReturnType> {
|
||||||
if size == 1 {
|
if size == 1 {
|
||||||
return f(&permutation);
|
return f(permutation);
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..size {
|
for i in 0..size {
|
||||||
|
@ -112,7 +112,7 @@ impl RouteSetSpecDetail {
|
|||||||
}
|
}
|
||||||
pub fn contains_nodes(&self, nodes: &[TypedKey]) -> bool {
|
pub fn contains_nodes(&self, nodes: &[TypedKey]) -> bool {
|
||||||
for tk in nodes {
|
for tk in nodes {
|
||||||
for (_pk, rsd) in &self.route_set {
|
for rsd in self.route_set.values() {
|
||||||
if rsd.crypto_kind == tk.kind && rsd.hops.contains(&tk.value) {
|
if rsd.crypto_kind == tk.kind && rsd.hops.contains(&tk.value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,6 @@ impl RouteSpecStore {
|
|||||||
Ok(rss)
|
Ok(rss)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self), err)]
|
#[instrument(level = "trace", skip(self), err)]
|
||||||
pub async fn save(&self) -> EyreResult<()> {
|
pub async fn save(&self) -> EyreResult<()> {
|
||||||
let content = {
|
let content = {
|
||||||
@ -99,7 +98,9 @@ impl RouteSpecStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Save our content
|
// Save our content
|
||||||
content.save(self.unlocked_inner.routing_table.clone()).await?;
|
content
|
||||||
|
.save(self.unlocked_inner.routing_table.clone())
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -166,6 +167,7 @@ impl RouteSpecStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self, inner, rti), ret, err)]
|
#[instrument(level = "trace", skip(self, inner, rti), ret, err)]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn allocate_route_inner(
|
fn allocate_route_inner(
|
||||||
&self,
|
&self,
|
||||||
inner: &mut RouteSpecStoreInner,
|
inner: &mut RouteSpecStoreInner,
|
||||||
@ -197,7 +199,9 @@ impl RouteSpecStore {
|
|||||||
let our_peer_info = rti.get_own_peer_info(RoutingDomain::PublicInternet);
|
let our_peer_info = rti.get_own_peer_info(RoutingDomain::PublicInternet);
|
||||||
|
|
||||||
// Get relay node if we have one
|
// Get relay node if we have one
|
||||||
let opt_own_relay_nr = rti.relay_node(RoutingDomain::PublicInternet).map(|nr| nr.locked(rti));
|
let opt_own_relay_nr = rti
|
||||||
|
.relay_node(RoutingDomain::PublicInternet)
|
||||||
|
.map(|nr| nr.locked(rti));
|
||||||
|
|
||||||
// Get list of all nodes, and sort them for selection
|
// Get list of all nodes, and sort them for selection
|
||||||
let cur_ts = get_aligned_timestamp();
|
let cur_ts = get_aligned_timestamp();
|
||||||
@ -218,7 +222,6 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// Process node info exclusions
|
// Process node info exclusions
|
||||||
let keep = entry.with_inner(|e| {
|
let keep = entry.with_inner(|e| {
|
||||||
|
|
||||||
// Exclude nodes that don't have our requested crypto kinds
|
// Exclude nodes that don't have our requested crypto kinds
|
||||||
let common_ck = e.common_crypto_kinds(crypto_kinds);
|
let common_ck = e.common_crypto_kinds(crypto_kinds);
|
||||||
if common_ck.len() != crypto_kinds.len() {
|
if common_ck.len() != crypto_kinds.len() {
|
||||||
@ -242,7 +245,7 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// Relay check
|
// Relay check
|
||||||
let relay_ids = sni.relay_ids();
|
let relay_ids = sni.relay_ids();
|
||||||
if relay_ids.len() != 0 {
|
if !relay_ids.is_empty() {
|
||||||
// Exclude nodes whose relays we have chosen to avoid
|
// Exclude nodes whose relays we have chosen to avoid
|
||||||
if relay_ids.contains_any(avoid_nodes) {
|
if relay_ids.contains_any(avoid_nodes) {
|
||||||
return false;
|
return false;
|
||||||
@ -254,7 +257,7 @@ impl RouteSpecStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
true
|
||||||
});
|
});
|
||||||
if !keep {
|
if !keep {
|
||||||
return false;
|
return false;
|
||||||
@ -262,9 +265,12 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// Exclude nodes with no publicinternet nodeinfo, or incompatible nodeinfo or node status won't route
|
// Exclude nodes with no publicinternet nodeinfo, or incompatible nodeinfo or node status won't route
|
||||||
entry.with_inner(|e| {
|
entry.with_inner(|e| {
|
||||||
e.signed_node_info(RoutingDomain::PublicInternet).map(|sni|
|
e.signed_node_info(RoutingDomain::PublicInternet)
|
||||||
sni.has_sequencing_matched_dial_info(sequencing) && sni.node_info().has_capability(CAP_ROUTE)
|
.map(|sni| {
|
||||||
).unwrap_or(false)
|
sni.has_sequencing_matched_dial_info(sequencing)
|
||||||
|
&& sni.node_info().has_capability(CAP_ROUTE)
|
||||||
|
})
|
||||||
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
) as RoutingTableEntryFilter;
|
) as RoutingTableEntryFilter;
|
||||||
@ -273,7 +279,6 @@ impl RouteSpecStore {
|
|||||||
entry1: &Option<Arc<BucketEntry>>,
|
entry1: &Option<Arc<BucketEntry>>,
|
||||||
entry2: &Option<Arc<BucketEntry>>|
|
entry2: &Option<Arc<BucketEntry>>|
|
||||||
-> Ordering {
|
-> Ordering {
|
||||||
|
|
||||||
// Our own node is filtered out
|
// Our own node is filtered out
|
||||||
let entry1 = entry1.as_ref().unwrap().clone();
|
let entry1 = entry1.as_ref().unwrap().clone();
|
||||||
let entry2 = entry2.as_ref().unwrap().clone();
|
let entry2 = entry2.as_ref().unwrap().clone();
|
||||||
@ -302,8 +307,14 @@ impl RouteSpecStore {
|
|||||||
if matches!(sequencing, Sequencing::PreferOrdered) {
|
if matches!(sequencing, Sequencing::PreferOrdered) {
|
||||||
let cmp_seq = entry1.with_inner(|e1| {
|
let cmp_seq = entry1.with_inner(|e1| {
|
||||||
entry2.with_inner(|e2| {
|
entry2.with_inner(|e2| {
|
||||||
let e1_can_do_ordered = e1.signed_node_info(RoutingDomain::PublicInternet).map(|sni| sni.has_sequencing_matched_dial_info(sequencing)).unwrap_or(false);
|
let e1_can_do_ordered = e1
|
||||||
let e2_can_do_ordered = e2.signed_node_info(RoutingDomain::PublicInternet).map(|sni| sni.has_sequencing_matched_dial_info(sequencing)).unwrap_or(false);
|
.signed_node_info(RoutingDomain::PublicInternet)
|
||||||
|
.map(|sni| sni.has_sequencing_matched_dial_info(sequencing))
|
||||||
|
.unwrap_or(false);
|
||||||
|
let e2_can_do_ordered = e2
|
||||||
|
.signed_node_info(RoutingDomain::PublicInternet)
|
||||||
|
.map(|sni| sni.has_sequencing_matched_dial_info(sequencing))
|
||||||
|
.unwrap_or(false);
|
||||||
e2_can_do_ordered.cmp(&e1_can_do_ordered)
|
e2_can_do_ordered.cmp(&e1_can_do_ordered)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -313,27 +324,22 @@ impl RouteSpecStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// always prioritize reliable nodes, but sort by oldest or fastest
|
// always prioritize reliable nodes, but sort by oldest or fastest
|
||||||
let cmpout = entry1.with_inner(|e1| {
|
|
||||||
|
entry1.with_inner(|e1| {
|
||||||
entry2.with_inner(|e2| match stability {
|
entry2.with_inner(|e2| match stability {
|
||||||
Stability::LowLatency => {
|
Stability::LowLatency => BucketEntryInner::cmp_fastest_reliable(cur_ts, e1, e2),
|
||||||
BucketEntryInner::cmp_fastest_reliable(cur_ts, e1, e2)
|
Stability::Reliable => BucketEntryInner::cmp_oldest_reliable(cur_ts, e1, e2),
|
||||||
}
|
|
||||||
Stability::Reliable => {
|
|
||||||
BucketEntryInner::cmp_oldest_reliable(cur_ts, e1, e2)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
});
|
})
|
||||||
cmpout
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let routing_table = self.unlocked_inner.routing_table.clone();
|
let routing_table = self.unlocked_inner.routing_table.clone();
|
||||||
let transform =
|
let transform = |_rti: &RoutingTableInner, entry: Option<Arc<BucketEntry>>| -> NodeRef {
|
||||||
|_rti: &RoutingTableInner, entry: Option<Arc<BucketEntry>>| -> NodeRef {
|
NodeRef::new(routing_table.clone(), entry.unwrap(), None)
|
||||||
NodeRef::new(routing_table.clone(), entry.unwrap(), None)
|
};
|
||||||
};
|
|
||||||
|
|
||||||
// Pull the whole routing table in sorted order
|
// Pull the whole routing table in sorted order
|
||||||
let nodes:Vec<NodeRef> =
|
let nodes: Vec<NodeRef> =
|
||||||
rti.find_peers_with_sort_and_filter(usize::MAX, cur_ts, filters, compare, transform);
|
rti.find_peers_with_sort_and_filter(usize::MAX, cur_ts, filters, compare, transform);
|
||||||
|
|
||||||
// If we couldn't find enough nodes, wait until we have more nodes in the routing table
|
// If we couldn't find enough nodes, wait until we have more nodes in the routing table
|
||||||
@ -343,20 +349,27 @@ impl RouteSpecStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get peer info for everything
|
// Get peer info for everything
|
||||||
let nodes_pi: Vec<PeerInfo> = nodes.iter().map(|nr| nr.locked(rti).make_peer_info(RoutingDomain::PublicInternet).unwrap()).collect();
|
let nodes_pi: Vec<PeerInfo> = nodes
|
||||||
|
.iter()
|
||||||
|
.map(|nr| {
|
||||||
|
nr.locked(rti)
|
||||||
|
.make_peer_info(RoutingDomain::PublicInternet)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
// Now go through nodes and try to build a route we haven't seen yet
|
// Now go through nodes and try to build a route we haven't seen yet
|
||||||
let mut perm_func = Box::new(|permutation: &[usize]| {
|
let mut perm_func = Box::new(|permutation: &[usize]| {
|
||||||
|
|
||||||
// Get the hop cache key for a particular route permutation
|
// Get the hop cache key for a particular route permutation
|
||||||
// uses the same algorithm as RouteSetSpecDetail::make_cache_key
|
// uses the same algorithm as RouteSetSpecDetail::make_cache_key
|
||||||
let route_permutation_to_hop_cache = |_rti: &RoutingTableInner, nodes: &[NodeRef], perm: &[usize]| -> Vec<u8> {
|
let route_permutation_to_hop_cache =
|
||||||
let mut cache: Vec<u8> = Vec::with_capacity(perm.len() * PUBLIC_KEY_LENGTH);
|
|_rti: &RoutingTableInner, nodes: &[NodeRef], perm: &[usize]| -> Vec<u8> {
|
||||||
for n in perm {
|
let mut cache: Vec<u8> = Vec::with_capacity(perm.len() * PUBLIC_KEY_LENGTH);
|
||||||
cache.extend_from_slice(&nodes[*n].locked(rti).best_node_id().value.bytes)
|
for n in perm {
|
||||||
}
|
cache.extend_from_slice(&nodes[*n].locked(rti).best_node_id().value.bytes)
|
||||||
cache
|
}
|
||||||
};
|
cache
|
||||||
|
};
|
||||||
let cache_key = route_permutation_to_hop_cache(rti, &nodes, permutation);
|
let cache_key = route_permutation_to_hop_cache(rti, &nodes, permutation);
|
||||||
|
|
||||||
// Skip routes we have already seen
|
// Skip routes we have already seen
|
||||||
@ -491,21 +504,36 @@ impl RouteSpecStore {
|
|||||||
drop(perm_func);
|
drop(perm_func);
|
||||||
|
|
||||||
// Got a unique route, lets build the details, register it, and return it
|
// Got a unique route, lets build the details, register it, and return it
|
||||||
let hop_node_refs:Vec<NodeRef> = route_nodes
|
let hop_node_refs: Vec<NodeRef> = route_nodes.iter().map(|k| nodes[*k].clone()).collect();
|
||||||
.iter()
|
|
||||||
.map(|k| nodes[*k].clone())
|
|
||||||
.collect();
|
|
||||||
let mut route_set = BTreeMap::<PublicKey, RouteSpecDetail>::new();
|
let mut route_set = BTreeMap::<PublicKey, RouteSpecDetail>::new();
|
||||||
for crypto_kind in crypto_kinds.iter().copied() {
|
for crypto_kind in crypto_kinds.iter().copied() {
|
||||||
let vcrypto = self.unlocked_inner.routing_table.crypto().get(crypto_kind).unwrap();
|
let vcrypto = self
|
||||||
|
.unlocked_inner
|
||||||
|
.routing_table
|
||||||
|
.crypto()
|
||||||
|
.get(crypto_kind)
|
||||||
|
.unwrap();
|
||||||
let keypair = vcrypto.generate_keypair();
|
let keypair = vcrypto.generate_keypair();
|
||||||
let hops: Vec<PublicKey> = route_nodes.iter().map(|v| nodes[*v].locked(rti).node_ids().get(crypto_kind).unwrap().value).collect();
|
let hops: Vec<PublicKey> = route_nodes
|
||||||
|
.iter()
|
||||||
|
.map(|v| {
|
||||||
|
nodes[*v]
|
||||||
|
.locked(rti)
|
||||||
|
.node_ids()
|
||||||
|
.get(crypto_kind)
|
||||||
|
.unwrap()
|
||||||
|
.value
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
route_set.insert(keypair.key, RouteSpecDetail {
|
route_set.insert(
|
||||||
crypto_kind,
|
keypair.key,
|
||||||
secret_key: keypair.secret,
|
RouteSpecDetail {
|
||||||
hops,
|
crypto_kind,
|
||||||
});
|
secret_key: keypair.secret,
|
||||||
|
hops,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let rssd = RouteSetSpecDetail::new(
|
let rssd = RouteSetSpecDetail::new(
|
||||||
@ -517,7 +545,6 @@ impl RouteSpecStore {
|
|||||||
can_do_sequenced,
|
can_do_sequenced,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// make id
|
// make id
|
||||||
let id = self.generate_allocated_route_id(&rssd)?;
|
let id = self.generate_allocated_route_id(&rssd)?;
|
||||||
|
|
||||||
@ -525,14 +552,17 @@ impl RouteSpecStore {
|
|||||||
inner.cache.add_to_cache(rti, &rssd);
|
inner.cache.add_to_cache(rti, &rssd);
|
||||||
|
|
||||||
// Keep route in spec store
|
// Keep route in spec store
|
||||||
inner.content.add_detail(id.clone(), rssd);
|
inner.content.add_detail(id, rssd);
|
||||||
|
|
||||||
Ok(Some(id))
|
Ok(Some(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// validate data using a private route's key and signature chain
|
/// validate data using a private route's key and signature chain
|
||||||
#[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, data, callback), ret))]
|
#[cfg_attr(
|
||||||
pub fn with_signature_validated_route<F,R>(
|
feature = "verbose-tracing",
|
||||||
|
instrument(level = "trace", skip(self, data, callback), ret)
|
||||||
|
)]
|
||||||
|
pub fn with_signature_validated_route<F, R>(
|
||||||
&self,
|
&self,
|
||||||
public_key: &TypedKey,
|
public_key: &TypedKey,
|
||||||
signatures: &[Signature],
|
signatures: &[Signature],
|
||||||
@ -540,8 +570,9 @@ impl RouteSpecStore {
|
|||||||
last_hop_id: PublicKey,
|
last_hop_id: PublicKey,
|
||||||
callback: F,
|
callback: F,
|
||||||
) -> Option<R>
|
) -> Option<R>
|
||||||
where F: FnOnce(&RouteSetSpecDetail, &RouteSpecDetail) -> R,
|
where
|
||||||
R: fmt::Debug,
|
F: FnOnce(&RouteSetSpecDetail, &RouteSpecDetail) -> R,
|
||||||
|
R: fmt::Debug,
|
||||||
{
|
{
|
||||||
let inner = &*self.inner.lock();
|
let inner = &*self.inner.lock();
|
||||||
let crypto = self.unlocked_inner.routing_table.crypto();
|
let crypto = self.unlocked_inner.routing_table.crypto();
|
||||||
@ -591,11 +622,13 @@ impl RouteSpecStore {
|
|||||||
Some(callback(rssd, rsd))
|
Some(callback(rssd, rsd))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self), ret, err))]
|
#[cfg_attr(
|
||||||
|
feature = "verbose-tracing",
|
||||||
|
instrument(level = "trace", skip(self), ret, err)
|
||||||
|
)]
|
||||||
async fn test_allocated_route(&self, private_route_id: RouteId) -> EyreResult<bool> {
|
async fn test_allocated_route(&self, private_route_id: RouteId) -> EyreResult<bool> {
|
||||||
// Make loopback route to test with
|
// Make loopback route to test with
|
||||||
let dest = {
|
let dest = {
|
||||||
|
|
||||||
// Get the best private route for this id
|
// Get the best private route for this id
|
||||||
let (key, hop_count) = {
|
let (key, hop_count) = {
|
||||||
let inner = &mut *self.inner.lock();
|
let inner = &mut *self.inner.lock();
|
||||||
@ -646,10 +679,8 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
#[instrument(level = "trace", skip(self), ret, err)]
|
#[instrument(level = "trace", skip(self), ret, err)]
|
||||||
async fn test_remote_route(&self, private_route_id: RouteId) -> EyreResult<bool> {
|
async fn test_remote_route(&self, private_route_id: RouteId) -> EyreResult<bool> {
|
||||||
|
|
||||||
// Make private route test
|
// Make private route test
|
||||||
let dest = {
|
let dest = {
|
||||||
|
|
||||||
// Get the route to test
|
// Get the route to test
|
||||||
let Some(private_route) = self.best_remote_private_route(&private_route_id) else {
|
let Some(private_route) = self.best_remote_private_route(&private_route_id) else {
|
||||||
bail!("no best key to test remote route");
|
bail!("no best key to test remote route");
|
||||||
@ -710,11 +741,17 @@ impl RouteSpecStore {
|
|||||||
pub fn is_route_id_remote(&self, id: &RouteId) -> bool {
|
pub fn is_route_id_remote(&self, id: &RouteId) -> bool {
|
||||||
let inner = &mut *self.inner.lock();
|
let inner = &mut *self.inner.lock();
|
||||||
let cur_ts = get_aligned_timestamp();
|
let cur_ts = get_aligned_timestamp();
|
||||||
inner.cache.peek_remote_private_route_mut(cur_ts, &id).is_some()
|
inner
|
||||||
|
.cache
|
||||||
|
.peek_remote_private_route_mut(cur_ts, id)
|
||||||
|
.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test an allocated route for continuity
|
/// Test an allocated route for continuity
|
||||||
#[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self), ret, err))]
|
#[cfg_attr(
|
||||||
|
feature = "verbose-tracing",
|
||||||
|
instrument(level = "trace", skip(self), ret, err)
|
||||||
|
)]
|
||||||
pub async fn test_route(&self, id: RouteId) -> EyreResult<bool> {
|
pub async fn test_route(&self, id: RouteId) -> EyreResult<bool> {
|
||||||
let is_remote = self.is_route_id_remote(&id);
|
let is_remote = self.is_route_id_remote(&id);
|
||||||
if is_remote {
|
if is_remote {
|
||||||
@ -737,8 +774,9 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
/// Find first matching unpublished route that fits into the selection criteria
|
/// Find first matching unpublished route that fits into the selection criteria
|
||||||
/// Don't pick any routes that have failed and haven't been tested yet
|
/// Don't pick any routes that have failed and haven't been tested yet
|
||||||
fn first_available_route_inner<'a>(
|
#[allow(clippy::too_many_arguments)]
|
||||||
inner: &'a RouteSpecStoreInner,
|
fn first_available_route_inner(
|
||||||
|
inner: &RouteSpecStoreInner,
|
||||||
crypto_kind: CryptoKind,
|
crypto_kind: CryptoKind,
|
||||||
min_hop_count: usize,
|
min_hop_count: usize,
|
||||||
max_hop_count: usize,
|
max_hop_count: usize,
|
||||||
@ -821,7 +859,7 @@ impl RouteSpecStore {
|
|||||||
pub fn debug_route(&self, id: &RouteId) -> Option<String> {
|
pub fn debug_route(&self, id: &RouteId) -> Option<String> {
|
||||||
let inner = &mut *self.inner.lock();
|
let inner = &mut *self.inner.lock();
|
||||||
let cur_ts = get_aligned_timestamp();
|
let cur_ts = get_aligned_timestamp();
|
||||||
if let Some(rpri) = inner.cache.peek_remote_private_route_mut(cur_ts, &id) {
|
if let Some(rpri) = inner.cache.peek_remote_private_route_mut(cur_ts, id) {
|
||||||
return Some(format!("{:#?}", rpri));
|
return Some(format!("{:#?}", rpri));
|
||||||
}
|
}
|
||||||
if let Some(rssd) = inner.content.get_detail(id) {
|
if let Some(rssd) = inner.content.get_detail(id) {
|
||||||
@ -840,7 +878,6 @@ impl RouteSpecStore {
|
|||||||
rpri.best_private_route()
|
rpri.best_private_route()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Compiles a safety route to the private route, with caching
|
/// Compiles a safety route to the private route, with caching
|
||||||
/// Returns an Err() if the parameters are wrong
|
/// Returns an Err() if the parameters are wrong
|
||||||
/// Returns Ok(None) if no allocation could happen at this time (not an error)
|
/// Returns Ok(None) if no allocation could happen at this time (not an error)
|
||||||
@ -879,15 +916,15 @@ impl RouteSpecStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let opt_first_hop = match pr_first_hop_node {
|
let opt_first_hop = match pr_first_hop_node {
|
||||||
RouteNode::NodeId(id) => rti.lookup_node_ref(routing_table.clone(), TypedKey::new(crypto_kind, id))?,
|
RouteNode::NodeId(id) => {
|
||||||
RouteNode::PeerInfo(pi) => {
|
rti.lookup_node_ref(routing_table.clone(), TypedKey::new(crypto_kind, id))?
|
||||||
Some(rti.register_node_with_peer_info(
|
|
||||||
routing_table.clone(),
|
|
||||||
RoutingDomain::PublicInternet,
|
|
||||||
pi,
|
|
||||||
false,
|
|
||||||
)?)
|
|
||||||
}
|
}
|
||||||
|
RouteNode::PeerInfo(pi) => Some(rti.register_node_with_peer_info(
|
||||||
|
routing_table.clone(),
|
||||||
|
RoutingDomain::PublicInternet,
|
||||||
|
*pi,
|
||||||
|
false,
|
||||||
|
)?),
|
||||||
};
|
};
|
||||||
if opt_first_hop.is_none() {
|
if opt_first_hop.is_none() {
|
||||||
// Can't reach this private route any more
|
// Can't reach this private route any more
|
||||||
@ -902,7 +939,10 @@ impl RouteSpecStore {
|
|||||||
// Return the compiled safety route
|
// Return the compiled safety route
|
||||||
//println!("compile_safety_route profile (stub): {} us", (get_timestamp() - profile_start_ts));
|
//println!("compile_safety_route profile (stub): {} us", (get_timestamp() - profile_start_ts));
|
||||||
return Ok(Some(CompiledRoute {
|
return Ok(Some(CompiledRoute {
|
||||||
safety_route: SafetyRoute::new_stub(routing_table.node_id(crypto_kind), private_route),
|
safety_route: SafetyRoute::new_stub(
|
||||||
|
routing_table.node_id(crypto_kind),
|
||||||
|
private_route,
|
||||||
|
),
|
||||||
secret: routing_table.node_id_secret_key(crypto_kind),
|
secret: routing_table.node_id_secret_key(crypto_kind),
|
||||||
first_hop,
|
first_hop,
|
||||||
}));
|
}));
|
||||||
@ -911,14 +951,24 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// If the safety route requested is also the private route, this is a loopback test, just accept it
|
// If the safety route requested is also the private route, this is a loopback test, just accept it
|
||||||
let opt_private_route_id = inner.content.get_id_by_key(&pr_pubkey);
|
let opt_private_route_id = inner.content.get_id_by_key(&pr_pubkey);
|
||||||
let sr_pubkey = if opt_private_route_id.is_some() && safety_spec.preferred_route == opt_private_route_id {
|
let sr_pubkey = 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 is also safety route during loopback test
|
||||||
pr_pubkey
|
pr_pubkey
|
||||||
} else {
|
} else {
|
||||||
let Some(avoid_node_id) = private_route.first_hop_node_id() else {
|
let Some(avoid_node_id) = private_route.first_hop_node_id() else {
|
||||||
bail!("compiled private route should have first hop");
|
bail!("compiled private route should have first hop");
|
||||||
};
|
};
|
||||||
let Some(sr_pubkey) = self.get_route_for_safety_spec_inner(inner, rti, crypto_kind, &safety_spec, Direction::Outbound.into(), &[avoid_node_id])? else {
|
let Some(sr_pubkey) = self.get_route_for_safety_spec_inner(
|
||||||
|
inner,
|
||||||
|
rti,
|
||||||
|
crypto_kind,
|
||||||
|
&safety_spec,
|
||||||
|
Direction::Outbound.into(),
|
||||||
|
&[avoid_node_id],
|
||||||
|
)?
|
||||||
|
else {
|
||||||
// No safety route could be found for this spec
|
// No safety route could be found for this spec
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
@ -939,7 +989,8 @@ impl RouteSpecStore {
|
|||||||
// We can optimize the peer info in this safety route if it has been successfully
|
// We can optimize the peer info in this safety route if it has been successfully
|
||||||
// communicated over either via an outbound test, or used as a private route inbound
|
// communicated over either via an outbound test, or used as a private route inbound
|
||||||
// and we are replying over the same route as our safety route outbound
|
// and we are replying over the same route as our safety route outbound
|
||||||
let optimize = safety_rssd.get_stats().last_tested_ts.is_some() || safety_rssd.get_stats().last_received_ts.is_some();
|
let optimize = safety_rssd.get_stats().last_tested_ts.is_some()
|
||||||
|
|| safety_rssd.get_stats().last_received_ts.is_some();
|
||||||
|
|
||||||
// Get the first hop noderef of the safety route
|
// Get the first hop noderef of the safety route
|
||||||
let mut first_hop = safety_rssd.hop_node_ref(0).unwrap();
|
let mut first_hop = safety_rssd.hop_node_ref(0).unwrap();
|
||||||
@ -952,7 +1003,10 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// See if we have a cached route we can use
|
// See if we have a cached route we can use
|
||||||
if optimize {
|
if optimize {
|
||||||
if let Some(safety_route) = inner.cache.lookup_compiled_route_cache(sr_pubkey, pr_pubkey) {
|
if let Some(safety_route) = inner
|
||||||
|
.cache
|
||||||
|
.lookup_compiled_route_cache(sr_pubkey, pr_pubkey)
|
||||||
|
{
|
||||||
// Build compiled route
|
// Build compiled route
|
||||||
let compiled_route = CompiledRoute {
|
let compiled_route = CompiledRoute {
|
||||||
safety_route,
|
safety_route,
|
||||||
@ -993,9 +1047,9 @@ impl RouteSpecStore {
|
|||||||
let dh_secret = vcrypto
|
let dh_secret = vcrypto
|
||||||
.cached_dh(&safety_rsd.hops[h], &safety_rsd.secret_key)
|
.cached_dh(&safety_rsd.hops[h], &safety_rsd.secret_key)
|
||||||
.wrap_err("dh failed")?;
|
.wrap_err("dh failed")?;
|
||||||
let enc_msg_data =
|
let enc_msg_data = vcrypto
|
||||||
vcrypto.encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
.encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
||||||
.wrap_err("encryption failed")?;
|
.wrap_err("encryption failed")?;
|
||||||
|
|
||||||
// Make route hop data
|
// Make route hop data
|
||||||
let route_hop_data = RouteHopData {
|
let route_hop_data = RouteHopData {
|
||||||
@ -1021,7 +1075,7 @@ impl RouteSpecStore {
|
|||||||
if pi.is_none() {
|
if pi.is_none() {
|
||||||
bail!("peer info should exist for route but doesn't");
|
bail!("peer info should exist for route but doesn't");
|
||||||
}
|
}
|
||||||
RouteNode::PeerInfo(pi.unwrap())
|
RouteNode::PeerInfo(Box::new(pi.unwrap()))
|
||||||
},
|
},
|
||||||
next_hop: Some(route_hop_data),
|
next_hop: Some(route_hop_data),
|
||||||
};
|
};
|
||||||
@ -1045,7 +1099,8 @@ impl RouteSpecStore {
|
|||||||
let dh_secret = vcrypto
|
let dh_secret = vcrypto
|
||||||
.cached_dh(&safety_rsd.hops[0], &safety_rsd.secret_key)
|
.cached_dh(&safety_rsd.hops[0], &safety_rsd.secret_key)
|
||||||
.map_err(RPCError::map_internal("dh failed"))?;
|
.map_err(RPCError::map_internal("dh failed"))?;
|
||||||
let enc_msg_data = vcrypto.encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
let enc_msg_data = vcrypto
|
||||||
|
.encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
||||||
.map_err(RPCError::map_internal("encryption failed"))?;
|
.map_err(RPCError::map_internal("encryption failed"))?;
|
||||||
|
|
||||||
let route_hop_data = RouteHopData {
|
let route_hop_data = RouteHopData {
|
||||||
@ -1065,7 +1120,9 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// Add to cache but only if we have an optimized route
|
// Add to cache but only if we have an optimized route
|
||||||
if optimize {
|
if optimize {
|
||||||
inner.cache.add_to_compiled_route_cache( pr_pubkey, safety_route.clone());
|
inner
|
||||||
|
.cache
|
||||||
|
.add_to_compiled_route_cache(pr_pubkey, safety_route.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build compiled route
|
// Build compiled route
|
||||||
@ -1081,7 +1138,10 @@ impl RouteSpecStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get an allocated route that matches a particular safety spec
|
/// Get an allocated route that matches a particular safety spec
|
||||||
#[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, inner, rti), ret, err))]
|
#[cfg_attr(
|
||||||
|
feature = "verbose-tracing",
|
||||||
|
instrument(level = "trace", skip(self, inner, rti), ret, err)
|
||||||
|
)]
|
||||||
fn get_route_for_safety_spec_inner(
|
fn get_route_for_safety_spec_inner(
|
||||||
&self,
|
&self,
|
||||||
inner: &mut RouteSpecStoreInner,
|
inner: &mut RouteSpecStoreInner,
|
||||||
@ -1146,13 +1206,23 @@ impl RouteSpecStore {
|
|||||||
sr_route_id
|
sr_route_id
|
||||||
};
|
};
|
||||||
|
|
||||||
let sr_pubkey = inner.content.get_detail(&sr_route_id).unwrap().get_route_set_keys().get(crypto_kind).unwrap().value;
|
let sr_pubkey = inner
|
||||||
|
.content
|
||||||
|
.get_detail(&sr_route_id)
|
||||||
|
.unwrap()
|
||||||
|
.get_route_set_keys()
|
||||||
|
.get(crypto_kind)
|
||||||
|
.unwrap()
|
||||||
|
.value;
|
||||||
|
|
||||||
Ok(Some(sr_pubkey))
|
Ok(Some(sr_pubkey))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a private route to use for the answer to question
|
/// Get a private route to use for the answer to question
|
||||||
#[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self), ret, err))]
|
#[cfg_attr(
|
||||||
|
feature = "verbose-tracing",
|
||||||
|
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,
|
crypto_kind: CryptoKind,
|
||||||
@ -1173,8 +1243,12 @@ impl RouteSpecStore {
|
|||||||
)?)
|
)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assemble_private_route_inner(&self, key: &PublicKey, rsd: &RouteSpecDetail, optimized: bool) -> EyreResult<PrivateRoute>
|
fn assemble_private_route_inner(
|
||||||
{
|
&self,
|
||||||
|
key: &PublicKey,
|
||||||
|
rsd: &RouteSpecDetail,
|
||||||
|
optimized: bool,
|
||||||
|
) -> EyreResult<PrivateRoute> {
|
||||||
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();
|
||||||
|
|
||||||
@ -1198,7 +1272,7 @@ impl RouteSpecStore {
|
|||||||
RouteNode::NodeId(node_id.value)
|
RouteNode::NodeId(node_id.value)
|
||||||
} else {
|
} else {
|
||||||
let pi = rti.get_own_peer_info(RoutingDomain::PublicInternet);
|
let pi = rti.get_own_peer_info(RoutingDomain::PublicInternet);
|
||||||
RouteNode::PeerInfo(pi)
|
RouteNode::PeerInfo(Box::new(pi))
|
||||||
},
|
},
|
||||||
next_hop: None,
|
next_hop: None,
|
||||||
};
|
};
|
||||||
@ -1220,7 +1294,8 @@ impl RouteSpecStore {
|
|||||||
let dh_secret = vcrypto
|
let dh_secret = vcrypto
|
||||||
.cached_dh(&rsd.hops[h], &rsd.secret_key)
|
.cached_dh(&rsd.hops[h], &rsd.secret_key)
|
||||||
.wrap_err("dh failed")?;
|
.wrap_err("dh failed")?;
|
||||||
let enc_msg_data = vcrypto.encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
let enc_msg_data = vcrypto
|
||||||
|
.encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
||||||
.wrap_err("encryption failed")?;
|
.wrap_err("encryption failed")?;
|
||||||
let route_hop_data = RouteHopData {
|
let route_hop_data = RouteHopData {
|
||||||
nonce,
|
nonce,
|
||||||
@ -1244,7 +1319,7 @@ impl RouteSpecStore {
|
|||||||
if pi.is_none() {
|
if pi.is_none() {
|
||||||
bail!("peer info should exist for route but doesn't",);
|
bail!("peer info should exist for route but doesn't",);
|
||||||
}
|
}
|
||||||
RouteNode::PeerInfo(pi.unwrap())
|
RouteNode::PeerInfo(Box::new(pi.unwrap()))
|
||||||
},
|
},
|
||||||
next_hop: Some(route_hop_data),
|
next_hop: Some(route_hop_data),
|
||||||
}
|
}
|
||||||
@ -1261,7 +1336,10 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
/// Assemble a single private route for publication
|
/// Assemble a single private route for publication
|
||||||
/// Returns a PrivateRoute object for an allocated private route key
|
/// Returns a PrivateRoute object for an allocated private route key
|
||||||
#[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self), err))]
|
#[cfg_attr(
|
||||||
|
feature = "verbose-tracing",
|
||||||
|
instrument(level = "trace", skip(self), err)
|
||||||
|
)]
|
||||||
pub fn assemble_private_route(
|
pub fn assemble_private_route(
|
||||||
&self,
|
&self,
|
||||||
key: &PublicKey,
|
key: &PublicKey,
|
||||||
@ -1277,18 +1355,24 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// See if we can optimize this compilation yet
|
// See if we can optimize this compilation yet
|
||||||
// We don't want to include full nodeinfo if we don't have to
|
// We don't want to include full nodeinfo if we don't have to
|
||||||
let optimized = optimized
|
let optimized = optimized.unwrap_or(
|
||||||
.unwrap_or(rssd.get_stats().last_tested_ts.is_some() || rssd.get_stats().last_received_ts.is_some());
|
rssd.get_stats().last_tested_ts.is_some()
|
||||||
|
|| rssd.get_stats().last_received_ts.is_some(),
|
||||||
|
);
|
||||||
|
|
||||||
let rsd = rssd.get_route_by_key(key).expect("route key index is broken");
|
let rsd = rssd
|
||||||
|
.get_route_by_key(key)
|
||||||
|
.expect("route key index is broken");
|
||||||
|
|
||||||
self.assemble_private_route_inner(key, rsd, optimized)
|
self.assemble_private_route_inner(key, rsd, optimized)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Assemble private route set for publication
|
/// Assemble private route set for publication
|
||||||
/// Returns a vec of PrivateRoute objects for an allocated private route
|
/// Returns a vec of PrivateRoute objects for an allocated private route
|
||||||
#[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self), err))]
|
#[cfg_attr(
|
||||||
|
feature = "verbose-tracing",
|
||||||
|
instrument(level = "trace", skip(self), err)
|
||||||
|
)]
|
||||||
pub fn assemble_private_routes(
|
pub fn assemble_private_routes(
|
||||||
&self,
|
&self,
|
||||||
id: &RouteId,
|
id: &RouteId,
|
||||||
@ -1301,8 +1385,10 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// See if we can optimize this compilation yet
|
// See if we can optimize this compilation yet
|
||||||
// We don't want to include full nodeinfo if we don't have to
|
// We don't want to include full nodeinfo if we don't have to
|
||||||
let optimized = optimized
|
let optimized = optimized.unwrap_or(
|
||||||
.unwrap_or(rssd.get_stats().last_tested_ts.is_some() || rssd.get_stats().last_received_ts.is_some());
|
rssd.get_stats().last_tested_ts.is_some()
|
||||||
|
|| rssd.get_stats().last_received_ts.is_some(),
|
||||||
|
);
|
||||||
|
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
for (key, rsd) in rssd.iter_route_set() {
|
for (key, rsd) in rssd.iter_route_set() {
|
||||||
@ -1314,12 +1400,18 @@ impl RouteSpecStore {
|
|||||||
/// Import a remote private route for compilation
|
/// Import a remote private route for compilation
|
||||||
/// It is safe to import the same route more than once and it will return the same route id
|
/// It is safe to import the same route more than once and it will return the same route id
|
||||||
/// Returns a route set id
|
/// Returns a route set id
|
||||||
#[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, blob), ret, err))]
|
#[cfg_attr(
|
||||||
|
feature = "verbose-tracing",
|
||||||
|
instrument(level = "trace", skip(self, blob), ret, err)
|
||||||
|
)]
|
||||||
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> EyreResult<RouteId> {
|
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> EyreResult<RouteId> {
|
||||||
let cur_ts = get_aligned_timestamp();
|
let cur_ts = get_aligned_timestamp();
|
||||||
|
|
||||||
// decode the pr blob
|
// decode the pr blob
|
||||||
let private_routes = RouteSpecStore::blob_to_private_routes(self.unlocked_inner.routing_table.crypto(), blob)?;
|
let private_routes = RouteSpecStore::blob_to_private_routes(
|
||||||
|
self.unlocked_inner.routing_table.crypto(),
|
||||||
|
blob,
|
||||||
|
)?;
|
||||||
|
|
||||||
// make the route id
|
// make the route id
|
||||||
let id = self.generate_remote_route_id(&private_routes)?;
|
let id = self.generate_remote_route_id(&private_routes)?;
|
||||||
@ -1327,7 +1419,6 @@ impl RouteSpecStore {
|
|||||||
// validate the private routes
|
// validate the private routes
|
||||||
let inner = &mut *self.inner.lock();
|
let inner = &mut *self.inner.lock();
|
||||||
for private_route in &private_routes {
|
for private_route in &private_routes {
|
||||||
|
|
||||||
// ensure private route has first hop
|
// ensure private route has first hop
|
||||||
if !matches!(private_route.hops, PrivateRouteHops::FirstHop(_)) {
|
if !matches!(private_route.hops, PrivateRouteHops::FirstHop(_)) {
|
||||||
bail!("private route must have first hop");
|
bail!("private route must have first hop");
|
||||||
@ -1339,21 +1430,25 @@ impl RouteSpecStore {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
inner.cache.cache_remote_private_route(cur_ts, id, private_routes);
|
inner
|
||||||
|
.cache
|
||||||
|
.cache_remote_private_route(cur_ts, id, private_routes);
|
||||||
|
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Release a remote private route that is no longer in use
|
/// Release a remote private route that is no longer in use
|
||||||
#[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self), ret))]
|
#[cfg_attr(
|
||||||
|
feature = "verbose-tracing",
|
||||||
|
instrument(level = "trace", skip(self), ret)
|
||||||
|
)]
|
||||||
pub fn release_remote_private_route(&self, id: RouteId) -> bool {
|
pub fn release_remote_private_route(&self, id: RouteId) -> bool {
|
||||||
let inner = &mut *self.inner.lock();
|
let inner = &mut *self.inner.lock();
|
||||||
inner.cache.remove_remote_private_route(id)
|
inner.cache.remove_remote_private_route(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a route id for a route's public key
|
/// Get a route id for a route's public key
|
||||||
pub fn get_route_id_for_key(&self, key: &PublicKey) -> Option<RouteId>
|
pub fn get_route_id_for_key(&self, key: &PublicKey) -> Option<RouteId> {
|
||||||
{
|
|
||||||
let inner = &mut *self.inner.lock();
|
let inner = &mut *self.inner.lock();
|
||||||
// Check for local route
|
// Check for local route
|
||||||
if let Some(id) = inner.content.get_id_by_key(key) {
|
if let Some(id) = inner.content.get_id_by_key(key) {
|
||||||
@ -1371,7 +1466,6 @@ 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, key: &PublicKey) -> bool {
|
pub fn has_remote_private_route_seen_our_node_info(&self, key: &PublicKey) -> bool {
|
||||||
|
|
||||||
let inner = &mut *self.inner.lock();
|
let inner = &mut *self.inner.lock();
|
||||||
|
|
||||||
// Check for local route. If this is not a remote private route,
|
// Check for local route. If this is not a remote private route,
|
||||||
@ -1383,9 +1477,11 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
if let Some(rrid) = inner.cache.get_remote_private_route_id_by_key(key) {
|
if let Some(rrid) = inner.cache.get_remote_private_route_id_by_key(key) {
|
||||||
let cur_ts = get_aligned_timestamp();
|
let cur_ts = get_aligned_timestamp();
|
||||||
if let Some(rpri) = inner.cache.peek_remote_private_route_mut(cur_ts, &rrid)
|
if let Some(rpri) = inner.cache.peek_remote_private_route_mut(cur_ts, &rrid) {
|
||||||
{
|
let our_node_info_ts = self
|
||||||
let our_node_info_ts = self.unlocked_inner.routing_table.get_own_node_info_ts(RoutingDomain::PublicInternet);
|
.unlocked_inner
|
||||||
|
.routing_table
|
||||||
|
.get_own_node_info_ts(RoutingDomain::PublicInternet);
|
||||||
return rpri.has_seen_our_node_info_ts(our_node_info_ts);
|
return rpri.has_seen_our_node_info_ts(our_node_info_ts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1404,7 +1500,10 @@ impl RouteSpecStore {
|
|||||||
key: &PublicKey,
|
key: &PublicKey,
|
||||||
cur_ts: Timestamp,
|
cur_ts: Timestamp,
|
||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
let our_node_info_ts = self.unlocked_inner.routing_table.get_own_node_info_ts(RoutingDomain::PublicInternet);
|
let our_node_info_ts = self
|
||||||
|
.unlocked_inner
|
||||||
|
.routing_table
|
||||||
|
.get_own_node_info_ts(RoutingDomain::PublicInternet);
|
||||||
|
|
||||||
let inner = &mut *self.inner.lock();
|
let inner = &mut *self.inner.lock();
|
||||||
|
|
||||||
@ -1416,8 +1515,7 @@ impl RouteSpecStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rrid) = inner.cache.get_remote_private_route_id_by_key(key) {
|
if let Some(rrid) = inner.cache.get_remote_private_route_id_by_key(key) {
|
||||||
if let Some(rpri) = inner.cache.peek_remote_private_route_mut(cur_ts, &rrid)
|
if let Some(rpri) = inner.cache.peek_remote_private_route_mut(cur_ts, &rrid) {
|
||||||
{
|
|
||||||
rpri.set_last_seen_our_node_info_ts(our_node_info_ts);
|
rpri.set_last_seen_our_node_info_ts(our_node_info_ts);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -1434,7 +1532,11 @@ impl RouteSpecStore {
|
|||||||
let inner = &mut *self.inner.lock();
|
let inner = &mut *self.inner.lock();
|
||||||
|
|
||||||
// Check for stub route
|
// Check for stub route
|
||||||
if self.unlocked_inner.routing_table.matches_own_node_id_key(key) {
|
if self
|
||||||
|
.unlocked_inner
|
||||||
|
.routing_table
|
||||||
|
.matches_own_node_id_key(key)
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1447,8 +1549,7 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// Check for remote route
|
// Check for remote route
|
||||||
if let Some(rrid) = inner.cache.get_remote_private_route_id_by_key(key) {
|
if let Some(rrid) = inner.cache.get_remote_private_route_id_by_key(key) {
|
||||||
if let Some(rpri) = inner.cache.peek_remote_private_route_mut(cur_ts, &rrid)
|
if let Some(rpri) = inner.cache.peek_remote_private_route_mut(cur_ts, &rrid) {
|
||||||
{
|
|
||||||
return Some(f(rpri.get_stats_mut()));
|
return Some(f(rpri.get_stats_mut()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1493,7 +1594,6 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
/// Convert private route list to binary blob
|
/// Convert private route list to binary blob
|
||||||
pub fn private_routes_to_blob(private_routes: &[PrivateRoute]) -> EyreResult<Vec<u8>> {
|
pub fn private_routes_to_blob(private_routes: &[PrivateRoute]) -> EyreResult<Vec<u8>> {
|
||||||
|
|
||||||
let mut buffer = vec![];
|
let mut buffer = vec![];
|
||||||
|
|
||||||
// Serialize count
|
// Serialize count
|
||||||
@ -1521,7 +1621,6 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
/// Convert binary blob to private route
|
/// Convert binary blob to private route
|
||||||
pub fn blob_to_private_routes(crypto: Crypto, blob: Vec<u8>) -> EyreResult<Vec<PrivateRoute>> {
|
pub fn blob_to_private_routes(crypto: Crypto, blob: Vec<u8>) -> EyreResult<Vec<PrivateRoute>> {
|
||||||
|
|
||||||
// Deserialize count
|
// Deserialize count
|
||||||
if blob.is_empty() {
|
if blob.is_empty() {
|
||||||
bail!("not deserializing empty private route blob");
|
bail!("not deserializing empty private route blob");
|
||||||
@ -1547,16 +1646,17 @@ impl RouteSpecStore {
|
|||||||
.get_root::<veilid_capnp::private_route::Reader>()
|
.get_root::<veilid_capnp::private_route::Reader>()
|
||||||
.map_err(RPCError::internal)
|
.map_err(RPCError::internal)
|
||||||
.wrap_err("failed to make reader for private_route")?;
|
.wrap_err("failed to make reader for private_route")?;
|
||||||
let private_route = decode_private_route(&pr_reader).wrap_err("failed to decode private route")?;
|
let private_route =
|
||||||
private_route.validate(crypto.clone()).wrap_err("failed to validate private route")?;
|
decode_private_route(&pr_reader).wrap_err("failed to decode private route")?;
|
||||||
|
private_route
|
||||||
|
.validate(crypto.clone())
|
||||||
|
.wrap_err("failed to validate private route")?;
|
||||||
|
|
||||||
out.push(private_route);
|
out.push(private_route);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't trust the order of the blob
|
// Don't trust the order of the blob
|
||||||
out.sort_by(|a,b| {
|
out.sort_by(|a, b| a.public_key.cmp(&b.public_key));
|
||||||
a.public_key.cmp(&b.public_key)
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
@ -1567,9 +1667,11 @@ impl RouteSpecStore {
|
|||||||
let crypto = self.unlocked_inner.routing_table.crypto();
|
let crypto = self.unlocked_inner.routing_table.crypto();
|
||||||
|
|
||||||
let mut idbytes = Vec::with_capacity(PUBLIC_KEY_LENGTH * route_set_keys.len());
|
let mut idbytes = Vec::with_capacity(PUBLIC_KEY_LENGTH * route_set_keys.len());
|
||||||
let mut best_kind : Option<CryptoKind> = None;
|
let mut best_kind: Option<CryptoKind> = None;
|
||||||
for tk in route_set_keys.iter() {
|
for tk in route_set_keys.iter() {
|
||||||
if best_kind.is_none() || compare_crypto_kind(&tk.kind, best_kind.as_ref().unwrap()) == cmp::Ordering::Less {
|
if best_kind.is_none()
|
||||||
|
|| compare_crypto_kind(&tk.kind, best_kind.as_ref().unwrap()) == cmp::Ordering::Less
|
||||||
|
{
|
||||||
best_kind = Some(tk.kind);
|
best_kind = Some(tk.kind);
|
||||||
}
|
}
|
||||||
idbytes.extend_from_slice(&tk.value.bytes);
|
idbytes.extend_from_slice(&tk.value.bytes);
|
||||||
@ -1580,7 +1682,6 @@ impl RouteSpecStore {
|
|||||||
let vcrypto = crypto.get(best_kind).unwrap();
|
let vcrypto = crypto.get(best_kind).unwrap();
|
||||||
|
|
||||||
Ok(RouteId::new(vcrypto.generate_hash(&idbytes).bytes))
|
Ok(RouteId::new(vcrypto.generate_hash(&idbytes).bytes))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate RouteId from set of private routes
|
/// Generate RouteId from set of private routes
|
||||||
@ -1588,9 +1689,12 @@ impl RouteSpecStore {
|
|||||||
let crypto = self.unlocked_inner.routing_table.crypto();
|
let crypto = self.unlocked_inner.routing_table.crypto();
|
||||||
|
|
||||||
let mut idbytes = Vec::with_capacity(PUBLIC_KEY_LENGTH * private_routes.len());
|
let mut idbytes = Vec::with_capacity(PUBLIC_KEY_LENGTH * private_routes.len());
|
||||||
let mut best_kind : Option<CryptoKind> = None;
|
let mut best_kind: Option<CryptoKind> = None;
|
||||||
for private_route in private_routes {
|
for private_route in private_routes {
|
||||||
if best_kind.is_none() || compare_crypto_kind(&private_route.public_key.kind, best_kind.as_ref().unwrap()) == cmp::Ordering::Less {
|
if best_kind.is_none()
|
||||||
|
|| compare_crypto_kind(&private_route.public_key.kind, best_kind.as_ref().unwrap())
|
||||||
|
== cmp::Ordering::Less
|
||||||
|
{
|
||||||
best_kind = Some(private_route.public_key.kind);
|
best_kind = Some(private_route.public_key.kind);
|
||||||
}
|
}
|
||||||
idbytes.extend_from_slice(&private_route.public_key.value.bytes);
|
idbytes.extend_from_slice(&private_route.public_key.value.bytes);
|
||||||
@ -1602,5 +1706,4 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
Ok(RouteId::new(vcrypto.generate_hash(&idbytes).bytes))
|
Ok(RouteId::new(vcrypto.generate_hash(&idbytes).bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ impl RouteSpecStoreCache {
|
|||||||
// also store in id by key table
|
// also store in id by key table
|
||||||
for private_route in rprinfo.get_private_routes() {
|
for private_route in rprinfo.get_private_routes() {
|
||||||
self.remote_private_routes_by_key
|
self.remote_private_routes_by_key
|
||||||
.insert(private_route.public_key.value, id.clone());
|
.insert(private_route.public_key.value, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut dead = None;
|
let mut dead = None;
|
||||||
|
@ -29,18 +29,20 @@ impl RouteSpecStoreContent {
|
|||||||
for (rsid, rssd) in content.details.iter_mut() {
|
for (rsid, rssd) in content.details.iter_mut() {
|
||||||
// Get best route since they all should resolve
|
// Get best route since they all should resolve
|
||||||
let Some(pk) = rssd.get_best_route_set_key() else {
|
let Some(pk) = rssd.get_best_route_set_key() else {
|
||||||
dead_ids.push(rsid.clone());
|
dead_ids.push(*rsid);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let Some(rsd) = rssd.get_route_by_key(&pk) else {
|
let Some(rsd) = rssd.get_route_by_key(&pk) else {
|
||||||
dead_ids.push(rsid.clone());
|
dead_ids.push(*rsid);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
// Go through best route and resolve noderefs
|
// Go through best route and resolve noderefs
|
||||||
let mut hop_node_refs = Vec::with_capacity(rsd.hops.len());
|
let mut hop_node_refs = Vec::with_capacity(rsd.hops.len());
|
||||||
for h in &rsd.hops {
|
for h in &rsd.hops {
|
||||||
let Ok(Some(nr)) = routing_table.lookup_node_ref(TypedKey::new(rsd.crypto_kind, *h)) else {
|
let Ok(Some(nr)) =
|
||||||
dead_ids.push(rsid.clone());
|
routing_table.lookup_node_ref(TypedKey::new(rsd.crypto_kind, *h))
|
||||||
|
else {
|
||||||
|
dead_ids.push(*rsid);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
hop_node_refs.push(nr);
|
hop_node_refs.push(nr);
|
||||||
@ -72,14 +74,14 @@ impl RouteSpecStoreContent {
|
|||||||
|
|
||||||
// also store in id by key table
|
// also store in id by key table
|
||||||
for (pk, _) in detail.iter_route_set() {
|
for (pk, _) in detail.iter_route_set() {
|
||||||
self.id_by_key.insert(*pk, id.clone());
|
self.id_by_key.insert(*pk, id);
|
||||||
}
|
}
|
||||||
self.details.insert(id.clone(), detail);
|
self.details.insert(id, detail);
|
||||||
}
|
}
|
||||||
pub fn remove_detail(&mut self, id: &RouteId) -> Option<RouteSetSpecDetail> {
|
pub fn remove_detail(&mut self, id: &RouteId) -> Option<RouteSetSpecDetail> {
|
||||||
let detail = self.details.remove(id)?;
|
let detail = self.details.remove(id)?;
|
||||||
for (pk, _) in detail.iter_route_set() {
|
for (pk, _) in detail.iter_route_set() {
|
||||||
self.id_by_key.remove(&pk).unwrap();
|
self.id_by_key.remove(pk).unwrap();
|
||||||
}
|
}
|
||||||
Some(detail)
|
Some(detail)
|
||||||
}
|
}
|
||||||
@ -106,7 +108,7 @@ impl RouteSpecStoreContent {
|
|||||||
/// Resets publication status and statistics for when our node info changes
|
/// Resets publication status and statistics for when our node info changes
|
||||||
/// Routes must be republished
|
/// Routes must be republished
|
||||||
pub fn reset_details(&mut self) {
|
pub fn reset_details(&mut self) {
|
||||||
for (_k, v) in &mut self.details {
|
for v in self.details.values_mut() {
|
||||||
// Must republish route now
|
// Must republish route now
|
||||||
v.set_published(false);
|
v.set_published(false);
|
||||||
// Restart stats for routes so we test the route again
|
// Restart stats for routes so we test the route again
|
||||||
|
@ -276,7 +276,7 @@ fn first_filtered_dial_info_detail_between_nodes(
|
|||||||
to_node: &NodeInfo,
|
to_node: &NodeInfo,
|
||||||
dial_info_filter: &DialInfoFilter,
|
dial_info_filter: &DialInfoFilter,
|
||||||
sequencing: Sequencing,
|
sequencing: Sequencing,
|
||||||
dif_sort: Option<Arc<dyn Fn(&DialInfoDetail, &DialInfoDetail) -> core::cmp::Ordering>>
|
dif_sort: Option<Arc<DialInfoDetailSort>>
|
||||||
) -> Option<DialInfoDetail> {
|
) -> Option<DialInfoDetail> {
|
||||||
let dial_info_filter = dial_info_filter.clone().filtered(
|
let dial_info_filter = dial_info_filter.clone().filtered(
|
||||||
&DialInfoFilter::all()
|
&DialInfoFilter::all()
|
||||||
@ -289,7 +289,7 @@ fn first_filtered_dial_info_detail_between_nodes(
|
|||||||
// based on an external preference table, for example the one kept by
|
// based on an external preference table, for example the one kept by
|
||||||
// AddressFilter to deprioritize dialinfo that have recently failed to connect
|
// AddressFilter to deprioritize dialinfo that have recently failed to connect
|
||||||
let (ordered, dial_info_filter) = dial_info_filter.with_sequencing(sequencing);
|
let (ordered, dial_info_filter) = dial_info_filter.with_sequencing(sequencing);
|
||||||
let sort: Option<Box<dyn Fn(&DialInfoDetail, &DialInfoDetail) -> core::cmp::Ordering>> = if ordered {
|
let sort: Option<Box<DialInfoDetailSort>> = if ordered {
|
||||||
if let Some(dif_sort) = dif_sort {
|
if let Some(dif_sort) = dif_sort {
|
||||||
Some(Box::new(move |a, b| {
|
Some(Box::new(move |a, b| {
|
||||||
let mut ord = dif_sort(a,b);
|
let mut ord = dif_sort(a,b);
|
||||||
@ -582,7 +582,7 @@ impl RoutingDomainDetail for LocalNetworkRoutingDomainDetail {
|
|||||||
// based on an external preference table, for example the one kept by
|
// based on an external preference table, for example the one kept by
|
||||||
// AddressFilter to deprioritize dialinfo that have recently failed to connect
|
// AddressFilter to deprioritize dialinfo that have recently failed to connect
|
||||||
let (ordered, dial_info_filter) = dial_info_filter.with_sequencing(sequencing);
|
let (ordered, dial_info_filter) = dial_info_filter.with_sequencing(sequencing);
|
||||||
let sort: Option<Box<dyn Fn(&DialInfoDetail, &DialInfoDetail) -> core::cmp::Ordering>> = if ordered {
|
let sort: Option<Box<DialInfoDetailSort>> = if ordered {
|
||||||
if let Some(dif_sort) = dif_sort {
|
if let Some(dif_sort) = dif_sort {
|
||||||
Some(Box::new(move |a, b| {
|
Some(Box::new(move |a, b| {
|
||||||
let mut ord = dif_sort(a,b);
|
let mut ord = dif_sort(a,b);
|
||||||
|
@ -227,7 +227,7 @@ impl RoutingTableInner {
|
|||||||
peer_b: &PeerInfo,
|
peer_b: &PeerInfo,
|
||||||
dial_info_filter: DialInfoFilter,
|
dial_info_filter: DialInfoFilter,
|
||||||
sequencing: Sequencing,
|
sequencing: Sequencing,
|
||||||
dif_sort: Option<Arc<dyn Fn(&DialInfoDetail, &DialInfoDetail) -> core::cmp::Ordering>>,
|
dif_sort: Option<Arc<DialInfoDetailSort>>,
|
||||||
) -> ContactMethod {
|
) -> ContactMethod {
|
||||||
self.with_routing_domain(routing_domain, |rdd| {
|
self.with_routing_domain(routing_domain, |rdd| {
|
||||||
rdd.get_contact_method(self, peer_a, peer_b, dial_info_filter, sequencing, dif_sort)
|
rdd.get_contact_method(self, peer_a, peer_b, dial_info_filter, sequencing, dif_sort)
|
||||||
|
@ -46,7 +46,7 @@ impl RoutingTable {
|
|||||||
|
|
||||||
// Envelope support
|
// Envelope support
|
||||||
let mut envelope_support = Vec::new();
|
let mut envelope_support = Vec::new();
|
||||||
for ess in records[1].split(",") {
|
for ess in records[1].split(',') {
|
||||||
let ess = ess.trim();
|
let ess = ess.trim();
|
||||||
let es = match ess.parse::<u8>() {
|
let es = match ess.parse::<u8>() {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
@ -64,9 +64,9 @@ impl RoutingTable {
|
|||||||
|
|
||||||
// Node Id
|
// Node Id
|
||||||
let mut node_ids = TypedKeyGroup::new();
|
let mut node_ids = TypedKeyGroup::new();
|
||||||
for node_id_str in records[2].split(",") {
|
for node_id_str in records[2].split(',') {
|
||||||
let node_id_str = node_id_str.trim();
|
let node_id_str = node_id_str.trim();
|
||||||
let node_id = match TypedKey::from_str(&node_id_str) {
|
let node_id = match TypedKey::from_str(node_id_str) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
bail!(
|
bail!(
|
||||||
@ -89,7 +89,7 @@ impl RoutingTable {
|
|||||||
|
|
||||||
// Resolve each record and store in node dial infos list
|
// Resolve each record and store in node dial infos list
|
||||||
let mut dial_info_details = Vec::new();
|
let mut dial_info_details = Vec::new();
|
||||||
for rec in records[4].split(",") {
|
for rec in records[4].split(',') {
|
||||||
let rec = rec.trim();
|
let rec = rec.trim();
|
||||||
let dial_infos = match DialInfo::try_vec_from_short(rec, hostname_str) {
|
let dial_infos = match DialInfo::try_vec_from_short(rec, hostname_str) {
|
||||||
Ok(dis) => dis,
|
Ok(dis) => dis,
|
||||||
@ -321,7 +321,7 @@ impl RoutingTable {
|
|||||||
// See if we are specifying a direct dialinfo for bootstrap, if so use the direct mechanism
|
// See if we are specifying a direct dialinfo for bootstrap, if so use the direct mechanism
|
||||||
let mut bootstrap_dialinfos = Vec::<DialInfo>::new();
|
let mut bootstrap_dialinfos = Vec::<DialInfo>::new();
|
||||||
for b in &bootstrap {
|
for b in &bootstrap {
|
||||||
if let Ok(bootstrap_di_vec) = DialInfo::try_vec_from_url(&b) {
|
if let Ok(bootstrap_di_vec) = DialInfo::try_vec_from_url(b) {
|
||||||
for bootstrap_di in bootstrap_di_vec {
|
for bootstrap_di in bootstrap_di_vec {
|
||||||
bootstrap_dialinfos.push(bootstrap_di);
|
bootstrap_dialinfos.push(bootstrap_di);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,9 @@ use futures_util::stream::{FuturesUnordered, StreamExt};
|
|||||||
use futures_util::FutureExt;
|
use futures_util::FutureExt;
|
||||||
use stop_token::future::FutureExt as StopFutureExt;
|
use stop_token::future::FutureExt as StopFutureExt;
|
||||||
|
|
||||||
|
type PingValidatorFuture =
|
||||||
|
SendPinBoxFuture<Result<NetworkResult<Answer<Option<SenderInfo>>>, RPCError>>;
|
||||||
|
|
||||||
impl RoutingTable {
|
impl RoutingTable {
|
||||||
// Ping each node in the routing table if they need to be pinged
|
// Ping each node in the routing table if they need to be pinged
|
||||||
// to determine their reliability
|
// to determine their reliability
|
||||||
@ -16,9 +19,7 @@ impl RoutingTable {
|
|||||||
&self,
|
&self,
|
||||||
cur_ts: Timestamp,
|
cur_ts: Timestamp,
|
||||||
relay_nr: NodeRef,
|
relay_nr: NodeRef,
|
||||||
unord: &mut FuturesUnordered<
|
unord: &mut FuturesUnordered<PingValidatorFuture>,
|
||||||
SendPinBoxFuture<Result<NetworkResult<Answer<Option<SenderInfo>>>, RPCError>>,
|
|
||||||
>,
|
|
||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
let rpc = self.rpc_processor();
|
let rpc = self.rpc_processor();
|
||||||
// Get our publicinternet dial info
|
// Get our publicinternet dial info
|
||||||
@ -123,9 +124,7 @@ impl RoutingTable {
|
|||||||
async fn ping_validator_public_internet(
|
async fn ping_validator_public_internet(
|
||||||
&self,
|
&self,
|
||||||
cur_ts: Timestamp,
|
cur_ts: Timestamp,
|
||||||
unord: &mut FuturesUnordered<
|
unord: &mut FuturesUnordered<PingValidatorFuture>,
|
||||||
SendPinBoxFuture<Result<NetworkResult<Answer<Option<SenderInfo>>>, RPCError>>,
|
|
||||||
>,
|
|
||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
let rpc = self.rpc_processor();
|
let rpc = self.rpc_processor();
|
||||||
|
|
||||||
@ -161,9 +160,7 @@ impl RoutingTable {
|
|||||||
async fn ping_validator_local_network(
|
async fn ping_validator_local_network(
|
||||||
&self,
|
&self,
|
||||||
cur_ts: Timestamp,
|
cur_ts: Timestamp,
|
||||||
unord: &mut FuturesUnordered<
|
unord: &mut FuturesUnordered<PingValidatorFuture>,
|
||||||
SendPinBoxFuture<Result<NetworkResult<Answer<Option<SenderInfo>>>, RPCError>>,
|
|
||||||
>,
|
|
||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
let rpc = self.rpc_processor();
|
let rpc = self.rpc_processor();
|
||||||
|
|
||||||
|
@ -76,10 +76,10 @@ pub fn decode_route_hop(reader: &veilid_capnp::route_hop::Reader) -> Result<Rout
|
|||||||
}
|
}
|
||||||
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(Box::new(
|
||||||
decode_peer_info(&pi_reader)
|
decode_peer_info(&pi_reader)
|
||||||
.map_err(RPCError::map_protocol("invalid peer info in route hop"))?,
|
.map_err(RPCError::map_protocol("invalid peer info in route hop"))?,
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ pub fn decode_private_route(
|
|||||||
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(Box::new(decode_route_hop(&rh_reader)?))
|
||||||
}
|
}
|
||||||
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)?;
|
||||||
|
@ -181,10 +181,17 @@ impl RPCProcessor {
|
|||||||
// Sent directly but with a safety route, respond to private route
|
// Sent directly but with a safety route, respond to private route
|
||||||
let crypto_kind = target.best_node_id().kind;
|
let crypto_kind = target.best_node_id().kind;
|
||||||
let Some(pr_key) = rss
|
let Some(pr_key) = rss
|
||||||
.get_private_route_for_safety_spec(crypto_kind, safety_spec, &target.node_ids())
|
.get_private_route_for_safety_spec(
|
||||||
.map_err(RPCError::internal)? else {
|
crypto_kind,
|
||||||
return Ok(NetworkResult::no_connection_other("no private route for response at this time"));
|
safety_spec,
|
||||||
};
|
&target.node_ids(),
|
||||||
|
)
|
||||||
|
.map_err(RPCError::internal)?
|
||||||
|
else {
|
||||||
|
return Ok(NetworkResult::no_connection_other(
|
||||||
|
"no private route for response at this time",
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
// Get the assembled route for response
|
// Get the assembled route for response
|
||||||
let private_route = rss
|
let private_route = rss
|
||||||
@ -211,9 +218,12 @@ impl RPCProcessor {
|
|||||||
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(crypto_kind, safety_spec, &avoid_nodes)
|
.get_private_route_for_safety_spec(crypto_kind, safety_spec, &avoid_nodes)
|
||||||
.map_err(RPCError::internal)? else {
|
.map_err(RPCError::internal)?
|
||||||
return Ok(NetworkResult::no_connection_other("no private route for response at this time"));
|
else {
|
||||||
};
|
return Ok(NetworkResult::no_connection_other(
|
||||||
|
"no private route for response at this time",
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
// Get the assembled route for response
|
// Get the assembled route for response
|
||||||
let private_route = rss
|
let private_route = rss
|
||||||
@ -228,7 +238,9 @@ impl RPCProcessor {
|
|||||||
safety_selection,
|
safety_selection,
|
||||||
} => {
|
} => {
|
||||||
let Some(avoid_node_id) = private_route.first_hop_node_id() else {
|
let Some(avoid_node_id) = private_route.first_hop_node_id() else {
|
||||||
return Err(RPCError::internal("destination private route must have first hop"));
|
return Err(RPCError::internal(
|
||||||
|
"destination private route must have first hop",
|
||||||
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
let crypto_kind = private_route.public_key.kind;
|
let crypto_kind = private_route.public_key.kind;
|
||||||
@ -250,7 +262,7 @@ impl RPCProcessor {
|
|||||||
} else {
|
} else {
|
||||||
let own_peer_info =
|
let own_peer_info =
|
||||||
routing_table.get_own_peer_info(RoutingDomain::PublicInternet);
|
routing_table.get_own_peer_info(RoutingDomain::PublicInternet);
|
||||||
RouteNode::PeerInfo(own_peer_info)
|
RouteNode::PeerInfo(Box::new(own_peer_info))
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(NetworkResult::value(RespondTo::PrivateRoute(
|
Ok(NetworkResult::value(RespondTo::PrivateRoute(
|
||||||
@ -271,10 +283,17 @@ impl RPCProcessor {
|
|||||||
} else {
|
} else {
|
||||||
// Get the private 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(crypto_kind, safety_spec, &[avoid_node_id])
|
.get_private_route_for_safety_spec(
|
||||||
.map_err(RPCError::internal)? else {
|
crypto_kind,
|
||||||
return Ok(NetworkResult::no_connection_other("no private route for response at this time"));
|
safety_spec,
|
||||||
};
|
&[avoid_node_id],
|
||||||
|
)
|
||||||
|
.map_err(RPCError::internal)?
|
||||||
|
else {
|
||||||
|
return Ok(NetworkResult::no_connection_other(
|
||||||
|
"no private route for response at this time",
|
||||||
|
));
|
||||||
|
};
|
||||||
pr_key
|
pr_key
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -812,7 +812,7 @@ impl RPCProcessor {
|
|||||||
};
|
};
|
||||||
let private_route = PrivateRoute::new_stub(
|
let private_route = PrivateRoute::new_stub(
|
||||||
destination_node_ref.best_node_id(),
|
destination_node_ref.best_node_id(),
|
||||||
RouteNode::PeerInfo(peer_info),
|
RouteNode::PeerInfo(Box::new(peer_info)),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Wrap with safety route
|
// Wrap with safety route
|
||||||
|
Loading…
Reference in New Issue
Block a user