blob: 8a2e2948d6e8fa0c83e3a8fabfadb2598e1e1bdc [file] [log] [blame]
// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
//! Reserved zone names.
//!
//! see [Special-Use Domain Names](https://tools.ietf.org/html/rfc6761), RFC 6761 February, 2013
use std::ops::Deref;
use lazy_static::lazy_static;
use crate::rr::domain::Name;
lazy_static! {
/// Default Name usage, everything is normal...
pub static ref DEFAULT: ZoneUsage = ZoneUsage::default();
}
lazy_static! {
static ref ARPA: Name = Name::from_ascii("arpa.").unwrap();
/// zone for ipv4 reverse addresses
pub static ref IN_ADDR_ARPA: Name = Name::from_ascii("in-addr").unwrap().append_domain(&*ARPA);
/// zone for ipv6 reverse addresses
pub static ref IP6_ARPA: Name = Name::from_ascii("ip6").unwrap().append_domain(&*ARPA);
}
lazy_static! {
/// localhost.
///
/// [Special-Use Domain Names](https://tools.ietf.org/html/rfc6761), RFC 6761 February, 2013
///
/// ```text
/// 6.3. Domain Name Reservation Considerations for "localhost."
///
/// The domain "localhost." and any names falling within ".localhost."
/// are special in the following ways:
/// ```
/// localhost. usage
pub static ref LOCALHOST: ZoneUsage = ZoneUsage::localhost(Name::from_ascii("localhost.").unwrap());
/// 127.in-addr.arpa. usage; 127/8 is reserved for loopback
pub static ref IN_ADDR_ARPA_127: ZoneUsage = ZoneUsage::localhost(Name::from_ascii("127").unwrap().append_domain(&*IN_ADDR_ARPA));
/// 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
pub static ref IP6_ARPA_1: ZoneUsage = ZoneUsage::localhost(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").unwrap().append_domain(&*IP6_ARPA));
}
lazy_static! {
/// .local.
///
/// [Multicast DNS](https://tools.ietf.org/html/rfc6762), RFC 6762 February 2013
///
/// ```text
/// This document specifies that the DNS top-level domain ".local." is a
/// special domain with special semantics, namely that any fully
/// qualified name ending in ".local." is link-local, and names within
/// this domain are meaningful only on the link where they originate.
/// This is analogous to IPv4 addresses in the 169.254/16 prefix or IPv6
/// addresses in the FE80::/10 prefix, which are link-local and
/// meaningful only on the link where they originate.
/// ```
/// localhost. usage
pub static ref LOCAL: ZoneUsage = ZoneUsage::local(Name::from_ascii("local.").unwrap());
// RFC 6762 Multicast DNS February 2013
// Any DNS query for a name ending with "254.169.in-addr.arpa." MUST
// be sent to the mDNS IPv4 link-local multicast address 224.0.0.251
// or the mDNS IPv6 multicast address FF02::FB. Since names under
// this domain correspond to IPv4 link-local addresses, it is logical
// that the local link is the best place to find information
// pertaining to those names.
//
// Likewise, any DNS query for a name within the reverse mapping
// domains for IPv6 link-local addresses ("8.e.f.ip6.arpa.",
// "9.e.f.ip6.arpa.", "a.e.f.ip6.arpa.", and "b.e.f.ip6.arpa.") MUST
// be sent to the mDNS IPv6 link-local multicast address FF02::FB or
// the mDNS IPv4 link-local multicast address 224.0.0.251.
/// 254.169.in-addr.arpa. usage link-local, i.e. mDNS
pub static ref IN_ADDR_ARPA_169_254: ZoneUsage = ZoneUsage::local(Name::from_ascii("254.169").unwrap().append_domain(&*IN_ADDR_ARPA));
/// 254.169.in-addr.arpa. usage link-local, i.e. mDNS
pub static ref IP6_ARPA_FE_8: ZoneUsage = ZoneUsage::local(Name::from_ascii("8.e.f").unwrap().append_domain(&*IP6_ARPA));
/// 254.169.in-addr.arpa. usage link-local, i.e. mDNS
pub static ref IP6_ARPA_FE_9: ZoneUsage = ZoneUsage::local(Name::from_ascii("9.e.f").unwrap().append_domain(&*IP6_ARPA));
/// 254.169.in-addr.arpa. usage link-local, i.e. mDNS
pub static ref IP6_ARPA_FE_B: ZoneUsage = ZoneUsage::local(Name::from_ascii("b.e.f").unwrap().append_domain(&*IP6_ARPA));
}
lazy_static! {
/// invalid.
///
/// [Special-Use Domain Names](https://tools.ietf.org/html/rfc6761), RFC 6761 February, 2013
///
/// ```text
/// 6.4. Domain Name Reservation Considerations for "invalid."
///
/// The domain "invalid." and any names falling within ".invalid." are
/// special in the ways listed below. In the text below, the term
/// "invalid" is used in quotes to signify such names, as opposed to
/// names that may be invalid for other reasons (e.g., being too long).
/// ```
/// invalid. name usage
pub static ref INVALID: ZoneUsage = ZoneUsage::invalid(Name::from_ascii("invalid.").unwrap());
}
/// Users:
///
/// Are human users expected to recognize these names as special and
/// use them differently? In what way?
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum UserUsage {
/// Users are free to use these names as they would any other
/// reverse-mapping names. However, since there is no central
/// authority responsible for use of private addresses, users SHOULD
/// be aware that these names are likely to yield different results
/// on different networks.
Normal,
/// Users are free to use localhost names as they would any other
/// domain names. Users may assume that IPv4 and IPv6 address
/// queries for localhost names will always resolve to the respective
/// IP loopback address.
Loopback,
/// Multi-cast link-local usage
LinkLocal,
/// Users are free to use "invalid" names as they would any other
/// domain names. Users MAY assume that queries for "invalid" names
/// will always return NXDOMAIN responses.
NxDomain,
}
/// Application Software:
///
/// Are writers of application software expected to make their
/// software recognize these names as special and treat them
/// differently? In what way? (For example, if a human user enters
/// such a name, should the application software reject it with an
/// error message?)
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum AppUsage {
/// Application software SHOULD NOT recognize these names as special,
/// and SHOULD use these names as they would other reverse-mapping
/// names.
///
/// Application software SHOULD NOT recognize test names as special,
/// and SHOULD use test names as they would other domain names.
///
/// Application software SHOULD NOT recognize example names as
/// special and SHOULD use example names as they would other domain
/// names.
Normal,
/// Application software MAY recognize localhost names as special, or
/// MAY pass them to name resolution APIs as they would for other
/// domain names.
Loopback,
/// Link local, generally for mDNS
LinkLocal,
/// Application software MAY recognize "invalid" names as special or
/// MAY pass them to name resolution APIs as they would for other
/// domain names.
NxDomain,
}
/// Name Resolution APIs and Libraries:
///
/// Are writers of name resolution APIs and libraries expected to
/// make their software recognize these names as special and treat
/// them differently? If so, how?
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum ResolverUsage {
/// Name resolution APIs and libraries SHOULD NOT recognize these
/// names as special and SHOULD NOT treat them differently. Name
/// resolution APIs SHOULD send queries for these names to their
/// configured caching DNS server(s).
///
/// Name resolution APIs and libraries SHOULD NOT recognize test
/// names as special and SHOULD NOT treat them differently. Name
/// resolution APIs SHOULD send queries for test names to their
/// configured caching DNS server(s).
///
/// Name resolution APIs and libraries SHOULD NOT recognize example
/// names as special and SHOULD NOT treat them differently. Name
/// resolution APIs SHOULD send queries for example names to their
/// configured caching DNS server(s).
Normal,
/// Name resolution APIs and libraries SHOULD recognize localhost
/// names as special and SHOULD always return the IP loopback address
/// for address queries and negative responses for all other query
/// types. Name resolution APIs SHOULD NOT send queries for
/// localhost names to their configured caching DNS server(s).
Loopback,
/// Link local, generally for mDNS
///
/// Any DNS query for a name ending with ".local." MUST be sent to the
/// mDNS IPv4 link-local multicast address 224.0.0.251 (or its IPv6
/// equivalent FF02::FB). The design rationale for using a fixed
/// multicast address instead of selecting from a range of multicast
/// addresses using a hash function is discussed in Appendix B.
/// Implementers MAY choose to look up such names concurrently via other
/// mechanisms (e.g., Unicast DNS) and coalesce the results in some
/// fashion. Implementers choosing to do this should be aware of the
/// potential for user confusion when a given name can produce different
/// results depending on external network conditions (such as, but not
/// limited to, which name lookup mechanism responds faster).
LinkLocal,
/// Name resolution APIs and libraries SHOULD recognize "invalid"
/// names as special and SHOULD always return immediate negative
/// responses. Name resolution APIs SHOULD NOT send queries for
/// "invalid" names to their configured caching DNS server(s).
NxDomain,
}
/// Caching DNS Servers:
///
/// Are developers of caching domain name servers expected to make
/// their implementations recognize these names as special and treat
/// them differently? If so, how?
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum CacheUsage {
/// Caching DNS servers SHOULD recognize these names as special and
/// SHOULD NOT, by default, attempt to look up NS records for them,
/// or otherwise query authoritative DNS servers in an attempt to
/// resolve these names. Instead, caching DNS servers SHOULD, by
/// default, generate immediate (positive or negative) responses for
/// all such queries. This is to avoid unnecessary load on the root
/// name servers and other name servers. Caching DNS servers SHOULD
/// offer a configuration option (disabled by default) to enable
/// upstream resolution of such names, for use in private networks
/// where private-address reverse-mapping names are known to be
/// handled by an authoritative DNS server in said private network.
NonRecursive,
/// Caching DNS servers SHOULD recognize "invalid" names as special
/// and SHOULD NOT attempt to look up NS records for them, or
/// otherwise query authoritative DNS servers in an attempt to
/// resolve "invalid" names. Instead, caching DNS servers SHOULD
/// generate immediate NXDOMAIN responses for all such queries. This
/// is to avoid unnecessary load on the root name servers and other
/// name servers.
NxDomain,
/// Caching DNS servers SHOULD recognize localhost names as special
/// and SHOULD NOT attempt to look up NS records for them, or
/// otherwise query authoritative DNS servers in an attempt to
/// resolve localhost names. Instead, caching DNS servers SHOULD,
/// for all such address queries, generate an immediate positive
/// response giving the IP loopback address, and for all other query
/// types, generate an immediate negative response. This is to avoid
/// unnecessary load on the root name servers and other name servers.
Loopback,
/// Caching DNS servers SHOULD NOT recognize example names as special
/// and SHOULD resolve them normally.
Normal,
}
/// Authoritative DNS Servers:
///
/// Are developers of authoritative domain name servers expected to
/// make their implementations recognize these names as special and
/// treat them differently? If so, how?
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum AuthUsage {
/// Authoritative DNS servers SHOULD recognize these names as special
/// and SHOULD, by default, generate immediate negative responses for
/// all such queries, unless explicitly configured by the
/// administrator to give positive answers for private-address
/// reverse-mapping names.
Local,
/// Authoritative DNS servers SHOULD recognize these names as special
/// and SHOULD, by default, generate immediate negative responses for
/// all such queries, unless explicitly configured by the
/// administrator to give positive answers for private-address
/// reverse-mapping names.
NxDomain,
/// Authoritative DNS servers SHOULD recognize localhost names as
/// special and handle them as described above for caching DNS
/// servers.
Loopback,
/// Authoritative DNS servers SHOULD NOT recognize example names as
/// special.
Normal,
}
/// DNS Server Operators:
///
/// Does this reserved Special-Use Domain Name have any potential
/// impact on DNS server operators? If they try to configure their
/// authoritative DNS server as authoritative for this reserved name,
/// will compliant name server software reject it as invalid? Do DNS
/// server operators need to know about that and understand why?
/// Even if the name server software doesn't prevent them from using
/// this reserved name, are there other ways that it may not work as
/// expected, of which the DNS server operator should be aware?
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum OpUsage {
/// DNS server operators SHOULD, if they are using private addresses,
/// configure their authoritative DNS servers to act as authoritative
/// for these names.
///
/// DNS server operators SHOULD, if they are using test names,
/// configure their authoritative DNS servers to act as authoritative
/// for test names.
Normal,
/// DNS server operators SHOULD be aware that the effective RDATA for
/// localhost names is defined by protocol specification and cannot
/// be modified by local configuration.
Loopback,
/// DNS server operators SHOULD be aware that the effective RDATA for
/// "invalid" names is defined by protocol specification to be
/// nonexistent and cannot be modified by local configuration.
NxDomain,
}
/// DNS Registries/Registrars:
///
/// How should DNS Registries/Registrars treat requests to register
/// this reserved domain name? Should such requests be denied?
/// Should such requests be allowed, but only to a specially-
/// designated entity? (For example, the name "www.example.org" is
/// reserved for documentation examples and is not available for
/// registration; however, the name is in fact registered; and there
/// is even a web site at that name, which states circularly that the
/// name is reserved for use in documentation and cannot be
/// registered!)
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum RegistryUsage {
/// Stanard checks apply
Normal,
/// DNS Registries/Registrars MUST NOT grant requests to register
/// test names in the normal way to any person or entity. Test names
/// are reserved for use in private networks and fall outside the set
/// of names available for allocation by registries/registrars.
/// Attempting to allocate a test name as if it were a normal DNS
/// domain name will probably not work as desired, for reasons 4, 5,
/// and 6 above.
///
/// DNS Registries/Registrars MUST NOT grant requests to register
/// localhost names in the normal way to any person or entity.
/// Localhost names are defined by protocol specification and fall
/// outside the set of names available for allocation by registries/
/// registrars. Attempting to allocate a localhost name as if it
/// were a normal DNS domain name will probably not work as desired,
/// for reasons 2, 3, 4, and 5 above.
///
/// DNS Registries/Registrars MUST NOT grant requests to register
/// "invalid" names in the normal way to any person or entity. These
/// "invalid" names are defined by protocol specification to be
/// nonexistent, and they fall outside the set of names available for
/// allocation by registries/registrars. Attempting to allocate a
/// "invalid" name as if it were a normal DNS domain name will
/// probably not work as desired, for reasons 2, 3, 4, and 5 above.
///
/// DNS Registries/Registrars MUST NOT grant requests to register
/// example names in the normal way to any person or entity. All
/// example names are registered in perpetuity to IANA:
Reserved,
}
/// ZoneUsage represents information about how a name falling in a given zone should be treated
pub struct ZoneUsage {
name: Name,
user: UserUsage,
app: AppUsage,
resolver: ResolverUsage,
cache: CacheUsage,
auth: AuthUsage,
op: OpUsage,
registry: RegistryUsage,
}
impl ZoneUsage {
/// Constructs a new ZoneUsage with the associated values
#[allow(clippy::too_many_arguments)]
pub fn new(
name: Name,
user: UserUsage,
app: AppUsage,
resolver: ResolverUsage,
cache: CacheUsage,
auth: AuthUsage,
op: OpUsage,
registry: RegistryUsage,
) -> Self {
ZoneUsage {
name,
user,
app,
resolver,
cache,
auth,
op,
registry,
}
}
/// Constructs a new Default, with all no restrictions
pub fn default() -> Self {
Self::new(
Name::root(),
UserUsage::Normal,
AppUsage::Normal,
ResolverUsage::Normal,
CacheUsage::Normal,
AuthUsage::Normal,
OpUsage::Normal,
RegistryUsage::Normal,
)
}
/// Restrictions for reverse zones
pub fn reverse(name: Name) -> Self {
Self::new(
name,
UserUsage::Normal,
AppUsage::Normal,
ResolverUsage::Normal,
CacheUsage::NonRecursive,
AuthUsage::Local,
OpUsage::Normal,
RegistryUsage::Reserved,
)
}
/// Restrictions for the .test. zone
pub fn test(name: Name) -> Self {
Self::new(
name,
UserUsage::Normal,
AppUsage::Normal,
ResolverUsage::Normal,
CacheUsage::NonRecursive,
AuthUsage::Local,
OpUsage::Normal,
RegistryUsage::Reserved,
)
}
/// Restrictions for the .localhost. zone
pub fn localhost(name: Name) -> Self {
Self::new(
name,
UserUsage::Loopback,
AppUsage::Loopback,
ResolverUsage::Loopback,
CacheUsage::Loopback,
AuthUsage::Loopback,
OpUsage::Loopback,
RegistryUsage::Reserved,
)
}
/// Restrictions for the .local. zone
pub fn local(name: Name) -> Self {
Self::new(
name,
UserUsage::LinkLocal,
AppUsage::LinkLocal,
ResolverUsage::LinkLocal,
CacheUsage::Normal,
AuthUsage::Local,
OpUsage::Normal,
RegistryUsage::Reserved,
)
}
/// Restrictions for the .invalid. zone
pub fn invalid(name: Name) -> Self {
Self::new(
name,
UserUsage::NxDomain,
AppUsage::NxDomain,
ResolverUsage::NxDomain,
CacheUsage::NxDomain,
AuthUsage::NxDomain,
OpUsage::NxDomain,
RegistryUsage::Reserved,
)
}
/// Restrictions for the .example. zone
pub fn example(name: Name) -> Self {
Self::new(
name,
UserUsage::Normal,
AppUsage::Normal,
ResolverUsage::Normal,
CacheUsage::Normal,
AuthUsage::Normal,
OpUsage::Normal,
RegistryUsage::Reserved,
)
}
/// A reference to this zone name
pub fn name(&self) -> &Name {
&self.name
}
/// Returns the UserUsage of this zone
pub fn user(&self) -> UserUsage {
self.user
}
/// Returns the AppUsage of this zone
pub fn app(&self) -> AppUsage {
self.app
}
/// Returns the ResolverUsage of this zone
pub fn resolver(&self) -> ResolverUsage {
self.resolver
}
/// Returns the CacheUsage of this zone
pub fn cache(&self) -> CacheUsage {
self.cache
}
/// Returns the AuthUsage of this zone
pub fn auth(&self) -> AuthUsage {
self.auth
}
/// Returns the OpUsage of this zone
pub fn op(&self) -> OpUsage {
self.op
}
/// Returns the RegistryUsage of this zone
pub fn registry(&self) -> RegistryUsage {
self.registry
}
}
impl Deref for ZoneUsage {
type Target = Name;
fn deref(&self) -> &Self::Target {
&self.name
}
}