1extern crate base64;
2extern crate byteorder;
3
4mod dnscrypt;
5mod doh;
6
7pub use self::dnscrypt::*;
8pub use self::doh::*;
9use std::io::{self, Write};
10
11#[derive(Copy, Clone, Debug)]
12pub enum Protocol {
13 Plain = 0x00,
14 DNSCrypt = 0x01,
15 DoH = 0x02,
16 DoT = 0x03,
17}
18
19pub enum InformalProperty {
20 DNSSEC,
21 NoLogs,
22 NoFilters,
23}
24
25impl From<InformalProperty> for u64 {
26 fn from(informal_property: InformalProperty) -> u64 {
27 match informal_property {
28 InformalProperty::DNSSEC => 0x01,
29 InformalProperty::NoLogs => 0x02,
30 InformalProperty::NoFilters => 0x04,
31 }
32 }
33}
34
35pub trait WithInformalProperty {
36 fn with_informal_property(self, informal_property: InformalProperty) -> Self;
37}
38
39fn lp_encode<W: Write>(writer: &mut W, string: &[u8]) -> io::Result<()> {
40 let mut encoded = vec![];
41 let len = string.len();
42 assert!(len <= 0xff);
43 encoded.push(len as u8);
44 encoded.extend(&string[..]);
45 writer.write_all(&encoded)
46}
47
48fn vlp_encode<W: Write>(writer: &mut W, strings: &[Vec<u8>]) -> io::Result<()> {
49 if strings.is_empty() {
50 return writer.write_all(&[0u8]);
51 }
52 let mut encoded = vec![];
53 let mut it = strings.iter();
54 let mut next = it.next();
55 while let Some(string) = next {
56 next = it.next();
57 let len = string.len();
58 assert!(len < 0x80);
59 match next {
60 None => encoded.push(len as u8),
61 _ => encoded.push(0x80 | len as u8),
62 };
63 encoded.extend(&string[..]);
64 }
65 writer.write_all(&encoded)
66}
67
68#[test]
69fn test_doh() {
70 let b = DoHBuilder::new("example.com".to_owned(), "/dns".to_owned())
71 .with_address("127.0.0.1:443".to_string())
72 .with_informal_property(InformalProperty::DNSSEC)
73 .serialize()
74 .unwrap();
75 assert_eq!(
76 b,
77 "sdns://AgEAAAAAAAAADTEyNy4wLjAuMTo0NDMAC2V4YW1wbGUuY29tBC9kbnM",
78 )
79}