1use std::{fmt, iter, mem, ops::Deref, sync::Arc};
11
12use tracing::{debug, warn};
13
14use crate::{
15 error::*,
16 op::{Edns, Header, MessageType, OpCode, Query, ResponseCode},
17 rr::{Record, RecordType},
18 serialize::binary::{BinDecodable, BinDecoder, BinEncodable, BinEncoder, EncodeMode},
19 xfer::DnsResponse,
20};
21
22#[derive(Clone, Debug, PartialEq, Eq, Default)]
65pub struct Message {
66 header: Header,
67 queries: Vec<Query>,
68 answers: Vec<Record>,
69 name_servers: Vec<Record>,
70 additionals: Vec<Record>,
71 signature: Vec<Record>,
72 edns: Option<Edns>,
73}
74
75pub fn update_header_counts(
77 current_header: &Header,
78 is_truncated: bool,
79 counts: HeaderCounts,
80) -> Header {
81 assert!(counts.query_count <= u16::max_value() as usize);
82 assert!(counts.answer_count <= u16::max_value() as usize);
83 assert!(counts.nameserver_count <= u16::max_value() as usize);
84 assert!(counts.additional_count <= u16::max_value() as usize);
85
86 let mut header = *current_header;
88 header
89 .set_query_count(counts.query_count as u16)
90 .set_answer_count(counts.answer_count as u16)
91 .set_name_server_count(counts.nameserver_count as u16)
92 .set_additional_count(counts.additional_count as u16)
93 .set_truncated(is_truncated);
94
95 header
96}
97
98#[derive(Clone, Copy, Debug)]
102pub struct HeaderCounts {
103 pub query_count: usize,
105 pub answer_count: usize,
107 pub nameserver_count: usize,
109 pub additional_count: usize,
111}
112
113impl Message {
114 pub fn new() -> Self {
116 Self {
117 header: Header::new(),
118 queries: Vec::new(),
119 answers: Vec::new(),
120 name_servers: Vec::new(),
121 additionals: Vec::new(),
122 signature: Vec::new(),
123 edns: None,
124 }
125 }
126
127 pub fn error_msg(id: u16, op_code: OpCode, response_code: ResponseCode) -> Self {
135 let mut message = Self::new();
136 message
137 .set_message_type(MessageType::Response)
138 .set_id(id)
139 .set_response_code(response_code)
140 .set_op_code(op_code);
141
142 message
143 }
144
145 pub fn truncate(&self) -> Self {
147 let mut truncated = self.clone();
148 truncated.set_truncated(true);
149 truncated.take_additionals();
151 truncated.take_answers();
152 truncated.take_queries();
153
154 truncated
156 }
157
158 pub fn set_header(&mut self, header: Header) -> &mut Self {
160 self.header = header;
161 self
162 }
163
164 pub fn set_id(&mut self, id: u16) -> &mut Self {
166 self.header.set_id(id);
167 self
168 }
169
170 pub fn set_message_type(&mut self, message_type: MessageType) -> &mut Self {
172 self.header.set_message_type(message_type);
173 self
174 }
175
176 pub fn set_op_code(&mut self, op_code: OpCode) -> &mut Self {
178 self.header.set_op_code(op_code);
179 self
180 }
181
182 pub fn set_authoritative(&mut self, authoritative: bool) -> &mut Self {
184 self.header.set_authoritative(authoritative);
185 self
186 }
187
188 pub fn set_truncated(&mut self, truncated: bool) -> &mut Self {
190 self.header.set_truncated(truncated);
191 self
192 }
193
194 pub fn set_recursion_desired(&mut self, recursion_desired: bool) -> &mut Self {
196 self.header.set_recursion_desired(recursion_desired);
197 self
198 }
199
200 pub fn set_recursion_available(&mut self, recursion_available: bool) -> &mut Self {
202 self.header.set_recursion_available(recursion_available);
203 self
204 }
205
206 pub fn set_authentic_data(&mut self, authentic_data: bool) -> &mut Self {
208 self.header.set_authentic_data(authentic_data);
209 self
210 }
211
212 pub fn set_checking_disabled(&mut self, checking_disabled: bool) -> &mut Self {
214 self.header.set_checking_disabled(checking_disabled);
215 self
216 }
217
218 pub fn set_response_code(&mut self, response_code: ResponseCode) -> &mut Self {
220 self.header.set_response_code(response_code);
221 self
222 }
223
224 pub fn add_query(&mut self, query: Query) -> &mut Self {
226 self.queries.push(query);
227 self
228 }
229
230 pub fn add_queries<Q, I>(&mut self, queries: Q) -> &mut Self
232 where
233 Q: IntoIterator<Item = Query, IntoIter = I>,
234 I: Iterator<Item = Query>,
235 {
236 for query in queries {
237 self.add_query(query);
238 }
239
240 self
241 }
242
243 pub fn add_answer(&mut self, record: Record) -> &mut Self {
245 self.answers.push(record);
246 self
247 }
248
249 pub fn add_answers<R, I>(&mut self, records: R) -> &mut Self
251 where
252 R: IntoIterator<Item = Record, IntoIter = I>,
253 I: Iterator<Item = Record>,
254 {
255 for record in records {
256 self.add_answer(record);
257 }
258
259 self
260 }
261
262 pub fn insert_answers(&mut self, records: Vec<Record>) {
268 assert!(self.answers.is_empty());
269 self.answers = records;
270 }
271
272 pub fn add_name_server(&mut self, record: Record) -> &mut Self {
274 self.name_servers.push(record);
275 self
276 }
277
278 pub fn add_name_servers<R, I>(&mut self, records: R) -> &mut Self
280 where
281 R: IntoIterator<Item = Record, IntoIter = I>,
282 I: Iterator<Item = Record>,
283 {
284 for record in records {
285 self.add_name_server(record);
286 }
287
288 self
289 }
290
291 pub fn insert_name_servers(&mut self, records: Vec<Record>) {
297 assert!(self.name_servers.is_empty());
298 self.name_servers = records;
299 }
300
301 pub fn add_additional(&mut self, record: Record) -> &mut Self {
303 self.additionals.push(record);
304 self
305 }
306
307 pub fn add_additionals<R, I>(&mut self, records: R) -> &mut Self
309 where
310 R: IntoIterator<Item = Record, IntoIter = I>,
311 I: Iterator<Item = Record>,
312 {
313 for record in records {
314 self.add_additional(record);
315 }
316
317 self
318 }
319
320 pub fn insert_additionals(&mut self, records: Vec<Record>) {
326 assert!(self.additionals.is_empty());
327 self.additionals = records;
328 }
329
330 pub fn set_edns(&mut self, edns: Edns) -> &mut Self {
332 self.edns = Some(edns);
333 self
334 }
335
336 #[cfg(feature = "dnssec")]
340 #[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
341 pub fn add_sig0(&mut self, record: Record) -> &mut Self {
342 assert_eq!(RecordType::SIG, record.rr_type());
343 self.signature.push(record);
344 self
345 }
346
347 #[cfg(feature = "dnssec")]
351 #[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
352 pub fn add_tsig(&mut self, record: Record) -> &mut Self {
353 assert_eq!(RecordType::TSIG, record.rr_type());
354 self.signature.push(record);
355 self
356 }
357
358 pub fn header(&self) -> &Header {
360 &self.header
361 }
362
363 pub fn id(&self) -> u16 {
365 self.header.id()
366 }
367
368 pub fn message_type(&self) -> MessageType {
370 self.header.message_type()
371 }
372
373 pub fn op_code(&self) -> OpCode {
375 self.header.op_code()
376 }
377
378 pub fn authoritative(&self) -> bool {
380 self.header.authoritative()
381 }
382
383 pub fn truncated(&self) -> bool {
385 self.header.truncated()
386 }
387
388 pub fn recursion_desired(&self) -> bool {
390 self.header.recursion_desired()
391 }
392
393 pub fn recursion_available(&self) -> bool {
395 self.header.recursion_available()
396 }
397
398 pub fn authentic_data(&self) -> bool {
400 self.header.authentic_data()
401 }
402
403 pub fn checking_disabled(&self) -> bool {
405 self.header.checking_disabled()
406 }
407
408 pub fn response_code(&self) -> ResponseCode {
413 self.header.response_code()
414 }
415
416 pub fn query(&self) -> Option<&Query> {
421 self.queries.first()
422 }
423
424 pub fn queries(&self) -> &[Query] {
428 &self.queries
429 }
430
431 pub fn queries_mut(&mut self) -> &mut Vec<Query> {
433 &mut self.queries
434 }
435
436 pub fn take_queries(&mut self) -> Vec<Query> {
438 mem::take(&mut self.queries)
439 }
440
441 pub fn answers(&self) -> &[Record] {
445 &self.answers
446 }
447
448 pub fn answers_mut(&mut self) -> &mut Vec<Record> {
450 &mut self.answers
451 }
452
453 pub fn take_answers(&mut self) -> Vec<Record> {
455 mem::take(&mut self.answers)
456 }
457
458 pub fn name_servers(&self) -> &[Record] {
464 &self.name_servers
465 }
466
467 pub fn name_servers_mut(&mut self) -> &mut Vec<Record> {
469 &mut self.name_servers
470 }
471
472 pub fn take_name_servers(&mut self) -> Vec<Record> {
474 mem::take(&mut self.name_servers)
475 }
476
477 pub fn additionals(&self) -> &[Record] {
482 &self.additionals
483 }
484
485 pub fn additionals_mut(&mut self) -> &mut Vec<Record> {
487 &mut self.additionals
488 }
489
490 pub fn take_additionals(&mut self) -> Vec<Record> {
492 mem::take(&mut self.additionals)
493 }
494
495 pub fn all_sections(&self) -> impl Iterator<Item = &Record> {
497 self.answers
498 .iter()
499 .chain(self.name_servers().iter())
500 .chain(self.additionals.iter())
501 }
502
503 #[deprecated(note = "Please use `extensions()`")]
533 pub fn edns(&self) -> Option<&Edns> {
534 self.edns.as_ref()
535 }
536
537 #[deprecated(
539 note = "Please use `extensions_mut()`. You can chain `.get_or_insert_with(Edns::new)` to recover original behavior of adding Edns if not present"
540 )]
541 pub fn edns_mut(&mut self) -> &mut Edns {
542 if self.edns.is_none() {
543 self.set_edns(Edns::new());
544 }
545 self.edns.as_mut().unwrap()
546 }
547
548 pub fn extensions(&self) -> &Option<Edns> {
550 &self.edns
551 }
552
553 pub fn extensions_mut(&mut self) -> &mut Option<Edns> {
555 &mut self.edns
556 }
557
558 pub fn max_payload(&self) -> u16 {
562 let max_size = self.edns.as_ref().map_or(512, Edns::max_payload);
563 if max_size < 512 {
564 512
565 } else {
566 max_size
567 }
568 }
569
570 pub fn version(&self) -> u8 {
574 self.edns.as_ref().map_or(0, Edns::version)
575 }
576
577 pub fn sig0(&self) -> &[Record] {
594 &self.signature
595 }
596
597 pub fn signature(&self) -> &[Record] {
612 &self.signature
613 }
614
615 pub fn take_signature(&mut self) -> Vec<Record> {
617 mem::take(&mut self.signature)
618 }
619
620 #[cfg(test)]
624 pub fn update_counts(&mut self) -> &mut Self {
625 self.header = update_header_counts(
626 &self.header,
627 self.truncated(),
628 HeaderCounts {
629 query_count: self.queries.len(),
630 answer_count: self.answers.len(),
631 nameserver_count: self.name_servers.len(),
632 additional_count: self.additionals.len(),
633 },
634 );
635 self
636 }
637
638 pub fn read_queries(decoder: &mut BinDecoder<'_>, count: usize) -> ProtoResult<Vec<Query>> {
640 let mut queries = Vec::with_capacity(count);
641 for _ in 0..count {
642 queries.push(Query::read(decoder)?);
643 }
644 Ok(queries)
645 }
646
647 #[cfg_attr(not(feature = "dnssec"), allow(unused_mut))]
653 pub fn read_records(
654 decoder: &mut BinDecoder<'_>,
655 count: usize,
656 is_additional: bool,
657 ) -> ProtoResult<(Vec<Record>, Option<Edns>, Vec<Record>)> {
658 let mut records: Vec<Record> = Vec::with_capacity(count);
659 let mut edns: Option<Edns> = None;
660 let mut sigs: Vec<Record> = Vec::with_capacity(if is_additional { 1 } else { 0 });
661
662 let mut saw_sig0 = false;
664 let mut saw_tsig = false;
666 for _ in 0..count {
667 let record = Record::read(decoder)?;
668 if saw_tsig {
669 return Err("tsig must be final resource record".into());
670 } if !is_additional {
672 if saw_sig0 {
673 return Err("sig0 must be final resource record".into());
674 } records.push(record)
676 } else {
677 match record.rr_type() {
678 #[cfg(feature = "dnssec")]
679 RecordType::SIG => {
680 saw_sig0 = true;
681 sigs.push(record);
682 }
683 #[cfg(feature = "dnssec")]
684 RecordType::TSIG => {
685 if saw_sig0 {
686 return Err("sig0 must be final resource record".into());
687 } saw_tsig = true;
689 sigs.push(record);
690 }
691 RecordType::OPT => {
692 if saw_sig0 {
693 return Err("sig0 must be final resource record".into());
694 } if edns.is_some() {
696 return Err("more than one edns record present".into());
697 }
698 edns = Some((&record).into());
699 }
700 _ => {
701 if saw_sig0 {
702 return Err("sig0 must be final resource record".into());
703 } records.push(record);
705 }
706 }
707 }
708 }
709
710 Ok((records, edns, sigs))
711 }
712
713 pub fn from_vec(buffer: &[u8]) -> ProtoResult<Self> {
715 let mut decoder = BinDecoder::new(buffer);
716 Self::read(&mut decoder)
717 }
718
719 pub fn to_vec(&self) -> Result<Vec<u8>, ProtoError> {
721 let mut buffer = Vec::with_capacity(512);
725 {
726 let mut encoder = BinEncoder::new(&mut buffer);
727 self.emit(&mut encoder)?;
728 }
729
730 Ok(buffer)
731 }
732
733 #[allow(clippy::match_single_binding)]
737 pub fn finalize<MF: MessageFinalizer>(
738 &mut self,
739 finalizer: &MF,
740 inception_time: u32,
741 ) -> ProtoResult<Option<MessageVerifier>> {
742 debug!("finalizing message: {:?}", self);
743 let (finals, verifier): (Vec<Record>, Option<MessageVerifier>) =
744 finalizer.finalize_message(self, inception_time)?;
745
746 for fin in finals {
748 match fin.rr_type() {
749 #[cfg(feature = "dnssec")]
751 RecordType::SIG => self.add_sig0(fin),
752 #[cfg(feature = "dnssec")]
753 RecordType::TSIG => self.add_tsig(fin),
754 _ => self.add_additional(fin),
755 };
756 }
757
758 Ok(verifier)
759 }
760
761 pub fn into_parts(self) -> MessageParts {
763 self.into()
764 }
765}
766
767#[derive(Clone, Debug, PartialEq, Eq, Default)]
776pub struct MessageParts {
777 pub header: Header,
779 pub queries: Vec<Query>,
781 pub answers: Vec<Record>,
783 pub name_servers: Vec<Record>,
785 pub additionals: Vec<Record>,
787 pub sig0: Vec<Record>,
791 pub edns: Option<Edns>,
793}
794
795impl From<Message> for MessageParts {
796 fn from(msg: Message) -> Self {
797 let Message {
798 header,
799 queries,
800 answers,
801 name_servers,
802 additionals,
803 signature,
804 edns,
805 } = msg;
806 Self {
807 header,
808 queries,
809 answers,
810 name_servers,
811 additionals,
812 sig0: signature,
813 edns,
814 }
815 }
816}
817
818impl From<MessageParts> for Message {
819 fn from(msg: MessageParts) -> Self {
820 let MessageParts {
821 header,
822 queries,
823 answers,
824 name_servers,
825 additionals,
826 sig0,
827 edns,
828 } = msg;
829 Self {
830 header,
831 queries,
832 answers,
833 name_servers,
834 additionals,
835 signature: sig0,
836 edns,
837 }
838 }
839}
840
841impl Deref for Message {
842 type Target = Header;
843
844 fn deref(&self) -> &Self::Target {
845 &self.header
846 }
847}
848
849pub type MessageVerifier = Box<dyn FnMut(&[u8]) -> ProtoResult<DnsResponse> + Send>;
851
852pub trait MessageFinalizer: Send + Sync + 'static {
857 fn finalize_message(
869 &self,
870 message: &Message,
871 current_time: u32,
872 ) -> ProtoResult<(Vec<Record>, Option<MessageVerifier>)>;
873
874 fn should_finalize_message(&self, message: &Message) -> bool {
877 [OpCode::Update, OpCode::Notify].contains(&message.op_code())
878 || message
879 .queries()
880 .iter()
881 .any(|q| [RecordType::AXFR, RecordType::IXFR].contains(&q.query_type()))
882 }
883}
884
885#[derive(Clone, Copy, Debug)]
889pub struct NoopMessageFinalizer;
890
891impl NoopMessageFinalizer {
892 pub fn new() -> Option<Arc<Self>> {
894 None
895 }
896}
897
898impl MessageFinalizer for NoopMessageFinalizer {
899 fn finalize_message(
900 &self,
901 _: &Message,
902 _: u32,
903 ) -> ProtoResult<(Vec<Record>, Option<MessageVerifier>)> {
904 panic!("Misused NoopMessageFinalizer, None should be used instead")
905 }
906
907 fn should_finalize_message(&self, _: &Message) -> bool {
908 true
909 }
910}
911
912pub fn count_was_truncated(result: ProtoResult<usize>) -> ProtoResult<(usize, bool)> {
914 result.map(|count| (count, false)).or_else(|e| {
915 if let ProtoErrorKind::NotAllRecordsWritten { count } = e.kind() {
916 return Ok((*count, true));
917 }
918
919 Err(e)
920 })
921}
922
923pub trait EmitAndCount {
925 fn emit(&mut self, encoder: &mut BinEncoder<'_>) -> ProtoResult<usize>;
927}
928
929impl<'e, I: Iterator<Item = &'e E>, E: 'e + BinEncodable> EmitAndCount for I {
930 fn emit(&mut self, encoder: &mut BinEncoder<'_>) -> ProtoResult<usize> {
931 encoder.emit_all(self)
932 }
933}
934
935#[allow(clippy::too_many_arguments)]
941pub fn emit_message_parts<Q, A, N, D>(
942 header: &Header,
943 queries: &mut Q,
944 answers: &mut A,
945 name_servers: &mut N,
946 additionals: &mut D,
947 edns: Option<&Edns>,
948 signature: &[Record],
949 encoder: &mut BinEncoder<'_>,
950) -> ProtoResult<Header>
951where
952 Q: EmitAndCount,
953 A: EmitAndCount,
954 N: EmitAndCount,
955 D: EmitAndCount,
956{
957 let include_signature: bool = encoder.mode() != EncodeMode::Signing;
958 let place = encoder.place::<Header>()?;
959
960 let query_count = queries.emit(encoder)?;
961 let answer_count = count_was_truncated(answers.emit(encoder))?;
964 let nameserver_count = count_was_truncated(name_servers.emit(encoder))?;
965 let mut additional_count = count_was_truncated(additionals.emit(encoder))?;
966
967 if let Some(mut edns) = edns.cloned() {
968 edns.set_rcode_high(header.response_code().high());
970
971 let count = count_was_truncated(encoder.emit_all(iter::once(&Record::from(&edns))))?;
972 additional_count.0 += count.0;
973 additional_count.1 |= count.1;
974 } else if header.response_code().high() > 0 {
975 warn!(
976 "response code: {} for request: {} requires EDNS but none available",
977 header.response_code(),
978 header.id()
979 );
980 }
981
982 if include_signature {
986 let count = count_was_truncated(encoder.emit_all(signature.iter()))?;
987 additional_count.0 += count.0;
988 additional_count.1 |= count.1;
989 }
990
991 let counts = HeaderCounts {
992 query_count,
993 answer_count: answer_count.0,
994 nameserver_count: nameserver_count.0,
995 additional_count: additional_count.0,
996 };
997 let was_truncated =
998 header.truncated() || answer_count.1 || nameserver_count.1 || additional_count.1;
999
1000 let final_header = update_header_counts(header, was_truncated, counts);
1001 place.replace(encoder, final_header)?;
1002 Ok(final_header)
1003}
1004
1005impl BinEncodable for Message {
1006 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
1007 emit_message_parts(
1008 &self.header,
1009 &mut self.queries.iter(),
1010 &mut self.answers.iter(),
1011 &mut self.name_servers.iter(),
1012 &mut self.additionals.iter(),
1013 self.edns.as_ref(),
1014 &self.signature,
1015 encoder,
1016 )?;
1017
1018 Ok(())
1019 }
1020}
1021
1022impl<'r> BinDecodable<'r> for Message {
1023 fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
1024 let mut header = Header::read(decoder)?;
1025
1026 let count = header.query_count() as usize;
1031 let mut queries = Vec::with_capacity(count);
1032 for _ in 0..count {
1033 queries.push(Query::read(decoder)?);
1034 }
1035
1036 let answer_count = header.answer_count() as usize;
1038 let name_server_count = header.name_server_count() as usize;
1039 let additional_count = header.additional_count() as usize;
1040
1041 let (answers, _, _) = Self::read_records(decoder, answer_count, false)?;
1042 let (name_servers, _, _) = Self::read_records(decoder, name_server_count, false)?;
1043 let (additionals, edns, signature) = Self::read_records(decoder, additional_count, true)?;
1044
1045 if let Some(edns) = &edns {
1047 let high_response_code = edns.rcode_high();
1048 header.merge_response_code(high_response_code);
1049 }
1050
1051 Ok(Self {
1052 header,
1053 queries,
1054 answers,
1055 name_servers,
1056 additionals,
1057 signature,
1058 edns,
1059 })
1060 }
1061}
1062
1063impl fmt::Display for Message {
1064 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
1065 let write_query = |slice, f: &mut fmt::Formatter<'_>| -> Result<(), fmt::Error> {
1066 for d in slice {
1067 writeln!(f, ";; {}", d)?;
1068 }
1069
1070 Ok(())
1071 };
1072
1073 let write_slice = |slice, f: &mut fmt::Formatter<'_>| -> Result<(), fmt::Error> {
1074 for d in slice {
1075 writeln!(f, "{}", d)?;
1076 }
1077
1078 Ok(())
1079 };
1080
1081 writeln!(f, "; header {header}", header = self.header())?;
1082
1083 if let Some(edns) = self.extensions() {
1084 writeln!(f, "; edns {}", edns)?;
1085 }
1086
1087 writeln!(f, "; query")?;
1088 write_query(self.queries(), f)?;
1089
1090 if self.header().message_type() == MessageType::Response
1091 || self.header().op_code() == OpCode::Update
1092 {
1093 writeln!(f, "; answers {}", self.answer_count())?;
1094 write_slice(self.answers(), f)?;
1095 writeln!(f, "; nameservers {}", self.name_server_count())?;
1096 write_slice(self.name_servers(), f)?;
1097 writeln!(f, "; additionals {}", self.additional_count())?;
1098 write_slice(self.additionals(), f)?;
1099 }
1100
1101 Ok(())
1102 }
1103}
1104
1105#[test]
1106fn test_emit_and_read_header() {
1107 let mut message = Message::new();
1108 message
1109 .set_id(10)
1110 .set_message_type(MessageType::Response)
1111 .set_op_code(OpCode::Update)
1112 .set_authoritative(true)
1113 .set_truncated(false)
1114 .set_recursion_desired(true)
1115 .set_recursion_available(true)
1116 .set_response_code(ResponseCode::ServFail);
1117
1118 test_emit_and_read(message);
1119}
1120
1121#[test]
1122fn test_emit_and_read_query() {
1123 let mut message = Message::new();
1124 message
1125 .set_id(10)
1126 .set_message_type(MessageType::Response)
1127 .set_op_code(OpCode::Update)
1128 .set_authoritative(true)
1129 .set_truncated(true)
1130 .set_recursion_desired(true)
1131 .set_recursion_available(true)
1132 .set_response_code(ResponseCode::ServFail)
1133 .add_query(Query::new())
1134 .update_counts(); test_emit_and_read(message);
1137}
1138
1139#[test]
1140fn test_emit_and_read_records() {
1141 let mut message = Message::new();
1142 message
1143 .set_id(10)
1144 .set_message_type(MessageType::Response)
1145 .set_op_code(OpCode::Update)
1146 .set_authoritative(true)
1147 .set_truncated(true)
1148 .set_recursion_desired(true)
1149 .set_recursion_available(true)
1150 .set_authentic_data(true)
1151 .set_checking_disabled(true)
1152 .set_response_code(ResponseCode::ServFail);
1153
1154 message.add_answer(Record::new());
1155 message.add_name_server(Record::new());
1156 message.add_additional(Record::new());
1157 message.update_counts(); test_emit_and_read(message);
1160}
1161
1162#[cfg(test)]
1163fn test_emit_and_read(message: Message) {
1164 let mut byte_vec: Vec<u8> = Vec::with_capacity(512);
1165 {
1166 let mut encoder = BinEncoder::new(&mut byte_vec);
1167 message.emit(&mut encoder).unwrap();
1168 }
1169
1170 let mut decoder = BinDecoder::new(&byte_vec);
1171 let got = Message::read(&mut decoder).unwrap();
1172
1173 assert_eq!(got, message);
1174}
1175
1176#[test]
1177#[rustfmt::skip]
1178fn test_legit_message() {
1179 let buf: Vec<u8> = vec![
1180 0x10,0x00,0x81,0x80, 0x00,0x01,0x00,0x01, 0x00,0x00,0x00,0x00, 0x03,b'w',b'w',b'w', 0x07,b'e',b'x',b'a', b'm',b'p',b'l',b'e', 0x03,b'c',b'o',b'm', 0x00, 0x00,0x01,0x00,0x01, 0xC0,0x0C, 0x00,0x01,0x00,0x01, 0x00,0x00,0x00,0x02, 0x00,0x04, 0x5D,0xB8,0xD8,0x22, ];
1197
1198 let mut decoder = BinDecoder::new(&buf);
1199 let message = Message::read(&mut decoder).unwrap();
1200
1201 assert_eq!(message.id(), 4096);
1202
1203 let mut buf: Vec<u8> = Vec::with_capacity(512);
1204 {
1205 let mut encoder = BinEncoder::new(&mut buf);
1206 message.emit(&mut encoder).unwrap();
1207 }
1208
1209 let mut decoder = BinDecoder::new(&buf);
1210 let message = Message::read(&mut decoder).unwrap();
1211
1212 assert_eq!(message.id(), 4096);
1213}
1214
1215#[test]
1216fn rdata_zero_roundtrip() {
1217 let buf = &[
1218 160, 160, 0, 13, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0,
1219 ];
1220
1221 assert!(Message::from_bytes(buf).is_err());
1222}