Skip to content

Commit

Permalink
feat: add host address type
Browse files Browse the repository at this point in the history
  • Loading branch information
jpcsmith authored and mlegner committed Sep 29, 2023
1 parent 4f3cdaf commit 4aca746
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 0 deletions.
3 changes: 3 additions & 0 deletions crates/scion/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ pub use ia::IsdAsn;
mod service;
pub use service::{ParseServiceAddressError, ServiceAddress};

mod host;
pub use host::{Host, HostAddress, HostType};

#[derive(Eq, PartialEq, Clone, Debug, thiserror::Error)]
pub enum AddressParseError {
#[error("AS number out of range, expected at most 2^48 - 1")]
Expand Down
88 changes: 88 additions & 0 deletions crates/scion/src/address/host.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use std::net::{IpAddr, SocketAddr};

use super::ServiceAddress;

/// The AS-local host identifier of a SCION address.
#[derive(Debug)]
pub enum Host {
/// An IPv4 or IPv6 host address
Ip(IpAddr),
/// A SCION-service host address
Svc(ServiceAddress),
}

/// Enum to discriminate among different types of Host addresses.
#[repr(u8)]
#[derive(Eq, PartialEq, Clone, Copy, Debug)]
pub enum HostType {
None = 0,
Ipv4,
Ipv6,
Svc,
}

impl HostType {
/// Convert a byte host-address type to its enum variant.
///
/// # Examples
///
/// ```
/// # use scion::address::HostType;
/// assert_eq!(HostType::from_byte(0), Some(HostType::None));
/// assert_eq!(HostType::from_byte(1), Some(HostType::Ipv4));
/// assert_eq!(HostType::from_byte(2), Some(HostType::Ipv6));
/// assert_eq!(HostType::from_byte(3), Some(HostType::Svc));
/// assert_eq!(HostType::from_byte(4), None);
/// ```
pub fn from_byte(byte: u8) -> Option<Self> {
match byte {
0 => Some(HostType::None),
1 => Some(HostType::Ipv4),
2 => Some(HostType::Ipv6),
3 => Some(HostType::Svc),
_ => None,
}
}
}

/// Trait to be implemented by address types that are supported by SCION
/// as valid AS-host addresses.
pub trait HostAddress {
/// Return the HostType associated with the host address
fn host_address_type(&self) -> HostType;
}

impl HostAddress for SocketAddr {
fn host_address_type(&self) -> HostType {
self.ip().host_address_type()
}
}

impl HostAddress for IpAddr {
fn host_address_type(&self) -> HostType {
match self {
IpAddr::V4(_) => HostType::Ipv4,
IpAddr::V6(_) => HostType::Ipv6,
}
}
}

impl HostAddress for Host {
fn host_address_type(&self) -> HostType {
match self {
Host::Ip(ip_address) => ip_address.host_address_type(),
Host::Svc(service_address) => service_address.host_address_type(),
}
}
}

impl<T> HostAddress for Option<T>
where
T: HostAddress,
{
fn host_address_type(&self) -> HostType {
self.as_ref()
.map(HostAddress::host_address_type)
.unwrap_or(HostType::None)
}
}
8 changes: 8 additions & 0 deletions crates/scion/src/address/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::{

use thiserror;

use super::{HostAddress, HostType};

/// A SCION service address.
///
/// A service address is a short identifier used to send anycast or multicast
Expand Down Expand Up @@ -118,6 +120,12 @@ impl Display for ServiceAddress {
}
}

impl HostAddress for ServiceAddress {
fn host_address_type(&self) -> HostType {
HostType::Svc
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 4aca746

Please sign in to comment.