use core::{
cmp::Ordering,
fmt,
hash::{Hash, Hasher},
};
use crate::{
new::base::{
build::BuildInMessage,
name::NameCompressor,
wire::{
AsBytes, BuildBytes, ParseBytes, ParseBytesZC, SplitBytes,
SplitBytesZC, TruncationError, U16,
},
CanonicalRecordData,
},
utils::dst::UnsizedCopy,
};
use super::SecAlg;
#[derive(Debug, AsBytes, BuildBytes, ParseBytesZC, UnsizedCopy)]
#[repr(C)]
pub struct DNSKey {
pub flags: DNSKeyFlags,
pub protocol: u8,
pub algorithm: SecAlg,
pub key: [u8],
}
impl CanonicalRecordData for DNSKey {
fn cmp_canonical(&self, other: &Self) -> Ordering {
self.as_bytes().cmp(other.as_bytes())
}
}
impl BuildInMessage for DNSKey {
fn build_in_message(
&self,
contents: &mut [u8],
start: usize,
_compressor: &mut NameCompressor,
) -> Result<usize, TruncationError> {
let bytes = self.as_bytes();
let end = start + bytes.len();
contents
.get_mut(start..end)
.ok_or(TruncationError)?
.copy_from_slice(bytes);
Ok(end)
}
}
#[cfg(feature = "alloc")]
impl Clone for alloc::boxed::Box<DNSKey> {
fn clone(&self) -> Self {
(*self).unsized_copy_into()
}
}
impl PartialEq for DNSKey {
fn eq(&self, other: &Self) -> bool {
self.as_bytes() == other.as_bytes()
}
}
impl Eq for DNSKey {}
impl Hash for DNSKey {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write(self.as_bytes())
}
}
#[derive(
Copy,
Clone,
Default,
Hash,
PartialEq,
Eq,
AsBytes,
BuildBytes,
ParseBytes,
ParseBytesZC,
SplitBytes,
SplitBytesZC,
UnsizedCopy,
)]
#[repr(transparent)]
pub struct DNSKeyFlags {
inner: U16,
}
impl DNSKeyFlags {
fn get_flag(&self, pos: u32) -> bool {
self.inner.get() & (1 << pos) != 0
}
fn set_flag(mut self, pos: u32, value: bool) -> Self {
self.inner &= !(1 << pos);
self.inner |= (value as u16) << pos;
self
}
pub fn bits(&self) -> u16 {
self.inner.get()
}
pub fn is_zone_key(&self) -> bool {
self.get_flag(8)
}
pub fn set_zone_key(self, value: bool) -> Self {
self.set_flag(8, value)
}
pub fn is_secure_entry_point(&self) -> bool {
self.get_flag(0)
}
pub fn set_secure_entry_point(self, value: bool) -> Self {
self.set_flag(0, value)
}
}
impl fmt::Debug for DNSKeyFlags {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DNSKeyFlags")
.field("zone_key", &self.is_zone_key())
.field("secure_entry_point", &self.is_secure_entry_point())
.field("bits", &self.bits())
.finish()
}
}