1 /*
2 * Copyright (C) 2015 Benjamin Fry <benjaminfry@me.com>
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //! Message metadata
18
19 use std::convert::From;
20
21 use super::op_code::OpCode;
22 use super::response_code::ResponseCode;
23 use crate::error::*;
24 use crate::serialize::binary::*;
25
26 /// Metadata for the `Message` struct.
27 ///
28 /// [RFC 1035, DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION, November 1987](https://tools.ietf.org/html/rfc1035)
29 ///
30 /// ```text
31 /// 4.1.1. Header section format
32 ///
33 /// The header contains the following fields
34 ///
35 /// 1 1 1 1 1 1
36 /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
37 /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
38 /// | ID |
39 /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
40 /// |QR| Opcode |AA|TC|RD|RA|ZZ|AD|CD| RCODE | /// AD and CD from RFC4035
41 /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
42 /// | QDCOUNT / ZCOUNT |
43 /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
44 /// | ANCOUNT / PRCOUNT |
45 /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
46 /// | NSCOUNT / UPCOUNT |
47 /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
48 /// | ARCOUNT / ADCOUNT |
49 /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
50 ///
51 /// where
52 ///
53 /// Z Reserved for future use. Must be zero in all queries
54 /// and responses.
55 ///
56 /// ```
57 ///
58 #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
59 pub struct Header {
60 id: u16,
61 message_type: MessageType,
62 op_code: OpCode,
63 authoritative: bool,
64 truncation: bool,
65 recursion_desired: bool,
66 recursion_available: bool,
67 authentic_data: bool,
68 checking_disabled: bool,
69 response_code: u8, /* ideally u4 */
70 query_count: u16,
71 answer_count: u16,
72 name_server_count: u16,
73 additional_count: u16,
74 }
75
76 /// Message types are either Query (also Update) or Response
77 #[derive(Debug, PartialEq, PartialOrd, Copy, Clone)]
78 pub enum MessageType {
79 /// Queries are Client requests, these are either Queries or Updates
80 Query,
81 /// Response message from the Server or upstream Resolver
82 Response,
83 }
84
85 impl Default for Header {
default() -> Self86 fn default() -> Self {
87 Header {
88 id: 0,
89 message_type: MessageType::Query,
90 op_code: OpCode::Query,
91 authoritative: false,
92 truncation: false,
93 recursion_desired: false,
94 recursion_available: false,
95 authentic_data: false,
96 checking_disabled: false,
97 response_code: 0,
98 query_count: 0,
99 answer_count: 0,
100 name_server_count: 0,
101 additional_count: 0,
102 }
103 }
104 }
105
106 impl Header {
107 // TODO: we should make id, message_type and op_code all required and non-editable
108 /// A default Header, not very useful.
new() -> Self109 pub fn new() -> Self {
110 Default::default()
111 }
112
113 /// Length of the header, always 12 bytes
114 #[inline(always)]
len() -> usize115 pub fn len() -> usize {
116 12 /* this is always 12 bytes */
117 }
118
119 /// Sets the id of the message, for queries this should be random.
set_id(&mut self, id: u16) -> &mut Self120 pub fn set_id(&mut self, id: u16) -> &mut Self {
121 self.id = id;
122 self
123 }
124
125 /// Sets the message type, Queries and Updates both use Query.
set_message_type(&mut self, message_type: MessageType) -> &mut Self126 pub fn set_message_type(&mut self, message_type: MessageType) -> &mut Self {
127 self.message_type = message_type;
128 self
129 }
130
131 /// Set the operation code for the message
set_op_code(&mut self, op_code: OpCode) -> &mut Self132 pub fn set_op_code(&mut self, op_code: OpCode) -> &mut Self {
133 self.op_code = op_code;
134 self
135 }
136
137 /// From the server is specifies that it is an authoritative response.
set_authoritative(&mut self, authoritative: bool) -> &mut Self138 pub fn set_authoritative(&mut self, authoritative: bool) -> &mut Self {
139 self.authoritative = authoritative;
140 self
141 }
142
143 /// Specifies that the records were too large for the payload.
144 ///
145 /// See EDNS or TCP for resolutions to truncation.
set_truncated(&mut self, truncated: bool) -> &mut Self146 pub fn set_truncated(&mut self, truncated: bool) -> &mut Self {
147 self.truncation = truncated;
148 self
149 }
150
151 /// Specify that the resolver should recursively request data from upstream DNS nodes
set_recursion_desired(&mut self, recursion_desired: bool) -> &mut Self152 pub fn set_recursion_desired(&mut self, recursion_desired: bool) -> &mut Self {
153 self.recursion_desired = recursion_desired;
154 self
155 }
156
157 /// Specifies that recursion is available from this or the remote resolver
set_recursion_available(&mut self, recursion_available: bool) -> &mut Self158 pub fn set_recursion_available(&mut self, recursion_available: bool) -> &mut Self {
159 self.recursion_available = recursion_available;
160 self
161 }
162
163 /// Specifies that the data is authentic, i.e. the resolver believes all data to be valid through DNSSec
set_authentic_data(&mut self, authentic_data: bool) -> &mut Self164 pub fn set_authentic_data(&mut self, authentic_data: bool) -> &mut Self {
165 self.authentic_data = authentic_data;
166 self
167 }
168
169 /// Used during recursive resolution to specified if a resolver should or should not validate DNSSec signatures
set_checking_disabled(&mut self, checking_disabled: bool) -> &mut Self170 pub fn set_checking_disabled(&mut self, checking_disabled: bool) -> &mut Self {
171 self.checking_disabled = checking_disabled;
172 self
173 }
174
175 /// The low response code (original response codes before EDNS extensions)
set_response_code(&mut self, response_code: ResponseCode) -> &mut Self176 pub fn set_response_code(&mut self, response_code: ResponseCode) -> &mut Self {
177 self.response_code = response_code.low();
178 self
179 }
180
181 /// Number or query records in the message
set_query_count(&mut self, query_count: u16) -> &mut Self182 pub fn set_query_count(&mut self, query_count: u16) -> &mut Self {
183 self.query_count = query_count;
184 self
185 }
186
187 /// Number of answer records in the message
set_answer_count(&mut self, answer_count: u16) -> &mut Self188 pub fn set_answer_count(&mut self, answer_count: u16) -> &mut Self {
189 self.answer_count = answer_count;
190 self
191 }
192
193 /// Number of name server records in the message
set_name_server_count(&mut self, name_server_count: u16) -> &mut Self194 pub fn set_name_server_count(&mut self, name_server_count: u16) -> &mut Self {
195 self.name_server_count = name_server_count;
196 self
197 }
198
199 /// Number of additional records in the message
set_additional_count(&mut self, additional_count: u16) -> &mut Self200 pub fn set_additional_count(&mut self, additional_count: u16) -> &mut Self {
201 self.additional_count = additional_count;
202 self
203 }
204
205 /// ```text
206 /// ID A 16 bit identifier assigned by the program that
207 /// generates any kind of query. This identifier is copied
208 /// the corresponding reply and can be used by the requester
209 /// to match up replies to outstanding queries.
210 /// ```
id(&self) -> u16211 pub fn id(&self) -> u16 {
212 self.id
213 }
214
215 /// ```text
216 /// QR A one bit field that specifies whether this message is a
217 /// query (0), or a response (1).
218 /// ```
message_type(&self) -> MessageType219 pub fn message_type(&self) -> MessageType {
220 self.message_type
221 }
222
223 /// ```text
224 /// OPCODE A four bit field that specifies kind of query in this
225 /// message. This value is set by the originator of a query
226 /// and copied into the response. The values are: <see super::op_code>
227 /// ```
op_code(&self) -> OpCode228 pub fn op_code(&self) -> OpCode {
229 self.op_code
230 }
231
232 /// ```text
233 /// AA Authoritative Answer - this bit is valid in responses,
234 /// and specifies that the responding name server is an
235 /// authority for the domain name in question section.
236 ///
237 /// Note that the contents of the answer section may have
238 /// multiple owner names because of aliases. The AA bit
239 /// corresponds to the name which matches the query name, or
240 /// the first owner name in the answer section.
241 /// ```
authoritative(&self) -> bool242 pub fn authoritative(&self) -> bool {
243 self.authoritative
244 }
245
246 /// ```text
247 /// TC TrunCation - specifies that this message was truncated
248 /// due to length greater than that permitted on the
249 /// transmission channel.
250 /// ```
truncated(&self) -> bool251 pub fn truncated(&self) -> bool {
252 self.truncation
253 }
254
255 /// ```text
256 /// RD Recursion Desired - this bit may be set in a query and
257 /// is copied into the response. If RD is set, it directs
258 /// the name server to pursue the query recursively.
259 /// Recursive query support is optional.
260 /// ```
recursion_desired(&self) -> bool261 pub fn recursion_desired(&self) -> bool {
262 self.recursion_desired
263 }
264
265 /// ```text
266 /// RA Recursion Available - this be is set or cleared in a
267 /// response, and denotes whether recursive query support is
268 /// available in the name server.
269 /// ```
recursion_available(&self) -> bool270 pub fn recursion_available(&self) -> bool {
271 self.recursion_available
272 }
273
274 /// [RFC 4035, DNSSEC Resource Records, March 2005](https://tools.ietf.org/html/rfc4035#section-3.1.6)
275 ///
276 /// ```text
277 ///
278 /// 3.1.6. The AD and CD Bits in an Authoritative Response
279 ///
280 /// The CD and AD bits are designed for use in communication between
281 /// security-aware resolvers and security-aware recursive name servers.
282 /// These bits are for the most part not relevant to query processing by
283 /// security-aware authoritative name servers.
284 ///
285 /// A security-aware name server does not perform signature validation
286 /// for authoritative data during query processing, even when the CD bit
287 /// is clear. A security-aware name server SHOULD clear the CD bit when
288 /// composing an authoritative response.
289 ///
290 /// A security-aware name server MUST NOT set the AD bit in a response
291 /// unless the name server considers all RRsets in the Answer and
292 /// Authority sections of the response to be authentic. A security-aware
293 /// name server's local policy MAY consider data from an authoritative
294 /// zone to be authentic without further validation. However, the name
295 /// server MUST NOT do so unless the name server obtained the
296 /// authoritative zone via secure means (such as a secure zone transfer
297 /// mechanism) and MUST NOT do so unless this behavior has been
298 /// configured explicitly.
299 ///
300 /// A security-aware name server that supports recursion MUST follow the
301 /// rules for the CD and AD bits given in Section 3.2 when generating a
302 /// response that involves data obtained via recursion.
303 /// ```
authentic_data(&self) -> bool304 pub fn authentic_data(&self) -> bool {
305 self.authentic_data
306 }
307
308 /// see `is_authentic_data()`
checking_disabled(&self) -> bool309 pub fn checking_disabled(&self) -> bool {
310 self.checking_disabled
311 }
312
313 /// ```text
314 /// RCODE Response code - this 4 bit field is set as part of
315 /// responses. The values have the following
316 /// interpretation: <see super::response_code>
317 /// ```
response_code(&self) -> u8318 pub fn response_code(&self) -> u8 {
319 self.response_code
320 }
321
322 /// ```text
323 /// QDCOUNT an unsigned 16 bit integer specifying the number of
324 /// entries in the question section.
325 /// ```
326 ///
327 /// # Return value
328 ///
329 /// If this is a query, this will return the number of queries in the query section of the
330 // message, fo updates this represents the zone count (must be no more than 1).
query_count(&self) -> u16331 pub fn query_count(&self) -> u16 {
332 self.query_count
333 }
334
335 /// ```text
336 /// ANCOUNT an unsigned 16 bit integer specifying the number of
337 /// resource records in the answer section.
338 /// ```
339 ///
340 /// # Return value
341 ///
342 /// For query responses this is the number of records in the answer section, should be 0 for
343 /// requests, for updates this is the count of prerequisite records.
answer_count(&self) -> u16344 pub fn answer_count(&self) -> u16 {
345 self.answer_count
346 }
347
348 /// for queries this is the nameservers which are authorities for the SOA of the Record
349 /// for updates this is the update record count
350 /// ```text
351 /// NSCOUNT an unsigned 16 bit integer specifying the number of name
352 /// server resource records in the authority records
353 /// section.
354 /// ```
355 ///
356 /// # Return value
357 ///
358 /// For query responses this is the number of authorities, or nameservers, in the name server
359 /// section, for updates this is the number of update records being sent.
name_server_count(&self) -> u16360 pub fn name_server_count(&self) -> u16 {
361 self.name_server_count
362 }
363
364 /// ```text
365 /// ARCOUNT an unsigned 16 bit integer specifying the number of
366 /// resource records in the additional records section.
367 /// ```
368 ///
369 /// # Return value
370 ///
371 /// This is the additional record section count, this section may include EDNS options.
additional_count(&self) -> u16372 pub fn additional_count(&self) -> u16 {
373 self.additional_count
374 }
375 }
376
377 impl BinEncodable for Header {
emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()>378 fn emit(&self, encoder: &mut BinEncoder<'_>) -> ProtoResult<()> {
379 encoder.reserve(12)?; // the 12 bytes for the following fields;
380
381 // Id
382 encoder.emit_u16(self.id)?;
383
384 // IsQuery, OpCode, Authoritative, Truncation, RecursionDesired
385 let mut q_opcd_a_t_r: u8 = if let MessageType::Response = self.message_type {
386 0x80
387 } else {
388 0x00
389 };
390 q_opcd_a_t_r |= u8::from(self.op_code) << 3;
391 q_opcd_a_t_r |= if self.authoritative { 0x4 } else { 0x0 };
392 q_opcd_a_t_r |= if self.truncation { 0x2 } else { 0x0 };
393 q_opcd_a_t_r |= if self.recursion_desired { 0x1 } else { 0x0 };
394 encoder.emit(q_opcd_a_t_r)?;
395
396 // IsRecursionAvailable, Triple 0's, ResponseCode
397 let mut r_z_ad_cd_rcod: u8 = if self.recursion_available {
398 0b1000_0000
399 } else {
400 0b0000_0000
401 };
402 r_z_ad_cd_rcod |= if self.authentic_data {
403 0b0010_0000
404 } else {
405 0b0000_0000
406 };
407 r_z_ad_cd_rcod |= if self.checking_disabled {
408 0b0001_0000
409 } else {
410 0b0000_0000
411 };
412 r_z_ad_cd_rcod |= self.response_code;
413 encoder.emit(r_z_ad_cd_rcod)?;
414
415 encoder.emit_u16(self.query_count)?;
416 encoder.emit_u16(self.answer_count)?;
417 encoder.emit_u16(self.name_server_count)?;
418 encoder.emit_u16(self.additional_count)?;
419
420 Ok(())
421 }
422 }
423
424 impl<'r> BinDecodable<'r> for Header {
read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self>425 fn read(decoder: &mut BinDecoder<'r>) -> ProtoResult<Self> {
426 let id = decoder.read_u16()?.unverified(/*it is valid for this to be any u16*/);
427
428 let q_opcd_a_t_r = decoder.pop()?.unverified(/*used as a bitfield, this is safe*/);
429 // if the first bit is set
430 let message_type = if (0b1000_0000 & q_opcd_a_t_r) == 0b1000_0000 {
431 MessageType::Response
432 } else {
433 MessageType::Query
434 };
435 // the 4bit opcode, masked and then shifted right 3bits for the u8...
436 let op_code: OpCode = OpCode::from_u8((0b0111_1000 & q_opcd_a_t_r) >> 3)?;
437 let authoritative = (0b0000_0100 & q_opcd_a_t_r) == 0b0000_0100;
438 let truncation = (0b0000_0010 & q_opcd_a_t_r) == 0b0000_0010;
439 let recursion_desired = (0b0000_0001 & q_opcd_a_t_r) == 0b0000_0001;
440
441 let r_z_ad_cd_rcod = decoder.pop()?.unverified(/*used as a bitfield, this is safe*/); // fail fast...
442
443 let recursion_available = (0b1000_0000 & r_z_ad_cd_rcod) == 0b1000_0000;
444 let authentic_data = (0b0010_0000 & r_z_ad_cd_rcod) == 0b0010_0000;
445 let checking_disabled = (0b0001_0000 & r_z_ad_cd_rcod) == 0b0001_0000;
446 let response_code: u8 = 0b0000_1111 & r_z_ad_cd_rcod;
447
448 // TODO: We should pass these restrictions on, they can't be trusted, but that would seriously complicate the Header type..
449 // TODO: perhaps the read methods for BinDecodable should return Restrict?
450 let query_count =
451 decoder.read_u16()?.unverified(/*this must be verified when reading queries*/);
452 let answer_count =
453 decoder.read_u16()?.unverified(/*this must be evaluated when reading records*/);
454 let name_server_count =
455 decoder.read_u16()?.unverified(/*this must be evaluated when reading records*/);
456 let additional_count =
457 decoder.read_u16()?.unverified(/*this must be evaluated when reading records*/);
458
459 // TODO: question, should this use the builder pattern instead? might be cleaner code, but
460 // this guarantees that the Header is fully instantiated with all values...
461 Ok(Header {
462 id,
463 message_type,
464 op_code,
465 authoritative,
466 truncation,
467 recursion_desired,
468 recursion_available,
469 authentic_data,
470 checking_disabled,
471 response_code,
472 query_count,
473 answer_count,
474 name_server_count,
475 additional_count,
476 })
477 }
478 }
479
480 #[test]
test_parse()481 fn test_parse() {
482 let byte_vec = vec![
483 0x01, 0x10, 0xAA, 0x83, // 0b1010 1010 1000 0011
484 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
485 ];
486
487 let mut decoder = BinDecoder::new(&byte_vec);
488
489 let expect = Header {
490 id: 0x0110,
491 message_type: MessageType::Response,
492 op_code: OpCode::Update,
493 authoritative: false,
494 truncation: true,
495 recursion_desired: false,
496 recursion_available: true,
497 authentic_data: false,
498 checking_disabled: false,
499 response_code: ResponseCode::NXDomain.low(),
500 query_count: 0x8877,
501 answer_count: 0x6655,
502 name_server_count: 0x4433,
503 additional_count: 0x2211,
504 };
505
506 let got = Header::read(&mut decoder).unwrap();
507
508 assert_eq!(got, expect);
509 }
510
511 #[test]
test_write()512 fn test_write() {
513 let header = Header {
514 id: 0x0110,
515 message_type: MessageType::Response,
516 op_code: OpCode::Update,
517 authoritative: false,
518 truncation: true,
519 recursion_desired: false,
520 recursion_available: true,
521 authentic_data: false,
522 checking_disabled: false,
523 response_code: ResponseCode::NXDomain.low(),
524 query_count: 0x8877,
525 answer_count: 0x6655,
526 name_server_count: 0x4433,
527 additional_count: 0x2211,
528 };
529
530 let expect: Vec<u8> = vec![
531 0x01, 0x10, 0xAA, 0x83, // 0b1010 1010 1000 0011
532 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
533 ];
534
535 let mut bytes = Vec::with_capacity(512);
536 {
537 let mut encoder = BinEncoder::new(&mut bytes);
538 header.emit(&mut encoder).unwrap();
539 }
540
541 assert_eq!(bytes, expect);
542 }
543