scion_stack/path/strategy/ranking.rs
1// Copyright 2025 Anapaya Systems
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Path ranking allows expressing preferences between paths.
16//!
17//! For example, preferring shorter paths, paths that were manually registered, or paths
18//! that go through certain ASes.
19
20use std::cmp::Ordering;
21
22use crate::path::types::PathManagerPath;
23
24/// Scion path ranking allows expressing preferences between paths.
25pub trait PathRanking: 'static + Send + Sync {
26 /// Ranks the order of two paths based on preference.
27 ///
28 /// # Return
29 /// Returns the **preference ordering** between two paths.
30 ///
31 /// - `Ordering::Less` if `this` is preferred over `other`
32 /// - `Ordering::Greater` if `other` is preferred over `this`
33 /// - `Ordering::Equal` if both paths are equally preferred
34 fn rank_order(&self, this: &PathManagerPath, other: &PathManagerPath) -> Ordering;
35}
36
37/// Selects the shortest path based on the number of hops.
38pub struct Shortest;
39
40impl PathRanking for Shortest {
41 fn rank_order(&self, this: &PathManagerPath, other: &PathManagerPath) -> Ordering {
42 // Prefer paths that were manually registered.
43 match (this.is_from_registration(), other.is_from_registration()) {
44 (true, false) => Ordering::Less,
45 (false, true) => Ordering::Greater,
46 _ => {
47 // Prefer shorter paths.
48 this.path
49 .interface_count()
50 .cmp(&other.path.interface_count())
51 }
52 }
53 }
54}