pub use crate::proto::rr::domain::usage::*;
use crate::proto::rr::domain::{Label, Name};
use crate::proto::serialize::binary::BinEncodable;
use lazy_static::lazy_static;
use radix_trie::{Trie, TrieKey};
lazy_static! {
pub static ref IN_ADDR_ARPA_10: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("10").unwrap().append_domain(&*IN_ADDR_ARPA));
static ref IN_ADDR_ARPA_172: Name = Name::from_ascii("172").unwrap().append_domain(&*IN_ADDR_ARPA);
pub static ref IN_ADDR_ARPA_172_16: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("16").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_17: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("17").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_18: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("18").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_19: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("19").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_20: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("20").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_21: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("21").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_22: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("22").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_23: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("23").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_24: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("24").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_25: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("25").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_26: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("26").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_27: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("27").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_28: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("28").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_29: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("29").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_30: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("30").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_172_31: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("31").unwrap().append_domain(&*IN_ADDR_ARPA_172));
pub static ref IN_ADDR_ARPA_192_168: ZoneUsage = ZoneUsage::reverse(Name::from_ascii("168.192").unwrap().append_domain(&*IN_ADDR_ARPA));
}
lazy_static! {
static ref COM: Label = Label::from_ascii("com").unwrap();
static ref NET: Label = Label::from_ascii("net").unwrap();
static ref ORG: Label = Label::from_ascii("org").unwrap();
static ref EXAMPLE_L: Label = Label::from_ascii("example").unwrap();
pub static ref EXAMPLE: ZoneUsage = ZoneUsage::example(Name::from_labels(vec![EXAMPLE_L.clone()]).unwrap());
pub static ref EXAMPLE_COM: ZoneUsage = ZoneUsage::example(Name::from_labels(vec![EXAMPLE_L.clone(), COM.clone()]).unwrap());
pub static ref EXAMPLE_NET: ZoneUsage = ZoneUsage::example(Name::from_labels(vec![EXAMPLE_L.clone(), NET.clone()]).unwrap());
pub static ref EXAMPLE_ORG: ZoneUsage = ZoneUsage::example(Name::from_labels(vec![EXAMPLE_L.clone(), ORG.clone()]).unwrap());
}
lazy_static! {
pub static ref TEST: ZoneUsage = ZoneUsage::test(Name::from_ascii("test.").unwrap());
}
#[derive(Clone, Eq, PartialEq)]
struct TrieName(Name);
impl From<Name> for TrieName {
fn from(n: Name) -> Self {
TrieName(n)
}
}
impl TrieKey for TrieName {
fn encode_bytes(&self) -> Vec<u8> {
let mut bytes = self.0.to_bytes().expect("bad name for trie");
bytes.reverse();
bytes
}
}
#[derive(Clone, Eq, PartialEq)]
struct TrieNameRef<'n>(&'n Name);
impl<'n> From<&'n Name> for TrieNameRef<'n> {
fn from(n: &'n Name) -> Self {
TrieNameRef(n)
}
}
impl<'n> TrieKey for TrieNameRef<'n> {
fn encode_bytes(&self) -> Vec<u8> {
let mut bytes = self.0.to_bytes().expect("bad name for trie");
bytes.reverse();
bytes
}
}
pub struct UsageTrie(Trie<TrieName, &'static ZoneUsage>);
impl UsageTrie {
#[allow(clippy::cognitive_complexity)]
fn default() -> Self {
let mut trie: Trie<TrieName, &'static ZoneUsage> = Trie::new();
assert!(trie.insert(DEFAULT.clone().into(), &DEFAULT).is_none());
assert!(trie
.insert(IN_ADDR_ARPA_10.clone().into(), &IN_ADDR_ARPA_10)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_16.clone().into(), &IN_ADDR_ARPA_172_16)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_17.clone().into(), &IN_ADDR_ARPA_172_17)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_18.clone().into(), &IN_ADDR_ARPA_172_18)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_19.clone().into(), &IN_ADDR_ARPA_172_19)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_20.clone().into(), &IN_ADDR_ARPA_172_20)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_21.clone().into(), &IN_ADDR_ARPA_172_21)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_22.clone().into(), &IN_ADDR_ARPA_172_22)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_23.clone().into(), &IN_ADDR_ARPA_172_23)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_24.clone().into(), &IN_ADDR_ARPA_172_24)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_25.clone().into(), &IN_ADDR_ARPA_172_25)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_26.clone().into(), &IN_ADDR_ARPA_172_26)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_27.clone().into(), &IN_ADDR_ARPA_172_27)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_28.clone().into(), &IN_ADDR_ARPA_172_28)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_29.clone().into(), &IN_ADDR_ARPA_172_29)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_30.clone().into(), &IN_ADDR_ARPA_172_30)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_172_31.clone().into(), &IN_ADDR_ARPA_172_31)
.is_none());
assert!(trie
.insert(IN_ADDR_ARPA_192_168.clone().into(), &IN_ADDR_ARPA_192_168)
.is_none());
assert!(trie.insert(TEST.clone().into(), &TEST).is_none());
assert!(trie.insert(LOCALHOST.clone().into(), &LOCALHOST).is_none());
assert!(trie
.insert(IN_ADDR_ARPA_127.clone().into(), &IN_ADDR_ARPA_127)
.is_none());
assert!(trie
.insert(IP6_ARPA_1.clone().into(), &IP6_ARPA_1)
.is_none());
assert!(trie.insert(INVALID.clone().into(), &INVALID).is_none());
assert!(trie.insert(EXAMPLE.clone().into(), &EXAMPLE).is_none());
assert!(trie
.insert(EXAMPLE_COM.clone().into(), &EXAMPLE_COM)
.is_none());
assert!(trie
.insert(EXAMPLE_NET.clone().into(), &EXAMPLE_NET)
.is_none());
assert!(trie
.insert(EXAMPLE_ORG.clone().into(), &EXAMPLE_ORG)
.is_none());
UsageTrie(trie)
}
pub fn get(&self, name: &Name) -> &'static ZoneUsage {
self.0
.get_ancestor_value(&TrieName::from(name.clone()))
.expect("DEFAULT root ZoneUsage should have been returned")
}
}
lazy_static! {
pub static ref USAGE: UsageTrie = UsageTrie::default();
}
#[cfg(test)]
mod tests {
use std::net::{Ipv4Addr, Ipv6Addr};
use super::*;
#[test]
fn test_root() {
let name = Name::from_ascii("com.").unwrap();
let usage = USAGE.get(&name);
assert!(usage.is_root());
}
#[test]
fn test_local_networks() {
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(9, 0, 0, 1))).name(),
DEFAULT.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(10, 0, 0, 1))).name(),
IN_ADDR_ARPA_10.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(11, 0, 0, 1))).name(),
DEFAULT.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 16, 0, 0))).name(),
IN_ADDR_ARPA_172_16.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 17, 0, 0))).name(),
IN_ADDR_ARPA_172_17.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 18, 0, 0))).name(),
IN_ADDR_ARPA_172_18.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 19, 0, 0))).name(),
IN_ADDR_ARPA_172_19.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 20, 0, 0))).name(),
IN_ADDR_ARPA_172_20.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 21, 0, 0))).name(),
IN_ADDR_ARPA_172_21.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 22, 0, 0))).name(),
IN_ADDR_ARPA_172_22.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 23, 0, 0))).name(),
IN_ADDR_ARPA_172_23.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 24, 0, 0))).name(),
IN_ADDR_ARPA_172_24.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 25, 0, 0))).name(),
IN_ADDR_ARPA_172_25.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 26, 0, 0))).name(),
IN_ADDR_ARPA_172_26.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 27, 0, 0))).name(),
IN_ADDR_ARPA_172_27.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 28, 0, 0))).name(),
IN_ADDR_ARPA_172_28.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 29, 0, 0))).name(),
IN_ADDR_ARPA_172_29.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 30, 0, 0))).name(),
IN_ADDR_ARPA_172_30.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 31, 0, 0))).name(),
IN_ADDR_ARPA_172_31.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 15, 0, 0))).name(),
DEFAULT.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(172, 32, 0, 0))).name(),
DEFAULT.name()
);
assert_eq!(
USAGE
.get(&Name::from(Ipv4Addr::new(192, 167, 255, 255)))
.name(),
DEFAULT.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(192, 168, 2, 3))).name(),
IN_ADDR_ARPA_192_168.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(192, 169, 0, 0))).name(),
DEFAULT.name()
);
}
#[test]
fn test_example() {
let name = Name::from_ascii("example.").unwrap();
let usage = USAGE.get(&name);
assert_eq!(usage.name(), EXAMPLE.name());
let name = Name::from_ascii("example.com.").unwrap();
let usage = USAGE.get(&name);
assert_eq!(usage.name(), EXAMPLE_COM.name());
let name = Name::from_ascii("example.net.").unwrap();
let usage = USAGE.get(&name);
assert_eq!(usage.name(), EXAMPLE_NET.name());
let name = Name::from_ascii("example.org.").unwrap();
let usage = USAGE.get(&name);
assert_eq!(usage.name(), EXAMPLE_ORG.name());
let name = Name::from_ascii("www.example.org.").unwrap();
let usage = USAGE.get(&name);
assert_eq!(usage.name(), EXAMPLE_ORG.name());
}
#[test]
fn test_localhost() {
let name = Name::from_ascii("localhost.").unwrap();
let usage = USAGE.get(&name);
assert_eq!(usage.name(), LOCALHOST.name());
let name = Name::from_ascii("this.localhost.").unwrap();
let usage = USAGE.get(&name);
assert_eq!(usage.name(), LOCALHOST.name());
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(127, 0, 0, 1))).name(),
IN_ADDR_ARPA_127.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(127, 0, 0, 2))).name(),
IN_ADDR_ARPA_127.name()
);
assert_eq!(
USAGE.get(&Name::from(Ipv4Addr::new(127, 255, 0, 0))).name(),
IN_ADDR_ARPA_127.name()
);
assert_eq!(
USAGE
.get(&Name::from(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)))
.name(),
IP6_ARPA_1.name()
);
}
#[test]
fn test_invalid() {
let name = Name::from_ascii("invalid.").unwrap();
let usage = USAGE.get(&name);
assert_eq!(usage.name(), INVALID.name());
let name = Name::from_ascii("something.invalid.").unwrap();
let usage = USAGE.get(&name);
assert_eq!(usage.name(), INVALID.name());
}
#[test]
fn test_test() {
let name = Name::from_ascii("test.").unwrap();
let usage = USAGE.get(&name);
assert_eq!(usage.name(), TEST.name());
let name = Name::from_ascii("foo.bar.test.").unwrap();
let usage = USAGE.get(&name);
assert_eq!(usage.name(), TEST.name());
}
}