use alloc::vec::Vec;
use core::{fmt, ops::Deref};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::{
dnssec::Algorithm,
error::ProtoResult,
rr::{Name, RData, Record, RecordData, RecordDataDecodable, RecordType},
serialize::binary::{BinDecoder, BinEncodable, BinEncoder, Restrict},
};
use super::{DNSSECRData, SIG};
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct RRSIG(SIG);
impl RRSIG {
#[allow(clippy::too_many_arguments)]
pub fn new(
type_covered: RecordType,
algorithm: Algorithm,
num_labels: u8,
original_ttl: u32,
sig_expiration: u32,
sig_inception: u32,
key_tag: u16,
signer_name: Name,
sig: Vec<u8>,
) -> Self {
Self(SIG::new(
type_covered,
algorithm,
num_labels,
original_ttl,
sig_expiration,
sig_inception,
key_tag,
signer_name,
sig,
))
}
pub fn authenticated_ttl(&self, record: &Record, current_time: u32) -> u32 {
record
.ttl()
.min(self.original_ttl())
.min(self.sig_expiration().0.saturating_sub(current_time))
}
}
impl Deref for RRSIG {
type Target = SIG;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl BinEncodable for RRSIG {
fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
self.0.emit(encoder)
}
}
impl<'r> RecordDataDecodable<'r> for RRSIG {
fn read_data(decoder: &mut BinDecoder<'r>, length: Restrict<u16>) -> ProtoResult<Self> {
SIG::read_data(decoder, length).map(Self)
}
}
impl RecordData for RRSIG {
fn try_from_rdata(data: RData) -> Result<Self, RData> {
match data {
RData::DNSSEC(DNSSECRData::RRSIG(csync)) => Ok(csync),
_ => Err(data),
}
}
fn try_borrow(data: &RData) -> Option<&Self> {
match data {
RData::DNSSEC(DNSSECRData::RRSIG(csync)) => Some(csync),
_ => None,
}
}
fn record_type(&self) -> RecordType {
RecordType::RRSIG
}
fn into_rdata(self) -> RData {
RData::DNSSEC(DNSSECRData::RRSIG(self))
}
}
impl fmt::Display for RRSIG {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}", self.0)
}
}