checkpoint
This commit is contained in:
@@ -58,8 +58,8 @@ impl RoutingTable {
|
||||
out += &format!(
|
||||
"{},{},{},{},{}",
|
||||
BOOTSTRAP_TXT_VERSION,
|
||||
MIN_VERSION,
|
||||
MAX_VERSION,
|
||||
MIN_CRYPTO_VERSION,
|
||||
MAX_CRYPTO_VERSION,
|
||||
self.node_id().encode(),
|
||||
some_hostname.unwrap()
|
||||
);
|
||||
|
@@ -9,7 +9,7 @@ mod routing_table_inner;
|
||||
mod stats_accounting;
|
||||
mod tasks;
|
||||
|
||||
use crate::dht::*;
|
||||
use crate::crypto::*;
|
||||
use crate::network_manager::*;
|
||||
use crate::rpc_processor::*;
|
||||
use crate::xx::*;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
use super::*;
|
||||
use crate::dht::*;
|
||||
use crate::crypto::*;
|
||||
use alloc::fmt;
|
||||
|
||||
// Connectionless protocols like UDP are dependent on a NAT translation timeout
|
||||
|
@@ -49,9 +49,9 @@ struct RouteSpecDetail {
|
||||
/// Directions this route is guaranteed to work in
|
||||
directions: DirectionSet,
|
||||
/// Stability preference (prefer reliable nodes over faster)
|
||||
stability: Stability,
|
||||
pub stability: Stability,
|
||||
/// Sequencing preference (connection oriented protocols vs datagram)
|
||||
sequencing: Sequencing,
|
||||
pub sequencing: Sequencing,
|
||||
}
|
||||
|
||||
/// The core representation of the RouteSpecStore that can be serialized
|
||||
@@ -616,11 +616,11 @@ impl RouteSpecStore {
|
||||
routing_table: RoutingTable,
|
||||
safety_selection: SafetySelection,
|
||||
private_route: PrivateRoute,
|
||||
) -> Result<Option<CompiledRoute>, RPCError> {
|
||||
) -> EyreResult<Option<CompiledRoute>> {
|
||||
let pr_hopcount = private_route.hop_count as usize;
|
||||
let max_route_hop_count = self.max_route_hop_count;
|
||||
if pr_hopcount > max_route_hop_count {
|
||||
return Err(RPCError::internal("private route hop count too long"));
|
||||
bail!("private route hop count too long");
|
||||
}
|
||||
|
||||
// See if we are using a safety route, if not, short circuit this operation
|
||||
@@ -628,7 +628,7 @@ impl RouteSpecStore {
|
||||
SafetySelection::Unsafe(sequencing) => {
|
||||
// Safety route stub with the node's public key as the safety route key since it's the 0th hop
|
||||
if private_route.first_hop.is_none() {
|
||||
return Err(RPCError::internal("can't compile zero length route"));
|
||||
bail!("can't compile zero length route");
|
||||
}
|
||||
let first_hop = private_route.first_hop.as_ref().unwrap();
|
||||
let opt_first_hop = match &first_hop.node {
|
||||
@@ -707,10 +707,10 @@ impl RouteSpecStore {
|
||||
// Ensure the total hop count isn't too long for our config
|
||||
let sr_hopcount = safety_spec.hop_count;
|
||||
if sr_hopcount == 0 {
|
||||
return Err(RPCError::internal("safety route hop count is zero"));
|
||||
bail!("safety route hop count is zero");
|
||||
}
|
||||
if sr_hopcount > max_route_hop_count {
|
||||
return Err(RPCError::internal("safety route hop count too long"));
|
||||
bail!("safety route hop count too long");
|
||||
}
|
||||
|
||||
// See if we can optimize this compilation yet
|
||||
@@ -746,10 +746,10 @@ impl RouteSpecStore {
|
||||
// Encrypt the previous blob ENC(nonce, DH(PKhop,SKsr))
|
||||
let dh_secret = crypto
|
||||
.cached_dh(&safety_rsd.hops[h], &safety_rsd.secret_key)
|
||||
.map_err(RPCError::map_internal("dh failed"))?;
|
||||
.wrap_err("dh failed")?;
|
||||
let enc_msg_data =
|
||||
Crypto::encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
||||
.map_err(RPCError::map_internal("encryption failed"))?;
|
||||
.wrap_err("encryption failed")?;
|
||||
|
||||
// Make route hop data
|
||||
let route_hop_data = RouteHopData {
|
||||
@@ -759,26 +759,23 @@ impl RouteSpecStore {
|
||||
|
||||
// Make route hop
|
||||
let route_hop = RouteHop {
|
||||
node: match optimize {
|
||||
node: if optimize {
|
||||
// Optimized, no peer info, just the dht key
|
||||
true => RouteNode::NodeId(NodeId::new(safety_rsd.hops[h])),
|
||||
RouteNode::NodeId(NodeId::new(safety_rsd.hops[h]))
|
||||
} else {
|
||||
// Full peer info, required until we are sure the route has been fully established
|
||||
false => {
|
||||
let node_id = safety_rsd.hops[h];
|
||||
let pi = rti
|
||||
.with_node_entry(node_id, |entry| {
|
||||
entry.with(rti, |_rti, e| {
|
||||
e.make_peer_info(node_id, RoutingDomain::PublicInternet)
|
||||
})
|
||||
let node_id = safety_rsd.hops[h];
|
||||
let pi = rti
|
||||
.with_node_entry(node_id, |entry| {
|
||||
entry.with(rti, |_rti, e| {
|
||||
e.make_peer_info(node_id, RoutingDomain::PublicInternet)
|
||||
})
|
||||
.flatten();
|
||||
if pi.is_none() {
|
||||
return Err(RPCError::internal(
|
||||
"peer info should exist for route but doesn't",
|
||||
));
|
||||
}
|
||||
RouteNode::PeerInfo(pi.unwrap())
|
||||
})
|
||||
.flatten();
|
||||
if pi.is_none() {
|
||||
bail!("peer info should exist for route but doesn't");
|
||||
}
|
||||
RouteNode::PeerInfo(pi.unwrap())
|
||||
},
|
||||
next_hop: Some(route_hop_data),
|
||||
};
|
||||
@@ -838,6 +835,86 @@ impl RouteSpecStore {
|
||||
Ok(Some(compiled_route))
|
||||
}
|
||||
|
||||
/// Assemble private route for publication
|
||||
pub fn assemble_private_route(
|
||||
&mut self,
|
||||
rti: &RoutingTableInner,
|
||||
routing_table: RoutingTable,
|
||||
key: &DHTKey,
|
||||
) -> EyreResult<PrivateRoute> {
|
||||
let rsd = self
|
||||
.detail(&key)
|
||||
.ok_or_else(|| eyre!("route does not exist"))?;
|
||||
|
||||
// See if we can optimize this compilation yet
|
||||
// We don't want to include full nodeinfo if we don't have to
|
||||
let optimize = rsd.reachable;
|
||||
|
||||
// Make innermost route hop to our own node
|
||||
let mut route_hop = RouteHop {
|
||||
node: if optimize {
|
||||
RouteNode::NodeId(NodeId::new(routing_table.node_id()))
|
||||
} else {
|
||||
RouteNode::PeerInfo(rti.get_own_peer_info(RoutingDomain::PublicInternet))
|
||||
},
|
||||
next_hop: None,
|
||||
};
|
||||
|
||||
let crypto = routing_table.network_manager().crypto();
|
||||
// Loop for each hop
|
||||
let hop_count = rsd.hops.len();
|
||||
for h in (0..hop_count).rev() {
|
||||
let nonce = Crypto::get_random_nonce();
|
||||
|
||||
let blob_data = {
|
||||
let mut rh_message = ::capnp::message::Builder::new_default();
|
||||
let mut rh_builder = rh_message.init_root::<veilid_capnp::route_hop::Builder>();
|
||||
encode_route_hop(&route_hop, &mut rh_builder)?;
|
||||
builder_to_vec(rh_message)?
|
||||
};
|
||||
|
||||
// Encrypt the previous blob ENC(nonce, DH(PKhop,SKpr))
|
||||
let dh_secret = crypto
|
||||
.cached_dh(&rsd.hops[h], &rsd.secret_key)
|
||||
.wrap_err("dh failed")?;
|
||||
let enc_msg_data = Crypto::encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
||||
.wrap_err("encryption failed")?;
|
||||
let route_hop_data = RouteHopData {
|
||||
nonce,
|
||||
blob: enc_msg_data,
|
||||
};
|
||||
|
||||
route_hop = RouteHop {
|
||||
node: if optimize {
|
||||
// Optimized, no peer info, just the dht key
|
||||
RouteNode::NodeId(NodeId::new(rsd.hops[h]))
|
||||
} else {
|
||||
// Full peer info, required until we are sure the route has been fully established
|
||||
let node_id = rsd.hops[h];
|
||||
let pi = rti
|
||||
.with_node_entry(node_id, |entry| {
|
||||
entry.with(rti, |_rti, e| {
|
||||
e.make_peer_info(node_id, RoutingDomain::PublicInternet)
|
||||
})
|
||||
})
|
||||
.flatten();
|
||||
if pi.is_none() {
|
||||
bail!("peer info should exist for route but doesn't",);
|
||||
}
|
||||
RouteNode::PeerInfo(pi.unwrap())
|
||||
},
|
||||
next_hop: Some(route_hop_data),
|
||||
}
|
||||
}
|
||||
|
||||
let private_route = PrivateRoute {
|
||||
public_key: key.clone(),
|
||||
hop_count: hop_count.try_into().unwrap(),
|
||||
first_hop: Some(route_hop),
|
||||
};
|
||||
Ok(private_route)
|
||||
}
|
||||
|
||||
/// Mark route as published
|
||||
/// When first deserialized, routes must be re-published in order to ensure they remain
|
||||
/// in the RouteSpecStore.
|
||||
|
@@ -126,8 +126,8 @@ impl RoutingDomainDetailCommon {
|
||||
network_class: self.network_class.unwrap_or(NetworkClass::Invalid),
|
||||
outbound_protocols: self.outbound_protocols,
|
||||
address_types: self.address_types,
|
||||
min_version: MIN_VERSION,
|
||||
max_version: MAX_VERSION,
|
||||
min_version: MIN_CRYPTO_VERSION,
|
||||
max_version: MAX_CRYPTO_VERSION,
|
||||
dial_info_detail_list: self.dial_info_details.clone(),
|
||||
relay_peer_info: self
|
||||
.relay_node
|
||||
|
Reference in New Issue
Block a user