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}