hickory_server/authority/
message_request.rs1use crate::proto::{
9 ProtoError, ProtoErrorKind,
10 op::{
11 Edns, Header, LowerQuery, Message, MessageType, OpCode, ResponseCode,
12 message::{self, EmitAndCount},
13 },
14 rr::Record,
15 serialize::binary::{BinDecodable, BinDecoder, BinEncodable, BinEncoder},
16};
17
18#[derive(Debug, PartialEq)]
20pub struct MessageRequest {
21 header: Header,
22 queries: Queries,
23 answers: Vec<Record>,
24 name_servers: Vec<Record>,
25 additionals: Vec<Record>,
26 sig0: Vec<Record>,
27 edns: Option<Edns>,
28}
29
30impl MessageRequest {
31 pub fn header(&self) -> &Header {
33 &self.header
34 }
35
36 pub fn id(&self) -> u16 {
38 self.header.id()
39 }
40
41 pub fn message_type(&self) -> MessageType {
43 self.header.message_type()
44 }
45
46 pub fn op_code(&self) -> OpCode {
48 self.header.op_code()
49 }
50
51 pub fn authoritative(&self) -> bool {
53 self.header.authoritative()
54 }
55
56 pub fn truncated(&self) -> bool {
58 self.header.truncated()
59 }
60
61 pub fn recursion_desired(&self) -> bool {
63 self.header.recursion_desired()
64 }
65
66 pub fn recursion_available(&self) -> bool {
68 self.header.recursion_available()
69 }
70
71 pub fn authentic_data(&self) -> bool {
73 self.header.authentic_data()
74 }
75
76 pub fn checking_disabled(&self) -> bool {
78 self.header.checking_disabled()
79 }
80
81 pub fn response_code(&self) -> ResponseCode {
86 self.header.response_code()
87 }
88
89 pub fn queries(&self) -> &[LowerQuery] {
93 &self.queries.queries
94 }
95
96 pub fn answers(&self) -> &[Record] {
100 &self.answers
101 }
102
103 pub fn name_servers(&self) -> &[Record] {
109 &self.name_servers
110 }
111
112 pub fn additionals(&self) -> &[Record] {
117 &self.additionals
118 }
119
120 pub fn edns(&self) -> Option<&Edns> {
150 self.edns.as_ref()
151 }
152
153 pub fn sig0(&self) -> &[Record] {
155 &self.sig0
156 }
157
158 pub fn max_payload(&self) -> u16 {
162 let max_size = self.edns.as_ref().map_or(512, Edns::max_payload);
163 if max_size < 512 { 512 } else { max_size }
164 }
165
166 pub fn version(&self) -> u8 {
170 self.edns.as_ref().map_or(0, Edns::version)
171 }
172
173 pub(crate) fn raw_queries(&self) -> &Queries {
175 &self.queries
176 }
177}
178
179impl<'q> BinDecodable<'q> for MessageRequest {
180 fn read(decoder: &mut BinDecoder<'q>) -> Result<Self, ProtoError> {
183 let mut header = Header::read(decoder)?;
184
185 let mut try_parse_rest = move || {
186 let query_count = header.query_count() as usize;
188 let answer_count = header.answer_count() as usize;
189 let name_server_count = header.name_server_count() as usize;
190 let additional_count = header.additional_count() as usize;
191
192 let queries = Queries::read(decoder, query_count)?;
193 let (answers, _, _) = Message::read_records(decoder, answer_count, false)?;
194 let (name_servers, _, _) = Message::read_records(decoder, name_server_count, false)?;
195 let (additionals, edns, sig0) = Message::read_records(decoder, additional_count, true)?;
196
197 if let Some(edns) = &edns {
199 let high_response_code = edns.rcode_high();
200 header.merge_response_code(high_response_code);
201 }
202
203 Ok(Self {
204 header,
205 queries,
206 answers,
207 name_servers,
208 additionals,
209 sig0,
210 edns,
211 })
212 };
213
214 match try_parse_rest() {
215 Ok(message) => Ok(message),
216 Err(e) => Err(ProtoErrorKind::FormError {
217 header,
218 error: Box::new(e),
219 }
220 .into()),
221 }
222 }
223}
224
225#[derive(Debug, PartialEq, Eq)]
227pub struct Queries {
228 queries: Vec<LowerQuery>,
229 original: Box<[u8]>,
230}
231
232impl Queries {
233 fn read_queries(
234 decoder: &mut BinDecoder<'_>,
235 count: usize,
236 ) -> Result<Vec<LowerQuery>, ProtoError> {
237 let mut queries = Vec::with_capacity(count);
238 for _ in 0..count {
239 queries.push(LowerQuery::read(decoder)?);
240 }
241 Ok(queries)
242 }
243
244 pub fn read(decoder: &mut BinDecoder<'_>, num_queries: usize) -> Result<Self, ProtoError> {
246 let queries_start = decoder.index();
247 let queries = Self::read_queries(decoder, num_queries)?;
248 let original = decoder
249 .slice_from(queries_start)?
250 .to_vec()
251 .into_boxed_slice();
252
253 Ok(Self { queries, original })
254 }
255
256 pub fn len(&self) -> usize {
258 self.queries.len()
259 }
260
261 pub fn is_empty(&self) -> bool {
263 self.queries.is_empty()
264 }
265
266 pub fn queries(&self) -> &[LowerQuery] {
268 &self.queries
269 }
270
271 pub fn as_bytes(&self) -> &[u8] {
273 self.original.as_ref()
274 }
275
276 pub(crate) fn as_emit_and_count(&self) -> QueriesEmitAndCount<'_> {
277 QueriesEmitAndCount {
278 length: self.queries.len(),
279 first_query: self.queries.first(),
282 cached_serialized: self.original.as_ref(),
283 }
284 }
285
286 pub(crate) fn try_as_query(&self) -> Result<&LowerQuery, ProtoError> {
289 let count = self.queries.len();
290 if count != 1 {
291 return Err(ProtoErrorKind::BadQueryCount(count).into());
292 }
293 Ok(&self.queries[0])
294 }
295
296 pub(crate) fn empty() -> Self {
298 Self {
299 queries: Vec::new(),
300 original: (*b"").into(),
301 }
302 }
303}
304
305pub(crate) struct QueriesEmitAndCount<'q> {
306 length: usize,
308 first_query: Option<&'q LowerQuery>,
310 cached_serialized: &'q [u8],
312}
313
314impl EmitAndCount for QueriesEmitAndCount<'_> {
315 fn emit(&mut self, encoder: &mut BinEncoder<'_>) -> Result<usize, ProtoError> {
316 let original_offset = encoder.offset();
317 encoder.emit_vec(self.cached_serialized)?;
318 if !encoder.is_canonical_names() && self.first_query.is_some() {
319 encoder.store_label_pointer(
320 original_offset,
321 original_offset + self.cached_serialized.len(),
322 )
323 }
324 Ok(self.length)
325 }
326}
327
328impl BinEncodable for MessageRequest {
329 fn emit(&self, encoder: &mut BinEncoder<'_>) -> Result<(), ProtoError> {
330 message::emit_message_parts(
331 &self.header,
332 &mut self.queries.queries.iter(),
335 &mut self.answers.iter(),
336 &mut self.name_servers.iter(),
337 &mut self.additionals.iter(),
338 self.edns.as_ref(),
339 &self.sig0,
340 encoder,
341 )?;
342
343 Ok(())
344 }
345}
346
347pub trait UpdateRequest {
349 fn id(&self) -> u16;
351
352 fn zone(&self) -> Result<&LowerQuery, ProtoError>;
354
355 fn prerequisites(&self) -> &[Record];
357
358 fn updates(&self) -> &[Record];
360
361 fn additionals(&self) -> &[Record];
363
364 fn sig0(&self) -> &[Record];
366}
367
368impl UpdateRequest for MessageRequest {
369 fn id(&self) -> u16 {
370 Self::id(self)
371 }
372
373 fn zone(&self) -> Result<&LowerQuery, ProtoError> {
374 self.raw_queries().try_as_query()
376 }
377
378 fn prerequisites(&self) -> &[Record] {
379 self.answers()
380 }
381
382 fn updates(&self) -> &[Record] {
383 self.name_servers()
384 }
385
386 fn additionals(&self) -> &[Record] {
387 self.additionals()
388 }
389
390 fn sig0(&self) -> &[Record] {
391 self.sig0()
392 }
393}