1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <netinet/in.h>
9 #include "resolved-forward.h"
12 #define DNSKEY_FLAG_SEP (UINT16_C(1) << 0)
13 #define DNSKEY_FLAG_REVOKE (UINT16_C(1) << 7)
14 #define DNSKEY_FLAG_ZONE_KEY (UINT16_C(1) << 8)
17 #define MDNS_RR_CACHE_FLUSH_OR_QU (UINT16_C(1) << 15)
19 /* DNSSEC algorithm identifiers, see
20 * http://tools.ietf.org/html/rfc4034#appendix-A.1 and
21 * https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
23 DNSSEC_ALGORITHM_RSAMD5
= 1,
27 DNSSEC_ALGORITHM_RSASHA1
,
28 DNSSEC_ALGORITHM_DSA_NSEC3_SHA1
,
29 DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
,
30 DNSSEC_ALGORITHM_RSASHA256
= 8, /* RFC 5702 */
31 DNSSEC_ALGORITHM_RSASHA512
= 10, /* RFC 5702 */
32 DNSSEC_ALGORITHM_ECC_GOST
= 12, /* RFC 5933 */
33 DNSSEC_ALGORITHM_ECDSAP256SHA256
= 13, /* RFC 6605 */
34 DNSSEC_ALGORITHM_ECDSAP384SHA384
= 14, /* RFC 6605 */
35 DNSSEC_ALGORITHM_ED25519
= 15, /* RFC 8080 */
36 DNSSEC_ALGORITHM_ED448
= 16, /* RFC 8080 */
37 DNSSEC_ALGORITHM_INDIRECT
= 252,
38 DNSSEC_ALGORITHM_PRIVATEDNS
,
39 DNSSEC_ALGORITHM_PRIVATEOID
,
40 _DNSSEC_ALGORITHM_MAX_DEFINED
43 /* DNSSEC digest identifiers, see
44 * https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */
46 DNSSEC_DIGEST_SHA1
= 1,
47 DNSSEC_DIGEST_SHA256
= 2, /* RFC 4509 */
48 DNSSEC_DIGEST_GOST_R_34_11_94
= 3, /* RFC 5933 */
49 DNSSEC_DIGEST_SHA384
= 4, /* RFC 6605 */
50 _DNSSEC_DIGEST_MAX_DEFINED
53 /* DNSSEC NSEC3 hash algorithms, see
54 * https://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml */
56 NSEC3_ALGORITHM_SHA1
= 1,
57 _NSEC3_ALGORITHM_MAX_DEFINED
60 /* SSHFP algorithm identifiers, see
61 * https://www.iana.org/assignments/dns-sshfp-rr-parameters/dns-sshfp-rr-parameters.xhtml */
63 SSHFP_ALGORITHM_RSA
= 1, /* RFC 4255 */
64 SSHFP_ALGORITHM_DSA
= 2, /* RFC 4255 */
65 SSHFP_ALGORITHM_ECDSA
= 3, /* RFC 6594 */
66 SSHFP_ALGORITHM_ED25519
= 4, /* RFC 7479 */
68 SSHFP_ALGORITHM_ED448
= 6, /* RFC 8709 */
69 _SSHFP_ALGORITHM_MAX_DEFINED
71 /* A helper to align printed output */
72 #define SSHFP_ALGORITHM_FMT "%-7s"
74 /* SSHFP key-type identifiers, see
75 * https://www.iana.org/assignments/dns-sshfp-rr-parameters/dns-sshfp-rr-parameters.xhtml */
77 SSHFP_KEY_TYPE_SHA1
= 1, /* RFC 4255 */
78 SSHFP_KEY_TYPE_SHA256
= 2, /* RFC 4255 */
79 _SSHFP_KEY_TYPE_MAX_DEFINED
81 /* A helper to align printed output */
82 #define SSHFP_KEY_TYPE_FMT "%-7s"
84 typedef struct DnsResourceKey
{
85 unsigned n_ref
; /* (unsigned -1) for const keys, see below */
87 char *_name
; /* don't access directly, use dns_resource_key_name()! */
90 /* Creates a temporary resource key. This is only useful to quickly
91 * look up something, without allocating a full DnsResourceKey object
92 * for it. Note that it is not OK to take references to this kind of
93 * resource key object. */
94 #define DNS_RESOURCE_KEY_CONST(c, t, n) \
102 typedef struct DnsTxtItem
{
104 LIST_FIELDS(DnsTxtItem
, items
);
108 typedef struct DnsSvcParam
{
111 LIST_FIELDS(DnsSvcParam
, params
);
113 DECLARE_FLEX_ARRAY(uint8_t, value
);
114 DECLARE_FLEX_ARRAY(struct in_addr
, value_in_addr
);
115 DECLARE_FLEX_ARRAY(struct in6_addr
, value_in6_addr
);
119 typedef struct DnsResourceRecord
{
122 usec_t expiry
; /* RRSIG signature expiry */
128 /* How many labels to strip to determine "signer" of the RRSIG (aka, the zone). -1 if not signed. */
129 uint8_t n_skip_labels_signer
;
130 /* How many labels to strip to determine "synthesizing source" of this RR, i.e. the wildcard's immediate parent. -1 if not signed. */
131 uint8_t n_skip_labels_source
;
134 bool wire_format_canonical
;
137 size_t wire_format_size
;
138 size_t wire_format_rdata_offset
;
155 } ptr
, ns
, cname
, dname
;
167 struct in_addr in_addr
;
171 struct in6_addr in6_addr
;
189 /* https://tools.ietf.org/html/rfc1876 */
200 /* https://tools.ietf.org/html/rfc4255#section-3.1 */
203 size_t fingerprint_size
;
209 /* http://tools.ietf.org/html/rfc4034#section-2.1 */
219 /* http://tools.ietf.org/html/rfc4034#section-3.1 */
223 size_t signature_size
;
225 uint16_t type_covered
;
228 uint32_t original_ttl
;
234 /* https://tools.ietf.org/html/rfc4034#section-4.1 */
236 char *next_domain_name
;
240 /* https://tools.ietf.org/html/rfc4034#section-5.1 */
254 void *next_hashed_name
;
255 size_t next_hashed_name_size
;
262 /* https://tools.ietf.org/html/draft-ietf-dane-protocol-23 */
269 uint8_t matching_type
;
272 /* https://tools.ietf.org/html/rfc9460 */
279 /* https://tools.ietf.org/html/rfc6844 */
288 /* https://datatracker.ietf.org/doc/html/rfc2915 */
299 /* Note: fields should be ordered to minimize alignment gaps. Use pahole! */
302 /* We use uint8_t for label counts above, and UINT8_MAX/-1 has special meaning. */
303 assert_cc(DNS_N_LABELS_MAX
< UINT8_MAX
);
305 static inline const void* DNS_RESOURCE_RECORD_RDATA(const DnsResourceRecord
*rr
) {
309 if (!rr
->wire_format
)
312 assert(rr
->wire_format_rdata_offset
<= rr
->wire_format_size
);
313 return (uint8_t*) rr
->wire_format
+ rr
->wire_format_rdata_offset
;
316 static inline size_t DNS_RESOURCE_RECORD_RDATA_SIZE(const DnsResourceRecord
*rr
) {
319 if (!rr
->wire_format
)
322 assert(rr
->wire_format_rdata_offset
<= rr
->wire_format_size
);
323 return rr
->wire_format_size
- rr
->wire_format_rdata_offset
;
326 static inline uint8_t DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(const DnsResourceRecord
*rr
) {
328 assert(rr
->key
->type
== DNS_TYPE_OPT
);
330 return ((rr
->ttl
>> 16) & 0xFF) == 0;
333 DnsResourceKey
* dns_resource_key_new(uint16_t class, uint16_t type
, const char *name
);
334 DnsResourceKey
* dns_resource_key_new_redirect(const DnsResourceKey
*key
, const DnsResourceRecord
*cname
);
335 int dns_resource_key_new_append_suffix(DnsResourceKey
**ret
, DnsResourceKey
*key
, char *name
);
336 DnsResourceKey
* dns_resource_key_new_consume(uint16_t class, uint16_t type
, char *name
);
337 DnsResourceKey
* dns_resource_key_ref(DnsResourceKey
*key
);
338 DnsResourceKey
* dns_resource_key_unref(DnsResourceKey
*key
);
340 #define DNS_RESOURCE_KEY_REPLACE(a, b) \
342 typeof(a)* _a = &(a); \
343 typeof(b) _b = (b); \
344 dns_resource_key_unref(*_a); \
348 const char* dns_resource_key_name(const DnsResourceKey
*key
);
349 bool dns_resource_key_is_address(const DnsResourceKey
*key
);
350 bool dns_resource_key_is_dnssd_ptr(const DnsResourceKey
*key
);
351 bool dns_resource_key_is_dnssd_two_label_ptr(const DnsResourceKey
*key
);
352 int dns_resource_key_equal(const DnsResourceKey
*a
, const DnsResourceKey
*b
);
353 int dns_resource_key_match_rr(const DnsResourceKey
*key
, DnsResourceRecord
*rr
, const char *search_domain
);
354 int dns_resource_key_match_cname_or_dname(const DnsResourceKey
*key
, const DnsResourceKey
*cname
, const char *search_domain
);
355 int dns_resource_key_match_soa(const DnsResourceKey
*key
, const DnsResourceKey
*soa
);
357 /* _DNS_{CLASS,TYPE}_STRING_MAX include one byte for NUL, which we use for space instead below.
358 * DNS_HOSTNAME_MAX does not include the NUL byte, so we need to add 1. */
359 #define DNS_RESOURCE_KEY_STRING_MAX (_DNS_CLASS_STRING_MAX + _DNS_TYPE_STRING_MAX + DNS_HOSTNAME_MAX + 1)
361 char* dns_resource_key_to_string(const DnsResourceKey
*key
, char *buf
, size_t buf_size
);
362 ssize_t
dns_resource_record_payload(DnsResourceRecord
*rr
, const void **ret
);
364 #define DNS_RESOURCE_KEY_TO_STRING(key) \
365 dns_resource_key_to_string(key, (char[DNS_RESOURCE_KEY_STRING_MAX]) {}, DNS_RESOURCE_KEY_STRING_MAX)
367 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceKey
*, dns_resource_key_unref
);
369 static inline bool dns_key_is_shared(const DnsResourceKey
*key
) {
370 return key
->type
== DNS_TYPE_PTR
;
373 bool dns_resource_key_reduce(DnsResourceKey
**a
, DnsResourceKey
**b
);
375 DnsResourceRecord
* dns_resource_record_new(DnsResourceKey
*key
);
376 DnsResourceRecord
* dns_resource_record_new_full(uint16_t class, uint16_t type
, const char *name
);
377 DnsResourceRecord
* dns_resource_record_ref(DnsResourceRecord
*rr
);
378 DnsResourceRecord
* dns_resource_record_unref(DnsResourceRecord
*rr
);
380 #define DNS_RR_REPLACE(a, b) \
382 typeof(a)* _a = &(a); \
383 typeof(b) _b = (b); \
384 dns_resource_record_unref(*_a); \
388 int dns_resource_record_new_reverse(DnsResourceRecord
**ret
, int family
, const union in_addr_union
*address
, const char *name
);
389 int dns_resource_record_new_address(DnsResourceRecord
**ret
, int family
, const union in_addr_union
*address
, const char *name
);
390 int dns_resource_record_equal(const DnsResourceRecord
*a
, const DnsResourceRecord
*b
);
391 int dns_resource_record_payload_equal(const DnsResourceRecord
*a
, const DnsResourceRecord
*b
);
393 const char* dns_resource_record_to_string(DnsResourceRecord
*rr
);
394 DnsResourceRecord
*dns_resource_record_copy(DnsResourceRecord
*rr
);
395 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord
*, dns_resource_record_unref
);
397 int dns_resource_record_to_wire_format(DnsResourceRecord
*rr
, bool canonical
);
399 int dns_resource_record_signer(DnsResourceRecord
*rr
, const char **ret
);
400 int dns_resource_record_source(DnsResourceRecord
*rr
, const char **ret
);
401 int dns_resource_record_is_signer(DnsResourceRecord
*rr
, const char *zone
);
402 int dns_resource_record_is_synthetic(DnsResourceRecord
*rr
);
404 int dns_resource_record_clamp_ttl(DnsResourceRecord
**rr
, uint32_t max_ttl
);
406 bool dns_resource_record_is_link_local_address(DnsResourceRecord
*rr
);
408 int dns_resource_record_get_cname_target(DnsResourceKey
*key
, DnsResourceRecord
*cname
, char **ret
);
410 DnsTxtItem
*dns_txt_item_free_all(DnsTxtItem
*i
);
411 bool dns_txt_item_equal(DnsTxtItem
*a
, DnsTxtItem
*b
);
412 DnsTxtItem
*dns_txt_item_copy(DnsTxtItem
*i
);
413 int dns_txt_item_new_empty(DnsTxtItem
**ret
);
415 DnsSvcParam
*dns_svc_param_free_all(DnsSvcParam
*i
);
416 bool dns_svc_params_equal(DnsSvcParam
*a
, DnsSvcParam
*b
);
417 DnsSvcParam
*dns_svc_params_copy(DnsSvcParam
*first
);
419 int dns_resource_record_new_from_raw(DnsResourceRecord
**ret
, const void *data
, size_t size
);
421 int dns_resource_key_to_json(DnsResourceKey
*key
, sd_json_variant
**ret
);
422 int dns_resource_key_from_json(sd_json_variant
*v
, DnsResourceKey
**ret
);
423 int dns_resource_record_to_json(DnsResourceRecord
*rr
, sd_json_variant
**ret
);
425 void dns_resource_key_hash_func(const DnsResourceKey
*k
, struct siphash
*state
);
426 int dns_resource_key_compare_func(const DnsResourceKey
*x
, const DnsResourceKey
*y
);
427 void dns_resource_record_hash_func(const DnsResourceRecord
*i
, struct siphash
*state
);
428 int dns_resource_record_compare_func(const DnsResourceRecord
*x
, const DnsResourceRecord
*y
);
430 extern const struct hash_ops dns_resource_key_hash_ops
;
431 extern const struct hash_ops dns_resource_record_hash_ops
;
432 extern const struct hash_ops dns_resource_record_hash_ops_by_key
;
434 int dnssec_algorithm_to_string_alloc(int i
, char **ret
);
435 int dnssec_algorithm_from_string(const char *s
) _pure_
;
437 int dnssec_digest_to_string_alloc(int i
, char **ret
);
438 int dnssec_digest_from_string(const char *s
) _pure_
;
440 int sshfp_algorithm_to_string_alloc(int i
, char **ret
);
441 int sshfp_algorithm_from_string(const char *s
) _pure_
;
443 int sshfp_key_type_to_string_alloc(int i
, char **ret
);
444 int sshfp_key_type_from_string(const char *s
) _pure_
;