flex_dns/rdata/
nsec3.rs

1use crate::{Buffer, DnsMessage, DnsMessageError, MutBuffer};
2use crate::characters::Characters;
3use crate::parse::Parse;
4use crate::rdata::{RData, RDataParse};
5use crate::write::WriteBytes;
6
7/// # Next secure record version 3
8/// This record is used to provide authenticated denial of existence for DNSSEC.
9#[derive(Copy, Clone, Debug, PartialEq)]
10pub struct Nsec3<'a> {
11    /// The hash algorithm used to hash the original owner name field.
12    pub hash_algorithm: u8,
13    /// The flags field.
14    pub flags: u8,
15    /// The number of iterations used to construct the hash.
16    pub iterations: u16,
17    /// The salt used to construct the hash.
18    pub salt: Characters<'a>,
19    /// The next hashed owner name in the canonical ordering of the zone.
20    pub next_hashed_owner_name: Characters<'a>,
21    /// The type bit maps field.
22    pub type_bit_maps: Characters<'a>,
23}
24
25impl<'a> RDataParse<'a> for Nsec3<'a> {
26    #[inline]
27    fn parse(rdata: &RData<'a>, i: &mut usize) -> Result<Self, DnsMessageError> {
28        let hash_algorithm = u8::parse(rdata, i)?;
29        let flags = u8::parse(rdata, i)?;
30        let iterations = u16::parse(rdata, i)?;
31        let salt = Characters::parse(rdata, i)?;
32        let next_hashed_owner_name = Characters::parse(rdata, i)?;
33        let type_bit_maps = Characters::parse(rdata, i)?;
34
35        Ok(Self {
36            hash_algorithm,
37            flags,
38            iterations,
39            salt,
40            next_hashed_owner_name,
41            type_bit_maps,
42        })
43    }
44}
45
46impl<'a> WriteBytes for Nsec3<'a> {
47    #[inline]
48    fn write<
49        const PTR_STORAGE: usize,
50        const DNS_SECTION: usize,
51        B: MutBuffer + Buffer,
52    >(&self, message: &mut DnsMessage<PTR_STORAGE, DNS_SECTION, B>) -> Result<usize, DnsMessageError> {
53        let mut bytes = 0;
54
55        bytes += self.hash_algorithm.write(message)?;
56        bytes += self.flags.write(message)?;
57        bytes += self.iterations.write(message)?;
58        bytes += self.salt.write(message)?;
59        bytes += self.next_hashed_owner_name.write(message)?;
60        bytes += self.type_bit_maps.write(message)?;
61
62        Ok(bytes)
63    }
64}
65
66#[cfg(test)]
67mod test {
68    use crate::rdata::testutils::parse_write_test;
69
70    use super::*;
71
72    parse_write_test!(
73        16,
74        [
75            0x0e, // hash algorithm
76            0x0a, // flags
77            0x00, 0x0e, // iterations
78            0x03, // length of salt
79            b'a', b'b', b'c',
80            0x03, // length of next hashed owner name
81            b'd', b'e', b'f',
82            0x03, // length of type bit maps
83            b'w', b'w', b'w',
84        ],
85        Nsec3 {
86            hash_algorithm: 0x0e,
87            flags: 0x0a,
88            iterations: 0x000e,
89            salt: unsafe { Characters::new_unchecked(b"abc") },
90            next_hashed_owner_name: unsafe { Characters::new_unchecked(b"def") },
91            type_bit_maps: unsafe { Characters::new_unchecked(b"www") },
92        },
93    );
94}