scion_stack/path/manager/traits.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
15use std::{io, time::Duration};
16
17use bytes::Bytes;
18use chrono::{DateTime, Utc};
19use scion_proto::{address::IsdAsn, path::Path};
20use thiserror::Error;
21
22use crate::types::ResFut;
23
24/// Trait for active path management with async interface.
25pub trait PathManager: SyncPathManager {
26 /// Returns a path to the destination from the path cache or requests a new path from the
27 /// SCION Control Plane.
28 fn path_wait(
29 &self,
30 src: IsdAsn,
31 dst: IsdAsn,
32 now: DateTime<Utc>,
33 ) -> impl ResFut<'_, Path<Bytes>, PathWaitError>;
34
35 /// Returns a path to the destination from the path cache or requests a new path from the
36 /// SCION Control Plane, with a maximum wait time.
37 fn path_timeout(
38 &self,
39 src: IsdAsn,
40 dst: IsdAsn,
41 now: DateTime<Utc>,
42 timeout: Duration,
43 ) -> impl ResFut<'_, Path<Bytes>, PathWaitTimeoutError> {
44 let fut = self.path_wait(src, dst, now);
45 async move {
46 match tokio::time::timeout(timeout, fut).await {
47 Ok(result) => {
48 result.map_err(|e| {
49 match e {
50 PathWaitError::FetchFailed(msg) => {
51 PathWaitTimeoutError::FetchFailed(msg)
52 }
53 PathWaitError::NoPathFound => PathWaitTimeoutError::NoPathFound,
54 }
55 })
56 }
57 Err(_) => Err(PathWaitTimeoutError::Timeout),
58 }
59 }
60 }
61}
62
63/// Path wait errors.
64#[derive(Debug, Clone, Error)]
65pub enum PathWaitError {
66 /// Path fetch failed.
67 #[error("path fetch failed: {0}")]
68 FetchFailed(String),
69 /// No path found.
70 #[error("no path found")]
71 NoPathFound,
72}
73
74/// Path wait errors.
75#[derive(Debug, Clone, Error)]
76pub enum PathWaitTimeoutError {
77 /// Path fetch failed.
78 #[error("path fetch failed: {0}")]
79 FetchFailed(String),
80 /// No path found.
81 #[error("no path found")]
82 NoPathFound,
83 /// Waiting for path timed out
84 #[error("waiting for path timed out")]
85 Timeout,
86}
87
88/// Trait for active path management with sync interface. Implementors of this trait should be
89/// able to be used in sync and async context. The functions must not block.
90pub trait SyncPathManager {
91 /// Add a path to the path cache. This can be used to register reverse paths.
92 fn register_path(&self, src: IsdAsn, dst: IsdAsn, now: DateTime<Utc>, path: Path<Bytes>);
93
94 /// Returns a path to the destination from the path cache.
95 /// If the path is not in the cache, it returns Ok(None), possibly causing the path to be
96 /// fetched in the background. If the cache is locked an io error WouldBlock is
97 /// returned.
98 fn try_cached_path(
99 &self,
100 src: IsdAsn,
101 dst: IsdAsn,
102 now: DateTime<Utc>,
103 ) -> io::Result<Option<Path<Bytes>>>;
104}
105
106/// Trait for prefetching paths in the path manager.
107pub trait PathPrefetcher {
108 /// Prefetch a paths for the given source and destination.
109 fn prefetch_path(&self, src: IsdAsn, dst: IsdAsn);
110}