flex_dns/rdata/
tkey.rs

1use crate::{Buffer, DnsMessage, DnsMessageError, MutBuffer};
2use crate::characters::Characters;
3use crate::name::DnsName;
4use crate::parse::Parse;
5use crate::rdata::{RData, RDataParse};
6use crate::write::WriteBytes;
7
8/// # Transaction key record (TKEY)
9/// This record is used to establish a shared key between two hosts.
10#[derive(Copy, Clone, Debug, PartialEq)]
11pub struct TKey<'a> {
12    /// The algorithm used to generate the key.
13    pub algorithm: DnsName<'a>,
14    /// The time the key was generated.
15    pub inception: u32,
16    /// The time the key will expire.
17    pub expiration: u32,
18    /// The mode of the key.
19    pub mode: u16,
20    /// The error that occurred.
21    pub error: u16,
22    /// The key data.
23    pub key: Characters<'a>,
24    /// The other data.
25    pub other: Characters<'a>,
26}
27
28impl<'a> RDataParse<'a> for TKey<'a> {
29    #[inline]
30    fn parse(rdata: &RData<'a>, i: &mut usize) -> Result<Self, DnsMessageError> {
31        let algorithm = DnsName::parse(rdata.buffer, i)?;
32        let inception = u32::parse(rdata.buffer, i)?;
33        let expiration = u32::parse(rdata.buffer, i)?;
34        let mode = u16::parse(rdata.buffer, i)?;
35        let error = u16::parse(rdata.buffer, i)?;
36        let key = Characters::parse(rdata.buffer, i)?;
37        let other = Characters::parse(rdata.buffer, i)?;
38
39        Ok(Self {
40            algorithm,
41            inception,
42            expiration,
43            mode,
44            error,
45            key,
46            other,
47        })
48    }
49}
50
51impl<'a> WriteBytes for TKey<'a> {
52    #[inline]
53    fn write<
54        const PTR_STORAGE: usize,
55        const DNS_SECTION: usize,
56        B: MutBuffer + Buffer,
57    >(&self, message: &mut DnsMessage<PTR_STORAGE, DNS_SECTION, B>) -> Result<usize, DnsMessageError> {
58        let mut bytes = 0;
59
60        bytes += self.algorithm.write(message)?;
61        bytes += self.inception.write(message)?;
62        bytes += self.expiration.write(message)?;
63        bytes += self.mode.write(message)?;
64        bytes += self.error.write(message)?;
65        bytes += self.key.write(message)?;
66        bytes += self.other.write(message)?;
67
68        Ok(bytes)
69    }
70}
71
72#[cfg(test)]
73mod test {
74    use crate::rdata::testutils::parse_write_test;
75
76    use super::*;
77
78    parse_write_test!(
79        25,
80        [
81            0x03, b'w', b'w', b'w', 0x00, // algorithm
82            0x00, 0x00, 0x00, 0x0a, // inception
83            0x00, 0x00, 0x00, 0x0b, // expiration
84            0x00, 0x0c, // mode
85            0x00, 0x0d, // error
86            0x03, b'w', b'w', b'w', // key
87            0x03, b'w', b'w', b'w', // other
88        ],
89        TKey {
90            algorithm: unsafe { DnsName::new_unchecked(b"\x03www\x00") },
91            inception: 10,
92            expiration: 11,
93            mode: 12,
94            error: 13,
95            key: unsafe { Characters::new_unchecked(b"www") },
96            other: unsafe { Characters::new_unchecked(b"www") },
97        },
98    );
99}