domain_core/bits/opt/
rfc8145.rs

1//! EDNS Options from RFC 8145.
2
3use bytes::{BigEndian, BufMut, ByteOrder, Bytes};
4use ::bits::compose::Compose;
5use ::bits::message_builder::OptBuilder;
6use ::bits::parse::{ParseAll, ParseAllError, Parser, ShortBuf};
7use ::iana::OptionCode;
8use super::CodeOptData;
9
10
11//------------ KeyTag -------------------------------------------------------
12
13#[derive(Clone, Debug, Eq, Hash, PartialEq)]
14pub struct KeyTag {
15    bytes: Bytes,
16}
17
18impl KeyTag {
19    pub fn new(bytes: Bytes) -> Self {
20        KeyTag { bytes }
21    }
22
23    pub fn push(builder: &mut OptBuilder, tags: &[u16])
24                -> Result<(), ShortBuf> {
25        let len = tags.len() * 2;
26        assert!(len <= ::std::u16::MAX as usize);
27        builder.build(OptionCode::KeyTag, len as u16, |buf| {
28            for tag in tags {
29                buf.compose(&tag)?
30            }
31            Ok(())
32        })
33    }
34
35    pub fn iter(&self) -> KeyTagIter {
36        KeyTagIter(self.bytes.as_ref())
37    }
38}
39
40
41//--- ParseAll and Compose
42
43impl ParseAll for KeyTag {
44    type Err = ParseAllError;
45
46    fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
47        if len % 2 == 1 {
48            Err(ParseAllError::TrailingData)
49        }
50        else {
51            Ok(Self::new(parser.parse_bytes(len)?))
52        }
53    }
54}
55
56impl Compose for KeyTag {
57    fn compose_len(&self) -> usize {
58        self.bytes.len()
59    }
60
61    fn compose<B: BufMut>(&self, buf: &mut B) {
62        buf.put_slice(self.bytes.as_ref())
63    }
64}
65
66
67//--- CodeOptData
68
69impl CodeOptData for KeyTag {
70    const CODE: OptionCode = OptionCode::KeyTag;
71}
72
73
74//--- IntoIterator
75
76impl<'a> IntoIterator for &'a KeyTag {
77    type Item = u16;
78    type IntoIter = KeyTagIter<'a>;
79
80    fn into_iter(self) -> Self::IntoIter {
81        self.iter()
82    }
83}
84
85
86//------------ KeyTagIter ----------------------------------------------------
87
88#[derive(Clone, Copy, Debug)]
89pub struct KeyTagIter<'a>(&'a [u8]);
90
91impl<'a> Iterator for KeyTagIter<'a> {
92    type Item = u16;
93
94    fn next(&mut self) -> Option<Self::Item> {
95        if self.0.len() < 2 {
96            None
97        }
98        else {
99            let (item, tail) = self.0.split_at(2);
100            self.0 = tail;
101            Some(BigEndian::read_u16(item))
102        }
103    }
104}
105