hickory_proto/rr/domain/usage.rs
1// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// https://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8//! Reserved zone names.
9//!
10//! see [Special-Use Domain Names](https://tools.ietf.org/html/rfc6761), RFC 6761 February, 2013
11
12use std::ops::Deref;
13
14use once_cell::sync::Lazy;
15
16use crate::rr::domain::Name;
17
18/// Default Name usage, everything is normal...
19pub static DEFAULT: Lazy<ZoneUsage> = Lazy::new(ZoneUsage::default);
20
21static ARPA: Lazy<Name> = Lazy::new(|| Name::from_ascii("arpa.").unwrap());
22/// zone for ipv4 reverse addresses
23pub static IN_ADDR_ARPA: Lazy<Name> = Lazy::new(|| {
24 Name::from_ascii("in-addr")
25 .unwrap()
26 .append_domain(&ARPA)
27 .unwrap()
28});
29/// zone for ipv6 reverse addresses
30pub static IP6_ARPA: Lazy<Name> = Lazy::new(|| {
31 Name::from_ascii("ip6")
32 .unwrap()
33 .append_domain(&ARPA)
34 .unwrap()
35});
36
37/// localhost.
38///
39/// [Special-Use Domain Names](https://tools.ietf.org/html/rfc6761), RFC 6761 February, 2013
40///
41/// ```text
42/// 6.3. Domain Name Reservation Considerations for "localhost."
43///
44/// The domain "localhost." and any names falling within ".localhost."
45/// are special in the following ways:
46/// ```
47///
48/// localhost. usage
49pub static LOCALHOST: Lazy<ZoneUsage> =
50 Lazy::new(|| ZoneUsage::localhost(Name::from_ascii("localhost.").unwrap()));
51
52/// 127.in-addr.arpa. usage; 127/8 is reserved for loopback
53pub static IN_ADDR_ARPA_127: Lazy<ZoneUsage> = Lazy::new(|| {
54 ZoneUsage::localhost(
55 Name::from_ascii("127")
56 .unwrap()
57 .append_domain(&IN_ADDR_ARPA)
58 .unwrap(),
59 )
60});
61
62/// 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. usage; 1/128 is the only address in ipv6 loopback
63pub static IP6_ARPA_1: Lazy<ZoneUsage> = Lazy::new(|| {
64 ZoneUsage::localhost(
65 Name::from_ascii("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0")
66 .unwrap()
67 .append_domain(&IP6_ARPA)
68 .unwrap(),
69 )
70});
71
72/// .local.
73///
74/// [Multicast DNS](https://tools.ietf.org/html/rfc6762), RFC 6762 February 2013
75///
76/// ```text
77/// This document specifies that the DNS top-level domain ".local." is a
78/// special domain with special semantics, namely that any fully
79/// qualified name ending in ".local." is link-local, and names within
80/// this domain are meaningful only on the link where they originate.
81/// This is analogous to IPv4 addresses in the 169.254/16 prefix or IPv6
82/// addresses in the FE80::/10 prefix, which are link-local and
83/// meaningful only on the link where they originate.
84/// ```
85///
86/// localhost. usage
87pub static LOCAL: Lazy<ZoneUsage> =
88 Lazy::new(|| ZoneUsage::local(Name::from_ascii("local.").unwrap()));
89
90// RFC 6762 Multicast DNS February 2013
91
92// Any DNS query for a name ending with "254.169.in-addr.arpa." MUST
93// be sent to the mDNS IPv4 link-local multicast address 224.0.0.251
94// or the mDNS IPv6 multicast address FF02::FB. Since names under
95// this domain correspond to IPv4 link-local addresses, it is logical
96// that the local link is the best place to find information
97// pertaining to those names.
98//
99// Likewise, any DNS query for a name within the reverse mapping
100// domains for IPv6 link-local addresses ("8.e.f.ip6.arpa.",
101// "9.e.f.ip6.arpa.", "a.e.f.ip6.arpa.", and "b.e.f.ip6.arpa.") MUST
102// be sent to the mDNS IPv6 link-local multicast address FF02::FB or
103// the mDNS IPv4 link-local multicast address 224.0.0.251.
104
105/// 254.169.in-addr.arpa. usage link-local, i.e. mDNS
106pub static IN_ADDR_ARPA_169_254: Lazy<ZoneUsage> = Lazy::new(|| {
107 ZoneUsage::local(
108 Name::from_ascii("254.169")
109 .unwrap()
110 .append_domain(&IN_ADDR_ARPA)
111 .unwrap(),
112 )
113});
114
115/// 254.169.in-addr.arpa. usage link-local, i.e. mDNS
116pub static IP6_ARPA_FE_8: Lazy<ZoneUsage> = Lazy::new(|| {
117 ZoneUsage::local(
118 Name::from_ascii("8.e.f")
119 .unwrap()
120 .append_domain(&IP6_ARPA)
121 .unwrap(),
122 )
123});
124/// 254.169.in-addr.arpa. usage link-local, i.e. mDNS
125pub static IP6_ARPA_FE_9: Lazy<ZoneUsage> = Lazy::new(|| {
126 ZoneUsage::local(
127 Name::from_ascii("9.e.f")
128 .unwrap()
129 .append_domain(&IP6_ARPA)
130 .unwrap(),
131 )
132});
133/// 254.169.in-addr.arpa. usage link-local, i.e. mDNS
134pub static IP6_ARPA_FE_B: Lazy<ZoneUsage> = Lazy::new(|| {
135 ZoneUsage::local(
136 Name::from_ascii("b.e.f")
137 .unwrap()
138 .append_domain(&IP6_ARPA)
139 .unwrap(),
140 )
141});
142
143/// invalid.
144///
145/// [Special-Use Domain Names](https://tools.ietf.org/html/rfc6761), RFC 6761 February, 2013
146///
147/// ```text
148/// 6.4. Domain Name Reservation Considerations for "invalid."
149///
150/// The domain "invalid." and any names falling within ".invalid." are
151/// special in the ways listed below. In the text below, the term
152/// "invalid" is used in quotes to signify such names, as opposed to
153/// names that may be invalid for other reasons (e.g., being too long).
154/// ```
155///
156/// invalid. name usage
157pub static INVALID: Lazy<ZoneUsage> =
158 Lazy::new(|| ZoneUsage::invalid(Name::from_ascii("invalid.").unwrap()));
159
160/// onion.
161///
162/// [The ".onion" Special-Use Domain Name](https://tools.ietf.org/html/rfc7686), RFC 7686 October, 2015
163///
164/// ```text
165/// 1. Introduction
166///
167/// The Tor network has the ability to host network
168/// services using the ".onion" Special-Use Top-Level Domain Name. Such
169/// names can be used as other domain names would be (e.g., in URLs
170/// [RFC3986]), but instead of using the DNS infrastructure, .onion names
171/// functionally correspond to the identity of a given service, thereby
172/// combining location and authentication.
173/// ```
174///
175/// onion. name usage
176pub static ONION: Lazy<ZoneUsage> = Lazy::new(|| ZoneUsage {
177 user: UserUsage::Normal, // the domain is special, but this is what seems to match the most
178 app: AppUsage::Normal, // the domain is special, but this is what seems to match the most
179 ..ZoneUsage::invalid(Name::from_ascii("onion.").unwrap())
180});
181
182/// Users:
183///
184/// Are human users expected to recognize these names as special and
185/// use them differently? In what way?
186#[derive(Clone, Copy, PartialEq, Eq)]
187pub enum UserUsage {
188 /// Users are free to use these names as they would any other
189 /// reverse-mapping names. However, since there is no central
190 /// authority responsible for use of private addresses, users SHOULD
191 /// be aware that these names are likely to yield different results
192 /// on different networks.
193 Normal,
194
195 /// Users are free to use localhost names as they would any other
196 /// domain names. Users may assume that IPv4 and IPv6 address
197 /// queries for localhost names will always resolve to the respective
198 /// IP loopback address.
199 Loopback,
200
201 /// Multi-cast link-local usage
202 LinkLocal,
203
204 /// Users are free to use "invalid" names as they would any other
205 /// domain names. Users MAY assume that queries for "invalid" names
206 /// will always return NXDOMAIN responses.
207 NxDomain,
208}
209
210/// Application Software:
211///
212/// Are writers of application software expected to make their
213/// software recognize these names as special and treat them
214/// differently? In what way? (For example, if a human user enters
215/// such a name, should the application software reject it with an
216/// error message?)
217#[derive(Clone, Copy, PartialEq, Eq)]
218pub enum AppUsage {
219 /// Application software SHOULD NOT recognize these names as special,
220 /// and SHOULD use these names as they would other reverse-mapping
221 /// names.
222 ///
223 /// Application software SHOULD NOT recognize test names as special,
224 /// and SHOULD use test names as they would other domain names.
225 ///
226 /// Application software SHOULD NOT recognize example names as
227 /// special and SHOULD use example names as they would other domain
228 /// names.
229 Normal,
230
231 /// Application software MAY recognize localhost names as special, or
232 /// MAY pass them to name resolution APIs as they would for other
233 /// domain names.
234 Loopback,
235
236 /// Link local, generally for mDNS
237 LinkLocal,
238
239 /// Application software MAY recognize "invalid" names as special or
240 /// MAY pass them to name resolution APIs as they would for other
241 /// domain names.
242 NxDomain,
243}
244
245/// Name Resolution APIs and Libraries:
246///
247/// Are writers of name resolution APIs and libraries expected to
248/// make their software recognize these names as special and treat
249/// them differently? If so, how?
250#[derive(Clone, Copy, PartialEq, Eq)]
251pub enum ResolverUsage {
252 /// Name resolution APIs and libraries SHOULD NOT recognize these
253 /// names as special and SHOULD NOT treat them differently. Name
254 /// resolution APIs SHOULD send queries for these names to their
255 /// configured caching DNS server(s).
256 ///
257 /// Name resolution APIs and libraries SHOULD NOT recognize test
258 /// names as special and SHOULD NOT treat them differently. Name
259 /// resolution APIs SHOULD send queries for test names to their
260 /// configured caching DNS server(s).
261 ///
262 /// Name resolution APIs and libraries SHOULD NOT recognize example
263 /// names as special and SHOULD NOT treat them differently. Name
264 /// resolution APIs SHOULD send queries for example names to their
265 /// configured caching DNS server(s).
266 Normal,
267
268 /// Name resolution APIs and libraries SHOULD recognize localhost
269 /// names as special and SHOULD always return the IP loopback address
270 /// for address queries and negative responses for all other query
271 /// types. Name resolution APIs SHOULD NOT send queries for
272 /// localhost names to their configured caching DNS server(s).
273 Loopback,
274
275 /// Link local, generally for mDNS
276 ///
277 /// Any DNS query for a name ending with ".local." MUST be sent to the
278 /// mDNS IPv4 link-local multicast address 224.0.0.251 (or its IPv6
279 /// equivalent FF02::FB). The design rationale for using a fixed
280 /// multicast address instead of selecting from a range of multicast
281 /// addresses using a hash function is discussed in Appendix B.
282 /// Implementers MAY choose to look up such names concurrently via other
283 /// mechanisms (e.g., Unicast DNS) and coalesce the results in some
284 /// fashion. Implementers choosing to do this should be aware of the
285 /// potential for user confusion when a given name can produce different
286 /// results depending on external network conditions (such as, but not
287 /// limited to, which name lookup mechanism responds faster).
288 LinkLocal,
289
290 /// Name resolution APIs and libraries SHOULD recognize "invalid"
291 /// names as special and SHOULD always return immediate negative
292 /// responses. Name resolution APIs SHOULD NOT send queries for
293 /// "invalid" names to their configured caching DNS server(s).
294 NxDomain,
295}
296
297/// Caching DNS Servers:
298///
299/// Are developers of caching domain name servers expected to make
300/// their implementations recognize these names as special and treat
301/// them differently? If so, how?
302#[derive(Clone, Copy, PartialEq, Eq)]
303pub enum CacheUsage {
304 /// Caching DNS servers SHOULD recognize these names as special and
305 /// SHOULD NOT, by default, attempt to look up NS records for them,
306 /// or otherwise query authoritative DNS servers in an attempt to
307 /// resolve these names. Instead, caching DNS servers SHOULD, by
308 /// default, generate immediate (positive or negative) responses for
309 /// all such queries. This is to avoid unnecessary load on the root
310 /// name servers and other name servers. Caching DNS servers SHOULD
311 /// offer a configuration option (disabled by default) to enable
312 /// upstream resolution of such names, for use in private networks
313 /// where private-address reverse-mapping names are known to be
314 /// handled by an authoritative DNS server in said private network.
315 NonRecursive,
316
317 /// Caching DNS servers SHOULD recognize "invalid" names as special
318 /// and SHOULD NOT attempt to look up NS records for them, or
319 /// otherwise query authoritative DNS servers in an attempt to
320 /// resolve "invalid" names. Instead, caching DNS servers SHOULD
321 /// generate immediate NXDOMAIN responses for all such queries. This
322 /// is to avoid unnecessary load on the root name servers and other
323 /// name servers.
324 NxDomain,
325
326 /// Caching DNS servers SHOULD recognize localhost names as special
327 /// and SHOULD NOT attempt to look up NS records for them, or
328 /// otherwise query authoritative DNS servers in an attempt to
329 /// resolve localhost names. Instead, caching DNS servers SHOULD,
330 /// for all such address queries, generate an immediate positive
331 /// response giving the IP loopback address, and for all other query
332 /// types, generate an immediate negative response. This is to avoid
333 /// unnecessary load on the root name servers and other name servers.
334 Loopback,
335
336 /// Caching DNS servers SHOULD NOT recognize example names as special
337 /// and SHOULD resolve them normally.
338 Normal,
339}
340
341/// Authoritative DNS Servers:
342///
343/// Are developers of authoritative domain name servers expected to
344/// make their implementations recognize these names as special and
345/// treat them differently? If so, how?
346#[derive(Clone, Copy, PartialEq, Eq)]
347pub enum AuthUsage {
348 /// Authoritative DNS servers SHOULD recognize these names as special
349 /// and SHOULD, by default, generate immediate negative responses for
350 /// all such queries, unless explicitly configured by the
351 /// administrator to give positive answers for private-address
352 /// reverse-mapping names.
353 Local,
354
355 /// Authoritative DNS servers SHOULD recognize these names as special
356 /// and SHOULD, by default, generate immediate negative responses for
357 /// all such queries, unless explicitly configured by the
358 /// administrator to give positive answers for private-address
359 /// reverse-mapping names.
360 NxDomain,
361
362 /// Authoritative DNS servers SHOULD recognize localhost names as
363 /// special and handle them as described above for caching DNS
364 /// servers.
365 Loopback,
366
367 /// Authoritative DNS servers SHOULD NOT recognize example names as
368 /// special.
369 Normal,
370}
371
372/// DNS Server Operators:
373///
374/// Does this reserved Special-Use Domain Name have any potential
375/// impact on DNS server operators? If they try to configure their
376/// authoritative DNS server as authoritative for this reserved name,
377/// will compliant name server software reject it as invalid? Do DNS
378/// server operators need to know about that and understand why?
379/// Even if the name server software doesn't prevent them from using
380/// this reserved name, are there other ways that it may not work as
381/// expected, of which the DNS server operator should be aware?
382#[derive(Clone, Copy, PartialEq, Eq)]
383pub enum OpUsage {
384 /// DNS server operators SHOULD, if they are using private addresses,
385 /// configure their authoritative DNS servers to act as authoritative
386 /// for these names.
387 ///
388 /// DNS server operators SHOULD, if they are using test names,
389 /// configure their authoritative DNS servers to act as authoritative
390 /// for test names.
391 Normal,
392
393 /// DNS server operators SHOULD be aware that the effective RDATA for
394 /// localhost names is defined by protocol specification and cannot
395 /// be modified by local configuration.
396 Loopback,
397
398 /// DNS server operators SHOULD be aware that the effective RDATA for
399 /// "invalid" names is defined by protocol specification to be
400 /// nonexistent and cannot be modified by local configuration.
401 NxDomain,
402}
403
404/// DNS Registries/Registrars:
405///
406/// How should DNS Registries/Registrars treat requests to register
407/// this reserved domain name? Should such requests be denied?
408/// Should such requests be allowed, but only to a specially-
409/// designated entity? (For example, the name "www.example.org" is
410/// reserved for documentation examples and is not available for
411/// registration; however, the name is in fact registered; and there
412/// is even a web site at that name, which states circularly that the
413/// name is reserved for use in documentation and cannot be
414/// registered!)
415#[derive(Clone, Copy, PartialEq, Eq)]
416pub enum RegistryUsage {
417 /// Stanard checks apply
418 Normal,
419
420 /// DNS Registries/Registrars MUST NOT grant requests to register
421 /// test names in the normal way to any person or entity. Test names
422 /// are reserved for use in private networks and fall outside the set
423 /// of names available for allocation by registries/registrars.
424 /// Attempting to allocate a test name as if it were a normal DNS
425 /// domain name will probably not work as desired, for reasons 4, 5,
426 /// and 6 above.
427 ///
428 /// DNS Registries/Registrars MUST NOT grant requests to register
429 /// localhost names in the normal way to any person or entity.
430 /// Localhost names are defined by protocol specification and fall
431 /// outside the set of names available for allocation by registries/
432 /// registrars. Attempting to allocate a localhost name as if it
433 /// were a normal DNS domain name will probably not work as desired,
434 /// for reasons 2, 3, 4, and 5 above.
435 ///
436 /// DNS Registries/Registrars MUST NOT grant requests to register
437 /// "invalid" names in the normal way to any person or entity. These
438 /// "invalid" names are defined by protocol specification to be
439 /// nonexistent, and they fall outside the set of names available for
440 /// allocation by registries/registrars. Attempting to allocate a
441 /// "invalid" name as if it were a normal DNS domain name will
442 /// probably not work as desired, for reasons 2, 3, 4, and 5 above.
443 ///
444 /// DNS Registries/Registrars MUST NOT grant requests to register
445 /// example names in the normal way to any person or entity. All
446 /// example names are registered in perpetuity to IANA:
447 Reserved,
448}
449
450/// ZoneUsage represents information about how a name falling in a given zone should be treated
451pub struct ZoneUsage {
452 name: Name,
453 user: UserUsage,
454 app: AppUsage,
455 resolver: ResolverUsage,
456 cache: CacheUsage,
457 auth: AuthUsage,
458 op: OpUsage,
459 registry: RegistryUsage,
460}
461
462impl ZoneUsage {
463 /// Constructs a new ZoneUsage with the associated values
464 #[allow(clippy::too_many_arguments)]
465 pub fn new(
466 name: Name,
467 user: UserUsage,
468 app: AppUsage,
469 resolver: ResolverUsage,
470 cache: CacheUsage,
471 auth: AuthUsage,
472 op: OpUsage,
473 registry: RegistryUsage,
474 ) -> Self {
475 Self {
476 name,
477 user,
478 app,
479 resolver,
480 cache,
481 auth,
482 op,
483 registry,
484 }
485 }
486
487 /// Restrictions for reverse zones
488 pub fn reverse(name: Name) -> Self {
489 Self::new(
490 name,
491 UserUsage::Normal,
492 AppUsage::Normal,
493 ResolverUsage::Normal,
494 CacheUsage::NonRecursive,
495 AuthUsage::Local,
496 OpUsage::Normal,
497 RegistryUsage::Reserved,
498 )
499 }
500
501 /// Restrictions for the .test. zone
502 pub fn test(name: Name) -> Self {
503 Self::new(
504 name,
505 UserUsage::Normal,
506 AppUsage::Normal,
507 ResolverUsage::Normal,
508 CacheUsage::NonRecursive,
509 AuthUsage::Local,
510 OpUsage::Normal,
511 RegistryUsage::Reserved,
512 )
513 }
514
515 /// Restrictions for the .localhost. zone
516 pub fn localhost(name: Name) -> Self {
517 Self::new(
518 name,
519 UserUsage::Loopback,
520 AppUsage::Loopback,
521 ResolverUsage::Loopback,
522 CacheUsage::Loopback,
523 AuthUsage::Loopback,
524 OpUsage::Loopback,
525 RegistryUsage::Reserved,
526 )
527 }
528
529 /// Restrictions for the .local. zone
530 pub fn local(name: Name) -> Self {
531 Self::new(
532 name,
533 UserUsage::LinkLocal,
534 AppUsage::LinkLocal,
535 ResolverUsage::LinkLocal,
536 CacheUsage::Normal,
537 AuthUsage::Local,
538 OpUsage::Normal,
539 RegistryUsage::Reserved,
540 )
541 }
542
543 /// Restrictions for the .invalid. zone
544 pub fn invalid(name: Name) -> Self {
545 Self::new(
546 name,
547 UserUsage::NxDomain,
548 AppUsage::NxDomain,
549 ResolverUsage::NxDomain,
550 CacheUsage::NxDomain,
551 AuthUsage::NxDomain,
552 OpUsage::NxDomain,
553 RegistryUsage::Reserved,
554 )
555 }
556
557 /// Restrictions for the .example. zone
558 pub fn example(name: Name) -> Self {
559 Self::new(
560 name,
561 UserUsage::Normal,
562 AppUsage::Normal,
563 ResolverUsage::Normal,
564 CacheUsage::Normal,
565 AuthUsage::Normal,
566 OpUsage::Normal,
567 RegistryUsage::Reserved,
568 )
569 }
570
571 /// A reference to this zone name
572 pub fn name(&self) -> &Name {
573 &self.name
574 }
575
576 /// Returns the UserUsage of this zone
577 pub fn user(&self) -> UserUsage {
578 self.user
579 }
580
581 /// Returns the AppUsage of this zone
582 pub fn app(&self) -> AppUsage {
583 self.app
584 }
585
586 /// Returns the ResolverUsage of this zone
587 pub fn resolver(&self) -> ResolverUsage {
588 self.resolver
589 }
590
591 /// Returns the CacheUsage of this zone
592 pub fn cache(&self) -> CacheUsage {
593 self.cache
594 }
595
596 /// Returns the AuthUsage of this zone
597 pub fn auth(&self) -> AuthUsage {
598 self.auth
599 }
600
601 /// Returns the OpUsage of this zone
602 pub fn op(&self) -> OpUsage {
603 self.op
604 }
605
606 /// Returns the RegistryUsage of this zone
607 pub fn registry(&self) -> RegistryUsage {
608 self.registry
609 }
610}
611
612/// Constructs a new Default, with all no restrictions
613impl Default for ZoneUsage {
614 fn default() -> Self {
615 Self::new(
616 Name::root(),
617 UserUsage::Normal,
618 AppUsage::Normal,
619 ResolverUsage::Normal,
620 CacheUsage::Normal,
621 AuthUsage::Normal,
622 OpUsage::Normal,
623 RegistryUsage::Normal,
624 )
625 }
626}
627
628impl Deref for ZoneUsage {
629 type Target = Name;
630
631 fn deref(&self) -> &Self::Target {
632 &self.name
633 }
634}