bug fixes
This commit is contained in:
parent
592c83d83a
commit
9c2a7488f1
@ -4,6 +4,7 @@ use super::*;
|
|||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use core::convert::TryInto;
|
use core::convert::TryInto;
|
||||||
|
use crate::routing_table::VersionRange;
|
||||||
|
|
||||||
// #[repr(C, packed)]
|
// #[repr(C, packed)]
|
||||||
// struct EnvelopeHeader {
|
// struct EnvelopeHeader {
|
||||||
@ -271,8 +272,11 @@ impl Envelope {
|
|||||||
self.version
|
self.version
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_min_max_version(&self) -> (u8, u8) {
|
pub fn get_min_max_version(&self) -> VersionRange {
|
||||||
(self.min_version, self.max_version)
|
VersionRange {
|
||||||
|
min: self.min_version,
|
||||||
|
max: self.max_version,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_timestamp(&self) -> u64 {
|
pub fn get_timestamp(&self) -> u64 {
|
||||||
|
@ -39,7 +39,7 @@ pub const DHT_SIGNATURE_LENGTH_ENCODED: usize = 86;
|
|||||||
macro_rules! byte_array_type {
|
macro_rules! byte_array_type {
|
||||||
($name:ident, $size:expr) => {
|
($name:ident, $size:expr) => {
|
||||||
#[derive(Clone, Copy, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
#[derive(Clone, Copy, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||||
#[archive_attr(repr(C), derive(CheckBytes))]
|
#[archive_attr(repr(C), derive(CheckBytes, Hash, Eq, PartialEq, PartialOrd, Ord))]
|
||||||
pub struct $name {
|
pub struct $name {
|
||||||
pub bytes: [u8; $size],
|
pub bytes: [u8; $size],
|
||||||
pub valid: bool,
|
pub valid: bool,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(target_arch = "wasm32")] {
|
if #[cfg(target_arch = "wasm32")] {
|
||||||
@ -223,7 +222,7 @@ impl<'a> TableDBTransaction<'a> {
|
|||||||
/// Store a key in rkyv format with a value in a column in the TableDB
|
/// Store a key in rkyv format with a value in a column in the TableDB
|
||||||
pub fn store_json<T>(&mut self, col: u32, key: &[u8], value: &T) -> EyreResult<()>
|
pub fn store_json<T>(&mut self, col: u32, key: &[u8], value: &T) -> EyreResult<()>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: serde::Serialize,
|
||||||
{
|
{
|
||||||
let v = serde_json::to_vec(value)?;
|
let v = serde_json::to_vec(value)?;
|
||||||
self.dbt.as_mut().unwrap().put(col, key, v.as_slice());
|
self.dbt.as_mut().unwrap().put(col, key, v.as_slice());
|
||||||
|
@ -646,15 +646,16 @@ impl NetworkManager {
|
|||||||
|
|
||||||
/// Get our node's capabilities in the PublicInternet routing domain
|
/// Get our node's capabilities in the PublicInternet routing domain
|
||||||
fn generate_public_internet_node_status(&self) -> PublicInternetNodeStatus {
|
fn generate_public_internet_node_status(&self) -> PublicInternetNodeStatus {
|
||||||
let node_info = self
|
let own_peer_info = self
|
||||||
.routing_table()
|
.routing_table()
|
||||||
.get_own_node_info(RoutingDomain::PublicInternet);
|
.get_own_peer_info(RoutingDomain::PublicInternet);
|
||||||
|
let own_node_info = own_peer_info.signed_node_info.node_info();
|
||||||
|
|
||||||
let will_route = node_info.can_inbound_relay(); // xxx: eventually this may have more criteria added
|
let will_route = own_node_info.can_inbound_relay(); // xxx: eventually this may have more criteria added
|
||||||
let will_tunnel = node_info.can_inbound_relay(); // xxx: we may want to restrict by battery life and network bandwidth at some point
|
let will_tunnel = own_node_info.can_inbound_relay(); // xxx: we may want to restrict by battery life and network bandwidth at some point
|
||||||
let will_signal = node_info.can_signal();
|
let will_signal = own_node_info.can_signal();
|
||||||
let will_relay = node_info.can_inbound_relay();
|
let will_relay = own_node_info.can_inbound_relay();
|
||||||
let will_validate_dial_info = node_info.can_validate_dial_info();
|
let will_validate_dial_info = own_node_info.can_validate_dial_info();
|
||||||
|
|
||||||
PublicInternetNodeStatus {
|
PublicInternetNodeStatus {
|
||||||
will_route,
|
will_route,
|
||||||
@ -666,12 +667,14 @@ impl NetworkManager {
|
|||||||
}
|
}
|
||||||
/// Get our node's capabilities in the LocalNetwork routing domain
|
/// Get our node's capabilities in the LocalNetwork routing domain
|
||||||
fn generate_local_network_node_status(&self) -> LocalNetworkNodeStatus {
|
fn generate_local_network_node_status(&self) -> LocalNetworkNodeStatus {
|
||||||
let node_info = self
|
let own_peer_info = self
|
||||||
.routing_table()
|
.routing_table()
|
||||||
.get_own_node_info(RoutingDomain::LocalNetwork);
|
.get_own_peer_info(RoutingDomain::LocalNetwork);
|
||||||
|
|
||||||
let will_relay = node_info.can_inbound_relay();
|
let own_node_info = own_peer_info.signed_node_info.node_info();
|
||||||
let will_validate_dial_info = node_info.can_validate_dial_info();
|
|
||||||
|
let will_relay = own_node_info.can_inbound_relay();
|
||||||
|
let will_validate_dial_info = own_node_info.can_validate_dial_info();
|
||||||
|
|
||||||
LocalNetworkNodeStatus {
|
LocalNetworkNodeStatus {
|
||||||
will_relay,
|
will_relay,
|
||||||
@ -960,17 +963,18 @@ impl NetworkManager {
|
|||||||
}
|
}
|
||||||
// Get node's min/max version and see if we can send to it
|
// Get node's min/max version 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 version = if let Some((node_min, node_max)) = node_ref.min_max_version() {
|
let version = if let Some(min_max_version) = node_ref.min_max_version() {
|
||||||
#[allow(clippy::absurd_extreme_comparisons)]
|
#[allow(clippy::absurd_extreme_comparisons)]
|
||||||
if node_min > MAX_CRYPTO_VERSION || node_max < MIN_CRYPTO_VERSION {
|
if min_max_version.min > MAX_CRYPTO_VERSION || min_max_version.max < MIN_CRYPTO_VERSION
|
||||||
|
{
|
||||||
bail!(
|
bail!(
|
||||||
"can't talk to this node {} because version is unsupported: ({},{})",
|
"can't talk to this node {} because version is unsupported: ({},{})",
|
||||||
via_node_id,
|
via_node_id,
|
||||||
node_min,
|
min_max_version.min,
|
||||||
node_max
|
min_max_version.max
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
cmp::min(node_max, MAX_CRYPTO_VERSION)
|
cmp::min(min_max_version.max, MAX_CRYPTO_VERSION)
|
||||||
} else {
|
} else {
|
||||||
MAX_CRYPTO_VERSION
|
MAX_CRYPTO_VERSION
|
||||||
};
|
};
|
||||||
|
@ -129,8 +129,8 @@ impl DiscoveryContext {
|
|||||||
move |rti: &RoutingTableInner, _k: DHTKey, v: Option<Arc<BucketEntry>>| {
|
move |rti: &RoutingTableInner, _k: DHTKey, v: Option<Arc<BucketEntry>>| {
|
||||||
let v = v.unwrap();
|
let v = v.unwrap();
|
||||||
v.with(rti, |_rti, e| {
|
v.with(rti, |_rti, e| {
|
||||||
if let Some(n) = e.node_info(RoutingDomain::PublicInternet) {
|
if let Some(n) = e.signed_node_info(RoutingDomain::PublicInternet) {
|
||||||
n.relay_peer_info.is_none()
|
n.relay_id().is_none()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -295,15 +295,14 @@ impl NetworkManager {
|
|||||||
if let Some(nr) = routing_table.register_node_with_signed_node_info(
|
if let Some(nr) = routing_table.register_node_with_signed_node_info(
|
||||||
RoutingDomain::PublicInternet,
|
RoutingDomain::PublicInternet,
|
||||||
k,
|
k,
|
||||||
SignedDirectNodeInfo::with_no_signature(NodeInfo {
|
SignedNodeInfo::Direct(SignedDirectNodeInfo::with_no_signature(NodeInfo {
|
||||||
network_class: NetworkClass::InboundCapable, // Bootstraps are always inbound capable
|
network_class: NetworkClass::InboundCapable, // Bootstraps are always inbound capable
|
||||||
outbound_protocols: ProtocolTypeSet::only(ProtocolType::UDP), // Bootstraps do not participate in relaying and will not make outbound requests, but will have UDP enabled
|
outbound_protocols: ProtocolTypeSet::only(ProtocolType::UDP), // Bootstraps do not participate in relaying and will not make outbound requests, but will have UDP enabled
|
||||||
address_types: AddressTypeSet::all(), // Bootstraps are always IPV4 and IPV6 capable
|
address_types: AddressTypeSet::all(), // Bootstraps are always IPV4 and IPV6 capable
|
||||||
min_version: v.min_version, // Minimum crypto version specified in txt record
|
min_version: v.min_version, // Minimum crypto version specified in txt record
|
||||||
max_version: v.max_version, // Maximum crypto version specified in txt record
|
max_version: v.max_version, // Maximum crypto version specified in txt record
|
||||||
dial_info_detail_list: v.dial_info_details, // Dial info is as specified in the bootstrap list
|
dial_info_detail_list: v.dial_info_details, // Dial info is as specified in the bootstrap list
|
||||||
relay_peer_info: None, // Bootstraps never require a relay themselves
|
})),
|
||||||
}),
|
|
||||||
true,
|
true,
|
||||||
) {
|
) {
|
||||||
// Add this our futures to process in parallel
|
// Add this our futures to process in parallel
|
||||||
@ -524,7 +523,8 @@ impl NetworkManager {
|
|||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
// Get our node's current node info and network class and do the right thing
|
// Get our node's current node info and network class and do the right thing
|
||||||
let routing_table = self.routing_table();
|
let routing_table = self.routing_table();
|
||||||
let node_info = routing_table.get_own_node_info(RoutingDomain::PublicInternet);
|
let own_peer_info = routing_table.get_own_peer_info(RoutingDomain::PublicInternet);
|
||||||
|
let own_node_info = own_peer_info.signed_node_info.node_info();
|
||||||
let network_class = routing_table.get_network_class(RoutingDomain::PublicInternet);
|
let network_class = routing_table.get_network_class(RoutingDomain::PublicInternet);
|
||||||
|
|
||||||
// Get routing domain editor
|
// Get routing domain editor
|
||||||
@ -541,7 +541,7 @@ impl NetworkManager {
|
|||||||
info!("Relay node died, dropping relay {}", relay_node);
|
info!("Relay node died, dropping relay {}", relay_node);
|
||||||
editor.clear_relay_node();
|
editor.clear_relay_node();
|
||||||
false
|
false
|
||||||
} else if !node_info.requires_relay() {
|
} else if !own_node_info.requires_relay() {
|
||||||
info!(
|
info!(
|
||||||
"Relay node no longer required, dropping relay {}",
|
"Relay node no longer required, dropping relay {}",
|
||||||
relay_node
|
relay_node
|
||||||
@ -557,7 +557,7 @@ impl NetworkManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Do we need a relay?
|
// Do we need a relay?
|
||||||
if !has_relay && node_info.requires_relay() {
|
if !has_relay && own_node_info.requires_relay() {
|
||||||
// Do we want an outbound relay?
|
// Do we want an outbound relay?
|
||||||
let mut got_outbound_relay = false;
|
let mut got_outbound_relay = false;
|
||||||
if network_class.outbound_wants_relay() {
|
if network_class.outbound_wants_relay() {
|
||||||
@ -604,7 +604,7 @@ impl NetworkManager {
|
|||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
// Get our node's current node info and network class and do the right thing
|
// Get our node's current node info and network class and do the right thing
|
||||||
let routing_table = self.routing_table();
|
let routing_table = self.routing_table();
|
||||||
let node_info = routing_table.get_own_node_info(RoutingDomain::PublicInternet);
|
let own_peer_info = routing_table.get_own_peer_info(RoutingDomain::PublicInternet);
|
||||||
let network_class = routing_table.get_network_class(RoutingDomain::PublicInternet);
|
let network_class = routing_table.get_network_class(RoutingDomain::PublicInternet);
|
||||||
|
|
||||||
// Get routing domain editor
|
// Get routing domain editor
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use core::sync::atomic::{AtomicU32, Ordering};
|
use core::sync::atomic::{AtomicU32, Ordering};
|
||||||
use serde::{Deserialize, Serialize};
|
use rkyv::with::Skip;
|
||||||
|
|
||||||
/// Reliable pings are done with increased spacing between pings
|
/// Reliable pings are done with increased spacing between pings
|
||||||
|
|
||||||
@ -40,10 +40,11 @@ pub enum BucketEntryState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||||
struct LastConnectionKey(ProtocolType, AddressType);
|
pub struct LastConnectionKey(ProtocolType, AddressType);
|
||||||
|
|
||||||
/// Bucket entry information specific to the LocalNetwork RoutingDomain
|
/// Bucket entry information specific to the LocalNetwork RoutingDomain
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||||
|
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||||
pub struct BucketEntryPublicInternet {
|
pub struct BucketEntryPublicInternet {
|
||||||
/// The PublicInternet node info
|
/// The PublicInternet node info
|
||||||
signed_node_info: Option<Box<SignedNodeInfo>>,
|
signed_node_info: Option<Box<SignedNodeInfo>>,
|
||||||
@ -54,7 +55,8 @@ pub struct BucketEntryPublicInternet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Bucket entry information specific to the LocalNetwork RoutingDomain
|
/// Bucket entry information specific to the LocalNetwork RoutingDomain
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||||
|
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||||
pub struct BucketEntryLocalNetwork {
|
pub struct BucketEntryLocalNetwork {
|
||||||
/// The LocalNetwork node info
|
/// The LocalNetwork node info
|
||||||
signed_node_info: Option<Box<SignedNodeInfo>>,
|
signed_node_info: Option<Box<SignedNodeInfo>>,
|
||||||
@ -65,16 +67,18 @@ pub struct BucketEntryLocalNetwork {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A range of cryptography versions supported by this entry
|
/// A range of cryptography versions supported by this entry
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||||
|
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||||
pub struct VersionRange {
|
pub struct VersionRange {
|
||||||
/// The minimum cryptography version supported by this entry
|
/// The minimum cryptography version supported by this entry
|
||||||
min: u8,
|
pub min: u8,
|
||||||
/// The maximum cryptography version supported by this entry
|
/// The maximum cryptography version supported by this entry
|
||||||
max: u8,
|
pub max: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The data associated with each bucket entry
|
/// The data associated with each bucket entry
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||||
|
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||||
pub struct BucketEntryInner {
|
pub struct BucketEntryInner {
|
||||||
/// The minimum and maximum range of cryptography versions supported by the node,
|
/// The minimum and maximum range of cryptography versions supported by the node,
|
||||||
/// inclusive of the requirements of any relay the node may be using
|
/// inclusive of the requirements of any relay the node may be using
|
||||||
@ -83,7 +87,7 @@ pub struct BucketEntryInner {
|
|||||||
/// and dial info has last changed, for example when our IP address changes
|
/// and dial info has last changed, for example when our IP address changes
|
||||||
updated_since_last_network_change: bool,
|
updated_since_last_network_change: bool,
|
||||||
/// The last connection descriptors used to contact this node, per protocol type
|
/// The last connection descriptors used to contact this node, per protocol type
|
||||||
#[serde(skip)]
|
#[with(Skip)]
|
||||||
last_connections: BTreeMap<LastConnectionKey, (ConnectionDescriptor, u64)>,
|
last_connections: BTreeMap<LastConnectionKey, (ConnectionDescriptor, u64)>,
|
||||||
/// The node info for this entry on the publicinternet routing domain
|
/// The node info for this entry on the publicinternet routing domain
|
||||||
public_internet: BucketEntryPublicInternet,
|
public_internet: BucketEntryPublicInternet,
|
||||||
@ -92,18 +96,18 @@ pub struct BucketEntryInner {
|
|||||||
/// Statistics gathered for the peer
|
/// Statistics gathered for the peer
|
||||||
peer_stats: PeerStats,
|
peer_stats: PeerStats,
|
||||||
/// The accounting for the latency statistics
|
/// The accounting for the latency statistics
|
||||||
#[serde(skip)]
|
#[with(Skip)]
|
||||||
latency_stats_accounting: LatencyStatsAccounting,
|
latency_stats_accounting: LatencyStatsAccounting,
|
||||||
/// The accounting for the transfer statistics
|
/// The accounting for the transfer statistics
|
||||||
#[serde(skip)]
|
#[with(Skip)]
|
||||||
transfer_stats_accounting: TransferStatsAccounting,
|
transfer_stats_accounting: TransferStatsAccounting,
|
||||||
/// Tracking identifier for NodeRef debugging
|
/// Tracking identifier for NodeRef debugging
|
||||||
#[cfg(feature = "tracking")]
|
#[cfg(feature = "tracking")]
|
||||||
#[serde(skip)]
|
#[with(Skip)]
|
||||||
next_track_id: usize,
|
next_track_id: usize,
|
||||||
/// Backtraces for NodeRef debugging
|
/// Backtraces for NodeRef debugging
|
||||||
#[cfg(feature = "tracking")]
|
#[cfg(feature = "tracking")]
|
||||||
#[serde(skip)]
|
#[with(Skip)]
|
||||||
node_ref_tracks: HashMap<usize, backtrace::Backtrace>,
|
node_ref_tracks: HashMap<usize, backtrace::Backtrace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl RoutingTable {
|
impl RoutingTable {
|
||||||
pub fn debug_info_nodeinfo(&self) -> String {
|
pub(crate) fn debug_info_nodeinfo(&self) -> String {
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
let inner = self.inner.read();
|
let inner = self.inner.read();
|
||||||
out += "Routing Table Info:\n";
|
out += "Routing Table Info:\n";
|
||||||
@ -23,7 +23,7 @@ impl RoutingTable {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn debug_info_txtrecord(&self) -> String {
|
pub(crate) async fn debug_info_txtrecord(&self) -> String {
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
|
|
||||||
let gdis = self.dial_info_details(RoutingDomain::PublicInternet);
|
let gdis = self.dial_info_details(RoutingDomain::PublicInternet);
|
||||||
@ -71,7 +71,7 @@ impl RoutingTable {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_info_dialinfo(&self) -> String {
|
pub(crate) fn debug_info_dialinfo(&self) -> String {
|
||||||
let ldis = self.dial_info_details(RoutingDomain::LocalNetwork);
|
let ldis = self.dial_info_details(RoutingDomain::LocalNetwork);
|
||||||
let gdis = self.dial_info_details(RoutingDomain::PublicInternet);
|
let gdis = self.dial_info_details(RoutingDomain::PublicInternet);
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
@ -100,7 +100,7 @@ impl RoutingTable {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_info_entries(&self, limit: usize, min_state: BucketEntryState) -> String {
|
pub(crate) fn debug_info_entries(&self, limit: usize, min_state: BucketEntryState) -> String {
|
||||||
let inner = self.inner.read();
|
let inner = self.inner.read();
|
||||||
let inner = &*inner;
|
let inner = &*inner;
|
||||||
let cur_ts = intf::get_timestamp();
|
let cur_ts = intf::get_timestamp();
|
||||||
@ -148,7 +148,7 @@ impl RoutingTable {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_info_entry(&self, node_id: DHTKey) -> String {
|
pub(crate) fn debug_info_entry(&self, node_id: DHTKey) -> String {
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
out += &format!("Entry {:?}:\n", node_id);
|
out += &format!("Entry {:?}:\n", node_id);
|
||||||
if let Some(nr) = self.lookup_node_ref(node_id) {
|
if let Some(nr) = self.lookup_node_ref(node_id) {
|
||||||
@ -160,7 +160,7 @@ impl RoutingTable {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_info_buckets(&self, min_state: BucketEntryState) -> String {
|
pub(crate) fn debug_info_buckets(&self, min_state: BucketEntryState) -> String {
|
||||||
let inner = self.inner.read();
|
let inner = self.inner.read();
|
||||||
let inner = &*inner;
|
let inner = &*inner;
|
||||||
let cur_ts = intf::get_timestamp();
|
let cur_ts = intf::get_timestamp();
|
||||||
|
@ -239,7 +239,7 @@ impl RoutingTable {
|
|||||||
let tdb = table_store.open("routing_table", 1).await?;
|
let tdb = table_store.open("routing_table", 1).await?;
|
||||||
let bucket_count = bucketvec.len();
|
let bucket_count = bucketvec.len();
|
||||||
let mut dbx = tdb.transact();
|
let mut dbx = tdb.transact();
|
||||||
if let Err(e) = dbx.store_frozen(0, b"bucket_count", &bucket_count) {
|
if let Err(e) = dbx.store_rkyv(0, b"bucket_count", &bucket_count) {
|
||||||
dbx.rollback();
|
dbx.rollback();
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
@ -845,8 +845,8 @@ impl RoutingTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// node can not be its own relay
|
// node can not be its own relay
|
||||||
if let Some(rpi) = &p.signed_node_info.node_info.relay_peer_info {
|
if let Some(rid) = &p.signed_node_info.relay_id() {
|
||||||
if rpi.node_id == p.node_id {
|
if rid.key == p.node_id.key {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::veilid_api::*;
|
use crate::veilid_api::*;
|
||||||
use serde::*;
|
use rkyv::with::Skip;
|
||||||
|
|
||||||
/// Compiled route (safety route + private route)
|
/// Compiled route (safety route + private route)
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -13,32 +13,40 @@ pub struct CompiledRoute {
|
|||||||
pub first_hop: NodeRef,
|
pub first_hop: NodeRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||||
struct RouteSpecDetail {
|
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||||
|
pub struct KeyPair {
|
||||||
|
key: DHTKey,
|
||||||
|
secret: DHTKeySecret,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||||
|
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||||
|
pub struct RouteSpecDetail {
|
||||||
/// Secret key
|
/// Secret key
|
||||||
#[serde(skip)]
|
#[with(Skip)]
|
||||||
pub secret_key: DHTKeySecret,
|
pub secret_key: DHTKeySecret,
|
||||||
/// Route hops
|
/// Route hops
|
||||||
pub hops: Vec<DHTKey>,
|
pub hops: Vec<DHTKey>,
|
||||||
/// Route noderefs
|
/// Route noderefs
|
||||||
#[serde(skip)]
|
#[with(Skip)]
|
||||||
hop_node_refs: Vec<NodeRef>,
|
hop_node_refs: Vec<NodeRef>,
|
||||||
/// Transfers up and down
|
/// Transfers up and down
|
||||||
transfer_stats_down_up: TransferStatsDownUp,
|
transfer_stats_down_up: TransferStatsDownUp,
|
||||||
/// Latency stats
|
/// Latency stats
|
||||||
latency_stats: LatencyStats,
|
latency_stats: LatencyStats,
|
||||||
/// Accounting mechanism for this route's RPC latency
|
/// Accounting mechanism for this route's RPC latency
|
||||||
#[serde(skip)]
|
#[with(Skip)]
|
||||||
latency_stats_accounting: LatencyStatsAccounting,
|
latency_stats_accounting: LatencyStatsAccounting,
|
||||||
/// Accounting mechanism for the bandwidth across this route
|
/// Accounting mechanism for the bandwidth across this route
|
||||||
#[serde(skip)]
|
#[with(Skip)]
|
||||||
transfer_stats_accounting: TransferStatsAccounting,
|
transfer_stats_accounting: TransferStatsAccounting,
|
||||||
/// Published private route, do not reuse for ephemeral routes
|
/// Published private route, do not reuse for ephemeral routes
|
||||||
/// Not serialized because all routes should be re-published when restarting
|
/// Not serialized because all routes should be re-published when restarting
|
||||||
#[serde(skip)]
|
#[with(Skip)]
|
||||||
published: bool,
|
published: bool,
|
||||||
// Can optimize the rendering of this route, using node ids only instead of full peer info
|
// Can optimize the rendering of this route, using node ids only instead of full peer info
|
||||||
#[serde(skip)]
|
#[with(Skip)]
|
||||||
reachable: bool,
|
reachable: bool,
|
||||||
/// Timestamp of when the route was created
|
/// Timestamp of when the route was created
|
||||||
created_ts: u64,
|
created_ts: u64,
|
||||||
@ -47,6 +55,7 @@ struct RouteSpecDetail {
|
|||||||
/// Timestamp of when the route was last used for anything
|
/// Timestamp of when the route was last used for anything
|
||||||
last_used_ts: Option<u64>,
|
last_used_ts: Option<u64>,
|
||||||
/// Directions this route is guaranteed to work in
|
/// Directions this route is guaranteed to work in
|
||||||
|
#[with(RkyvEnumSet)]
|
||||||
directions: DirectionSet,
|
directions: DirectionSet,
|
||||||
/// Stability preference (prefer reliable nodes over faster)
|
/// Stability preference (prefer reliable nodes over faster)
|
||||||
pub stability: Stability,
|
pub stability: Stability,
|
||||||
@ -55,7 +64,8 @@ struct RouteSpecDetail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The core representation of the RouteSpecStore that can be serialized
|
/// The core representation of the RouteSpecStore that can be serialized
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||||
|
#[archive_attr(repr(C), 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<DHTKey, RouteSpecDetail>,
|
details: HashMap<DHTKey, RouteSpecDetail>,
|
||||||
@ -225,7 +235,7 @@ impl RouteSpecStore {
|
|||||||
let table_store = routing_table.network_manager().table_store();
|
let table_store = routing_table.network_manager().table_store();
|
||||||
let rsstdb = table_store.open("RouteSpecStore", 1).await?;
|
let rsstdb = table_store.open("RouteSpecStore", 1).await?;
|
||||||
let mut content: RouteSpecStoreContent =
|
let mut content: RouteSpecStoreContent =
|
||||||
rsstdb.load_json(0, b"content")?.unwrap_or_default();
|
rsstdb.load_rkyv(0, b"content")?.unwrap_or_default();
|
||||||
|
|
||||||
// Look up all route hop noderefs since we can't serialize those
|
// Look up all route hop noderefs since we can't serialize those
|
||||||
let mut dead_keys = Vec::new();
|
let mut dead_keys = Vec::new();
|
||||||
@ -245,17 +255,17 @@ impl RouteSpecStore {
|
|||||||
|
|
||||||
// Load secrets from pstore
|
// Load secrets from pstore
|
||||||
let pstore = routing_table.network_manager().protected_store();
|
let pstore = routing_table.network_manager().protected_store();
|
||||||
let out: Vec<(DHTKey, DHTKeySecret)> = pstore
|
let out: Vec<KeyPair> = pstore
|
||||||
.load_user_secret_rkyv("RouteSpecStore")
|
.load_user_secret_rkyv("RouteSpecStore")
|
||||||
.await?
|
.await?
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let mut dead_keys = Vec::new();
|
let mut dead_keys = Vec::new();
|
||||||
for (k, v) in out {
|
for KeyPair { key, secret } in out {
|
||||||
if let Some(rsd) = content.details.get_mut(&k) {
|
if let Some(rsd) = content.details.get_mut(&key) {
|
||||||
rsd.secret_key = v;
|
rsd.secret_key = secret;
|
||||||
} else {
|
} else {
|
||||||
dead_keys.push(k);
|
dead_keys.push(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for k in dead_keys {
|
for k in dead_keys {
|
||||||
@ -296,7 +306,7 @@ impl RouteSpecStore {
|
|||||||
.network_manager()
|
.network_manager()
|
||||||
.table_store();
|
.table_store();
|
||||||
let rsstdb = table_store.open("RouteSpecStore", 1).await?;
|
let rsstdb = table_store.open("RouteSpecStore", 1).await?;
|
||||||
rsstdb.store_json(0, b"content", &content)?;
|
rsstdb.store_rkyv(0, b"content", &content)?;
|
||||||
|
|
||||||
// // Keep secrets in protected store as well
|
// // Keep secrets in protected store as well
|
||||||
let pstore = self
|
let pstore = self
|
||||||
@ -305,14 +315,15 @@ impl RouteSpecStore {
|
|||||||
.network_manager()
|
.network_manager()
|
||||||
.protected_store();
|
.protected_store();
|
||||||
|
|
||||||
let mut out: Vec<(DHTKey, DHTKeySecret)> = Vec::with_capacity(content.details.len());
|
let mut out: Vec<KeyPair> = Vec::with_capacity(content.details.len());
|
||||||
for (k, v) in &content.details {
|
for (k, v) in &content.details {
|
||||||
out.push((*k, v.secret_key));
|
out.push(KeyPair {
|
||||||
|
key: *k,
|
||||||
|
secret: v.secret_key,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = pstore
|
let _ = pstore.save_user_secret_rkyv("RouteSpecStore", &out).await?; // ignore if this previously existed or not
|
||||||
.save_user_secret_frozen("RouteSpecStore", &out)
|
|
||||||
.await?; // ignore if this previously existed or not
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -648,7 +648,11 @@ impl RPCProcessor {
|
|||||||
if target.has_seen_our_node_info(RoutingDomain::PublicInternet) {
|
if target.has_seen_our_node_info(RoutingDomain::PublicInternet) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(routing_table.get_own_signed_node_info(RoutingDomain::PublicInternet))
|
Some(
|
||||||
|
routing_table
|
||||||
|
.get_own_peer_info(RoutingDomain::PublicInternet)
|
||||||
|
.signed_node_info,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Destination::Relay {
|
Destination::Relay {
|
||||||
relay: _,
|
relay: _,
|
||||||
@ -659,7 +663,11 @@ impl RPCProcessor {
|
|||||||
if target.has_seen_our_node_info(RoutingDomain::PublicInternet) {
|
if target.has_seen_our_node_info(RoutingDomain::PublicInternet) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(routing_table.get_own_signed_node_info(RoutingDomain::PublicInternet))
|
Some(
|
||||||
|
routing_table
|
||||||
|
.get_own_peer_info(RoutingDomain::PublicInternet)
|
||||||
|
.signed_node_info,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -929,7 +937,7 @@ impl RPCProcessor {
|
|||||||
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_node_info) = operation.sender_node_info() {
|
||||||
// Sender NodeInfo was specified, update our routing table with it
|
// Sender NodeInfo was specified, update our routing table with it
|
||||||
if !self.filter_node_info(routing_domain, &sender_node_info.node_info) {
|
if !self.filter_node_info(routing_domain, &sender_node_info) {
|
||||||
return Err(RPCError::invalid_format(
|
return Err(RPCError::invalid_format(
|
||||||
"sender signednodeinfo has invalid peer scope",
|
"sender signednodeinfo has invalid peer scope",
|
||||||
));
|
));
|
||||||
|
@ -832,9 +832,58 @@ impl NodeInfo {
|
|||||||
dial_info_detail_list
|
dial_info_detail_list
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_direct_dial_info(&self) -> bool {
|
/// Does this node has some dial info
|
||||||
|
pub fn has_dial_info(&self) -> bool {
|
||||||
!self.dial_info_detail_list.is_empty()
|
!self.dial_info_detail_list.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Is some relay required either for signal or inbound relay or outbound relay?
|
||||||
|
pub fn requires_relay(&self) -> bool {
|
||||||
|
match self.network_class {
|
||||||
|
NetworkClass::InboundCapable => {
|
||||||
|
for did in &self.dial_info_detail_list {
|
||||||
|
if did.class.requires_relay() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NetworkClass::OutboundOnly => {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
NetworkClass::WebApp => {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
NetworkClass::Invalid => {}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Can this node assist with signalling? Yes but only if it doesn't require signalling, itself.
|
||||||
|
pub fn can_signal(&self) -> bool {
|
||||||
|
// Must be inbound capable
|
||||||
|
if !matches!(self.network_class, NetworkClass::InboundCapable) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Do any of our dial info require signalling? if so, we can't offer signalling
|
||||||
|
for did in &self.dial_info_detail_list {
|
||||||
|
if did.class.requires_signal() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Can this node relay be an inbound relay?
|
||||||
|
pub fn can_inbound_relay(&self) -> bool {
|
||||||
|
// For now this is the same
|
||||||
|
self.can_signal()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Is this node capable of validating dial info
|
||||||
|
pub fn can_validate_dial_info(&self) -> bool {
|
||||||
|
// For now this is the same
|
||||||
|
self.can_signal()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::derive_hash_xor_eq)]
|
#[allow(clippy::derive_hash_xor_eq)]
|
||||||
@ -2079,7 +2128,7 @@ impl SignedNodeInfo {
|
|||||||
pub fn has_valid_signature(&self) -> bool {
|
pub fn has_valid_signature(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
SignedNodeInfo::Direct(d) => d.has_valid_signature(),
|
SignedNodeInfo::Direct(d) => d.has_valid_signature(),
|
||||||
SignedNodeInfo::Relayed(r) => true,
|
SignedNodeInfo::Relayed(_) => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2098,19 +2147,19 @@ impl SignedNodeInfo {
|
|||||||
}
|
}
|
||||||
pub fn relay_id(&self) -> Option<NodeId> {
|
pub fn relay_id(&self) -> Option<NodeId> {
|
||||||
match self {
|
match self {
|
||||||
SignedNodeInfo::Direct(d) => None,
|
SignedNodeInfo::Direct(_) => None,
|
||||||
SignedNodeInfo::Relayed(r) => Some(r.relay_id.clone()),
|
SignedNodeInfo::Relayed(r) => Some(r.relay_id.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn relay_info(&self) -> Option<&NodeInfo> {
|
pub fn relay_info(&self) -> Option<&NodeInfo> {
|
||||||
match self {
|
match self {
|
||||||
SignedNodeInfo::Direct(d) => None,
|
SignedNodeInfo::Direct(_) => None,
|
||||||
SignedNodeInfo::Relayed(r) => Some(&r.relay_info.node_info),
|
SignedNodeInfo::Relayed(r) => Some(&r.relay_info.node_info),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn relay_peer_info(&self) -> Option<PeerInfo> {
|
pub fn relay_peer_info(&self) -> Option<PeerInfo> {
|
||||||
match self {
|
match self {
|
||||||
SignedNodeInfo::Direct(d) => None,
|
SignedNodeInfo::Direct(_) => None,
|
||||||
SignedNodeInfo::Relayed(r) => Some(PeerInfo::new(
|
SignedNodeInfo::Relayed(r) => Some(PeerInfo::new(
|
||||||
r.relay_id.clone(),
|
r.relay_id.clone(),
|
||||||
SignedNodeInfo::Direct(r.relay_info.clone()),
|
SignedNodeInfo::Direct(r.relay_info.clone()),
|
||||||
@ -2118,10 +2167,10 @@ impl SignedNodeInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn has_any_dial_info(&self) -> bool {
|
pub fn has_any_dial_info(&self) -> bool {
|
||||||
self.node_info().has_direct_dial_info()
|
self.node_info().has_dial_info()
|
||||||
|| self
|
|| self
|
||||||
.relay_info()
|
.relay_info()
|
||||||
.map(|relay_ni| relay_ni.has_direct_dial_info())
|
.map(|relay_ni| relay_ni.has_dial_info())
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2173,66 +2222,6 @@ impl PeerInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PeerInfo {
|
|
||||||
/*
|
|
||||||
|
|
||||||
xxx move these back to NodeInfo
|
|
||||||
|
|
||||||
pub fn has_direct_dial_info(&self) -> bool {
|
|
||||||
!self.dial_info_detail_list.is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is some relay required either for signal or inbound relay or outbound relay?
|
|
||||||
pub fn requires_relay(&self) -> bool {
|
|
||||||
match self.network_class {
|
|
||||||
NetworkClass::InboundCapable => {
|
|
||||||
for did in &self.dial_info_detail_list {
|
|
||||||
if did.class.requires_relay() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NetworkClass::OutboundOnly => {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
NetworkClass::WebApp => {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
NetworkClass::Invalid => {}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can this node assist with signalling? Yes but only if it doesn't require signalling, itself.
|
|
||||||
pub fn can_signal(&self) -> bool {
|
|
||||||
// Must be inbound capable
|
|
||||||
if !matches!(self.network_class, NetworkClass::InboundCapable) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Do any of our dial info require signalling? if so, we can't offer signalling
|
|
||||||
for did in &self.dial_info_detail_list {
|
|
||||||
if did.class.requires_signal() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can this node relay be an inbound relay?
|
|
||||||
pub fn can_inbound_relay(&self) -> bool {
|
|
||||||
// For now this is the same
|
|
||||||
self.can_signal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is this node capable of validating dial info
|
|
||||||
pub fn can_validate_dial_info(&self) -> bool {
|
|
||||||
// For now this is the same
|
|
||||||
self.can_signal()
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Copy,
|
Copy,
|
||||||
Clone,
|
Clone,
|
||||||
|
@ -199,12 +199,13 @@ where
|
|||||||
D: rkyv::Fallible + ?Sized,
|
D: rkyv::Fallible + ?Sized,
|
||||||
T: EnumSetType + EnumSetTypeWithRepr,
|
T: EnumSetType + EnumSetTypeWithRepr,
|
||||||
<T as EnumSetTypeWithRepr>::Repr: rkyv::Archive,
|
<T as EnumSetTypeWithRepr>::Repr: rkyv::Archive,
|
||||||
rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>: rkyv::Deserialize<EnumSet<T>, D>,
|
rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>:
|
||||||
|
rkyv::Deserialize<<T as EnumSetTypeWithRepr>::Repr, D>,
|
||||||
{
|
{
|
||||||
fn deserialize_with(
|
fn deserialize_with(
|
||||||
field: &rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>,
|
field: &rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>,
|
||||||
deserializer: &mut D,
|
deserializer: &mut D,
|
||||||
) -> Result<EnumSet<T>, D::Error> {
|
) -> Result<EnumSet<T>, D::Error> {
|
||||||
Ok(field.deserialize(deserializer)?.into())
|
Ok(EnumSet::<T>::from_repr(field.deserialize(deserializer)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user