domain_core/bits/opt/
rfc5001.rs

1/// EDNS0 Options from RFC 5001.
2
3use std::fmt;
4use bytes::{BufMut, Bytes};
5use ::bits::compose::Compose;
6use ::bits::message_builder::OptBuilder;
7use ::bits::parse::{ParseAll, Parser, ShortBuf};
8use ::iana::OptionCode;
9use super::CodeOptData;
10
11
12//------------ Nsid ---------------------------------------------------------/
13
14/// The Name Server Identifier (NSID) Option.
15///
16/// Specified in RFC 5001.
17#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
18pub struct Nsid {
19    bytes: Bytes
20}
21
22impl Nsid {
23    pub fn new(bytes: Bytes) -> Self {
24        Nsid { bytes }
25    }
26
27    pub fn push<T: AsRef<[u8]>>(builder: &mut OptBuilder, data: &T)
28                                -> Result<(), ShortBuf> {
29        let data = data.as_ref();
30        assert!(data.len() <= ::std::u16::MAX as usize);
31        builder.build(OptionCode::Nsid, data.len() as u16, |buf| {
32            buf.compose(data)
33        })
34    }
35}
36
37impl ParseAll for Nsid {
38    type Err = ShortBuf;
39
40    fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
41        parser.parse_bytes(len).map(Nsid::new)
42    }
43}
44
45impl CodeOptData for Nsid {
46    const CODE: OptionCode = OptionCode::Nsid;
47}
48
49
50impl Compose for Nsid {
51    fn compose_len(&self) -> usize {
52        self.bytes.len()
53    }
54
55    fn compose<B: BufMut>(&self, buf: &mut B) {
56        assert!(self.bytes.len() < ::std::u16::MAX as usize);
57        buf.put_slice(self.bytes.as_ref())
58    }
59}
60
61impl fmt::Display for Nsid {
62    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63        // RFC 5001 § 2.4:
64        // | User interfaces MUST read and write the contents of the NSID
65        // | option as a sequence of hexadecimal digits, two digits per
66        // | payload octet.
67        for v in self.bytes.as_ref() {
68            write!(f, "{:X}", *v)?
69        }
70        Ok(())
71    }
72}
73
74