use core::cmp::Ordering;
use domain_macros::*;
use crate::new::base::build::BuildInMessage;
use crate::new::base::name::{CanonicalName, Name, NameCompressor};
use crate::new::base::wire::{AsBytes, BuildBytes, TruncationError, U16};
use crate::new::base::{CanonicalRecordData, RType, Serial, TTL};
use super::SecAlg;
#[derive(Clone, Debug, PartialEq, Eq, Hash, BuildBytes, ParseBytes)]
pub struct RRSig<'a> {
pub rtype: RType,
pub algorithm: SecAlg,
pub labels: u8,
pub ttl: TTL,
pub expiration: Serial,
pub inception: Serial,
pub keytag: U16,
pub signer: &'a Name,
pub signature: &'a [u8],
}
impl RRSig<'_> {
#[cfg(feature = "bumpalo")]
pub fn clone_to_bump<'r>(&self, bump: &'r bumpalo::Bump) -> RRSig<'r> {
use crate::utils::dst::copy_to_bump;
RRSig {
signer: copy_to_bump(self.signer, bump),
signature: bump.alloc_slice_copy(self.signature),
..self.clone()
}
}
}
impl CanonicalRecordData for RRSig<'_> {
fn cmp_canonical(&self, that: &Self) -> Ordering {
let this_initial = (
self.rtype,
self.algorithm,
self.labels,
self.ttl,
self.expiration.as_bytes(),
self.inception.as_bytes(),
self.keytag,
);
let that_initial = (
that.rtype,
that.algorithm,
that.labels,
that.ttl,
that.expiration.as_bytes(),
that.inception.as_bytes(),
that.keytag,
);
this_initial
.cmp(&that_initial)
.then_with(|| self.signer.cmp_lowercase_composed(that.signer))
.then_with(|| self.signature.cmp(that.signature))
}
}
impl BuildInMessage for RRSig<'_> {
fn build_in_message(
&self,
contents: &mut [u8],
start: usize,
_compressor: &mut NameCompressor,
) -> Result<usize, TruncationError> {
let bytes = contents.get_mut(start..).ok_or(TruncationError)?;
let rest = self.build_bytes(bytes)?.len();
Ok(contents.len() - rest)
}
}