1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//! The DNAME record data type.
//!
//! See [RFC 6672](https://datatracker.ietf.org/doc/html/rfc6672).
use Ordering;
use crate;
use crate;
use crate;
use crate;
use crateUnsizedCopy;
//----------- DName ----------------------------------------------------------
/// Redirection for the descendants of this domain.
///
/// A [`DName`] record indicates that a doamin name is a (partial!) alias.
/// Queries for data _under_ that domain name (not that domain name itself)
/// are redirected to the specified target. A domain name can have at most one
/// [`DName`] record; in this case, it cannot define subordinate records nor
/// have a [`CName`] record. It is conceptually similar to [`CName`].
///
/// [`DName`] is specified by [RFC 6672].
///
/// [`CName`]: super::CName
/// [RFC 6672]: https://datatracker.ietf.org/doc/html/rfc6672
///
/// ## Wire Format
///
/// The wire format of a [`DName`] record is simply the target domain name.
/// This domain name *cannot* be compressed in DNS messages.
///
/// The memory layout of the [`DName`] type is identical to its serialization
/// in the wire format. This means that it can be parsed from the wire format
/// in a zero-copy fashion, which is more efficient.
///
/// ## Usage
///
/// Because [`DName`] is a record data type, it is usually handled within
/// an enum like [`RecordData`]. This section describes how to use it
/// independently (or when building new record data from scratch).
///
/// [`RecordData`]: crate::new::rdata::RecordData
///
/// [`DName`] is a _dynamically sized type_ (DST). It is not possible to
/// store an [`DName`] in place (e.g. in a local variable); it must be held
/// indirectly, via a reference or a smart pointer type like [`Box`]. This
/// makes it more difficult to _create_ new [`DName`]s; but once they are
/// placed somewhere, they can be used by reference (i.e. `&DName`) exactly
/// like any other type.
///
/// [`Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html
///
/// It is currently a bit difficult to build a new [`DName`] from scratch.
/// It is easiest to use [`DName::new()`] on a reference to a [`Name`], or to
/// build the wire format representation of the [`DName`] manually and then to
/// parse it.
///
/// ```
/// # use domain::new::base::wire::{AsBytes, ParseBytes};
/// # use domain::new::base::name::NameBuf;
/// # use domain::new::rdata::DName;
/// # use domain::utils::dst::UnsizedCopy;
/// #
/// // Parse a 'Name' and build a 'DName' from there:
/// let name = "example.org".parse::<NameBuf>().unwrap();
/// let dname = DName::new(&name);
///
/// // Parse a 'DName' from the DNS wire format:
/// let bytes = b"\x07example\x03org\x00";
/// let from_bytes: &DName = <&DName>::parse_bytes(bytes).unwrap();
/// assert_eq!(dname.as_bytes(), bytes);
///
/// // Copy a 'DName' onto the heap:
/// let heaped: Box<DName> = dname.unsized_copy_into();
/// ```
///
/// As a DST, [`DName`] does not implement [`Copy`] or [`Clone`]. Instead, it
/// implements [`UnsizedCopy`]. A [`DName`], held by reference, can be copied
/// into a different container (e.g. `Box`) using [`unsized_copy_into()`]
///
/// [`unsized_copy_into()`]: UnsizedCopy::unsized_copy_into()
///
/// For debugging, [`DName`] can be formatted using [`fmt::Debug`].
///
/// [`fmt::Debug`]: core::fmt::Debug
///
/// To serialize a [`DName`] in the wire format, use [`BuildBytes`]
/// (which will serialize it to a given buffer) or [`AsBytes`] (which will
/// cast the [`DName`] into a byte sequence in place). It also supports
/// [`BuildInMessage`].
//--- Construction
//--- Canonical operations
//--- Building into DNS messages
//--- Parsing from bytes
//--- Parsing record data