128 lines
2.8 KiB
Rust
128 lines
2.8 KiB
Rust
use bytes::Bytes;
|
|
use errors::*;
|
|
use ser::packet::{DnsPacketData, DnsPacketWriteContext};
|
|
use ser::text::{DnsTextData, DnsTextFormatter, DnsTextContext, next_field, parse_with};
|
|
use std::fmt;
|
|
use std::io::Cursor;
|
|
use std::ops::{Deref, DerefMut};
|
|
use std::str::FromStr;
|
|
|
|
use super::{DnsName, DnsNameIterator, DnsLabelRef};
|
|
|
|
/// names that should be written in canonical form for DNSSEC according
|
|
/// to https://tools.ietf.org/html/rfc4034#section-6.2
|
|
///
|
|
/// DnsCompressedName always needs to be written in canonical form for
|
|
/// DNSSEC.
|
|
#[derive(Clone)]
|
|
pub struct DnsCanonicalName(pub DnsName);
|
|
|
|
impl DnsCanonicalName {
|
|
/// Create new name representing the DNS root (".")
|
|
pub fn new_root() -> Self {
|
|
DnsCanonicalName(DnsName::new_root())
|
|
}
|
|
|
|
/// Parse text representation of a domain name
|
|
pub fn parse(context: &DnsTextContext, value: &str) -> Result<Self>
|
|
{
|
|
Ok(DnsCanonicalName(DnsName::parse(context, value)?))
|
|
}
|
|
}
|
|
|
|
impl Deref for DnsCanonicalName {
|
|
type Target = DnsName;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl DerefMut for DnsCanonicalName {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.0
|
|
}
|
|
}
|
|
|
|
impl AsRef<DnsName> for DnsCanonicalName {
|
|
fn as_ref(&self) -> &DnsName {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl AsMut<DnsName> for DnsCanonicalName {
|
|
fn as_mut(&mut self) -> &mut DnsName {
|
|
&mut self.0
|
|
}
|
|
}
|
|
|
|
impl<'a> IntoIterator for &'a DnsCanonicalName {
|
|
type Item = DnsLabelRef<'a>;
|
|
type IntoIter = DnsNameIterator<'a>;
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
self.labels()
|
|
}
|
|
}
|
|
|
|
impl PartialEq<DnsName> for DnsCanonicalName
|
|
{
|
|
fn eq(&self, rhs: &DnsName) -> bool {
|
|
let this: &DnsName = self;
|
|
this == rhs
|
|
}
|
|
}
|
|
|
|
impl<T> PartialEq<T> for DnsCanonicalName
|
|
where
|
|
T: AsRef<DnsName>
|
|
{
|
|
fn eq(&self, rhs: &T) -> bool {
|
|
let this: &DnsName = self.as_ref();
|
|
this == rhs
|
|
}
|
|
}
|
|
|
|
impl Eq for DnsCanonicalName{}
|
|
|
|
impl fmt::Debug for DnsCanonicalName {
|
|
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
|
self.0.fmt(w)
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for DnsCanonicalName {
|
|
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
|
self.0.fmt(w)
|
|
}
|
|
}
|
|
|
|
impl FromStr for DnsCanonicalName {
|
|
type Err = ::failure::Error;
|
|
|
|
fn from_str(s: &str) -> Result<Self> {
|
|
parse_with(s, |data| DnsCanonicalName::dns_parse(&DnsTextContext::new(), data))
|
|
}
|
|
}
|
|
|
|
impl DnsTextData for DnsCanonicalName {
|
|
fn dns_parse(context: &DnsTextContext, data: &mut &str) -> Result<Self> {
|
|
let field = next_field(data)?;
|
|
DnsCanonicalName::parse(context, field)
|
|
}
|
|
|
|
fn dns_format(&self, f: &mut DnsTextFormatter) -> fmt::Result {
|
|
self.0.dns_format(f)
|
|
}
|
|
}
|
|
|
|
impl DnsPacketData for DnsCanonicalName {
|
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
|
Ok(DnsCanonicalName(super::name_packet_parser::deserialize_name(data, false)?))
|
|
}
|
|
|
|
fn serialize(&self, context: &mut DnsPacketWriteContext, packet: &mut Vec<u8>) -> Result<()> {
|
|
context.write_canonical_name(packet, self)
|
|
}
|
|
}
|