Skip to content

Commit

Permalink
feat: implement standard path reversal
Browse files Browse the repository at this point in the history
  • Loading branch information
mlegner committed Dec 11, 2023
1 parent e5cb4aa commit 83933b1
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 67 deletions.
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ repos:
language: rust
types: [rust]
pass_filenames: false
- id: doc
name: doc
- id: cargo-doc
name: cargo-doc
entry: cargo doc
args: ["--workspace", "--no-deps"]
language: rust
Expand All @@ -70,6 +70,6 @@ repos:
name: cargo-deny
entry: cargo deny
files: Cargo.(lock|toml)
args: ["--all-features", "check"]
args: ["--all-features", "check", "-D", "warnings"]
language: rust
pass_filenames: false
8 changes: 8 additions & 0 deletions crates/scion-proto/src/packet/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ pub struct ByEndpoint<T> {
pub destination: T,
}

impl<T> ByEndpoint<T> {
/// Swaps source and destination.
pub fn reverse(&mut self) -> &mut Self {
std::mem::swap(&mut self.source, &mut self.destination);
self
}
}

impl<T: Clone> ByEndpoint<T> {
/// Create a new instance where both the source and destination have the same value.
pub fn with_cloned(source_and_destination: T) -> Self {
Expand Down
7 changes: 7 additions & 0 deletions crates/scion-proto/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ impl Path {
self.dataplane_path.is_empty()
}

pub fn reverse(&mut self) -> Result<&mut Self, UnsupportedPathType> {
self.dataplane_path.reverse()?;
self.isd_asn.reverse();
self.metadata.as_mut().map(PathMetadata::reverse);
Ok(self)
}

#[tracing::instrument]
pub fn try_from_grpc_with_endpoints(
mut value: daemon_grpc::Path,
Expand Down
44 changes: 42 additions & 2 deletions crates/scion-proto/src/path/dataplane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ impl DataplanePath {
}
}

/// Reverses the path.
pub fn reverse(&mut self) -> Result<&mut Self, UnsupportedPathType> {
match self {
Self::EmptyPath => (),
Self::Standard(standard_path) => *self = Self::Standard(standard_path.reverse()),
Self::Unsupported { path_type, .. } => {
return Err(UnsupportedPathType(u8::from(*path_type)))
}
}
Ok(self)
}

/// Returns true iff the path is a [`DataplanePath::EmptyPath`]
pub fn is_empty(&self) -> bool {
self == &Self::EmptyPath
Expand Down Expand Up @@ -191,7 +203,35 @@ mod tests {
};
}

test_path_create_encode_decode!(empty, DataplanePath::EmptyPath, 0);
macro_rules! test_path_create_encode_decode_reverse {
($name:ident, $dataplane_path:expr, $expected_length:expr) => {
mod $name {
use super::*;

test_path_create_encode_decode!(
create_encode_decode,
$dataplane_path,
$expected_length
);

#[test]
fn reverse_twice_identity() {
let dataplane_path = $dataplane_path;
assert_eq!(
dataplane_path
.deep_copy()
.reverse()
.unwrap()
.reverse()
.unwrap(),
&dataplane_path
);
}
}
};
}

test_path_create_encode_decode_reverse!(empty, DataplanePath::EmptyPath, 0);
test_path_create_encode_decode!(
other,
DataplanePath::Unsupported {
Expand All @@ -200,7 +240,7 @@ mod tests {
},
4
);
test_path_create_encode_decode!(
test_path_create_encode_decode_reverse!(
standard,
{
let mut path_raw = BytesMut::with_capacity(36);
Expand Down
27 changes: 27 additions & 0 deletions crates/scion-proto/src/path/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,33 @@ pub struct PathMetadata {
pub epic_auths: Option<EpicAuths>,
}

impl PathMetadata {
/// Reverses the path metadata such that it applies to the reversed path.
pub fn reverse(&mut self) -> &mut Self {
self.interfaces[..].reverse();
if let Some(v) = self.latency.as_mut() {
v[..].reverse()
}
if let Some(v) = self.bandwidth_kbps.as_mut() {
v[..].reverse()
}
if let Some(v) = self.geo.as_mut() {
v[..].reverse()
}
if let Some(v) = self.link_type.as_mut() {
v[..].reverse()
}
if let Some(v) = self.internal_hops.as_mut() {
v[..].reverse()
}
if let Some(v) = self.notes.as_mut() {
v[..].reverse()
}
self.epic_auths = None;
self
}
}

macro_rules! some_if_length_matches {
($input_vec:expr, $expected_length:expr, $result:expr) => {
if $input_vec.len() == $expected_length {
Expand Down
Loading

0 comments on commit 83933b1

Please sign in to comment.