xfer
This commit is contained in:
parent
fd26acec16
commit
4a9d516f32
@ -388,12 +388,21 @@ impl RouteSpecStore {
|
||||
sequencing: Sequencing,
|
||||
hop_count: usize,
|
||||
directions: DirectionSet,
|
||||
avoid_node_id: Option<DHTKey>,
|
||||
) -> EyreResult<Option<DHTKey>> {
|
||||
let inner = &mut *self.inner.lock();
|
||||
let routing_table = self.unlocked_inner.routing_table.clone();
|
||||
let rti = &mut *routing_table.inner.write();
|
||||
|
||||
self.allocate_route_inner(inner, rti, stability, sequencing, hop_count, directions)
|
||||
self.allocate_route_inner(
|
||||
inner,
|
||||
rti,
|
||||
stability,
|
||||
sequencing,
|
||||
hop_count,
|
||||
directions,
|
||||
avoid_node_id,
|
||||
)
|
||||
}
|
||||
|
||||
fn allocate_route_inner(
|
||||
@ -404,6 +413,7 @@ impl RouteSpecStore {
|
||||
sequencing: Sequencing,
|
||||
hop_count: usize,
|
||||
directions: DirectionSet,
|
||||
avoid_node_id: Option<DHTKey>,
|
||||
) -> EyreResult<Option<DHTKey>> {
|
||||
use core::cmp::Ordering;
|
||||
|
||||
@ -418,7 +428,7 @@ impl RouteSpecStore {
|
||||
// Get list of all nodes, and sort them for selection
|
||||
let cur_ts = intf::get_timestamp();
|
||||
let filter = Box::new(
|
||||
move |rti: &RoutingTableInner, _k: DHTKey, v: Option<Arc<BucketEntry>>| -> bool {
|
||||
move |rti: &RoutingTableInner, k: DHTKey, v: Option<Arc<BucketEntry>>| -> bool {
|
||||
// Exclude our own node from routes
|
||||
if v.is_none() {
|
||||
return false;
|
||||
@ -433,6 +443,13 @@ impl RouteSpecStore {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exclude node we have specifically chosen to avoid
|
||||
if let Some(ani) = avoid_node_id {
|
||||
if k == ani {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude nodes with no publicinternet nodeinfo, or incompatible nodeinfo or node status won't route
|
||||
v.with(rti, move |_rti, e| {
|
||||
let node_info_ok =
|
||||
@ -748,6 +765,7 @@ impl RouteSpecStore {
|
||||
stability: Stability,
|
||||
sequencing: Sequencing,
|
||||
directions: DirectionSet,
|
||||
avoid_node_id: Option<DHTKey>,
|
||||
) -> Option<DHTKey> {
|
||||
let inner = self.inner.lock();
|
||||
|
||||
@ -759,9 +777,17 @@ impl RouteSpecStore {
|
||||
&& detail.1.directions.is_subset(directions)
|
||||
&& !detail.1.published
|
||||
{
|
||||
let mut avoid = false;
|
||||
if let Some(ani) = &avoid_node_id {
|
||||
if detail.1.hops.contains(ani) {
|
||||
avoid = true;
|
||||
}
|
||||
}
|
||||
if !avoid {
|
||||
return Some(*detail.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
@ -800,16 +826,15 @@ impl RouteSpecStore {
|
||||
if pr_hopcount > max_route_hop_count {
|
||||
bail!("private route hop count too long");
|
||||
}
|
||||
let Some(pr_first_hop) = &private_route.first_hop else {
|
||||
bail!("compiled private route should have first_hop");
|
||||
};
|
||||
|
||||
// See if we are using a safety route, if not, short circuit this operation
|
||||
let safety_spec = match safety_selection {
|
||||
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() {
|
||||
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 {
|
||||
let opt_first_hop = match &pr_first_hop.node {
|
||||
RouteNode::NodeId(id) => rti.lookup_node_ref(routing_table.clone(), id.key),
|
||||
RouteNode::PeerInfo(pi) => rti.register_node_with_signed_node_info(
|
||||
routing_table.clone(),
|
||||
@ -851,6 +876,13 @@ impl RouteSpecStore {
|
||||
// Safety route exists
|
||||
safety_rsd
|
||||
} else {
|
||||
// Avoid having the first node in the private route in our chosen safety route
|
||||
// We would avoid all of them, but by design only the first node is knowable
|
||||
let avoid_node_id = match &pr_first_hop.node {
|
||||
RouteNode::NodeId(n) => n.key,
|
||||
RouteNode::PeerInfo(p) => p.node_id.key,
|
||||
};
|
||||
|
||||
// Select a safety route from the pool or make one if we don't have one that matches
|
||||
if let Some(sr_pubkey) = self.first_unpublished_route(
|
||||
safety_spec.hop_count,
|
||||
@ -858,6 +890,7 @@ impl RouteSpecStore {
|
||||
safety_spec.stability,
|
||||
safety_spec.sequencing,
|
||||
Direction::Outbound.into(),
|
||||
Some(avoid_node_id),
|
||||
) {
|
||||
// Found a route to use
|
||||
(Self::detail_mut(inner, &sr_pubkey).unwrap(), sr_pubkey)
|
||||
@ -871,6 +904,7 @@ impl RouteSpecStore {
|
||||
safety_spec.sequencing,
|
||||
safety_spec.hop_count,
|
||||
Direction::Outbound.into(),
|
||||
Some(avoid_node_id),
|
||||
)
|
||||
.map_err(RPCError::internal)?
|
||||
{
|
||||
|
@ -566,7 +566,7 @@ impl VeilidAPI {
|
||||
}
|
||||
|
||||
async fn debug_route_allocate(&self, args: Vec<String>) -> Result<String, VeilidAPIError> {
|
||||
// [ord|*ord] [rel] [<count>] [in|out]
|
||||
// [ord|*ord] [rel] [<count>] [in|out] [avoid_node_id]
|
||||
|
||||
let netman = self.network_manager()?;
|
||||
let routing_table = netman.routing_table();
|
||||
@ -582,6 +582,7 @@ impl VeilidAPI {
|
||||
let mut stability = Stability::LowLatency;
|
||||
let mut hop_count = default_route_hop_count;
|
||||
let mut directions = DirectionSet::all();
|
||||
let mut avoid_node_id = None;
|
||||
|
||||
while ai < args.len() {
|
||||
if let Ok(seq) =
|
||||
@ -600,6 +601,10 @@ impl VeilidAPI {
|
||||
get_debug_argument_at(&args, ai, "debug_route", "direction_set", get_direction_set)
|
||||
{
|
||||
directions = ds;
|
||||
} else if let Ok(ani) =
|
||||
get_debug_argument_at(&args, ai, "debug_route", "avoid_node_id", get_dht_key)
|
||||
{
|
||||
avoid_node_id = Some(ani);
|
||||
} else {
|
||||
return Ok(format!("Invalid argument specified: {}", args[ai]));
|
||||
}
|
||||
@ -607,7 +612,8 @@ impl VeilidAPI {
|
||||
}
|
||||
|
||||
// Allocate route
|
||||
let out = match rss.allocate_route(stability, sequencing, hop_count, directions) {
|
||||
let out =
|
||||
match rss.allocate_route(stability, sequencing, hop_count, directions, avoid_node_id) {
|
||||
Ok(Some(v)) => format!("{}", v.encode()),
|
||||
Ok(None) => format!("<unavailable>"),
|
||||
Err(e) => {
|
||||
|
Loading…
Reference in New Issue
Block a user