dns_stamp/
dnscrypt.rs

1use byteorder::{LittleEndian, WriteBytesExt};
2use crate::{lp_encode, vlp_encode, InformalProperty, WithInformalProperty};
3use std::io;
4
5#[derive(Default, Debug)]
6pub struct DNSCryptProvider {
7    name: String,
8    pk: Vec<u8>,
9}
10
11impl DNSCryptProvider {
12    pub fn new(name: String, pk: Vec<u8>) -> Self {
13        DNSCryptProvider { name, pk }
14    }
15}
16
17#[derive(Default, Debug)]
18pub struct DNSCryptBuilder {
19    informal_properties: u64,
20    addrs: Vec<String>,
21    provider: DNSCryptProvider,
22}
23
24impl DNSCryptBuilder {
25    pub fn new(provider: DNSCryptProvider) -> Self {
26        DNSCryptBuilder {
27            informal_properties: 0,
28            addrs: vec![],
29            provider,
30        }
31    }
32
33    pub fn with_addr(mut self, addr: String) -> Self {
34        self.addrs.push(addr);
35        self
36    }
37
38    pub fn serialize(self) -> io::Result<String> {
39        let mut bin = vec![];
40        bin.push(0x01);
41        bin.write_u64::<LittleEndian>(self.informal_properties)?;
42        let addrs_bin: Vec<_> = self
43            .addrs
44            .iter()
45            .map(|addr| addr.as_bytes().to_vec())
46            .collect();
47        vlp_encode(&mut bin, &addrs_bin)?;
48        let provider_bin = {
49            let mut bin = vec![];
50            bin.extend(&self.provider.pk);
51            bin.extend(self.provider.name.as_str().as_bytes());
52            bin
53        };
54        lp_encode(&mut bin, &provider_bin)?;
55        let serialized = base64::encode_config(
56            &bin,
57            base64::Config::new(base64::CharacterSet::UrlSafe, false),
58        );
59        Ok(format!("sdns://{}", serialized))
60    }
61}
62
63impl WithInformalProperty for DNSCryptBuilder {
64    fn with_informal_property(mut self, informal_property: InformalProperty) -> Self {
65        self.informal_properties |= u64::from(informal_property);
66        self
67    }
68}