1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use identity::{Address, Secret, Signature};
use std::net::SocketAddr;
#[derive(Clone, Debug)]
pub struct DnsRecord {
pub priority: u8,
pub addr: SocketAddr,
pub x: Address,
pub epoch: u32,
}
impl DnsRecord {
pub fn to_signed_txt(&self, sign: &Secret) -> String {
let txt = format!(
"carrier=3 c={} p={} n={} x={}",
self.epoch,
self.priority,
self.addr,
self.x.to_string()
);
let sig = sign.sign(b"carrier dns record", txt.as_bytes());
format!("{} {}", txt, sig.to_string())
}
pub fn from_signed_txt<S: AsRef<str>>(s: S) -> Option<Self> {
let mut epoch = None;
let mut priority = None;
let mut net = None;
let mut xaddr = None;
let s = s.as_ref();
let mut s: Vec<&str> = s.split(" ").collect();
let sig: Signature = if let Some(s) = s.pop() {
if let Ok(v) = s.parse() {
v
} else {
return None;
}
} else {
return None;
};
for s in &s {
let s: Vec<&str> = s.split("=").collect();
if s.len() != 2 {
continue;
}
if s[0] == "c" {
if let Ok(v) = s[1].parse() {
epoch = Some(v);
}
}
if s[0] == "p" {
if let Ok(v) = s[1].parse() {
priority = Some(v);
}
}
if s[0] == "n" {
if let Ok(v) = s[1].parse() {
net = Some(v);
}
}
if s[0] == "x" {
if let Ok(v) = s[1].parse() {
xaddr = Some(v);
}
}
}
if let (Some(epoch), Some(priority), Some(addr), Some(x)) = (epoch, priority, net, xaddr) {
Some(DnsRecord {
priority,
addr,
x,
epoch,
})
} else {
None
}
}
}