5 // Copyright (c) 2020 Apple Inc. All rights reserved.
8 #ifndef DNSSEC_v2_STRUCTS_H
9 #define DNSSEC_v2_STRUCTS_H
11 #pragma mark - Includes
12 #include "mDNSEmbeddedAPI.h"
13 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2)
15 #include "mDNSEmbeddedAPI.h"
16 #include "ClientRequests.h"
22 #pragma mark dnssec_validation_result_t
23 typedef enum dnssec_validation_result
{
24 // chain of trust validation error
25 dnssec_validation_invalid
,
26 dnssec_validation_valid
,
27 dnssec_validation_not_trusted
,
28 dnssec_validation_trusted
,
29 dnssec_validation_invalid_internal_state
,
30 dnssec_validation_non_dnskey_ds_record_chain
,
31 dnssec_validation_no_matching_key_tag
,
33 // DNSSEC record general error
34 dnssec_validation_algorithm_number_not_equal
,
36 // DS validation error
37 dnssec_validation_ds_digest_not_supported
,
39 // DNSKEY validation error
40 dnssec_validation_dnskey_algorithm_not_supported
,
41 dnssec_validation_dnskey_invalid_flags
,
42 dnssec_validation_dnskey_wrong_protocol
,
44 // RRSIG validation error
45 dnssec_validation_rrsig_use_before_inception
,
46 dnssec_validation_rrsig_use_after_expiration
,
48 // NSEC validation error
49 dnssec_validation_nsec_invalid_nsec_result
,
50 dnssec_validation_nsec_malformated_record
,
51 // Verifiable NSEC error
52 dnssec_validation_nsec_name_error
,
53 dnssec_validation_nsec_no_data
,
54 dnssec_validation_nsec_wildcard_answer
,
55 dnssec_validation_nsec_wildcard_no_data
,
57 // NSEC3 validation error
58 dnssec_validation_nsec3_invalid_hash_iteration
,
59 dnssec_validation_nsec3_unsupported_hash_algorithm
,
60 dnssec_validation_nsec3_unsupported_flag
,
61 dnssec_validation_nsec3_different_hash_iteration_salt
,
62 dnssec_validation_nsec3_provable_closest_encloser
,
63 dnssec_validation_nsec3_nsec3_not_from_the_zone
,
64 dnssec_validation_nsec3_malformated_record
,
65 // Verifiable NSEC3 error
66 dnssec_validation_nsec3_name_error
,
67 dnssec_validation_nsec3_wildcard_no_data
,
68 dnssec_validation_nsec3_no_data_response
,
69 dnssec_validation_nsec3_no_data_response_opt_out
,
70 dnssec_validation_nsec3_wildcard_answer_response
,
72 // path validation error
73 dnssec_validation_path_invalid_node_type
,
74 dnssec_validation_path_unmatched_owner_name
,
75 dnssec_validation_path_unmatched_class
,
76 dnssec_validation_path_unmatched_type_covered
,
77 dnssec_validation_path_invalid_label_count
,
80 dnssec_validation_trust_anchor_not_available
,
81 dnssec_validation_trust_anchor_does_not_macth
,
84 dnssec_validation_validating
,
85 dnssec_validation_no_memory
,
86 dnssec_validation_bogus
87 } dnssec_validation_result_t
;
89 #pragma mark - Structures
93 #pragma mark - DNSSEC-related records wire format
97 #pragma mark dns_type_cname_t
98 // DNS CNAME record data fields (see <https://tools.ietf.org/html/rfc1035#section-3.3.1>)
99 typedef struct dns_type_cname dns_type_cname_t
;
100 struct dns_type_cname
{
101 mDNSu8 cname
[0]; // To CNAME rdata.
104 #pragma mark dns_type_ds_t
105 typedef struct dns_type_ds dns_type_ds_t
;
106 // DNS DS record data fields (see <https://tools.ietf.org/html/rfc4034#section-5.1>)
108 mDNSu16 key_tag
; // key tag that identifies a specific DNSKEY.
109 mDNSu8 algorithm
; // The DNSKEY algorithm that is used to sign the data.
110 mDNSu8 digest_type
; // The type of the DS digest.
111 mDNSu8 digest
[0]; // To digest rdata.
114 #pragma mark dns_type_dnskey_t
115 // DNS DNSKEY record data fields (see <https://tools.ietf.org/html/rfc4034#section-2.1>)
116 typedef struct dns_type_dnskey dns_type_dnskey_t
;
117 struct dns_type_dnskey
{
118 mDNSu16 flags
; // The DNSKEY flags.
119 mDNSu8 protocol
; // Protocol that identifies DNSKEY as a key used in DNSSEC, it should always be 3.
120 mDNSu8 algorithm
; // The DNSKEY algorithm that is used to sign the data.
121 mDNSu8 public_key
[0]; // To public rdata.
124 #pragma mark dns_type_rrsig_t
125 // DNS RRSIG record data fields (see <https://tools.ietf.org/html/rfc4034#section-3.1>)
126 typedef struct dns_type_rrsig dns_type_rrsig_t
;
127 struct dns_type_rrsig
{
128 mDNSu16 type_covered
; // Indicates which DNS type RRSIG covers
129 mDNSu8 algorithm
; // The DNSKEY algorithm that is used to sign the data.
130 mDNSu8 labels
; // The number of labels in the RRSIG owner name, it is used to check wild matching.
131 mDNSu32 original_TTL
; // The original TTL of the records that are covered by the RRSIG, it is used to reconstruct the signed data.
132 mDNSu32 signature_expiration
; // The epoch time when the RRSIG expires.
133 mDNSu32 signature_inception
; // The epoch time when the RRSIG should start to be valid to validate.
134 mDNSu16 key_tag
; // The key tag that identifies which DNSKEY it uses to generate the current RRSIG.
135 mDNSu8 signer_name
[0]; // To the signer name.
136 // mDNSu8 signature[0]; // To the signature rdata.
139 #pragma mark dns_type_nsec_t
140 // DNS NSEC record data fields (see <https://tools.ietf.org/html/rfc4034#section-2.1>)
141 typedef struct dns_type_nsec dns_type_nsec_t
;
142 struct dns_type_nsec
{
143 mDNSu8 next_domain_name
[0]; // The next domain that exists in the zone
144 // mDNSu8 type_bit_maps[0]; // To the type bit map that indicates what DNS types are covered by the current NSEC record.
147 #pragma mark dns_type_nsec3_t
148 // DNS NSEC3 record data fields (see <https://tools.ietf.org/html/rfc5155#section-3.1>)
149 typedef struct dns_type_nsec3 dns_type_nsec3_t
;
150 struct dns_type_nsec3
{
151 mDNSu8 hash_algorithm
; // Which hash algorithm that NSEC3 uses to generate the hash.
152 mDNSu8 flags
; // The NSEC3 flags
153 mDNSu16 iterations
; // The iterations of hash operation on the data
155 mDNSu8 salt
[0]; // varied-size array
156 // mDNSu8 hash_length;
157 // mDNSu8 next_hashed_owner_name[0];// The next hashed domain that exists in the zone
158 // mDNSu8 * type_bit_maps; // To the type bit map that indicates what DNS types are covered by the current NSEC3 record.
161 #pragma mark - DNSSEC records in memory
163 #pragma mark dnssec_rr_t
164 typedef struct dnssec_rr dnssec_rr_t
;
165 struct dnssec_rr
{ // Represents a resource record
166 mDNSu16 rr_type
; // The DNS type of the resource record.
167 mDNSu16 rr_class
; // The internet class of the record, should be IN
168 mDNSu16 rdata_length
; // The length of the rdata
169 mDNSu32 name_hash
; // The hash of the owner name that is used to compare name quickly
170 mDNSu32 rdata_hash
; // The hash of the rdata that is used to compare rdata quickly
171 domainname name
; // The owner name of the record
172 mDNSu8
* _Nullable rdata
; // The rdata
173 ResourceRecord
* _Nullable rr
; // Points to ResourceRecord in the mDNSCore cache
176 #pragma mark dnssec_original_t
177 typedef struct dnssec_original dnssec_original_t
;
178 struct dnssec_original
{ // The response that answers user's question.
179 mDNSBool answer_from_cache
; // Indicates If we get the answer from the cache, instead of refresh response from DNS server.
180 DNSServiceErrorType dns_error
; // DNSServiceErrorType when mDNSCore returns the answer.
181 QC_result qc_result
; // Event type for the current resource record including QC_add, QC_rmv, QC_supressed.
182 dnssec_rr_t dnssec_rr
; // Store the answer returned from mDNSCore.
185 #pragma mark dnssec_cname_t
186 typedef struct dnssec_cname dnssec_cname_t
;
187 struct dnssec_cname
{ // The response that does not answer user's question, but provides a CNAME to continue the query
188 mDNSu8
* _Nullable cname
; // The CNAME rdata.
189 dnssec_rr_t dnssec_rr
; // Store the answer returned from mDNSCore.
192 #pragma mark dnssec_ds_t
193 typedef struct dnssec_ds dnssec_ds_t
;
194 struct dnssec_ds
{ // The response that answers DS query from mDNSResponder
195 mDNSu16 key_tag
; // ID that identifies the DNSKEY that the current DS verifies.
196 mDNSu8 algorithm
; // The algorithm of the DNSKEY that the current DS verifies.
197 mDNSu8 digest_type
; // The digest type that is used to caluclate the current DS from the DNSKEY.
198 mDNSu16 digest_length
; // The length of the digest.
199 const mDNSu8
* _Nullable digest
; // The DS rdata.
200 dnssec_rr_t dnssec_rr
; // Store the answer returned from mDNSCore.
204 #define DNSKEY_FLAG_ZONE_KEY 0x100
205 #define DNSKEY_FLAG_SECURITY_ENTRY_POINT 0x1
207 #pragma mark dnssec_dnskey_t
208 typedef struct dnssec_dnskey dnssec_dnskey_t
;
209 struct dnssec_dnskey
{ // The response that answeres DNSKEY query from mDNSResponder.
210 mDNSu16 flags
; // The bit flags for DNSKEY.
211 mDNSu8 protocol
; // Should always be value 3.
212 mDNSu8 algorithm
; // The type of crypoto algorithm that the current DNSKEY applies to.
213 mDNSu16 key_tag
; // ID that identifies the current DNSKEY
214 mDNSu16 public_key_length
; // The length of the DNSKEY.
215 mDNSu8
* _Nullable public_key
; // The DNSKEY rdata
216 dnssec_rr_t dnssec_rr
; // Store the answer returned from mDNSCore.
219 #pragma mark dnssec_rrsig_t
220 typedef struct dnssec_rrsig dnssec_rrsig_t
;
221 struct dnssec_rrsig
{
222 mDNSu16 type_covered
; // The DNS type that is covered by the current RRSIG
223 mDNSu8 algorithm
; // The algorithm of DNSKEY that is used to generate the current RRSIG
224 mDNSu8 labels
; // The number of labels of RRSIG's owner, used for wildcard matching
225 mDNSu32 original_TTL
; // The original TTL of the records that are used to generate the current RRSIG, used to reconstruct the signed data
226 mDNSu32 signature_expiration
; // The epoch time when the RRSIG expires.
227 mDNSu32 signature_inception
; // The epoch time when the RRSIG should start to be valid to validate.
228 mDNSu16 key_tag
; // The key tag that identifies which DNSKEY it uses to generate the current RRSIG.
229 mDNSu16 signature_length
; // The length of the signature.
230 mDNSu8
* _Nullable signer_name
; // The name of signer that signs the covered records
231 mDNSu8
* _Nullable signature
; // The signature rdata
232 dnssec_rr_t dnssec_rr
; // Store the answer returned from mDNSCore.
235 #pragma mark dnssec_nsec_t
236 typedef struct dnssec_nsec dnssec_nsec_t
;
238 mDNSu8
* _Nullable exist_domain_name
; // The owner name of records that exist before next_domain_name by canonical order in the zone.
239 mDNSu8
* _Nullable next_domain_name
; // The owner name of records that exist after next_domain_name by canonical order in the zone.
240 mDNSu8
* _Nullable type_bit_maps
; // The type bit map that indicates what DNS types are covered by the current NSEC record.
241 mDNSu16 type_bit_maps_length
; // The length of the type bit map.
242 dnssec_rr_t dnssec_rr
; // Store the answer returned from mDNSCore.
245 #pragma mark dnssec_nsec3_t
246 typedef struct dnssec_nsec3 dnssec_nsec3_t
;
247 struct dnssec_nsec3
{
248 mDNSu8 hash_algorithm
; // The hash algorithm that NSEC3 uses to generate the hash
249 mDNSu8 flags
; // The NSEC3 flags
250 mDNSu16 iterations
; // The iterations of hash operation on the data
251 mDNSu8 salt_length
; // The length of the salt added when doing hash
252 mDNSu8 hash_length
; // The length of the final hash result
253 mDNSu16 type_bit_maps_length
; // The length of the type bit map.
254 mDNSu8
* _Nullable salt
; // The salt added to the hash result for every iteration
255 mDNSu8
* _Nullable next_hashed_owner_name
; // The binary-format hashed owner name of records that exist after the owner name of current NSEC3 record by canonical order in the zone.
256 mDNSu8
* _Nullable type_bit_maps
; // The type bit map that indicates what DNS types are covered by the current NSEC3 record.
257 char * _Nullable next_hashed_owner_name_b32
; // The b32-format string of hashed owner name
258 mDNSu32 next_hashed_owner_name_b32_length
; // The length of next_hashed_owner_name_b32 string
259 dnssec_rr_t dnssec_rr
; // Store the answer returned from mDNSCore.
262 #pragma mark - Validation tree structures
266 #pragma mark nsecs_with_rrsig_t
267 typedef struct nsecs_with_rrsig nsecs_with_rrsig_t
;
268 struct nsecs_with_rrsig
{ // The NSEC response from DNS server that indicates the non-existence of the record in the query.
269 list_t nsec_and_rrsigs_same_name
; // list_t<one_nsec_with_rrsigs_t>, the list of one_nsec_with_rrsigs_t structure, each one_nsec_with_rrsigs_t represents one NSEC record with its corresponding RRSIG.
270 list_t wildcard_answers
; // list_t<dnssec_rr_t>, the list of dnssec_rr_t structure, each dnssec_rr_t represents one wildcard record.
271 list_t wildcard_rrsigs
; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structure, each dnssec_rrsig_t represents one RRSIG that is used to validate the wildcard answer in wildcard_answers.
272 ResourceRecord
* _Nullable negative_rr
; // The negative answer generated by mDNSResponder, that NSEC records try to prove.
273 dnssec_validation_result_t nsec_result
; // The validation result after validating the current NSEC records, it is only meaningful after we finish the validation.
276 #pragma mark one_nsec_with_rrsigs_t
277 typedef struct one_nsec_with_rrsigs one_nsec_with_rrsigs_t
;
278 struct one_nsec_with_rrsigs
{ // One NSEC record that form a complete NSEC response with other NSEC records.
279 const mDNSu8
* _Nullable owner_name
; // The onwer name of NSEC record, also indicates that this name does exist in the zone.
280 dnssec_nsec_t nsec_record
; // The dnssec_nsec_t that holds the NSEC record.
281 list_t rrsig_records
; // list_t<dnssec_rrsig_t>, the RRSIGs that generated from the current NSEC record.
284 #pragma mark nsec3s_with_rrsig_t
285 typedef struct nsec3s_with_rrsig nsec3s_with_rrsig_t
;
286 struct nsec3s_with_rrsig
{ // The NSEC3 response from DNS server that indicates the non-existence of the record in the query.
287 list_t nsec3_and_rrsigs_same_name
; // list_t<one_nsec3_with_rrsigs_t>, the list of one_nsec3_with_rrsigs_t structure, each one_nsec3_with_rrsigs_t represents one NSEC3 record with its corresponding RRSIG.
288 list_t wildcard_answers
; // list_t<dnssec_rr_t>, the list of dnssec_rr_t structure, each dnssec_rr_t represents one wildcard record.
289 list_t wildcard_rrsigs
; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structure, each dnssec_rrsig_t represents one RRSIG that is used to validate the wildcard answer in wildcard_answers.
290 ResourceRecord
* _Nullable negative_rr
; // The negative answer generated by mDNSResponder, that NSEC3 records try to prove.
291 dnssec_validation_result_t nsec3_result
; // The validation result after validating the current NSEC3 records, it is only meaningful after we finish the validation.
294 #pragma mark one_nsec3_with_rrsigs_t
295 typedef struct one_nsec3_with_rrsigs one_nsec3_with_rrsigs_t
;
296 struct one_nsec3_with_rrsigs
{ // One NSEC3 record that form a complete NSEC response with other NSEC records.
297 const mDNSu8
* _Nullable owner_name
; // The onwer name of NSEC3 record, also indicates that this name does exist in the zone.
298 dnssec_nsec3_t nsec3_record
; // The dnssec_nsec_t that holds the NSEC3 record.
299 list_t rrsig_records
; // list_t<dnssec_rrsig_t>, the RRSIGs that generated from the current NSEC3 record.
302 #pragma mark cnames_with_rrsig_t
303 typedef struct cnames_with_rrsig cnames_with_rrsig_t
;
304 struct cnames_with_rrsig
{ // The CNAME response from DNS server that indicates the current query name is a alias of another name.
305 list_t cname_records
; // list_t<dnssec_cname_t>, the list of dnssec_cname_t structure, each dnssec_cname_t represents one CNAME, in fact there should only be one CNAME in the list.
306 list_t rrsig_records
; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structure, each dnssec_rrsig_t represents one RRSIG that i sused to validate the CNAME record in cname_records.
309 #pragma mark trust_anchor_t
310 typedef struct trust_anchors trust_anchors_t
;
311 struct trust_anchors
{ // The trust anchor structure that mDNSResponder loads during initialization, it stays unchanged during the life time of mDNSResponder.
312 domainname name
; // The owner name of the trust anchor
313 mDNSu32 name_hash
; // The hash of the owner name, used to speed up name comparsion.
314 list_t dnskey_trust_anchors
; // list_t<dnssec_dnskey_t>, the list of dnssec_dnskey_t structures, the trust anchor could be a DNSKEY record. When mDNSResponder can use this trusted DNSKEY to validate the record, then the entire validation chain rooted in the validated record could be trusted.
315 list_t ds_trust_anchors
; // list_t<dnssec_ds_t>, the list of dnssec_ds_t structures, the trust anchor could also be a DS record. When mDNSResponder can use this trusted DS to match DNSKEY record, then the entire validation chain rooted in the validated DNSKEY record could be trusted.
318 #pragma mark response_type_t
319 typedef enum response_type
{ // The response type for any DNS query in DNSSEC environment.
320 unknown_response
, // The initial state, which means we have not received any response.
321 original_response
, // The DNS server returns what the user expects, thus it is a original response for the query.
322 cname_response
, // The DNS server returns a CNAME for user's NOn-CNAME query
323 nsec_response
, // The DNS server returns a NSEC response trying to prove that the name or the record type does not exist.
324 nsec3_response
// The DNS server returns a NSEC3 response trying to prove that the name or the record type does not exist.
327 #pragma mark originals_with_rrsig_t
328 typedef struct originals_with_rrsig originals_with_rrsig_t
;
329 struct originals_with_rrsig
{ // This structure holds the response that will be returned to the user after validation.
330 union { // The response can only be original_response/cname_response/nsec_response/nsec3_response.
332 list_t original_records
; // list_t<dnssec_original_t>, the list of dnssec_original_t structures, each dnssec_original_t holds one response that user expects.
333 list_t rrsig_records
; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structures, each dnssec_rrsig_t holds one RRSIG generated from the dnssec_original_t above.
334 ResourceRecord
* _Nullable negative_rr
; // The query may be suppressed by mDNSResponder, it is a denial of existence response that does not need NSEC/NSEC3 to validate, just put it in original.
335 mDNSBool suppressed_response
; // Indicates if the original response is a suppressed one.
336 } original
; // Used when the type is original_response.
337 cnames_with_rrsig_t cname_with_rrsig
; // Used when the type is cname_response.
338 // NSEC and NSEC3 RRs can not co-exist in a zone.
339 nsecs_with_rrsig_t nsecs_with_rrsig
; // Used when the type is nsec_response.
340 nsec3s_with_rrsig_t nsec3s_with_rrsig
; // Used when the type is nsec3_response.
342 response_type_t type
; // original_response/cname_response/nsec_response/nsec3_response.
345 #pragma mark dses_with_rrsig_t
346 typedef struct dses_with_rrsig dses_with_rrsig_t
;
347 struct dses_with_rrsig
{ // This structure holds the DS response that DNSSEC handler queries for.
348 union { // The response can only be original_response/nsec_response/nsec3_response.
350 list_t ds_records
; // list_t<dnssec_ds_t>, the list of dnssec_ds_t structure, each dnssec_ds_t holds one DS record that could be used to verifies one DNSKEY record
351 list_t rrsig_records
; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structure, each dnssec_rrsig_t holds one RRSIG generated from the dnssec_ds_t above.
353 // NSEC and NSEC3 RRs can not co-exist in a zone.
354 nsecs_with_rrsig_t nsecs_with_rrsig
; // Used when the type is nsec_response.
355 nsec3s_with_rrsig_t nsec3s_with_rrsig
; // Used when the type is nsec3_response.
357 response_type_t type
; // original_response/nsec_response/nsec3_response, CNAME can only be the leaf node, thus there should never be CNAME for DS query.
358 mDNSBool set_completed
; // Indicates if we have already get the DS records.
361 #pragma mark dnskeys_with_rrsig_t
362 typedef struct dnskeys_with_rrsig dnskeys_with_rrsig_t
;
363 struct dnskeys_with_rrsig
{ // This structure holds the DNSKEY response that DNSSEC handler queries for. The response can only be original_response, because both NSEC and NSEC3 indicate that DNSKEY does exist in order to validate the NSEC/NSEC3.
364 list_t dnskey_records
; // list_t<dnssec_dnskey_t>, the list of dnssec_dnskey_t structures, each dnssec_dnskey_t holds one DNSKEY that could be used to validate signer's records with the corresponding RRSIG.
365 list_t rrsig_records
; // list_t<dnssec_rrsig_t>, the list of dnssec_rrsig_t structures, each dnssec_rrsig_t holds one RRSIG generated from the dnssec_dnskey_t above.
366 mDNSBool set_completed
; // Indicates if we have already get the DNSKEY records.
369 #pragma mark dnssec_zone_t
370 // This structure represents one zone node in the validation tree. For example, if the user queries for the AAAA record
371 // of "www.internetsociety.org.", there will be 3 zone nodes at last:
372 // Root zone node: "." DNSKEY
373 // Zone node: "org." DNSKEY/DS
374 // Zone node: "internetsociety.org." DNSKEY/DS
375 // Response: "www.internetsociety.org." AAAA
376 // Each node contains 2 kinds of records: DNSKEY and DS records
377 typedef struct dnssec_zone dnssec_zone_t
;
379 // general field that is used to fecth records
380 domainname domain_name
; // DNS representation of the zone name.
381 mDNSu32 name_hash
; // The name hash to speed up name comparison.
383 // dnssec resource records
385 QueryRecordClientRequest ds_request
; // The DS request handler
386 mDNSBool ds_request_started
; // Indicates if we issued the DS request, sometimes we do not want to issue query such as we are in root "." node, and root node does not have DS record.
387 mDNSBool dses_initialized
; // Indicate if the DS list is initialized
388 dses_with_rrsig_t dses_with_rrsig
; // list_t<dses_with_rrsig_t>, the list of dses_with_rrsig_t structures, each dses_with_rrsig_t holds the DS records and the corresponding RRSIG records for the current zone.
389 mDNSs32 last_time_ds_add
; // last time that DS records are added
390 mDNSs32 last_time_ds_rmv
; // last time that DS records are removed
393 QueryRecordClientRequest dnskey_request
; // The DNSKEY request handler
394 mDNSBool dnskey_request_started
; // Indicates if we issue the DNSKEY request, sometimes we do not issue the query because the current zone has a trust anchor for DNSKEY.
395 dnskeys_with_rrsig_t dnskeys_with_rrsig
; // list_t<dnssec_dnskey_t>, the list of dnskeys_with_rrsig structures, each dnssec_dnskey_t holds the DNSKEY records and the corresponding RRSIG records for the current zone.
396 mDNSs32 last_time_dnskey_add
; // last time that DNSKEY records are added
397 mDNSs32 last_time_dnskey_rmv
; // last time that DNSKEY records are removed
399 // The current zone may have trust anchor installed in the system
400 const trust_anchors_t
* _Nullable trust_anchor
; // list_t<trust_anchor_t>, the list of trust_anchor_t structures, each trust_anchor_t represent one trust anchor.
403 #pragma mark original_request_parameters_t
404 typedef struct original_request_parameters original_request_parameters_t
;
405 struct original_request_parameters
{ // This structure contains the original request paramters set by the user.
407 domainname question_name
;
408 mDNSu32 question_name_hash
;
409 mDNSu16 question_type
;
410 mDNSu16 question_class
;
411 mDNSInterfaceID _Nullable interface_id
;
414 mDNSBool append_search_domains
;
416 mDNSu8 uuid
[UUID_SIZE
];
418 #if MDNSRESPONDER_SUPPORTS(APPLE, AUDIT_TOKEN)
419 audit_token_t peer_audit_token
;
420 mDNSBool has_peer_audit_token
;
421 audit_token_t delegate_audit_token
;
422 mDNSBool has_delegate_audit_token
;
424 #if MDNSRESPONDER_SUPPORTS(APPLE, QUERIER)
425 mDNSu8 resolver_uuid
[UUID_SIZE
];
426 mDNSBool need_encryption
;
427 mdns_dns_service_id_t custom_id
;
429 QueryRecordResultHandler _Nullable user_handler
;
430 void * _Nullable user_context
;
433 #pragma mark denial_of_existence_records_t
434 typedef struct denial_of_existence_records denial_of_existence_records_t
;
435 struct denial_of_existence_records
{
436 list_t resource_records
; //list_t<ResourceRecord>;
439 #pragma mark original_t
440 typedef struct original original_t
;
441 struct original
{ // This structure contains all the useful information about the user's original request.
442 original_request_parameters_t original_parameters
; // The original paramters getting from the user
443 originals_with_rrsig_t original_result_with_rrsig
; // The original response that will be returned to the user.
444 const trust_anchors_t
* _Nullable original_trust_anchor
; // It is possible that the returned original response is a trust anchor installed.
445 mDNSs32 last_time_add
; // Last time that originals_with_rrsig_t records are added.
446 mDNSs32 last_time_rmv
; // Last time that originals_with_rrsig_t records are removed.
449 #pragma mark returned_answers_t
450 typedef struct returned_answers returned_answers_t
;
451 struct returned_answers
{ // This structure contains all the records that are returned to the user, these information is tracked to properly deliver ADD/RMV event to the user
452 list_t answers
; // list_t<ResourceRecord *>, the list of "ResourceRecord *" pointers, each pointer points to a ResourceRecord in the cache that has been returned to the user.
453 dnssec_result_t dnssec_result
; // The dnssec_result_t that has been returned to the user.
454 DNSServiceErrorType error
; // The returned DNSServiceErrorType
455 response_type_t type
; // The type of the returned answer, it could be original_response(including suppressed case)/nsec_response/nsec3_response
458 #pragma mark dnssec_context_t
459 // This structure contains the DNSSEC context that is needed to track additional information that is not provided by
460 // mDNSCore, each DNSSEC-enabled DNS request would have a seperated DNSSEC context.
461 typedef struct dnssec_context dnssec_context_t
;
462 struct dnssec_context
{
464 QueryRecordClientRequest
* _Nonnull me
; // The request of the question that we are currently working on.
465 QueryRecordClientRequest request_to_follow_cname
; // An idle request unless there is a need to follow the CNAME reference, and start a sub request.
467 // Zone records that could be used to validate records.
468 list_t zone_chain
; // list_t<dnssec_zone_t>, the validation tree consists of zone nodes from root to leaf.
470 // original request fields
471 original_t original
; // Information about the user's original request.
473 // denial of existence fields
474 denial_of_existence_records_t
* _Nullable denial_of_existence_records
; // It is a temporary field that is used to pass the NSEC/NSEC3 records to the DNSSEC handler, will be cleared after running DNSSEC handler.
476 // save the records that are returned to the user
477 returned_answers_t returned_answers
; // The records that have been returned to the user.
479 // DNSSEC context pointer
480 dnssec_context_t
* _Nullable primary_dnssec_context
; // This points to the initial DNSSEC context of the first query coming from the user, i.e. the first name in the CNAME chain.
481 dnssec_context_t
* _Nullable subtask_dnssec_context
; // If the DNSSEC-enabled DNS query has CNAMEs, this field is used to create another new DNSSEC context that resolves and validates the new CNAME.
485 #pragma mark - Functions
489 #pragma mark - dns_type_*_t records parsing
493 #pragma mark parsse_dns_type_cname_t
495 parsse_dns_type_cname_t(const void * const _Nonnull rdata
, mDNSu8
* _Nullable
* const _Nonnull out_cname
);
497 #pragma mark parse_dns_type_ds_t
500 const void * const _Nonnull rdata
,
501 const mDNSu16 rdata_length
,
502 mDNSu16
* const _Nullable out_key_tag
,
503 mDNSu8
* const _Nullable out_algorithm
,
504 mDNSu8
* const _Nullable out_digest_type
,
505 mDNSu16
* const _Nullable out_digest_length
,
506 const mDNSu8
* _Nonnull
* const _Nullable out_digest
);
508 #pragma mark parse_dns_type_dnskey_t
510 parse_dns_type_dnskey_t(
511 const void * const _Nonnull rdata
,
512 const mDNSu16 rdata_length
,
513 mDNSu16
* const _Nullable out_flags
,
514 mDNSu8
* const _Nullable out_protocol
,
515 mDNSu8
* const _Nullable out_algorithm
,
516 mDNSu16
* const _Nullable out_public_key_length
,
517 mDNSu8
* _Nonnull
* const _Nullable out_public_key
);
519 #pragma mark parse_dns_type_rrsig_t
521 parse_dns_type_rrsig_t(
522 const void * const _Nonnull rdata
,
523 const mDNSu16 rdata_length
,
524 mDNSu16
* const _Nullable out_type_covered
,
525 mDNSu8
* const _Nullable out_algorithm
,
526 mDNSu8
* const _Nullable out_labels
,
527 mDNSu32
* const _Nullable out_original_ttl
,
528 mDNSu32
* const _Nullable out_signature_expiration
,
529 mDNSu32
* const _Nullable out_signature_inception
,
530 mDNSu16
* const _Nullable out_key_tag
,
531 mDNSu16
* const _Nullable out_signature_length
,
532 mDNSu8
* _Nonnull
* const _Nullable out_signer_name
,
533 mDNSu8
* _Nonnull
* const _Nullable out_signature
);
535 #pragma mark parse_dns_type_nsec_t
537 parse_dns_type_nsec_t(
538 const void * const _Nonnull rdata
,
539 const mDNSu16 rdata_length
,
540 mDNSu16
* const _Nonnull out_type_bit_maps_length
,
541 mDNSu8
* _Nonnull
* const _Nullable out_next_domain_name
,
542 mDNSu8
* _Nonnull
* const _Nullable out_type_bit_maps
);
544 #pragma mark parse_dns_type_nsec3_t
546 parse_dns_type_nsec3_t(
547 const void * const _Nonnull rdata
,
548 const mDNSu16 rdata_length
,
549 mDNSu8
* const _Nullable out_hash_algorithm
,
550 mDNSu8
* const _Nullable out_flags
,
551 mDNSu16
* const _Nullable out_iterations
,
552 mDNSu8
* const _Nullable out_salt_length
,
553 mDNSu8
* const _Nullable out_hash_length
,
554 mDNSu16
* const _Nullable out_type_bit_maps_length
,
555 mDNSu8
* _Nonnull
* const _Nullable out_salt
,
556 mDNSu8
* _Nonnull
* const _Nullable out_next_hashed_owner_name
,
557 mDNSu8
* _Nonnull
* const _Nullable out_type_bit_maps
);
559 #pragma mark get_covered_type_of_dns_type_rrsig_t
561 get_covered_type_of_dns_type_rrsig_t(const void * const _Nonnull rdata
);
563 // dnssec_rr_t function prototypes
564 #pragma mark - dnssec_rr_t functions
567 initialize_dnssec_rr_t(dnssec_rr_t
* const _Nonnull dnssec_rr
, ResourceRecord
* const _Nonnull rr
);
570 uninitialize_dnssec_rr_t(dnssec_rr_t
* const _Nonnull dnssec_rr
);
573 equal_dnssec_rr_t(const dnssec_rr_t
* const _Nonnull left
, const dnssec_rr_t
* const _Nonnull right
);
576 print_dnssec_rr_t(const dnssec_rr_t
* const _Nonnull dnssec_rr
, mDNSu8 num_of_tabs
);
578 // dnssec_original_t function prototypes
579 #pragma mark - dnssec_original_t functions
582 initialize_dnssec_original_t(
583 dnssec_original_t
* const _Nonnull original
,
584 ResourceRecord
* const _Nonnull rr
,
585 const mDNSBool answer_from_cache
,
586 const DNSServiceErrorType dns_error
,
587 const QC_result qc_result
);
590 uninitialize_dnssec_original_t(dnssec_original_t
* const _Nonnull original
);
593 print_dnssec_original_t(const dnssec_original_t
* const _Nonnull original
, mDNSu8 num_of_tabs
);
595 #pragma mark - dnssec_cname_t functions
598 initialize_dnssec_cname_t(dnssec_cname_t
* const _Nonnull cname
, ResourceRecord
* const _Nonnull rr
);
601 uninitialize_dnssec_cname_t(dnssec_cname_t
* const _Nonnull cname
);
604 print_dnssec_cname_t(const dnssec_cname_t
* const _Nonnull cname
, mDNSu8 num_of_tabs
);
606 #pragma mark - dnssec_ds_t functions
609 initialize_dnssec_ds_t(dnssec_ds_t
* const _Nonnull ds
, ResourceRecord
* const _Nonnull rr
);
612 equals_dnssec_ds_t(const dnssec_ds_t
* const _Nonnull left
, const dnssec_ds_t
* const _Nonnull right
);
615 uninitialize_dnssec_ds_t(dnssec_ds_t
* const _Nonnull ds
);
618 print_dnssec_ds_t(const dnssec_ds_t
* const _Nonnull ds
, mDNSu8 num_of_tabs
);
620 #pragma mark - dnssec_dnskey_t functions
623 initialize_dnssec_dnskey_t(dnssec_dnskey_t
* const _Nonnull dnskey
, ResourceRecord
* const _Nonnull rr
);
626 equals_dnssec_dnskey_t(const dnssec_dnskey_t
* const _Nonnull left
, const dnssec_dnskey_t
* const _Nonnull right
);
629 uninitialize_dnssec_dnskey_t(dnssec_dnskey_t
* const _Nonnull dnskey
);
632 print_dnssec_dnskey_t(const dnssec_dnskey_t
* const _Nonnull dnskey
, mDNSu8 num_of_tabs
);
634 #pragma mark - dnssec_rrsig_t functions
637 initialize_dnssec_rrsig_t(dnssec_rrsig_t
* const _Nonnull rrsig
, ResourceRecord
* const _Nonnull rr
);
640 uninitialize_dnssec_rrsig_t(dnssec_rrsig_t
* const _Nonnull rrsig
);
643 print_dnssec_rrsig_t(const dnssec_rrsig_t
* const _Nonnull rrsig
, mDNSu8 num_of_tabs
);
645 #pragma mark - dnssec_nsec_t functions
648 initialize_dnssec_nsec_t(dnssec_nsec_t
* const _Nonnull nsec
, ResourceRecord
* const _Nonnull rr
);
651 uninitialize_dnssec_nsec_t(dnssec_nsec_t
* const _Nonnull nsec
);
654 print_dnssec_nsec_t(const dnssec_nsec_t
* const _Nonnull nsec
, mDNSu8 num_of_tabs
);
656 #pragma mark - dnssec_nsec3_t functions
659 initialize_dnssec_nsec3_t(dnssec_nsec3_t
* const _Nonnull nsec3
, ResourceRecord
* const _Nonnull rr
);
662 uninitialize_dnssec_nsec3_t(dnssec_nsec3_t
* const _Nonnull nsec3
);
665 print_dnssec_nsec3_t(const dnssec_nsec3_t
* const _Nonnull nsec3
, mDNSu8 num_of_tabs
);
667 #pragma mark - nsecs_with_rrsig_t functions
670 initialize_nsecs_with_rrsig_t(nsecs_with_rrsig_t
* const _Nonnull nsecs
);
673 uninitialize_nsecs_with_rrsig_t(nsecs_with_rrsig_t
* const _Nonnull nsecs
);
676 print_nsecs_with_rrsig_t(const nsecs_with_rrsig_t
* const _Nonnull nsecs
, mDNSu8 num_of_tabs
);
678 # pragma mark - one_nsec_with_rrsigs_t functions
681 initialize_one_nsec_with_rrsigs_t(
682 one_nsec_with_rrsigs_t
* const _Nonnull one_nsec_with_rrsigs
,
683 ResourceRecord
* const _Nonnull rr
);
686 uninitialize_one_nsec_with_rrsigs_t(one_nsec_with_rrsigs_t
* const _Nonnull one_nsec_with_rrsigs
);
688 # pragma mark - one_nsec3_with_rrsigs_t functions
691 initialize_one_nsec3_with_rrsigs_t(
692 one_nsec3_with_rrsigs_t
* const _Nonnull one_nsec3_with_rrsigs
,
693 ResourceRecord
* const _Nonnull rr
);
696 uninitialize_one_nsec3_with_rrsigs_t(one_nsec3_with_rrsigs_t
* const _Nonnull one_nsec3_with_rrsigs
);
698 #pragma mark - nsec3s_with_rrsig_t functions
701 initialize_nsec3s_with_rrsig_t(nsec3s_with_rrsig_t
* const _Nonnull nsec3s
);
704 uninitialize_nsec3s_with_rrsig_t(nsec3s_with_rrsig_t
* const _Nonnull nsec3s
);
707 print_nsec3s_with_rrsig_t(const nsec3s_with_rrsig_t
* const _Nonnull nsec3s
, mDNSu8 num_of_tabs
);
709 #pragma mark - cnames_with_rrsig_t
712 initialize_cname_with_rrsig_t(cnames_with_rrsig_t
* const _Nonnull cname
);
715 uninitialize_cname_with_rrsig_t(cnames_with_rrsig_t
* const _Nonnull cname
);
718 print_cname_with_rrsig_t(const cnames_with_rrsig_t
* const _Nonnull cname
, mDNSu8 num_of_tabs
);
720 #pragma mark - response_type_t functions
722 mDNSexport
const char * _Nonnull
723 response_type_value_to_string(response_type_t type
);
725 #pragma mark - originals_with_rrsig_t
728 initialize_originals_with_rrsig_t(originals_with_rrsig_t
* const _Nonnull original
, const response_type_t type
);
731 uninitialize_originals_with_rrsig_t(originals_with_rrsig_t
* const _Nonnull original
);
734 contains_rrsig_in_originals_with_rrsig_t(const originals_with_rrsig_t
* const _Nonnull original
);
737 print_originals_with_rrsig_t(const originals_with_rrsig_t
* const _Nonnull original
, mDNSu8 num_of_tabs
);
739 #pragma mark - dses_with_rrsig_t functions
742 initialize_dses_with_rrsig_t(dses_with_rrsig_t
* const _Nonnull ds
, const response_type_t type
);
745 uninitialize_dses_with_rrsig_t(dses_with_rrsig_t
* const _Nonnull ds
);
748 contains_rrsig_in_dses_with_rrsig_t(const dses_with_rrsig_t
* const _Nonnull ds
);
751 print_dses_with_rrsig_t(const dses_with_rrsig_t
* const _Nonnull ds
, mDNSu8 num_of_tabs
);
753 #pragma mark - dses_with_rrsig_t functions
756 initialize_dnskeys_with_rrsig_t(dnskeys_with_rrsig_t
* const _Nonnull dnskey
);
759 uninitialize_dnskeys_with_rrsig_t(dnskeys_with_rrsig_t
* const _Nonnull dnskey
);
762 contains_rrsig_in_dnskeys_with_rrsig_t(const dnskeys_with_rrsig_t
* const _Nonnull dnskey
);
765 print_dnskeys_with_rrsig_t(const dnskeys_with_rrsig_t
* const _Nonnull dnskey
, mDNSu8 num_of_tabs
);
768 print_original_request_parameters_t(const original_request_parameters_t
* const _Nonnull parameters
, mDNSu8 num_of_tabs
);
770 #pragma mark - dnssec_zone_t functions
773 initialize_dnssec_zone_t(
774 dnssec_zone_t
* const _Nonnull zone
,
775 const mDNSu8
* const _Nonnull domain_name
);
778 uninitialize_dnssec_zone_t(dnssec_zone_t
* const _Nonnull zone
);
781 stop_and_clean_dnssec_zone_t(dnssec_zone_t
* const _Nonnull zone
);
784 print_dnssec_zone_t(const dnssec_zone_t
* const _Nonnull zone
, mDNSu8 num_of_tabs
);
786 #pragma mark - returned_answers_t
789 initialize_returned_answers_t(
790 returned_answers_t
* const _Nonnull returned_answers
,
791 const dnssec_result_t dnssec_result
,
792 const DNSServiceErrorType error
);
795 uninitialize_returned_answers_t(returned_answers_t
* const _Nonnull returned_answers
);
798 print_returned_answers_t(const returned_answers_t
* const _Nonnull returned_answers
, mDNSu8 num_of_tabs
);
800 #endif // MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2)
801 #endif // DNSSEC_v2_STRUCTS_H