simple_dns/dns/rdata/
srv.rs1use crate::{bytes_buffer::BytesBuffer, dns::WireFormat, lib::Write, Name};
2
3use super::RR;
4
5#[derive(Debug, PartialEq, Eq, Hash, Clone)]
7pub struct SRV<'a> {
8 pub priority: u16,
12 pub weight: u16,
16 pub port: u16,
18 pub target: Name<'a>,
20}
21
22impl RR for SRV<'_> {
23 const TYPE_CODE: u16 = 33;
24}
25
26impl SRV<'_> {
27 pub fn into_owned<'b>(self) -> SRV<'b> {
29 SRV {
30 priority: self.priority,
31 weight: self.weight,
32 port: self.port,
33 target: self.target.into_owned(),
34 }
35 }
36}
37
38impl<'a> WireFormat<'a> for SRV<'a> {
39 const MINIMUM_LEN: usize = 6;
40
41 fn parse(data: &mut BytesBuffer<'a>) -> crate::Result<Self>
42 where
43 Self: Sized,
44 {
45 let priority = data.get_u16()?;
46 let weight = data.get_u16()?;
47 let port = data.get_u16()?;
48 let target = Name::parse(data)?;
49
50 Ok(Self {
51 priority,
52 weight,
53 port,
54 target,
55 })
56 }
57
58 fn write_to<T: Write>(&self, out: &mut T) -> crate::Result<()> {
59 out.write_all(&self.priority.to_be_bytes())?;
60 out.write_all(&self.weight.to_be_bytes())?;
61 out.write_all(&self.port.to_be_bytes())?;
62
63 self.target.write_to(out)
64 }
65
66 fn len(&self) -> usize {
67 self.target.len() + Self::MINIMUM_LEN
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::lib::Vec;
75
76 #[test]
77 fn parse_and_write_srv() {
78 let srv = SRV {
79 priority: 1,
80 weight: 2,
81 port: 3,
82 target: Name::new("_srv._tcp.example.com").unwrap(),
83 };
84
85 let mut bytes = Vec::new();
86 assert!(srv.write_to(&mut bytes).is_ok());
87
88 let srv = SRV::parse(&mut bytes[..].into());
89 assert!(srv.is_ok());
90 let srv = srv.unwrap();
91
92 assert_eq!(1, srv.priority);
93 assert_eq!(2, srv.weight);
94 assert_eq!(3, srv.port);
95 assert_eq!(bytes.len(), srv.len());
96 }
97
98 #[test]
99 fn srv_should_not_be_compressed() {
100 use crate::lib::Cursor;
101
102 let srv = SRV {
103 priority: 1,
104 weight: 2,
105 port: 3,
106 target: Name::new("_srv._tcp.example.com").unwrap(),
107 };
108
109 let mut plain = Vec::new();
110 let mut compressed = Cursor::new(Vec::new());
111 let mut names = Default::default();
112
113 assert!(srv.write_to(&mut plain).is_ok());
114 assert!(srv.write_compressed_to(&mut compressed, &mut names).is_ok());
115
116 assert_eq!(plain, compressed.into_inner());
117 }
118
119 #[test]
120 #[cfg(feature = "std")]
121 fn parse_sample() -> Result<(), Box<dyn std::error::Error>> {
122 use crate::{rdata::RData, ResourceRecord};
123 let sample_file = std::fs::read("samples/zonefile/SRV.sample")?;
124
125 let sample_rdata = match ResourceRecord::parse(&mut sample_file[..].into())?.rdata {
126 RData::SRV(rdata) => rdata,
127 _ => unreachable!(),
128 };
129
130 assert_eq!(sample_rdata.priority, 65535);
131 assert_eq!(sample_rdata.weight, 65535);
132 assert_eq!(sample_rdata.port, 65535);
133 assert_eq!(sample_rdata.target, "old-slow-box.sample".try_into()?);
134
135 Ok(())
136 }
137}