Skip to main content

ddns/core/parser/record/
srv.rs

1use nom::number::streaming::be_u16;
2
3use crate::core::parser::name::{Name, be_name};
4
5#[derive(Debug, PartialEq, Eq, Hash, Clone)]
6pub struct Srv {
7    priority: u16,
8    weight: u16,
9    port: u16,
10    target: Name,
11}
12
13impl Srv {
14    pub fn new(priority: u16, weight: u16, port: u16, target: Name) -> Self {
15        Self {
16            priority,
17            weight,
18            port,
19            target,
20        }
21    }
22
23    pub fn priority(&self) -> u16 {
24        self.priority
25    }
26
27    pub fn weight(&self) -> u16 {
28        self.weight
29    }
30
31    pub fn port(&self) -> u16 {
32        self.port
33    }
34
35    pub fn target(&self) -> &Name {
36        &self.target
37    }
38}
39
40pub fn be_srv<'a>(input: &'a [u8], origin: &'a [u8]) -> nom::IResult<&'a [u8], Srv> {
41    let (remain, priority) = be_u16(input)?;
42    let (remain, weight) = be_u16(remain)?;
43    let (remain, port) = be_u16(remain)?;
44    let (remain, target) = be_name(remain, origin)?;
45    Ok((
46        remain,
47        Srv {
48            priority,
49            weight,
50            port,
51            target,
52        },
53    ))
54}
55
56#[cfg(test)]
57mod test {
58    use super::*;
59    use crate::core::parser::{
60        packet::be_packet,
61        question::{QueryClass, QueryType},
62        record::{Class, RData},
63    };
64    #[test]
65    fn parse_response() {
66        let response = b"[\xd9\x81\x80\x00\x01\x00\x05\x00\x00\x00\x00\
67            \x0c_xmpp-server\x04_tcp\x05gmail\x03com\x00\x00!\x00\x01\
68            \xc0\x0c\x00!\x00\x01\x00\x00\x03\x84\x00 \x00\x05\x00\x00\
69            \x14\x95\x0bxmpp-server\x01l\x06google\x03com\x00\xc0\x0c\x00!\
70            \x00\x01\x00\x00\x03\x84\x00%\x00\x14\x00\x00\x14\x95\
71            \x04alt3\x0bxmpp-server\x01l\x06google\x03com\x00\
72            \xc0\x0c\x00!\x00\x01\x00\x00\x03\x84\x00%\x00\x14\x00\x00\
73            \x14\x95\x04alt1\x0bxmpp-server\x01l\x06google\x03com\x00\
74            \xc0\x0c\x00!\x00\x01\x00\x00\x03\x84\x00%\x00\x14\x00\x00\
75            \x14\x95\x04alt2\x0bxmpp-server\x01l\x06google\x03com\x00\
76            \xc0\x0c\x00!\x00\x01\x00\x00\x03\x84\x00%\x00\x14\x00\x00\
77            \x14\x95\x04alt4\x0bxmpp-server\x01l\x06google\x03com\x00";
78
79        let (_, packet) = be_packet(response).unwrap();
80
81        assert_eq!(packet.header.id, 23513);
82        assert_eq!(packet.header.questions_count, 1);
83        assert!(packet.header.flags.recursion_desired());
84        assert_eq!(packet.header.answers_count, 5);
85        assert_eq!(packet.questions.len(), 1);
86        assert_eq!(packet.questions[0].qtype, QueryType::Srv);
87        assert_eq!(packet.questions[0].qclass, QueryClass::IN);
88        assert_eq!(
89            &packet.questions[0].name.to_string()[..],
90            "_xmpp-server._tcp.gmail.com"
91        );
92        assert_eq!(packet.answers.len(), 5);
93        let items = [
94            (5, 0, 5269, "xmpp-server.l.google.com"),
95            (20, 0, 5269, "alt3.xmpp-server.l.google.com"),
96            (20, 0, 5269, "alt1.xmpp-server.l.google.com"),
97            (20, 0, 5269, "alt2.xmpp-server.l.google.com"),
98            (20, 0, 5269, "alt4.xmpp-server.l.google.com"),
99        ];
100        for (i, item) in items.iter().enumerate() {
101            assert_eq!(
102                &packet.answers[i].name.to_string()[..],
103                "_xmpp-server._tcp.gmail.com"
104            );
105            assert_eq!(packet.answers[i].cls, Class::IN);
106            assert_eq!(packet.answers[i].ttl, 900);
107            match &packet.answers[i].data {
108                RData::Srv(Srv {
109                    priority,
110                    weight,
111                    port,
112                    target,
113                }) => {
114                    assert_eq!(priority, &item.0);
115                    assert_eq!(weight, &item.1);
116                    assert_eq!(port, &item.2);
117                    assert_eq!(target.to_string(), item.3);
118                }
119                _ => panic!("Wrong rdata"),
120            }
121        }
122    }
123}