domain_core/bits/opt/
rfc7830.rs

1//! EDNS Options from RFC 7830
2
3use bytes::BufMut;
4use rand::random;
5use ::bits::compose::Compose;
6use ::bits::message_builder::OptBuilder;
7use ::bits::parse::{ParseAll, Parser, ShortBuf};
8use ::iana::OptionCode;
9use super::CodeOptData;
10
11
12//------------ PaddingMode ---------------------------------------------------
13
14#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
15pub enum PaddingMode {
16    Zero,
17    Random,
18}
19
20
21//------------ Padding -------------------------------------------------------
22
23#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
24pub struct Padding {
25    len: u16,
26    mode: PaddingMode
27}
28
29
30#[allow(len_without_is_empty)] // It’s not that kind of len.
31impl Padding {
32    pub fn new(len: u16, mode: PaddingMode) -> Self {
33        Padding { len, mode }
34    }
35    
36    pub fn push(builder: &mut OptBuilder, len: u16, mode: PaddingMode)
37                -> Result<(), ShortBuf> {
38        builder.push(&Self::new(len, mode))
39    }
40
41    pub fn len(self) -> u16 {
42        self.len
43    }
44
45    pub fn mode(self) -> PaddingMode {
46        self.mode
47    }
48}
49
50
51//--- ParseAll and Compose
52
53impl ParseAll for Padding {
54    type Err = ShortBuf;
55
56    fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
57        // XXX Check whether there really are all zeros.
58        parser.advance(len)?;
59        Ok(Padding::new(len as u16, PaddingMode::Zero))
60    }
61}
62
63impl Compose for Padding {
64    fn compose_len(&self) -> usize {
65        self.len as usize
66    }
67
68    fn compose<B: BufMut>(&self, buf: &mut B) {
69        match self.mode {
70            PaddingMode::Zero => {
71                for _ in 0..self.len {
72                    buf.put_u8(0)
73                }
74            }
75            PaddingMode::Random => {
76                for _ in 0..self.len {
77                    buf.put_u8(random())
78                }
79            }
80        }
81    }
82}
83
84impl CodeOptData for Padding {
85    const CODE: OptionCode = OptionCode::Padding;
86}
87