use std::hash;
use std::cmp::Ordering;
use std::time::Duration;
use routecore::addr::MaxLenPrefix;
use routecore::asn::Asn;
use routecore::bgpsec::KeyIdentifier;
use super::pdu::RouterKeyInfo;
#[derive(Clone, Copy, Debug)]
pub struct RouteOrigin {
pub prefix: MaxLenPrefix,
pub asn: Asn,
}
impl RouteOrigin {
pub fn new(prefix: MaxLenPrefix, asn: Asn) -> Self {
RouteOrigin { prefix, asn }
}
}
impl PartialEq for RouteOrigin {
fn eq(&self, other: &Self) -> bool {
self.prefix.prefix() == other.prefix.prefix()
&& self.prefix.resolved_max_len() == other.prefix.resolved_max_len()
&& self.asn == other.asn
}
}
impl Eq for RouteOrigin { }
impl PartialOrd for RouteOrigin {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for RouteOrigin {
fn cmp(&self, other: &Self) -> Ordering {
match self.prefix.prefix().cmp(&other.prefix.prefix()) {
Ordering::Equal => { }
other => return other
}
match self.prefix.resolved_max_len().cmp(
&other.prefix.resolved_max_len()
) {
Ordering::Equal => { }
other => return other
}
self.asn.cmp(&other.asn)
}
}
impl hash::Hash for RouteOrigin {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.prefix.prefix().hash(state);
self.prefix.resolved_max_len().hash(state);
self.asn.hash(state);
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct RouterKey {
pub key_identifier: KeyIdentifier,
pub asn: Asn,
pub key_info: RouterKeyInfo,
}
impl RouterKey {
pub fn new(
key_identifier: KeyIdentifier, asn: Asn, key_info: RouterKeyInfo
) -> Self {
RouterKey { key_identifier, asn, key_info }
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Payload {
Origin(RouteOrigin),
RouterKey(RouterKey),
}
impl Payload {
pub fn origin(prefix: MaxLenPrefix, asn: Asn) -> Self {
Payload::Origin(RouteOrigin::new(prefix, asn))
}
pub fn router_key(
key_identifier: KeyIdentifier, asn: Asn, key_info: RouterKeyInfo
) -> Self {
Payload::RouterKey(RouterKey::new(key_identifier, asn, key_info))
}
pub fn to_origin(&self) -> Option<RouteOrigin> {
match *self {
Payload::Origin(origin) => Some(origin),
_ => None
}
}
pub fn as_router_key(&self) -> Option<&RouterKey> {
match *self {
Payload::RouterKey(ref key) => Some(key),
_ => None
}
}
}
impl From<RouteOrigin> for Payload {
fn from(src: RouteOrigin) -> Self {
Payload::Origin(src)
}
}
impl From<RouterKey> for Payload {
fn from(src: RouterKey) -> Self {
Payload::RouterKey(src)
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum Action {
Announce,
Withdraw,
}
impl Action {
pub fn is_announce(self) -> bool {
matches!(self, Action::Announce)
}
pub fn is_withdraw(self) -> bool {
matches!(self, Action::Withdraw)
}
pub fn from_flags(flags: u8) -> Self {
if flags & 1 == 1 {
Action::Announce
}
else {
Action::Withdraw
}
}
pub fn into_flags(self) -> u8 {
match self {
Action::Announce => 1,
Action::Withdraw => 0
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct Timing {
pub refresh: u32,
pub retry: u32,
pub expire: u32
}
impl Timing {
pub fn refresh_duration(self) -> Duration {
Duration::from_secs(u64::from(self.refresh))
}
}
impl Default for Timing {
fn default() -> Self {
Timing {
refresh: 3600,
retry: 600,
expire: 7200
}
}
}