1use tracing::{debug, error};
9
10use crate::{
11 net::xfer::Protocol,
12 proto::{
13 ProtoError,
14 op::{
15 Edns, Header, HeaderCounts, MessageType, Metadata, OpCode, ResponseCode,
16 emit_message_parts,
17 },
18 rr::{Record, rdata::TSIG},
19 serialize::binary::{BinEncodable, BinEncoder},
20 },
21 server::ResponseInfo,
22 zone_handler::{Queries, message_request::MessageRequest},
23};
24
25#[derive(Debug)]
30pub struct MessageResponse<'q, 'a, Answers, Authorities, Soa, Additionals>
31where
32 Answers: Iterator<Item = &'a Record> + Send + 'a,
33 Authorities: Iterator<Item = &'a Record> + Send + 'a,
34 Soa: Iterator<Item = &'a Record> + Send + 'a,
35 Additionals: Iterator<Item = &'a Record> + Send + 'a,
36{
37 metadata: Metadata,
38 queries: &'q Queries,
39 answers: Answers,
40 authorities: Authorities,
41 soa: Soa,
42 additionals: Additionals,
43 signature: Option<Box<Record<TSIG>>>,
44 edns: Option<&'q Edns>,
45}
46
47impl<'q, 'a, A, N, S, D> MessageResponse<'q, 'a, A, N, S, D>
48where
49 A: Iterator<Item = &'a Record> + Send + 'a,
50 N: Iterator<Item = &'a Record> + Send + 'a,
51 S: Iterator<Item = &'a Record> + Send + 'a,
52 D: Iterator<Item = &'a Record> + Send + 'a,
53{
54 pub fn metadata(&self) -> &Metadata {
56 &self.metadata
57 }
58
59 pub fn metadata_mut(&mut self) -> &mut Metadata {
61 &mut self.metadata
62 }
63
64 pub fn set_edns(&mut self, edns: &'q Edns) -> &mut Self {
66 self.edns = Some(edns);
67 self
68 }
69
70 pub fn edns(&self) -> Option<&'q Edns> {
72 self.edns
73 }
74
75 pub fn set_signature(&mut self, signature: Box<Record<TSIG>>) {
77 self.signature = Some(signature);
78 }
79
80 pub(crate) fn encode(self, protocol: Protocol) -> Result<(ResponseInfo, Vec<u8>), ProtoError> {
81 let id = self.metadata.id;
82 debug!(
83 id,
84 response_code = %self.metadata.response_code,
85 "encoding response"
86 );
87
88 let mut bytes = Vec::with_capacity(512);
89 let mut encoder = BinEncoder::new(&mut bytes);
90 encoder.set_max_size(match protocol {
91 Protocol::Udp => match &self.edns {
92 Some(edns) => edns.max_payload(),
93 None => 512,
96 },
97 _ => u16::MAX,
98 });
99
100 let error = match self.destructive_emit(&mut encoder) {
101 Ok(info) => return Ok((info, bytes)),
102 Err(error) => error,
103 };
104
105 error!(%error, "error encoding message");
106 bytes.clear();
107 let mut encoder = BinEncoder::new(&mut bytes);
108 encoder.set_max_size(512);
109
110 let mut metadata = Metadata::new(id, MessageType::Response, OpCode::Query);
111 metadata.response_code = ResponseCode::ServFail;
112 let header = Header {
113 metadata,
114 counts: HeaderCounts::default(),
115 };
116
117 header.emit(&mut encoder)?;
118 Ok((ResponseInfo::from(header), bytes))
119 }
120
121 pub fn destructive_emit(
123 mut self,
124 encoder: &mut BinEncoder<'_>,
125 ) -> Result<ResponseInfo, ProtoError> {
126 let mut authorities = self.authorities.chain(self.soa);
128
129 let header = emit_message_parts(
130 &self.metadata,
131 &mut self.queries.as_emit_and_count(),
132 &mut self.answers,
133 &mut authorities,
134 &mut self.additionals,
135 self.edns,
136 self.signature.as_deref(),
137 encoder,
138 )?;
139
140 Ok(ResponseInfo::from(header))
141 }
142}
143
144pub struct MessageResponseBuilder<'q> {
146 queries: &'q Queries,
147 signature: Option<Box<Record<TSIG>>>,
148 edns: Option<&'q Edns>,
149}
150
151impl<'q> MessageResponseBuilder<'q> {
152 pub fn new(queries: &'q Queries, edns: Option<&'q Edns>) -> Self {
159 MessageResponseBuilder {
160 queries,
161 signature: None,
162 edns,
163 }
164 }
165
166 pub fn from_message_request(message: &'q MessageRequest) -> Self {
194 Self::new(&message.queries, None)
195 }
196
197 pub fn edns(&mut self, edns: &'q Edns) -> &mut Self {
199 self.edns = Some(edns);
200 self
201 }
202
203 pub fn build<'a, A, N, S, D>(
205 self,
206 metadata: Metadata,
207 answers: A,
208 authorities: N,
209 soa: S,
210 additionals: D,
211 ) -> MessageResponse<'q, 'a, A::IntoIter, N::IntoIter, S::IntoIter, D::IntoIter>
212 where
213 A: IntoIterator<Item = &'a Record> + Send + 'a,
214 A::IntoIter: Send,
215 N: IntoIterator<Item = &'a Record> + Send + 'a,
216 N::IntoIter: Send,
217 S: IntoIterator<Item = &'a Record> + Send + 'a,
218 S::IntoIter: Send,
219 D: IntoIterator<Item = &'a Record> + Send + 'a,
220 D::IntoIter: Send,
221 {
222 MessageResponse {
223 metadata,
224 queries: self.queries,
225 answers: answers.into_iter(),
226 authorities: authorities.into_iter(),
227 soa: soa.into_iter(),
228 additionals: additionals.into_iter(),
229 signature: self.signature,
230 edns: self.edns,
231 }
232 }
233
234 pub fn build_no_records<'a>(
236 self,
237 metadata: Metadata,
238 ) -> MessageResponse<
239 'q,
240 'a,
241 impl Iterator<Item = &'a Record> + Send + 'a,
242 impl Iterator<Item = &'a Record> + Send + 'a,
243 impl Iterator<Item = &'a Record> + Send + 'a,
244 impl Iterator<Item = &'a Record> + Send + 'a,
245 > {
246 MessageResponse {
247 metadata,
248 queries: self.queries,
249 answers: Box::new(None.into_iter()),
250 authorities: Box::new(None.into_iter()),
251 soa: Box::new(None.into_iter()),
252 additionals: Box::new(None.into_iter()),
253 signature: self.signature,
254 edns: self.edns,
255 }
256 }
257
258 pub fn error_msg<'a>(
260 self,
261 request_meta: &Metadata,
262 response_code: ResponseCode,
263 ) -> MessageResponse<
264 'q,
265 'a,
266 impl Iterator<Item = &'a Record> + Send + 'a,
267 impl Iterator<Item = &'a Record> + Send + 'a,
268 impl Iterator<Item = &'a Record> + Send + 'a,
269 impl Iterator<Item = &'a Record> + Send + 'a,
270 > {
271 let mut metadata = Metadata::response_from_request(request_meta);
272 metadata.response_code = response_code;
273
274 MessageResponse {
275 metadata,
276 queries: self.queries,
277 answers: Box::new(None.into_iter()),
278 authorities: Box::new(None.into_iter()),
279 soa: Box::new(None.into_iter()),
280 additionals: Box::new(None.into_iter()),
281 signature: self.signature,
282 edns: self.edns,
283 }
284 }
285}
286
287#[cfg(test)]
288mod tests {
289 use std::iter;
290 use std::net::Ipv4Addr;
291 use std::str::FromStr;
292
293 use crate::proto::op::{Header, Message, MessageType, Metadata, OpCode, Query};
294 use crate::proto::rr::{DNSClass, Name, RData, Record, RecordType};
295 use crate::proto::serialize::binary::{BinDecodable, BinDecoder, BinEncoder};
296
297 use super::*;
298
299 #[test]
300 fn test_truncation_ridiculous_number_answers() {
301 let mut buf = Vec::with_capacity(512);
302 {
303 let mut encoder = BinEncoder::new(&mut buf);
304 encoder.set_max_size(512);
305
306 let mut answer = Record::from_rdata(
307 Name::from_str("www.example.com.").unwrap(),
308 0,
309 RData::A(Ipv4Addr::new(93, 184, 215, 14).into()),
310 );
311 answer.dns_class = DNSClass::NONE;
312
313 let message = MessageResponse {
314 metadata: Metadata::new(10, MessageType::Response, OpCode::Query),
315 queries: &Queries::empty(),
316 answers: iter::repeat(&answer),
317 authorities: iter::once(&answer),
318 soa: iter::once(&answer),
319 additionals: iter::once(&answer),
320 signature: None,
321 edns: None,
322 };
323
324 message
325 .destructive_emit(&mut encoder)
326 .expect("failed to encode");
327 }
328
329 let response = Message::from_vec(&buf).expect("failed to decode");
330 assert!(response.metadata.truncation);
331 assert!(response.answers.len() > 1);
332 assert_eq!(response.authorities.len(), 0);
334 }
335
336 #[test]
337 fn test_truncation_ridiculous_number_nameservers() {
338 let mut buf = Vec::with_capacity(512);
339 {
340 let mut encoder = BinEncoder::new(&mut buf);
341 encoder.set_max_size(512);
342
343 let mut answer = Record::from_rdata(
344 Name::from_str("www.example.com.").unwrap(),
345 0,
346 RData::A(Ipv4Addr::new(93, 184, 215, 14).into()),
347 );
348 answer.dns_class = DNSClass::NONE;
349
350 let message = MessageResponse {
351 metadata: Metadata::new(10, MessageType::Response, OpCode::Query),
352 queries: &Queries::empty(),
353 answers: iter::empty(),
354 authorities: iter::repeat(&answer),
355 soa: iter::repeat(&answer),
356 additionals: iter::repeat(&answer),
357 signature: None,
358 edns: None,
359 };
360
361 message
362 .destructive_emit(&mut encoder)
363 .expect("failed to encode");
364 }
365
366 let response = Message::from_vec(&buf).expect("failed to decode");
367 assert!(response.metadata.truncation);
368 assert_eq!(response.answers.len(), 0);
369 assert!(response.authorities.len() > 1);
370 }
371
372 #[test]
375 fn test_non_edns_udp_response_is_bounded_at_512() {
376 let answer = Record::from_rdata(
377 Name::from_str("www.example.com.").unwrap(),
378 0,
379 RData::A(Ipv4Addr::new(93, 184, 215, 14).into()),
380 );
381
382 let request = MessageRequest::mock(
383 Metadata::new(10, MessageType::Query, OpCode::Query),
384 Query::query(Name::root(), RecordType::A),
385 );
386 assert_eq!(request.max_payload(), 512);
387
388 let response = MessageResponseBuilder::from_message_request(&request).build(
389 Metadata::new(10, MessageType::Response, OpCode::Query),
390 iter::repeat(&answer),
391 [],
392 [],
393 [],
394 );
395
396 let (_info, buf) = response.encode(Protocol::Udp).expect("failed to encode");
397 assert!(buf.len() <= 512, "response was {} bytes", buf.len());
398
399 let response = Message::from_vec(&buf).expect("failed to decode");
400 assert!(response.metadata.truncation);
401 assert!(response.answers.len() > 1);
402 }
403
404 #[test]
436 fn bad_length_of_named_pointers() {
437 let mut buf = Vec::with_capacity(512);
438 let mut encoder = BinEncoder::new(&mut buf);
439
440 let data: &[u8] = &[
441 0x08u8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00,
442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
445 ];
446
447 let mut decoder = BinDecoder::new(data);
448 let header = Header::read(&mut decoder).unwrap();
449 let msg = MessageRequest::read(&mut decoder, header).unwrap();
450
451 eprintln!("queries: {:?}", msg.queries.queries());
452
453 MessageResponseBuilder::new(&msg.queries, None)
454 .build_no_records(Metadata::response_from_request(&msg.metadata))
455 .destructive_emit(&mut encoder)
456 .unwrap();
457 }
458}